Compare commits
240 Commits
drop-porta
...
wip/jtojna
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d3f85ae6ea | ||
![]() |
56265e91d6 | ||
![]() |
224ab2e543 | ||
![]() |
dee738e24f | ||
![]() |
84c7890917 | ||
![]() |
fd484099ae | ||
![]() |
727c84251d | ||
![]() |
37e55df298 | ||
![]() |
2644f62318 | ||
![]() |
893bde0ca1 | ||
![]() |
bd0bf3d3d0 | ||
![]() |
05c918dc1a | ||
![]() |
3651cb2047 | ||
![]() |
b9c7631a55 | ||
![]() |
b59c9c6946 | ||
![]() |
f02313c1c6 | ||
![]() |
6493789bc9 | ||
![]() |
4081b97462 | ||
![]() |
c20451c2e7 | ||
![]() |
16dcb1ac15 | ||
![]() |
c1ee656c35 | ||
![]() |
cd09144069 | ||
![]() |
7851069d9c | ||
![]() |
e42700a308 | ||
![]() |
febc0690c1 | ||
![]() |
308b4f81b5 | ||
![]() |
66a3ad42da | ||
![]() |
1b84a3ecb2 | ||
![]() |
78fd9d9e4f | ||
![]() |
baa5bfcf49 | ||
![]() |
5d88729fc1 | ||
![]() |
15b59414d6 | ||
![]() |
2b39d6e95a | ||
![]() |
73eaf0df9f | ||
![]() |
54e2d3ceb7 | ||
![]() |
d3cfb5801b | ||
![]() |
143cda628e | ||
![]() |
e90940ae10 | ||
![]() |
34207cc457 | ||
![]() |
cedcda0ccc | ||
![]() |
cfcf1d5192 | ||
![]() |
8d9bc4bc4c | ||
![]() |
d456e938d2 | ||
![]() |
f15208e26d | ||
![]() |
1999a359fa | ||
![]() |
3c180bc8f7 | ||
![]() |
8de42d1f63 | ||
![]() |
1769a96362 | ||
![]() |
37a3d0d09a | ||
![]() |
e16def0c43 | ||
![]() |
83d083f189 | ||
![]() |
b1ea4f6c35 | ||
![]() |
60c540e93a | ||
![]() |
f3b56e0eb1 | ||
![]() |
c8d02be14a | ||
![]() |
42b50051ac | ||
![]() |
bda18888c0 | ||
![]() |
c150fe95b9 | ||
![]() |
8b4b9d396b | ||
![]() |
9c0f069f86 | ||
![]() |
8929c89d1f | ||
![]() |
881eab7669 | ||
![]() |
141652b7ec | ||
![]() |
b5651e38c7 | ||
![]() |
33ae220ad2 | ||
![]() |
6ec996e45b | ||
![]() |
4f3e847897 | ||
![]() |
07a1f107cc | ||
![]() |
e062f27edc | ||
![]() |
36c417e6d9 | ||
![]() |
87ca1e034f | ||
![]() |
dbf1ffc9d4 | ||
![]() |
c5bed7e963 | ||
![]() |
fa915ff7ea | ||
![]() |
cbced1ce28 | ||
![]() |
900d36d0ea | ||
![]() |
62441ebeb4 | ||
![]() |
051f081db7 | ||
![]() |
ddbc4ef42e | ||
![]() |
fc4dfa11c3 | ||
![]() |
60f12da3cd | ||
![]() |
40f7d61524 | ||
![]() |
1263f84c3f | ||
![]() |
9d91b586d8 | ||
![]() |
ab8bce35f1 | ||
![]() |
7287ee3651 | ||
![]() |
9d7a319721 | ||
![]() |
b7df1133b8 | ||
![]() |
dfb8737007 | ||
![]() |
a06a418ac1 | ||
![]() |
35063c9e7c | ||
![]() |
ded4586781 | ||
![]() |
89790ac723 | ||
![]() |
d253b0671b | ||
![]() |
e58dcd3040 | ||
![]() |
050a1898ab | ||
![]() |
79a8fa2ede | ||
![]() |
7819f8f82e | ||
![]() |
5c570460cf | ||
![]() |
07882c4b6a | ||
![]() |
f26eb304f5 | ||
![]() |
7b33e240ed | ||
![]() |
a205f4e249 | ||
![]() |
e16c64dbdd | ||
![]() |
404ae0a897 | ||
![]() |
9e00e8a0fb | ||
![]() |
529829a561 | ||
![]() |
ed84541050 | ||
![]() |
075f4a5efc | ||
![]() |
f1bd94a367 | ||
![]() |
db69ad876a | ||
![]() |
c6f297e4e5 | ||
![]() |
1067642300 | ||
![]() |
059524b007 | ||
![]() |
1d72f28a1c | ||
![]() |
5b92e3a9a8 | ||
![]() |
8795668c41 | ||
![]() |
872c84a1c3 | ||
![]() |
b47879d0a7 | ||
![]() |
679fc20765 | ||
![]() |
db85e7084c | ||
![]() |
1afd2c6ad2 | ||
![]() |
a74a9f6443 | ||
![]() |
f49e20bbae | ||
![]() |
9916989272 | ||
![]() |
1054f7533a | ||
![]() |
5f457f6ed2 | ||
![]() |
9df2edc87e | ||
![]() |
28eb94402e | ||
![]() |
d2bf869c16 | ||
![]() |
05ea1bdac2 | ||
![]() |
454e85f0a9 | ||
![]() |
45c5f21f6c | ||
![]() |
59bd2dd1e3 | ||
![]() |
3c47923953 | ||
![]() |
dbaf5687dd | ||
![]() |
20895c7791 | ||
![]() |
ddeb2fa05d | ||
![]() |
7a1f4f9af3 | ||
![]() |
dc578a9e79 | ||
![]() |
040c1638ea | ||
![]() |
ded8412a2a | ||
![]() |
2f3738fae0 | ||
![]() |
a59da75830 | ||
![]() |
2b184a10d6 | ||
![]() |
fc36837606 | ||
![]() |
4871845d01 | ||
![]() |
53ac00eabb | ||
![]() |
75905ebd3c | ||
![]() |
12f033ee0f | ||
![]() |
964106513e | ||
![]() |
9aca26916c | ||
![]() |
5a006d9e79 | ||
![]() |
bd016c6b49 | ||
![]() |
484dd98448 | ||
![]() |
84d92bf65e | ||
![]() |
8d88a9b9c4 | ||
![]() |
b86ef8cde5 | ||
![]() |
bd48b0641f | ||
![]() |
0f4aeb2654 | ||
![]() |
0b3fec22d7 | ||
![]() |
9009b50bd1 | ||
![]() |
eee0657727 | ||
![]() |
056f5e5100 | ||
![]() |
5b2c604fe4 | ||
![]() |
db9ef11f28 | ||
![]() |
ea5732fe6f | ||
![]() |
b7e828fa3c | ||
![]() |
cbc9bc5fc6 | ||
![]() |
9c785ca6b6 | ||
![]() |
375d1892bf | ||
![]() |
2dae3f5656 | ||
![]() |
0a5d07871d | ||
![]() |
2490a2ffda | ||
![]() |
3eaa19ab0f | ||
![]() |
4c4846e9bd | ||
![]() |
747ba97dbd | ||
![]() |
74393c700e | ||
![]() |
3f21c21532 | ||
![]() |
526c601512 | ||
![]() |
6d2c834694 | ||
![]() |
0b51a52c9b | ||
![]() |
7224afd32a | ||
![]() |
d5dbc28f77 | ||
![]() |
2996d9d977 | ||
![]() |
eec25367fc | ||
![]() |
7388e4006a | ||
![]() |
6c1cd1d8be | ||
![]() |
5e08c80857 | ||
![]() |
26b78e7d77 | ||
![]() |
b674cdbde2 | ||
![]() |
68598f7c0c | ||
![]() |
ee7e62c9c8 | ||
![]() |
a750d04bdb | ||
![]() |
ef035c1b60 | ||
![]() |
854bd93385 | ||
![]() |
9c589297d5 | ||
![]() |
aae59801f1 | ||
![]() |
c95926aaed | ||
![]() |
c61685e617 | ||
![]() |
a0d49bad36 | ||
![]() |
2b89efab4e | ||
![]() |
eb8b82b62a | ||
![]() |
d9b3d6745c | ||
![]() |
c2956e8bd2 | ||
![]() |
397454d844 | ||
![]() |
7638485f9e | ||
![]() |
49170585b3 | ||
![]() |
88ac339774 | ||
![]() |
ed647f5937 | ||
![]() |
b49023c31c | ||
![]() |
9e9f3ff6b4 | ||
![]() |
b4cf07d05f | ||
![]() |
aba3336b51 | ||
![]() |
2cabef97b6 | ||
![]() |
4e26e0e53c | ||
![]() |
6eacbeb203 | ||
![]() |
84f490cceb | ||
![]() |
786aa8302d | ||
![]() |
b4ed8a3d06 | ||
![]() |
9f0ef0044d | ||
![]() |
5f3f4c3301 | ||
![]() |
1ef7306149 | ||
![]() |
e15d8eeb17 | ||
![]() |
1f7c99d9fb | ||
![]() |
f7620b385a | ||
![]() |
9746c00a22 | ||
![]() |
dc6f36bf5e | ||
![]() |
973c920284 | ||
![]() |
1dad5f3ffa | ||
![]() |
802c8d5844 | ||
![]() |
7781f973f2 | ||
![]() |
53c12dc33e | ||
![]() |
f46d10c4f9 | ||
![]() |
e573d739af | ||
![]() |
6c0c5f8ed4 | ||
![]() |
4333820f8e | ||
![]() |
ad2d95d523 | ||
![]() |
479c14c766 | ||
![]() |
56805a4c85 |
42
NEWS
42
NEWS
@@ -1,3 +1,45 @@
|
||||
3.35.90
|
||||
=======
|
||||
* Update default favorite apps [Michael; !907]
|
||||
* Add Shell.Blur effect [Georges; !864, !924]
|
||||
* Overhaul scroll/swipe gestures [Alexander; !821, !825, !826]
|
||||
* Fix VPN connections when delaying request [Florian; #2008]
|
||||
* Overhaul theme [Sam, Jakub, nana-4; !904, !931, !957]
|
||||
* Improve visual appearance of Weather integration [Florian; #1143]
|
||||
* Implement new system dialog designs [Jonas; #1343]
|
||||
* Animate position changes of app icons [Georges; !882]
|
||||
* Add St.Viewport [Georges; !929]
|
||||
* Make app folders behave as dialogs [Georges; !896]
|
||||
* Add do-not-disturb functionality to calendar popup [Florian; #239]
|
||||
* Show hint actor in focused entries [Jonas; !944]
|
||||
* Switch screen-recorder back to VP8 [Björn; #256]
|
||||
* Allow to run perf-tool as wayland compositor [Olivier; !941]
|
||||
* Handle extension updates [Florian; !945]
|
||||
* Animate showing and hiding caps-lock warning [Jonas; !952]
|
||||
* Support "auto" lengths in CSS [Florian; !971]
|
||||
* Turn extension-prefs into the offical Extensions app [Florian; #1968]
|
||||
* Sandbox the portal helper [Michael; !983]
|
||||
* Misc. bug fixes and cleanups [Florian, Björn, Jakub, Alexander, Daniel V.,
|
||||
Jonas, nana-4, Carlos, Sebastian, Daniel G., Georges, Piotr; !918, !917,
|
||||
!919, !920, #763, #791659, !927, #2091, !930, !926, !888, !934, !168, #2133,
|
||||
#682, #2142, #2131, !943, #2132, #1958, #2146, !951, #1779, #2130, !964,
|
||||
!965, !948, #2151, #1746, !967, !760, !968, !970, !973, #2169, #2176, !978,
|
||||
!980, !979, #2177, !981, #2180, !974]
|
||||
|
||||
Contributors:
|
||||
Michael Catanzaro, Björn Daase, Jonas Dreßler, Piotr Drąg, Olivier Fourdan,
|
||||
Carlos Garnacho, Sam Hewitt, Sebastian Keller, Andre Klapper,
|
||||
Alexander Mikhaylenko, Daniel García Moreno, Florian Müllner,
|
||||
Georges Basile Stavracas Neto, Jakub Steiner, Daniel van Vugt, nana-4
|
||||
|
||||
Translators:
|
||||
Asier Sarasua Garmendia [eu], Daniel Mustieles [es], Andrej Shadura [sk],
|
||||
Carmen Bianca BAKKER [eo], Sucipto [id], Dušan Kazik [sk], Goran Vidović [hr],
|
||||
sicklylife [ja], Kukuh Syafaat [id], Yi-Jyun Pan [zh_TW],
|
||||
Rafael Fontenelle [pt_BR], Jordi Mas [ca], Jiri Grönroos [fi],
|
||||
Fabio Tomat [fur], Umarzuki Bin Mochlis Moktar [ms], Daniel Korostil [uk],
|
||||
Jor Teron [mjw], Anders Jonsson [sv], Aurimas Černius [lt]
|
||||
|
||||
3.35.3
|
||||
======
|
||||
* Add discrete GPU support for NVidia drivers [Bastien; #1810]
|
||||
|
@@ -18,7 +18,6 @@
|
||||
<file alias="icons/message-indicator-symbolic.svg">message-indicator-symbolic.svg</file>
|
||||
<file>no-events.svg</file>
|
||||
<file>no-notifications.svg</file>
|
||||
<file>noise-texture.png</file>
|
||||
<file>pad-osd.css</file>
|
||||
<file alias="icons/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
|
||||
<file alias="icons/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
|
||||
|
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 128 128" version="1.1">
|
||||
<g id="surface43907">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(10.196079%,37.254903%,70.588237%);fill-opacity:1;" d="M 58.847656 15.683594 L 49.074219 30.632812 C 46.921875 33.84375 42.480469 36.65625 39.378906 35.300781 C 34.488281 33.164062 35.859375 28.144531 31.28125 25.292969 C 28.070312 23.292969 16.839844 20.449219 14.804688 27.644531 C 13.761719 31.339844 14.480469 37.410156 17.398438 41.019531 C 20.164062 44.441406 26.8125 43.355469 28.898438 47.230469 C 30.34375 49.925781 29.738281 51.628906 28.347656 54.351562 C 26.796875 57.375 22.839844 61.359375 19.265625 64.585938 C 17.480469 66.199219 13.273438 65.710938 12.03125 66.730469 C 11.753906 66.949219 12.511719 70.285156 12.511719 70.285156 C 12.511719 70.285156 19.90625 82.707031 25.539062 87.285156 C 27.773438 89.101562 30.089844 91.808594 32.742188 90.695312 C 36.035156 89.316406 35.304688 82.289062 37.644531 79.597656 C 41.976562 74.605469 50.292969 73.761719 55.582031 78.144531 C 61.277344 82.867188 60.882812 89.472656 57.941406 94.683594 C 55.175781 99.578125 49.472656 98.453125 47.484375 102.28125 C 46.730469 103.730469 47.578125 105.664062 48.765625 106.785156 C 54.628906 112.335938 71.210938 118.988281 71.210938 118.988281 L 81.605469 102.429688 C 83.757812 99.222656 86.707031 97.742188 90.011719 98.46875 C 94.605469 99.472656 95.160156 105.945312 98.914062 108.785156 C 103.195312 112.019531 110.546875 111.765625 114.351562 105.753906 C 117.128906 101.371094 116.761719 97.449219 113.765625 91.414062 C 111.808594 87.476562 103.253906 89.382812 101.171875 85.507812 C 99.722656 82.8125 99.992188 80.214844 101.859375 77.796875 C 106.332031 72 117.003906 62.699219 117.003906 62.699219 C 117.003906 62.699219 117.144531 60.824219 116.246094 59.363281 C 115.15625 57.589844 107.472656 49.273438 104.65625 46.984375 C 102.421875 45.167969 99.6875 41.921875 97.03125 43.035156 C 93.742188 44.414062 94.417969 51.058594 92.082031 53.753906 C 86.5 60.179688 78.4375 59.101562 73.914062 54.648438 C 68.644531 49.453125 68.511719 44.488281 71.453125 39.277344 C 74.222656 34.382812 79.921875 35.3125 81.910156 31.484375 C 82.664062 30.035156 81.484375 27.070312 80.597656 25.390625 C 79.277344 22.890625 65.976562 18.902344 58.847656 15.683594 Z M 58.847656 15.683594 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(20.784314%,51.764709%,89.411765%);fill-opacity:1;" d="M 58.089844 12.347656 L 48.316406 27.300781 C 46.164062 30.507812 41.726562 33.320312 38.625 31.964844 C 33.734375 29.828125 35.101562 24.808594 30.523438 21.960938 C 27.3125 19.957031 19.445312 19.160156 15.683594 25.625 C 13.730469 28.976562 13.722656 34.074219 16.644531 37.6875 C 19.410156 41.105469 26.058594 40.023438 28.140625 43.898438 C 29.589844 46.589844 28.984375 48.292969 27.589844 51.015625 C 24.492188 57.066406 11.753906 66.949219 11.753906 66.949219 C 11.753906 66.949219 19.148438 79.371094 24.785156 83.949219 C 27.019531 85.765625 29.332031 88.472656 31.988281 87.363281 C 35.277344 85.984375 34.550781 78.957031 36.886719 76.261719 C 41.21875 71.273438 49.535156 70.425781 54.824219 74.8125 C 60.519531 79.53125 60.125 86.140625 57.183594 91.347656 C 54.417969 96.242188 48.714844 95.117188 46.726562 98.949219 C 45.976562 100.398438 46.824219 102.328125 48.011719 103.449219 C 53.871094 109 70.457031 115.652344 70.457031 115.652344 L 80.847656 99.097656 C 83 95.886719 85.953125 94.40625 89.257812 95.132812 C 93.847656 96.140625 94.402344 102.609375 98.160156 105.449219 C 102.4375 108.683594 109.789062 108.433594 113.597656 102.421875 C 116.375 98.035156 116.152344 94.195312 112.175781 89.128906 C 109.460938 85.667969 102.496094 86.046875 100.414062 82.171875 C 98.96875 79.480469 99.234375 76.878906 101.101562 74.460938 C 105.578125 68.667969 116.246094 59.363281 116.246094 59.363281 C 116.246094 59.363281 109.535156 48.226562 103.898438 43.648438 C 101.664062 41.835938 98.929688 38.585938 96.277344 39.699219 C 92.988281 41.078125 93.660156 47.726562 91.324219 50.417969 C 85.746094 56.84375 77.679688 55.769531 73.15625 51.3125 C 67.886719 46.121094 67.757812 41.152344 70.699219 35.945312 C 73.464844 31.046875 79.164062 31.980469 81.152344 28.148438 C 81.90625 26.699219 80.066406 24.476562 78.878906 23.355469 C 73.015625 17.804688 58.089844 12.347656 58.089844 12.347656 Z M 58.089844 12.347656 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M6.5 1C5.669 1 5 1.669 5 2.5V4H2c-.554 0-1 .446-1 1v3h1.5C3.331 8 4 8.669 4 9.5S3.331 11 2.5 11H1v3c0 .554.446 1 1 1h3v-1.5c0-.831.669-1.5 1.5-1.5s1.5.669 1.5 1.5V15h3c.554 0 1-.446 1-1v-3h1.5c.831 0 1.5-.669 1.5-1.5S14.331 8 13.5 8H12V5c0-.554-.446-1-1-1H8V2.5C8 1.669 7.331 1 6.5 1z" style="isolation:auto;mix-blend-mode:normal;marker:none" color="#000" overflow="visible" fill="#474747"/></svg>
|
After Width: | Height: | Size: 469 B |
1
data/icons/meson.build
Normal file
1
data/icons/meson.build
Normal file
@@ -0,0 +1 @@
|
||||
install_subdir('hicolor', install_dir: icondir)
|
@@ -1,6 +1,6 @@
|
||||
desktop_files = [
|
||||
'org.gnome.Shell.desktop',
|
||||
'gnome-shell-extension-prefs.desktop'
|
||||
'org.gnome.Extensions.desktop',
|
||||
]
|
||||
service_files = []
|
||||
|
||||
@@ -43,6 +43,7 @@ endforeach
|
||||
|
||||
|
||||
subdir('dbus-interfaces')
|
||||
subdir('icons')
|
||||
subdir('theme')
|
||||
|
||||
data_resources = [
|
||||
|
@@ -1,8 +1,9 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Shell Extensions
|
||||
Name=Extensions
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
Icon=org.gnome.Extensions
|
||||
Comment=Configure GNOME Shell Extensions
|
||||
Exec=@bindir@/gnome-shell-extension-prefs %u
|
||||
Categories=GNOME;GTK;
|
||||
OnlyShowIn=GNOME;
|
||||
NoDisplay=true
|
@@ -91,13 +91,9 @@ stage {
|
||||
|
||||
// icon tiles
|
||||
%icon_tile {
|
||||
background-color: transparent; // no background
|
||||
color: $osd_fg_color;
|
||||
border-radius: $base_border_radius + 4px;
|
||||
padding: $base_padding;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border: 2px solid transparent;
|
||||
transition-duration: 100ms;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -155,14 +151,17 @@ stage {
|
||||
|
||||
|
||||
// notification styling
|
||||
%notification_bubble {
|
||||
@mixin notification_bubble($flat: false) {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius:$base_border_radius + 2px;
|
||||
padding: 0;
|
||||
border-radius: $base_border_radius + 2px;
|
||||
margin: $base_margin;
|
||||
|
||||
@include button(normal);
|
||||
@if $flat {
|
||||
@include button(undecorated);
|
||||
} @else {
|
||||
@include button(normal);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@include button(focus);
|
||||
|
@@ -137,7 +137,7 @@
|
||||
// normal button
|
||||
@if $t==normal {
|
||||
color: $tc;
|
||||
background-color: lighten($c, 3%) !important;
|
||||
background-color: lighten($c, 3%);
|
||||
border-color: draw_border_color($c);
|
||||
@include draw_shadows($button_shadow);
|
||||
// box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1);
|
||||
@@ -157,7 +157,7 @@
|
||||
// hover button
|
||||
@else if $t==hover {
|
||||
color: $tc;
|
||||
background-color: lighten($c, if($variant == 'light', 8%, 5%)) !important;
|
||||
background-color: lighten($c, if($variant == 'light', 8%, 5%));
|
||||
border-color: if($variant == 'light', draw_border_color(lighten($c, 7%)), draw_border_color($c));
|
||||
@include draw_shadows($button_shadow);
|
||||
text-shadow: 0 1px $text_shadow_color;
|
||||
@@ -167,7 +167,7 @@
|
||||
// active button
|
||||
@else if $t==active {
|
||||
color: $tc;
|
||||
background-color: darken($c,3%) !important;
|
||||
background-color: darken($c,3%);
|
||||
border-color: draw_border_color(if($variant == 'light', $c, darken($c,7%)));
|
||||
text-shadow: none;
|
||||
icon-shadow: none;
|
||||
@@ -178,7 +178,7 @@
|
||||
@else if $t==insensitive {
|
||||
color: $insensitive_fg_color;
|
||||
border-color: $insensitive_borders_color;
|
||||
background-color: $insensitive_bg_color !important;
|
||||
background-color: $insensitive_bg_color;
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
icon-shadow: none;
|
||||
@@ -194,3 +194,38 @@
|
||||
icon-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
// overview icons
|
||||
@mixin overview-icon($color) {
|
||||
.overview-icon {
|
||||
@extend %icon_tile;
|
||||
color: $color;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:selected {
|
||||
.overview-icon {
|
||||
background-color: transparentize($color, .9);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
.overview-icon {
|
||||
background-color: transparentize($color, .7);
|
||||
// border-color: $selected_bg_color;
|
||||
}
|
||||
}
|
||||
|
||||
&:drop {
|
||||
.overview-icon {
|
||||
background-color: transparentize($selected_bg_color, .15);
|
||||
}
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:checked {
|
||||
.overview-icon {
|
||||
background-color: transparentize(darken($osd_bg_color, 10%), .5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@
|
||||
@import 'widgets/corner-ripple';
|
||||
@import 'widgets/dash';
|
||||
@import 'widgets/dialogs';
|
||||
@import 'widgets/end-session-dialog';
|
||||
@import 'widgets/entries';
|
||||
@import 'widgets/hotplug';
|
||||
@import 'widgets/ibus-popup';
|
||||
@@ -36,4 +35,4 @@
|
||||
@import 'widgets/switches';
|
||||
@import 'widgets/tiled-previews';
|
||||
@import 'widgets/window-picker';
|
||||
@import 'widgets/workspace-switcher';
|
||||
@import 'widgets/workspace-switcher';
|
||||
|
@@ -11,7 +11,6 @@ $app_icon_padding: 24px;
|
||||
|
||||
.overview-icon {
|
||||
icon-size: $app_icon_size;
|
||||
StIcon { margin-bottom: $base_margin; } // margin on icon so label isn't close
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,47 +32,14 @@ $app_grid_fg_color: #fff;
|
||||
|
||||
// Icon tiles in the app grid
|
||||
.app-well-app,
|
||||
.app-folder {
|
||||
%app-well-app {
|
||||
@include overview-icon($app_grid_fg_color);
|
||||
|
||||
.overview-icon {
|
||||
@extend %icon_tile;
|
||||
color: $app_grid_fg_color !important;
|
||||
}
|
||||
.overview-icon.overview-icon-with-label {
|
||||
padding: 10px 8px 5px 8px;
|
||||
|
||||
&:selected {
|
||||
.overview-icon {
|
||||
background-color: transparentize($osd_bg_color,0.7);
|
||||
color: $app_grid_fg_color;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:selected {
|
||||
.overview-icon {
|
||||
background-color: transparentize($osd_fg_color,0.9);
|
||||
color: $osd_fg_color;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
.overview-icon {
|
||||
background-color: transparentize($osd_fg_color,0.7 );
|
||||
// border-color: $selected_bg_color;
|
||||
color: $app_grid_fg_color;
|
||||
}
|
||||
}
|
||||
|
||||
&:drop {
|
||||
.overview-icon {
|
||||
background-color: transparentize($selected_bg_color,.15);
|
||||
}
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:checked {
|
||||
.overview-icon {
|
||||
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
|
||||
> StBoxLayout {
|
||||
spacing: $base_spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,19 +47,52 @@ $app_grid_fg_color: #fff;
|
||||
/* App Folders */
|
||||
.app-folder {
|
||||
.overview-icon {
|
||||
@extend %icon_tile;
|
||||
}
|
||||
}
|
||||
|
||||
// expanded folder
|
||||
.app-folder-popup {
|
||||
-arrow-border-radius: 8px;
|
||||
-arrow-background-color: transparentize(darken($osd_bg_color,10%), 0.5);
|
||||
-arrow-base: 24px;
|
||||
-arrow-rise: 11px;
|
||||
}
|
||||
.app-folder-dialog {
|
||||
border-radius: $modal_radius * 1.5;
|
||||
border: 1px solid $osd_outer_borders_color;
|
||||
spacing: 12px;
|
||||
background-color: transparentize(darken($osd_bg_color,10%), 0.05);
|
||||
|
||||
.app-folder-popup-bin { padding: $base_padding - 1px; }
|
||||
& .folder-name-container {
|
||||
padding: 24px 36px 0;
|
||||
spacing: 12px;
|
||||
|
||||
& .folder-name-label,
|
||||
& .folder-name-entry {
|
||||
font-size: 18pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .folder-name-entry { width: 300px }
|
||||
|
||||
/* FIXME: this is to keep the label in sync with the entry */
|
||||
& .folder-name-label { padding: 5px 7px }
|
||||
|
||||
& .edit-folder-button {
|
||||
@extend %button;
|
||||
|
||||
padding: 0;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
|
||||
& > StIcon { icon-size: 16px }
|
||||
}
|
||||
}
|
||||
|
||||
& StButton#vhandle,
|
||||
& StButton#vhandle:hover,
|
||||
& StButton#vhandle:active { background-color: transparent; }
|
||||
}
|
||||
.app-folder-dialog-container {
|
||||
padding: 12px;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.app-folder-icon {
|
||||
padding: $base_padding;
|
||||
@@ -144,11 +143,6 @@ $app_grid_fg_color: #fff;
|
||||
padding: 0px 88px 10px 88px;
|
||||
}
|
||||
|
||||
.app-well-app > .overview-icon.overview-icon-with-label {
|
||||
padding: 10px 8px 5px 8px;
|
||||
spacing: $base_spacing;
|
||||
}
|
||||
|
||||
// Label when no frequent apps
|
||||
.no-frequent-applications-label { @extend %status_text; }
|
||||
|
||||
@@ -168,41 +162,35 @@ $app_grid_fg_color: #fff;
|
||||
}
|
||||
|
||||
// buttons
|
||||
.app-view-control {
|
||||
padding: $base_padding $base_padding*5;
|
||||
margin: 0;
|
||||
background-color: transparentize($osd_bg_color, 0.5);
|
||||
border-width: 1px;
|
||||
color: darken($osd_fg_color, 25%);
|
||||
.app-view-control {
|
||||
padding: 4px 32px;
|
||||
margin: 0 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: transparentize($osd_bg_color, 0.5) !important;
|
||||
box-shadow:none !important;
|
||||
&, &:hover, &:checked {
|
||||
@include button(undecorated);
|
||||
color: darken($osd_fg_color, 25%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $osd_fg_color;
|
||||
box-shadow: inset 0 -2px darken($osd_fg_color, 25%);
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
background-color: $selected_bg_color !important;
|
||||
&:hover {
|
||||
background-color: lighten($selected_bg_color, 11%) !important;
|
||||
}
|
||||
box-shadow: inset 0 -2px $osd_fg_color;
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background-color: $selected_bg_color !important;
|
||||
color: $selected_fg_color;
|
||||
box-shadow: none;
|
||||
&:active { background-color: darken($selected_bg_color, 4%) !important; }
|
||||
&:hover { background-color: lighten($selected_bg_color, 7%) !important; }
|
||||
color: $osd_fg_color;
|
||||
box-shadow: inset 0 -2px $selected_bg_color;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-right-width: 0 !important;
|
||||
border-radius: $base_border_radius 0 0 $base_border_radius;
|
||||
border-right-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 $base_border_radius $base_border_radius 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,85 +1,58 @@
|
||||
/* Date/Time Menu */
|
||||
|
||||
.clock-display-box { spacing: $base_spacing; }
|
||||
|
||||
// overall menu
|
||||
#calendarArea {
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
// Calendar menu side column
|
||||
.datemenu-calendar-column {
|
||||
spacing: 0;
|
||||
spacing: $base_spacing;
|
||||
border: 0 solid $bubble_borders_color;
|
||||
padding: $base_padding * 2;
|
||||
padding-bottom: 3em; // account for the notifications clear button
|
||||
padding-top:0;
|
||||
padding: 0 $base_padding * 2;
|
||||
|
||||
&:ltr {margin-right: $base_margin * 2; border-left-width: 1px; }
|
||||
&:rtl {margin-left: $base_margin * 2; border-right-width: 1px; }
|
||||
|
||||
// today button (the date)
|
||||
.datemenu-today-button {
|
||||
padding: $base_padding * 1.5;
|
||||
margin: $base_margin;
|
||||
border: 1px solid transparent;
|
||||
border-radius: $base_border_radius + 2px;
|
||||
|
||||
&:hover { @include button(hover);}
|
||||
&:focus { @include button(focus);}
|
||||
|
||||
&:active {
|
||||
@include button(active);
|
||||
}
|
||||
|
||||
// weekday label
|
||||
.day-label {
|
||||
@include fontsize($base_font_size+1);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
// date label
|
||||
.date-label {
|
||||
@include fontsize($base_font_size+7);
|
||||
font-weight: 1000;
|
||||
}
|
||||
}
|
||||
|
||||
// calendar
|
||||
.calendar {
|
||||
@extend %notification_bubble;
|
||||
margin:$base_margin !important;
|
||||
margin-bottom: $base_padding + $base_margin !important;
|
||||
padding:$base_padding !important;
|
||||
|
||||
// more below for sub-elements
|
||||
}
|
||||
|
||||
.datemenu-displays-section {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.datemenu-displays-box {
|
||||
spacing: $base_spacing;
|
||||
margin:0;
|
||||
|
||||
// world clocks and weather
|
||||
.world-clocks-button,
|
||||
.weather-button {
|
||||
@extend %notification_bubble;
|
||||
padding:$base_padding !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.events-section-title {
|
||||
@include notification_bubble($flat: true);
|
||||
color: desaturate(darken($fg_color,40%), 10%);
|
||||
font-weight: bold;
|
||||
border-radius: 4px;
|
||||
padding: .4em;
|
||||
}
|
||||
|
||||
/* today button (the date) */
|
||||
.datemenu-today-button {
|
||||
@include notification_bubble($flat: true);
|
||||
padding: $base_padding * 1.5;
|
||||
|
||||
// weekday label
|
||||
.day-label {
|
||||
@include fontsize($base_font_size+1);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
// date label
|
||||
.date-label {
|
||||
@include fontsize($base_font_size+7);
|
||||
font-weight: 1000;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calendar */
|
||||
.calendar {
|
||||
@include notification_bubble;
|
||||
padding: $base_padding;
|
||||
|
||||
// month
|
||||
.calendar-month-label {
|
||||
@@ -130,6 +103,7 @@
|
||||
@include fontsize($base_font_size - 4);
|
||||
}
|
||||
}
|
||||
|
||||
.calendar-day { //border collapse hack - see calendar.js
|
||||
border-width: 0;
|
||||
}
|
||||
@@ -138,8 +112,12 @@
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.calendar-day-left { border-left-width: 1px; }
|
||||
.calendar-day-left {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.calendar-work-day {}
|
||||
|
||||
.calendar-nonwork-day {
|
||||
color: $insensitive_fg_color;
|
||||
}
|
||||
@@ -159,13 +137,14 @@
|
||||
&:active,&:selected {
|
||||
background-color: $selected_bg_color;
|
||||
color: $selected_fg_color;
|
||||
|
||||
&:hover,&:focus {
|
||||
background-color:lighten($selected_bg_color, 3%);
|
||||
color: $selected_fg_color;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.calendar-day-with-events {
|
||||
color: lighten($fg_color,10%);
|
||||
font-weight: bold;
|
||||
@@ -174,7 +153,6 @@
|
||||
|
||||
.calendar-other-month-day {
|
||||
color: transparentize($fg_color ,0.5);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.calendar-week-number {
|
||||
@@ -190,51 +168,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* World clocks */
|
||||
.world-clocks-button {
|
||||
@include notification_bubble;
|
||||
padding: $base_padding * 2;
|
||||
|
||||
/* Weather */
|
||||
.weather-box {
|
||||
spacing: $base_spacing;
|
||||
padding:$base_padding;
|
||||
|
||||
.weather-header {
|
||||
color: desaturate(darken($fg_color,40%), 10%);
|
||||
font-weight: bold;
|
||||
&.location {
|
||||
font-weight: normal;
|
||||
@include fontsize($base_font_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
.weather-grid {
|
||||
margin-top: $base_margin;
|
||||
.world-clocks-grid {
|
||||
spacing-rows: $base_spacing;
|
||||
spacing-columns: $base_spacing * 2;
|
||||
}
|
||||
|
||||
.weather-forecast-time {
|
||||
color: darken($fg_color,30%);
|
||||
font-feature-settings: "tnum";
|
||||
@include fontsize($base_font_size - 2);
|
||||
font-weight: normal;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.4em;
|
||||
}
|
||||
|
||||
.weather-forecast-icon {
|
||||
icon-size: $base_icon_size * 2;
|
||||
}
|
||||
|
||||
.weather-forecast-temp {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
/* World clocks */
|
||||
.world-clocks-grid {
|
||||
padding:$base_padding;
|
||||
spacing-rows: $base_spacing;
|
||||
spacing-columns: $base_spacing * 2;
|
||||
|
||||
// title
|
||||
.world-clocks-header {
|
||||
color: desaturate(darken($fg_color,40%), 10%);
|
||||
@@ -263,4 +206,50 @@
|
||||
font-feature-settings: "tnum";
|
||||
@include fontsize($base_font_size - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Weather */
|
||||
.weather-button {
|
||||
@include notification_bubble;
|
||||
padding: $base_padding * 2;
|
||||
|
||||
.weather-box {
|
||||
spacing: $base_spacing + $base_margin;
|
||||
}
|
||||
|
||||
.weather-header-box {
|
||||
spacing: $base_spacing;
|
||||
}
|
||||
|
||||
.weather-header {
|
||||
color: desaturate(darken($fg_color,40%), 10%);
|
||||
font-weight: bold;
|
||||
|
||||
&.location {
|
||||
font-weight: normal;
|
||||
@include fontsize($base_font_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
.weather-grid {
|
||||
spacing-rows: $base_spacing;
|
||||
spacing-columns: $base_spacing * 2;
|
||||
}
|
||||
|
||||
.weather-forecast-time {
|
||||
color: darken($fg_color,30%);
|
||||
font-feature-settings: "tnum";
|
||||
@include fontsize($base_font_size - 2);
|
||||
font-weight: normal;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.4em;
|
||||
}
|
||||
|
||||
.weather-forecast-icon {
|
||||
icon-size: $base_icon_size * 2;
|
||||
}
|
||||
|
||||
.weather-forecast-temp {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
@@ -9,12 +9,11 @@ $dash_border_radius: $modal_radius * 1.5;
|
||||
@include fontsize($base_font_size - 2);
|
||||
padding: ($dash_spacing / 2) 0;
|
||||
|
||||
//fixme: can't have non uniform borders :(
|
||||
border-radius: 0 $dash_border_radius $dash_border_radius 0;
|
||||
border-left-width: 0 !important;
|
||||
&:rtl {
|
||||
border-left-width: 0;
|
||||
&:rtl {
|
||||
border-radius: $dash_border_radius 0 0 $dash_border_radius;
|
||||
border-right-width: 0 !important;
|
||||
border-right-width: 0;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
@@ -42,7 +41,6 @@ $dash_border_radius: $modal_radius * 1.5;
|
||||
border:none;
|
||||
box-shadow:0 0 0 1px $osd_outer_borders_color;
|
||||
color: $osd_fg_color;
|
||||
margin-top: $base_margin + 4px;
|
||||
padding: $base_padding $base_padding + 2px;
|
||||
text-align: center;
|
||||
-x-offset: $base_margin * 2; // distance from the dash edge
|
||||
@@ -50,36 +48,13 @@ $dash_border_radius: $modal_radius * 1.5;
|
||||
|
||||
// Show apps button
|
||||
.show-apps {
|
||||
color: $osd_fg_color;
|
||||
@include overview-icon($osd_fg_color);
|
||||
|
||||
& .overview-icon {
|
||||
@extend %icon_tile;
|
||||
color: $osd_fg_color;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:selected {
|
||||
.overview-icon {
|
||||
background-color: transparentize($osd_fg_color,0.9);
|
||||
color: $osd_fg_color;
|
||||
}
|
||||
}
|
||||
|
||||
&:drop .overview-icon {
|
||||
background-color: transparentize($selected_bg_color,.15);
|
||||
}
|
||||
|
||||
&:active, &:checked {
|
||||
&:checked {
|
||||
.overview-icon {
|
||||
background-color: darken($osd_bg_color,10%);
|
||||
}
|
||||
}
|
||||
|
||||
&:checked, &:focus {
|
||||
.show-apps-icon {
|
||||
color: $fg_color;
|
||||
transition-duration: 100ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,17 @@
|
||||
@include fontsize($base_font_size + 3);
|
||||
}
|
||||
|
||||
/* End Session Dialog */
|
||||
|
||||
.end-session-dialog {
|
||||
width: 30em;
|
||||
|
||||
.end-session-dialog-battery-warning,
|
||||
.dialog-list-title {
|
||||
color: $warning_color;
|
||||
}
|
||||
}
|
||||
|
||||
/* Message Dialog */
|
||||
.message-dialog-content {
|
||||
spacing: 18px;
|
||||
@@ -58,177 +69,79 @@
|
||||
|
||||
/* Run Dialog */
|
||||
.run-dialog {
|
||||
.run-dialog-entry { width: 20em; margin-bottom: 6px; }
|
||||
.run-dialog-error-box {
|
||||
padding-top: 16px;
|
||||
spacing: 6px;
|
||||
.modal-dialog-content-box {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.run-dialog-label {
|
||||
@include fontsize($base_font_size + 1.1);
|
||||
font-weight: normal;
|
||||
color: $fg_color;
|
||||
padding-bottom: .4em;
|
||||
.run-dialog-entry { width: 20em; }
|
||||
.run-dialog-description {
|
||||
@include fontsize($base_font_size - 1);
|
||||
text-align: center;
|
||||
color: darken($fg_color, 20%);
|
||||
}
|
||||
}
|
||||
|
||||
/* ShellMountOperation Dialogs */
|
||||
.shell-mount-operation-icon {
|
||||
icon-size: $base_icon_size * 3;
|
||||
}
|
||||
|
||||
.mount-dialog {
|
||||
spacing: 24px;
|
||||
|
||||
.message-dialog-title {
|
||||
padding-top: 10px;
|
||||
padding-left: 17px;
|
||||
padding-bottom: 6px;
|
||||
max-width: 34em;
|
||||
}
|
||||
|
||||
.message-dialog-title:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px;
|
||||
}
|
||||
|
||||
.message-dialog-description {
|
||||
padding-left: 17px;
|
||||
width: 28em;
|
||||
}
|
||||
|
||||
.message-dialog-description:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.mount-dialog-app-list {
|
||||
max-height: 200px;
|
||||
padding-top: 24px;
|
||||
padding-left: 49px;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
.mount-dialog-app-list:rtl {
|
||||
padding-right: 49px;
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
.mount-dialog-app-list-item {
|
||||
color: lighten($fg_color,10%);
|
||||
&:hover { color: $fg_color; }
|
||||
&:ltr { padding-right: 1em; }
|
||||
&:rtl { padding-left: 1em; }
|
||||
}
|
||||
|
||||
.mount-dialog-app-list-item-icon {
|
||||
&:ltr { padding-right: 17px; }
|
||||
&:rtl { padding-left: 17px; }
|
||||
}
|
||||
|
||||
.mount-dialog-app-list-item-name {
|
||||
@include fontsize($base_font_size - 1);
|
||||
}
|
||||
|
||||
|
||||
/* Password or Authentication Dialog */
|
||||
|
||||
.prompt-dialog {
|
||||
//this is the width of the entire modal popup
|
||||
width: 34em;
|
||||
width: 28em;
|
||||
|
||||
.message-dialog-content { spacing: $base_spacing * 4; }
|
||||
.message-dialog-title { color: lighten($fg_color,15%); }
|
||||
.modal-dialog-content-box {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.prompt-dialog-description:rtl {
|
||||
text-align: right;
|
||||
.prompt-dialog-password-grid {
|
||||
spacing-rows: 8px;
|
||||
spacing-columns: 4px;
|
||||
|
||||
.prompt-dialog-password-entry {
|
||||
width: auto;
|
||||
|
||||
// 4px (spacing) + 16px (spinner-width)
|
||||
&:ltr { margin-left: 20px; }
|
||||
&:rtl { margin-right: 20px; }
|
||||
}
|
||||
}
|
||||
|
||||
.prompt-dialog-password-box {
|
||||
spacing: 1em;
|
||||
padding-bottom: 1em;
|
||||
.prompt-dialog-password-layout {
|
||||
spacing: 8px;
|
||||
}
|
||||
|
||||
.prompt-dialog-password-entry {
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.prompt-dialog-error-label,
|
||||
.prompt-dialog-info-label,
|
||||
.prompt-dialog-null-label {
|
||||
text-align: center;
|
||||
@include fontsize($base_font_size - 1);
|
||||
}
|
||||
|
||||
.prompt-dialog-error-label {
|
||||
@include fontsize($base_font_size - 1);
|
||||
color: $warning_color;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.prompt-dialog-info-label {
|
||||
@include fontsize($base_font_size - 1);
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.prompt-dialog-null-label {
|
||||
@include fontsize($base_font_size - 1);
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.prompt-dialog-pim-box {
|
||||
spacing: 1em;
|
||||
}
|
||||
|
||||
.prompt-dialog-grid {
|
||||
spacing-rows: 15px;
|
||||
spacing-columns: 1em;
|
||||
}
|
||||
|
||||
.prompt-dialog-keyfiles-box {
|
||||
spacing: 1em;
|
||||
}
|
||||
|
||||
.prompt-dialog-button.button {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.prompt-dialog-caps-lock-warning {
|
||||
@extend .prompt-dialog-error-label;
|
||||
padding-left: 6.2em;
|
||||
}
|
||||
|
||||
|
||||
/* Polkit Dialog */
|
||||
|
||||
.polkit-dialog-user-layout {
|
||||
padding-left: 10px;
|
||||
spacing: 10px;
|
||||
&:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 10px;
|
||||
text-align: center;
|
||||
spacing: 8px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
.polkit-dialog-user-icon {
|
||||
border-radius: 99px;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.polkit-dialog-user-root-label {
|
||||
color: $warning_color;
|
||||
}
|
||||
|
||||
.polkit-dialog-user-icon {
|
||||
border-radius: 99px;
|
||||
background-size: contain;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
.polkit-dialog-user-root-label { color: $warning_color; }
|
||||
}
|
||||
|
||||
/* Audio selection dialog */
|
||||
.audio-device-selection-dialog {
|
||||
spacing: 30px;
|
||||
}
|
||||
|
||||
.audio-selection-content {
|
||||
spacing: 20px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.audio-selection-title {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.audio-selection-box {
|
||||
spacing: 20px;
|
||||
.modal-dialog-content-box { margin-bottom: 28px; }
|
||||
.audio-selection-box { spacing: 20px; }
|
||||
}
|
||||
|
||||
.audio-selection-device {
|
||||
@@ -254,30 +167,3 @@
|
||||
.access-dialog {
|
||||
spacing: 30px;
|
||||
}
|
||||
|
||||
/* Geolocation Dialog */
|
||||
.geolocation-dialog {
|
||||
spacing: 30px;
|
||||
}
|
||||
|
||||
/* Extension Dialog */
|
||||
.extension-dialog {
|
||||
.message-dialog-title { font-weight: normal; color: $fg_color; }
|
||||
}
|
||||
|
||||
/* Inhibit-Shortcuts Dialog */
|
||||
.inhibit-shortcuts-dialog {
|
||||
spacing: 30px;
|
||||
}
|
||||
|
||||
/* Network Agent Dialog */
|
||||
|
||||
.network-dialog-secret-table {
|
||||
spacing-rows: 15px;
|
||||
spacing-columns: 1em;
|
||||
}
|
||||
|
||||
.keyring-dialog-control-table {
|
||||
spacing-rows: 15px;
|
||||
spacing-columns: 1em;
|
||||
}
|
||||
|
@@ -1,12 +0,0 @@
|
||||
/* End Session Dialog */
|
||||
|
||||
$end_session_dialog_width: 28em;
|
||||
|
||||
.end-session-dialog-battery-warning {
|
||||
width: $end_session_dialog_width;
|
||||
color: $warning_color;
|
||||
}
|
||||
|
||||
.end-session-dialog .dialog-list-title {
|
||||
color: $warning_color;
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
|
||||
StEntry {
|
||||
border-radius: $base_border_radius;
|
||||
padding: 4px;
|
||||
padding: 8px;
|
||||
border-width: 1px;
|
||||
color: $fg_color;
|
||||
@include entry(normal);
|
||||
@@ -20,4 +20,8 @@ StEntry {
|
||||
icon-size: $base_icon_size;
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
StLabel.hint-text {
|
||||
margin-left: 2px;
|
||||
color: transparentize($fg_color, 0.3);
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
|
||||
// draw keys using button function
|
||||
#keyboard {
|
||||
background-color: transparentize(if($variant=='light', darken($bg_color, 5%), darken($bg_color, 8%)), 0.1);
|
||||
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color !important;
|
||||
box-shadow: inset 0 1px 0 0 $osd_outer_borders_color;
|
||||
|
||||
.page-indicator {
|
||||
padding: $base_padding;
|
||||
@@ -121,4 +121,4 @@ $default_key_bg_color: if($variant=='light', darken($osd_bg_color, 11%), lighten
|
||||
@include fontsize($base_font_size + 3);
|
||||
spacing: 12px;
|
||||
min-height: 20pt;
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
.message-list-sections {
|
||||
spacing: $base_spacing;
|
||||
margin: $base_margin * 4; // to account for scrollbar
|
||||
margin: 0 $base_margin * 4; // to account for scrollbar
|
||||
}
|
||||
|
||||
.message-list-section,
|
||||
@@ -19,39 +19,61 @@
|
||||
spacing: $base_spacing;
|
||||
}
|
||||
|
||||
.message-list-section-list {
|
||||
&:ltr {padding:0;}
|
||||
&:rtl {padding:0;}
|
||||
}
|
||||
|
||||
// clear button
|
||||
.message-list-clear-button.button {
|
||||
margin:$base_margin $base_margin*2;
|
||||
// do-not-disturb + clear button
|
||||
.message-list-controls {
|
||||
margin: ($base_margin * 2) ($base_margin * 4) 0;
|
||||
// NOTE: remove the padding if notification_bubble could remove margin for drop shadow
|
||||
padding: $base_margin;
|
||||
spacing: $base_spacing;
|
||||
}
|
||||
|
||||
// message bubbles
|
||||
.message {
|
||||
@extend %notification_bubble;
|
||||
@include notification_bubble;
|
||||
|
||||
// title
|
||||
.message-title {
|
||||
color: $fg_color;
|
||||
font-weight: bold;
|
||||
margin-bottom:4px;
|
||||
// icon container
|
||||
.message-icon-bin {
|
||||
padding: ($base_padding * 3) 0 ($base_padding * 3) ($base_padding * 2);
|
||||
|
||||
&:rtl {
|
||||
padding: ($base_padding * 3) ($base_padding * 2) ($base_padding * 3) 0;
|
||||
}
|
||||
|
||||
// icon size and color
|
||||
> StIcon {
|
||||
icon-size: $base_icon_size*2; // 32px
|
||||
-st-icon-style: symbolic;
|
||||
}
|
||||
|
||||
// fallback
|
||||
> .fallback-app-icon {
|
||||
width: $base_icon_size;
|
||||
height: $base_icon_size;
|
||||
}
|
||||
}
|
||||
|
||||
// content
|
||||
.message-content {
|
||||
color: darken($fg_color, 10%);
|
||||
padding: $base_padding 0;
|
||||
margin:$base_margin * 2;
|
||||
&:ltr {
|
||||
margin-left: $base_margin;
|
||||
padding-right:$base_padding;
|
||||
}
|
||||
&:rtl {
|
||||
margin-right: $base_margin;
|
||||
padding-left:$base_padding;
|
||||
padding: $base_padding + $base_margin * 2;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
// title
|
||||
.message-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
// secondary container in title box
|
||||
.message-secondary-bin {
|
||||
padding: 0 $base_margin * 2;
|
||||
|
||||
// notification time stamp
|
||||
> .event-time {
|
||||
color: transparentize($fg_color, 0.5);
|
||||
@include fontsize($base_font_size - 2);
|
||||
text-align: right;
|
||||
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
|
||||
padding-bottom: 0.13em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,48 +84,10 @@
|
||||
&:active { color: if($variant=='light', lighten($fg_color, 40%), darken($fg_color, 20%)); }
|
||||
}
|
||||
|
||||
|
||||
// icon container
|
||||
.message-icon-bin {
|
||||
padding: $base_padding;
|
||||
margin:$base_padding 0;
|
||||
|
||||
&:rtl {
|
||||
// padding: $base_padding;
|
||||
}
|
||||
|
||||
// icon size and color
|
||||
> StIcon {
|
||||
color: $fg_color;
|
||||
icon-size: $base_icon_size*2; // 32px
|
||||
-st-icon-style: symbolic;
|
||||
|
||||
padding:0;
|
||||
margin:$base_padding;
|
||||
}
|
||||
|
||||
// fallback
|
||||
> .fallback-window-icon {
|
||||
width: $base_icon_size;
|
||||
height: $base_icon_size;
|
||||
}
|
||||
// body
|
||||
.message-body {
|
||||
color: darken($fg_color, 10%);
|
||||
}
|
||||
|
||||
// secondary container in title box
|
||||
.message-secondary-bin {
|
||||
padding: 0;
|
||||
|
||||
// notification time stamp
|
||||
> .event-time {
|
||||
color: transparentize($fg_color, 0.5);
|
||||
@include fontsize($base_font_size - 2);
|
||||
text-align: right;
|
||||
margin: 0 $base_margin * 2;
|
||||
/* HACK: the label should be baseline-aligned with a 1em label, fake this with some bottom padding */
|
||||
padding-bottom: $base_padding;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Media Controls */
|
||||
@@ -124,9 +108,9 @@
|
||||
|
||||
&:insensitive { color: darken($fg_color,40%); }
|
||||
|
||||
// fix border-radius for last button on hover
|
||||
&:last-child:ltr { &:hover {border-radius: 0 $base_border_radius+2 $base_border_radius+2 0;} }
|
||||
&:last-child:rtl { &:hover {border-radius: $base_border_radius+2 0 0 $base_border_radius+2;} }
|
||||
// fix border-radius for last button
|
||||
&:last-child:ltr { border-radius: 0 $base_border_radius+2 $base_border_radius+2 0; }
|
||||
&:last-child:rtl { border-radius: $base_border_radius+2 0 0 $base_border_radius+2; }
|
||||
}
|
||||
|
||||
// album-art
|
||||
@@ -141,6 +125,5 @@
|
||||
border: 1px solid transparent;
|
||||
border-radius: $base_border_radius;
|
||||
icon-size: $base_icon_size * 2 !important;
|
||||
padding: $base_padding * 2;
|
||||
}
|
||||
}
|
||||
|
@@ -56,4 +56,12 @@
|
||||
|
||||
|
||||
// Hidden
|
||||
.hidden { color: rgba(0,0,0,0);}
|
||||
.hidden { color: rgba(0,0,0,0);}
|
||||
|
||||
// Caps-lock warning
|
||||
.caps-lock-warning-label {
|
||||
text-align: center;
|
||||
padding-bottom: 8px;
|
||||
@include fontsize($base_font_size - 1);
|
||||
color: $warning_color;
|
||||
}
|
||||
|
@@ -7,39 +7,8 @@ $notification_banner_width: 34em;
|
||||
.notification-banner {
|
||||
min-height: $notification_banner_height;
|
||||
width: $notification_banner_width;
|
||||
@include fontsize($base_font_size);
|
||||
margin: $base_margin;
|
||||
border-radius: $modal_radius;
|
||||
|
||||
.message-title { color: $fg_color }
|
||||
.message-content { color: $fg_color; }
|
||||
|
||||
&:hover { background: $bg_color; }
|
||||
&, &:focus, &:active {
|
||||
background-color: $bg_color;
|
||||
.message-title { color: $fg_color }
|
||||
.message-content { color: $fg_color; }
|
||||
}
|
||||
|
||||
// icon
|
||||
.message-icon-bin > StIcon {
|
||||
icon-size: $base_icon_size * 2;
|
||||
color: $fg_color;
|
||||
}
|
||||
|
||||
.notification-icon {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.notification-content {
|
||||
padding: 5px;
|
||||
spacing: 5px;
|
||||
}
|
||||
|
||||
.secondary-icon { icon-size: $base_icon_size; }
|
||||
|
||||
.notification-actions {
|
||||
padding-top: 0;
|
||||
spacing: 0;
|
||||
}
|
||||
|
||||
@@ -63,8 +32,6 @@ $notification_banner_width: 34em;
|
||||
border-radius: 0.9em; // should be 0.8 but whatever; wish I could do 50%;
|
||||
}
|
||||
|
||||
.secondary-icon { icon-size: $base_icon_size; }
|
||||
|
||||
// chat bubbles
|
||||
.chat-body { spacing: 5px; }
|
||||
.chat-response { margin: 5px; }
|
||||
@@ -87,4 +54,4 @@ $notification_banner_width: 34em;
|
||||
font-weight: bold;
|
||||
color: lighten($fg_color,18%);
|
||||
&:rtl { padding-left: 0; padding-right: 4px; }
|
||||
}
|
||||
}
|
||||
|
@@ -15,8 +15,7 @@ $panel_height: 1.86em;
|
||||
|
||||
// transparent panel on lock & login screens
|
||||
&.unlock-screen,
|
||||
&.login-screen,
|
||||
&.lock-screen {
|
||||
&.login-screen {
|
||||
background-color: transparent;
|
||||
|
||||
.panel-corner {
|
||||
@@ -77,8 +76,7 @@ $panel_height: 1.86em;
|
||||
|
||||
// lock & login screen styles
|
||||
.unlock-screen &,
|
||||
.login-screen &,
|
||||
.lock-screen & {
|
||||
.login-screen & {
|
||||
color: lighten($fg_color, 10%);
|
||||
&:focus, &:hover, &:active { color: lighten($fg_color, 10%); }
|
||||
}
|
||||
|
@@ -87,7 +87,6 @@ $popover_arrow_height: 12px;
|
||||
height: 1px; //not really the whole box
|
||||
margin: 6px 64px;
|
||||
background-color: lighten($borders_color, 2%);
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
// desktop background menu
|
||||
@@ -118,4 +117,4 @@ $popover_arrow_height: 12px;
|
||||
margin-right: $base_icon_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,68 +1,53 @@
|
||||
/* Screen Shield */
|
||||
|
||||
$_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
|
||||
|
||||
.screen-shield-arrows {
|
||||
padding-bottom: 3em;
|
||||
}
|
||||
|
||||
.screen-shield-arrows Gjs_Arrow {
|
||||
.unlock-dialog-clock {
|
||||
color: white;
|
||||
width: 80px;
|
||||
height: 48px;
|
||||
-arrow-thickness: 12px;
|
||||
-arrow-shadow: $_screenshield_shadow;
|
||||
}
|
||||
|
||||
.screen-shield-clock {
|
||||
color: white;
|
||||
text-shadow: $_screenshield_shadow;
|
||||
font-weight: bold;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
padding-bottom: 1.5em;
|
||||
padding-bottom: 2.5em;
|
||||
}
|
||||
|
||||
.screen-shield-clock-time {
|
||||
font-size: 72pt;
|
||||
text-shadow: $_screenshield_shadow;
|
||||
.unlock-dialog-clock-time {
|
||||
font-size: 64pt;
|
||||
padding-bottom: 24px;
|
||||
font-feature-settings: "tnum";
|
||||
}
|
||||
|
||||
.screen-shield-clock-date {
|
||||
font-size: 28pt;
|
||||
.unlock-dialog-clock-date {
|
||||
font-size: 16pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.screen-shield-notifications-container {
|
||||
.unlock-dialog-notifications-container {
|
||||
margin: 12px 0;
|
||||
spacing: 6px;
|
||||
width: 30em;
|
||||
width: 23em;
|
||||
background-color: transparent;
|
||||
max-height: 500px;
|
||||
.summary-notification-stack-scrollview {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.notification,
|
||||
.screen-shield-notification-source {
|
||||
.unlock-dialog-notification-source {
|
||||
padding: 12px 6px;
|
||||
border: 1px solid $osd_outer_borders_color;
|
||||
background-color: transparentize($osd_bg_color,0.5);
|
||||
color: $osd_fg_color;
|
||||
border-radius: 4px;
|
||||
|
||||
&.critical { background-color: transparentize($osd_bg_color,0.1) }
|
||||
}
|
||||
.notification { margin-right: 15px; } //compensate for space allocated to the scrollbar
|
||||
}
|
||||
|
||||
|
||||
.screen-shield-notification-label {
|
||||
font-weight: bold;
|
||||
.unlock-dialog-notification-label {
|
||||
padding: 0px 0px 0px 12px;
|
||||
}
|
||||
|
||||
.screen-shield-notification-count-text { padding: 0px 0px 0px 12px; }
|
||||
|
||||
#panel.lock-screen { background-color: transparentize($osd_bg_color, 0.5); }
|
||||
.unlock-dialog-notification-count-text {
|
||||
weight: bold;
|
||||
padding: 0px 12px;
|
||||
}
|
||||
|
||||
.screen-shield-background { //just the shadow, really
|
||||
background: black;
|
||||
@@ -70,14 +55,13 @@ $_screenshield_shadow: 0px 0px 6px rgba(0, 0, 0, 0.726);
|
||||
}
|
||||
|
||||
#lockDialogGroup {
|
||||
background: lighten(#2e3436, 8%) url(resource:///org/gnome/shell/theme/noise-texture.png);
|
||||
background-repeat: repeat;
|
||||
background-color: lighten(#2e3436, 8%);
|
||||
}
|
||||
|
||||
#screenShieldNotifications {
|
||||
#unlockDialogNotifications {
|
||||
StButton#vhandle, StButton#hhandle {
|
||||
background-color: transparentize($bg_color,0.7);
|
||||
&:hover, &:focus { background-color: transparentize($bg_color,0.5); }
|
||||
&:active { background-color: transparentize($selected_bg_color,0.5); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,19 +3,16 @@
|
||||
// search overview container
|
||||
#searchResultsContent {
|
||||
max-width: 1024px;
|
||||
spacing: $base_margin * 2;
|
||||
}
|
||||
|
||||
// search results sections "the boxes"
|
||||
.search-section {
|
||||
// This should be equal to #searchResultsContent spacing
|
||||
spacing: $base_margin * 2;
|
||||
padding:0 !important;
|
||||
margin:0 !important;
|
||||
background-color:transparent;
|
||||
box-shadow:none;
|
||||
border:none;
|
||||
|
||||
// separator
|
||||
.search-section-separator {
|
||||
// margin-top: $base_padding * 2;
|
||||
// height: 1px;
|
||||
// background-color: $osd_outer_borders_color;
|
||||
height: 0;
|
||||
@@ -32,8 +29,24 @@
|
||||
text-shadow: 0 1px if($variant == 'light', rgba(255,255,255,0.2), rgba(0,0,0,0.2));
|
||||
color: $osd_fg_color;
|
||||
padding: $base_padding * 3;
|
||||
margin: $base_margin 0;
|
||||
spacing: 0;
|
||||
// This is the space between the provider icon and the results container
|
||||
spacing: $base_margin * 2;
|
||||
}
|
||||
|
||||
%search-section-content-item {
|
||||
@extend %icon_tile;
|
||||
|
||||
&:focus,
|
||||
&:hover,
|
||||
&:selected {
|
||||
background-color: transparentize($osd_fg_color, .9);
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:checked {
|
||||
background-color: transparentize(darken($osd_bg_color, 10%), .1);
|
||||
}
|
||||
}
|
||||
|
||||
// "no results" text
|
||||
@@ -43,54 +56,12 @@
|
||||
|
||||
// Search results with icons
|
||||
.grid-search-result {
|
||||
> .overview-icon {
|
||||
@extend %icon_tile;
|
||||
color: $osd_fg_color;
|
||||
}
|
||||
|
||||
> .overview-icon.overview-icon-with-label {
|
||||
padding: 10px 8px 5px 8px;
|
||||
spacing: $base_spacing;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:selected {
|
||||
.overview-icon {
|
||||
background-color: transparentize($osd_bg_color,0.8);
|
||||
color: $osd_fg_color;
|
||||
}
|
||||
}
|
||||
|
||||
&:drop .overview-icon {
|
||||
background-color: transparentize($selected_bg_color,.15);
|
||||
}
|
||||
|
||||
&:active .overview-icon,
|
||||
&:checked .overview-icon {
|
||||
background-color: transparentize(darken($osd_bg_color,10%), 0.5);
|
||||
}
|
||||
@extend %app-well-app;
|
||||
}
|
||||
|
||||
// search result provider
|
||||
.search-provider-icon {
|
||||
@extend %icon_tile;
|
||||
|
||||
padding: $base_padding;
|
||||
spacing: 0;
|
||||
margin-right: $base_margin * 2;
|
||||
|
||||
&:focus,
|
||||
&:selected,
|
||||
&:hover {
|
||||
background-color: transparentize($osd_fg_color,.9);
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:checked {
|
||||
background-color: transparentize(darken($osd_bg_color,10%),.1);
|
||||
}
|
||||
@extend %search-section-content-item;
|
||||
|
||||
// content
|
||||
.list-search-provider-content {
|
||||
@@ -113,34 +84,16 @@
|
||||
|
||||
// search result listitem
|
||||
.list-search-result {
|
||||
@extend %icon_tile;
|
||||
spacing: 0;
|
||||
padding: $base_padding;
|
||||
color: $osd_fg_color;
|
||||
|
||||
border-radius: $base_border_radius + 2px !important;
|
||||
|
||||
&:focus,
|
||||
&:selected,
|
||||
&:hover {
|
||||
background-color: transparentize($osd_fg_color,.9);
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
&:active,
|
||||
&:checked {
|
||||
background-color: transparentize(darken($osd_bg_color,10%),.1);
|
||||
}
|
||||
@extend %search-section-content-item;
|
||||
|
||||
// content
|
||||
.list-search-result-content {
|
||||
spacing: 0;
|
||||
spacing: $base_padding;
|
||||
}
|
||||
|
||||
// list item title
|
||||
// list item title (with leading icon)
|
||||
.list-search-result-title {
|
||||
color: $osd_fg_color;
|
||||
spacing: $base_spacing * 2;
|
||||
padding-right: $base_padding;
|
||||
// font-weight: bold;
|
||||
}
|
||||
|
||||
|
@@ -45,14 +45,11 @@
|
||||
padding: $base_padding;
|
||||
|
||||
border-radius: $modal_radius 0 0 $modal_radius;
|
||||
border-right-width: 0 !important;
|
||||
//fixme: can't have non uniform borders :(
|
||||
border-top-left-radius:0 !important;
|
||||
border-bottom-left-radius:0 !important;
|
||||
border-right-width: 0;
|
||||
|
||||
&:rtl {
|
||||
&:rtl {
|
||||
border-radius: 0 $modal_radius $modal_radius 0;
|
||||
border-left-width: 0 !important;
|
||||
border-left-width: 0;
|
||||
}
|
||||
|
||||
// drag and drop indicator
|
||||
@@ -69,4 +66,4 @@
|
||||
border-radius: 3px;
|
||||
padding: 0px;
|
||||
// background-color: transparentize($selected_bg_color, 0.9);
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,6 @@ theme_sources = files([
|
||||
'gnome-shell-sass/widgets/_corner-ripple.scss',
|
||||
'gnome-shell-sass/widgets/_dash.scss',
|
||||
'gnome-shell-sass/widgets/_dialogs.scss',
|
||||
'gnome-shell-sass/widgets/_end-session-dialog.scss',
|
||||
'gnome-shell-sass/widgets/_entries.scss',
|
||||
'gnome-shell-sass/widgets/_hotplug.scss',
|
||||
'gnome-shell-sass/widgets/_ibus-popup.scss',
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 78 KiB |
11
js/extensionPrefs/css/application.css
Normal file
11
js/extensionPrefs/css/application.css
Normal file
@@ -0,0 +1,11 @@
|
||||
.details-button image {
|
||||
transition: 250ms;
|
||||
}
|
||||
.details-button.expanded:dir(ltr) image {
|
||||
-gtk-icon-transform: rotate(0.25turn);
|
||||
}
|
||||
.details-button.expanded:dir(rtl) image {
|
||||
-gtk-icon-transform: rotate(-0.25turn);
|
||||
}
|
||||
|
||||
image.warning { color: @warning_color; }
|
@@ -3,15 +3,16 @@ imports.gi.versions.Gdk = '3.0';
|
||||
imports.gi.versions.Gtk = '3.0';
|
||||
|
||||
const Gettext = imports.gettext;
|
||||
const { Gdk, GLib, Gio, GObject, Gtk, Pango } = imports.gi;
|
||||
const { Gdk, GLib, Gio, GObject, Gtk } = imports.gi;
|
||||
const Format = imports.format;
|
||||
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
const { ExtensionState } = ExtensionUtils;
|
||||
const { ExtensionState, ExtensionType } = ExtensionUtils;
|
||||
|
||||
const GnomeShellIface = loadInterfaceXML('org.gnome.Shell.Extensions');
|
||||
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
|
||||
@@ -27,26 +28,144 @@ class Application extends Gtk.Application {
|
||||
_init() {
|
||||
GLib.set_prgname('gnome-shell-extension-prefs');
|
||||
super._init({
|
||||
application_id: 'org.gnome.shell.ExtensionPrefs',
|
||||
application_id: 'org.gnome.Extensions',
|
||||
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
|
||||
});
|
||||
|
||||
this._startupUuid = null;
|
||||
this._loaded = false;
|
||||
this._skipMainWindow = false;
|
||||
this._shellProxy = null;
|
||||
}
|
||||
|
||||
get shellProxy() {
|
||||
return this._shellProxy;
|
||||
}
|
||||
|
||||
_showPrefs(uuid) {
|
||||
let row = this._extensionSelector.get_children().find(c => {
|
||||
return c.uuid === uuid && c.hasPrefs;
|
||||
vfunc_activate() {
|
||||
this._shellProxy.CheckForUpdatesRemote();
|
||||
this._window.present();
|
||||
}
|
||||
|
||||
vfunc_startup() {
|
||||
super.vfunc_startup();
|
||||
|
||||
let provider = new Gtk.CssProvider();
|
||||
let uri = 'resource:///org/gnome/shell/css/application.css';
|
||||
try {
|
||||
provider.load_from_file(Gio.File.new_for_uri(uri));
|
||||
} catch (e) {
|
||||
logError(e, 'Failed to add application style');
|
||||
}
|
||||
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
|
||||
provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
|
||||
this._window = new ExtensionsWindow({ application: this });
|
||||
}
|
||||
|
||||
vfunc_command_line(commandLine) {
|
||||
let args = commandLine.get_arguments();
|
||||
|
||||
if (args.length) {
|
||||
let uuid = args[0];
|
||||
|
||||
// Strip off "extension:///" prefix which fakes a URI, if it exists
|
||||
uuid = stripPrefix(uuid, 'extension:///');
|
||||
|
||||
this._window.openPrefs(uuid);
|
||||
} else {
|
||||
this.activate();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
var ExtensionsWindow = GObject.registerClass({
|
||||
GTypeName: 'ExtensionsWindow',
|
||||
Template: 'resource:///org/gnome/shell/ui/extensions-window.ui',
|
||||
InternalChildren: [
|
||||
'userList',
|
||||
'systemList',
|
||||
'killSwitch',
|
||||
'mainBox',
|
||||
'mainStack',
|
||||
'scrolledWindow',
|
||||
'updatesBar',
|
||||
'updatesLabel',
|
||||
],
|
||||
}, class ExtensionsWindow extends Gtk.ApplicationWindow {
|
||||
_init(params) {
|
||||
super._init(params);
|
||||
|
||||
this._startupUuid = null;
|
||||
this._loaded = false;
|
||||
this._prefsDialog = null;
|
||||
this._updatesCheckId = 0;
|
||||
|
||||
this._mainBox.set_focus_vadjustment(this._scrolledWindow.vadjustment);
|
||||
|
||||
let action;
|
||||
action = new Gio.SimpleAction({ name: 'show-about' });
|
||||
action.connect('activate', this._showAbout.bind(this));
|
||||
this.add_action(action);
|
||||
|
||||
action = new Gio.SimpleAction({ name: 'logout' });
|
||||
action.connect('activate', this._logout.bind(this));
|
||||
this.add_action(action);
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
|
||||
this._settings.bind('disable-user-extensions',
|
||||
this._killSwitch, 'active',
|
||||
Gio.SettingsBindFlags.DEFAULT | Gio.SettingsBindFlags.INVERT_BOOLEAN);
|
||||
|
||||
this._userList.set_sort_func(this._sortList.bind(this));
|
||||
this._userList.set_header_func(this._updateHeader.bind(this));
|
||||
|
||||
this._systemList.set_sort_func(this._sortList.bind(this));
|
||||
this._systemList.set_header_func(this._updateHeader.bind(this));
|
||||
|
||||
this._shellProxy.connectSignal('ExtensionStateChanged',
|
||||
this._onExtensionStateChanged.bind(this));
|
||||
|
||||
this._scanExtensions();
|
||||
}
|
||||
|
||||
get _shellProxy() {
|
||||
return this.application.shellProxy;
|
||||
}
|
||||
|
||||
uninstall(uuid) {
|
||||
let row = this._findExtensionRow(uuid);
|
||||
|
||||
let dialog = new Gtk.MessageDialog({
|
||||
transient_for: this,
|
||||
modal: true,
|
||||
text: _('Remove “%s”?').format(row.name),
|
||||
secondary_text: _('If you remove the extension, you need to return to download it if you want to enable it again'),
|
||||
});
|
||||
|
||||
if (!row)
|
||||
dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL);
|
||||
dialog.add_button(_('Remove'), Gtk.ResponseType.ACCEPT)
|
||||
.get_style_context().add_class('destructive-action');
|
||||
|
||||
dialog.connect('response', (dlg, response) => {
|
||||
if (response === Gtk.ResponseType.ACCEPT)
|
||||
this._shellProxy.UninstallExtensionRemote(uuid);
|
||||
dialog.destroy();
|
||||
});
|
||||
dialog.present();
|
||||
}
|
||||
|
||||
openPrefs(uuid) {
|
||||
if (!this._loaded)
|
||||
this._startupUuid = uuid;
|
||||
else if (!this._showPrefs(uuid))
|
||||
this.present();
|
||||
}
|
||||
|
||||
_showPrefs(uuid) {
|
||||
if (this._prefsDialog)
|
||||
return false;
|
||||
|
||||
let row = this._findExtensionRow(uuid);
|
||||
if (!row || !row.hasPrefs)
|
||||
return false;
|
||||
|
||||
let widget;
|
||||
@@ -57,33 +176,73 @@ class Application extends Gtk.Application {
|
||||
widget = this._buildErrorUI(row, e);
|
||||
}
|
||||
|
||||
let dialog = new Gtk.Window({
|
||||
modal: !this._skipMainWindow,
|
||||
this._prefsDialog = new Gtk.Window({
|
||||
application: this.application,
|
||||
default_width: 600,
|
||||
default_height: 400,
|
||||
modal: this.visible,
|
||||
type_hint: Gdk.WindowTypeHint.DIALOG,
|
||||
window_position: Gtk.WindowPosition.CENTER,
|
||||
});
|
||||
dialog.set_titlebar(new Gtk.HeaderBar({
|
||||
|
||||
this._prefsDialog.set_titlebar(new Gtk.HeaderBar({
|
||||
show_close_button: true,
|
||||
title: row.name,
|
||||
visible: true,
|
||||
}));
|
||||
|
||||
if (this._skipMainWindow) {
|
||||
this.add_window(dialog);
|
||||
if (this._window)
|
||||
this._window.destroy();
|
||||
this._window = dialog;
|
||||
this._window.window_position = Gtk.WindowPosition.CENTER;
|
||||
} else {
|
||||
dialog.transient_for = this._window;
|
||||
}
|
||||
if (this.visible)
|
||||
this._prefsDialog.transient_for = this;
|
||||
|
||||
dialog.set_default_size(600, 400);
|
||||
dialog.add(widget);
|
||||
dialog.show();
|
||||
this._prefsDialog.connect('destroy', () => {
|
||||
this._prefsDialog = null;
|
||||
|
||||
if (!this.visible)
|
||||
this.destroy();
|
||||
});
|
||||
|
||||
this._prefsDialog.add(widget);
|
||||
this._prefsDialog.show();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_showAbout() {
|
||||
let aboutDialog = new Gtk.AboutDialog({
|
||||
authors: [
|
||||
'Florian Müllner <fmuellner@gnome.org>',
|
||||
'Jasper St. Pierre <jstpierre@mecheye.net>',
|
||||
'Didier Roche <didrocks@ubuntu.com>',
|
||||
],
|
||||
translator_credits: _('translator-credits'),
|
||||
program_name: _('Extensions'),
|
||||
comments: _('Manage your GNOME Extensions'),
|
||||
license_type: Gtk.License.GPL_2_0,
|
||||
logo_icon_name: 'org.gnome.Extensions',
|
||||
version: Config.PACKAGE_VERSION,
|
||||
|
||||
transient_for: this,
|
||||
modal: true,
|
||||
});
|
||||
aboutDialog.present();
|
||||
}
|
||||
|
||||
_logout() {
|
||||
this.application.get_dbus_connection().call(
|
||||
'org.gnome.SessionManager',
|
||||
'/org/gnome/SessionManager',
|
||||
'org.gnome.SessionManager',
|
||||
'Logout',
|
||||
new GLib.Variant('(u)', [0]),
|
||||
null,
|
||||
Gio.DBusCallFlags.NONE,
|
||||
-1,
|
||||
null,
|
||||
(o, res) => {
|
||||
o.call_finish(res);
|
||||
});
|
||||
}
|
||||
|
||||
_buildErrorUI(row, exc) {
|
||||
let scroll = new Gtk.ScrolledWindow({
|
||||
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||
@@ -178,7 +337,7 @@ class Application extends Gtk.Application {
|
||||
label: _("Homepage"),
|
||||
tooltip_text: _("Visit extension homepage"),
|
||||
no_show_all: true,
|
||||
visible: row.url != null,
|
||||
visible: row.url !== '',
|
||||
});
|
||||
toolbar.add(urlButton);
|
||||
|
||||
@@ -199,47 +358,6 @@ class Application extends Gtk.Application {
|
||||
return scroll;
|
||||
}
|
||||
|
||||
_buildUI() {
|
||||
this._window = new Gtk.ApplicationWindow({ application: this,
|
||||
window_position: Gtk.WindowPosition.CENTER });
|
||||
|
||||
this._window.set_default_size(800, 500);
|
||||
|
||||
this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
|
||||
title: _("Shell Extensions") });
|
||||
this._window.set_titlebar(this._titlebar);
|
||||
|
||||
let killSwitch = new Gtk.Switch({ valign: Gtk.Align.CENTER });
|
||||
this._titlebar.pack_end(killSwitch);
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
|
||||
this._settings.bind('disable-user-extensions', killSwitch, 'active',
|
||||
Gio.SettingsBindFlags.DEFAULT |
|
||||
Gio.SettingsBindFlags.INVERT_BOOLEAN);
|
||||
|
||||
this._mainStack = new Gtk.Stack({
|
||||
transition_type: Gtk.StackTransitionType.CROSSFADE,
|
||||
});
|
||||
this._window.add(this._mainStack);
|
||||
|
||||
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||
|
||||
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
|
||||
this._extensionSelector.set_sort_func(this._sortList.bind(this));
|
||||
this._extensionSelector.set_header_func(this._updateHeader.bind(this));
|
||||
|
||||
scroll.add(this._extensionSelector);
|
||||
|
||||
this._mainStack.add_named(scroll, 'listing');
|
||||
this._mainStack.add_named(new EmptyPlaceholder(), 'placeholder');
|
||||
|
||||
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
|
||||
this._shellProxy.connectSignal('ExtensionStateChanged',
|
||||
this._onExtensionStateChanged.bind(this));
|
||||
|
||||
this._window.show_all();
|
||||
}
|
||||
|
||||
_sortList(row1, row2) {
|
||||
return row1.name.localeCompare(row2.name);
|
||||
}
|
||||
@@ -253,13 +371,26 @@ class Application extends Gtk.Application {
|
||||
}
|
||||
|
||||
_findExtensionRow(uuid) {
|
||||
return this._extensionSelector.get_children().find(c => c.uuid === uuid);
|
||||
return [
|
||||
...this._userList.get_children(),
|
||||
...this._systemList.get_children(),
|
||||
].find(c => c.uuid === uuid);
|
||||
}
|
||||
|
||||
_onExtensionStateChanged(proxy, senderName, [uuid, newState]) {
|
||||
let extension = ExtensionUtils.deserializeExtension(newState);
|
||||
let row = this._findExtensionRow(uuid);
|
||||
|
||||
this._queueUpdatesCheck();
|
||||
|
||||
// the extension's type changed; remove the corresponding row
|
||||
// and reset the variable to null so that we create a new row
|
||||
// below and add it to the appropriate list
|
||||
if (row && row.type !== extension.type) {
|
||||
row.destroy();
|
||||
row = null;
|
||||
}
|
||||
|
||||
if (row) {
|
||||
if (extension.state === ExtensionState.UNINSTALLED)
|
||||
row.destroy();
|
||||
@@ -273,7 +404,6 @@ class Application extends Gtk.Application {
|
||||
if (e) {
|
||||
if (e instanceof Gio.DBusError) {
|
||||
log(`Failed to connect to shell proxy: ${e}`);
|
||||
this._mainStack.add_named(new NoShellPlaceholder(), 'noshell');
|
||||
this._mainStack.visible_child_name = 'noshell';
|
||||
} else {
|
||||
throw e;
|
||||
@@ -291,58 +421,53 @@ class Application extends Gtk.Application {
|
||||
|
||||
_addExtensionRow(extension) {
|
||||
let row = new ExtensionRow(extension);
|
||||
|
||||
row.prefsButton.connect('clicked', () => {
|
||||
this._showPrefs(row.uuid);
|
||||
});
|
||||
|
||||
row.show_all();
|
||||
this._extensionSelector.add(row);
|
||||
|
||||
if (row.type === ExtensionType.PER_USER)
|
||||
this._userList.add(row);
|
||||
else
|
||||
this._systemList.add(row);
|
||||
}
|
||||
|
||||
_queueUpdatesCheck() {
|
||||
if (this._updatesCheckId)
|
||||
return;
|
||||
|
||||
this._updatesCheckId = GLib.timeout_add_seconds(
|
||||
GLib.PRIORITY_DEFAULT, 1, () => {
|
||||
this._checkUpdates();
|
||||
|
||||
this._updatesCheckId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
_checkUpdates() {
|
||||
let nUpdates = this._userList.get_children().filter(c => c.hasUpdate).length;
|
||||
|
||||
this._updatesLabel.label = Gettext.ngettext(
|
||||
'%d extension will be updated on next login.',
|
||||
'%d extensions will be updated on next login.',
|
||||
nUpdates).format(nUpdates);
|
||||
this._updatesBar.visible = nUpdates > 0;
|
||||
}
|
||||
|
||||
_extensionsLoaded() {
|
||||
if (this._extensionSelector.get_children().length > 0)
|
||||
this._mainStack.visible_child_name = 'listing';
|
||||
this._userList.visible = this._userList.get_children().length > 0;
|
||||
this._systemList.visible = this._systemList.get_children().length > 0;
|
||||
|
||||
if (this._userList.visible || this._systemList.visible)
|
||||
this._mainStack.visible_child_name = 'main';
|
||||
else
|
||||
this._mainStack.visible_child_name = 'placeholder';
|
||||
|
||||
this._checkUpdates();
|
||||
|
||||
if (this._startupUuid)
|
||||
this._showPrefs(this._startupUuid);
|
||||
this._startupUuid = null;
|
||||
this._skipMainWindow = false;
|
||||
this._loaded = true;
|
||||
}
|
||||
|
||||
vfunc_activate() {
|
||||
this._window.present();
|
||||
}
|
||||
|
||||
vfunc_startup() {
|
||||
super.vfunc_startup();
|
||||
|
||||
this._buildUI();
|
||||
this._scanExtensions();
|
||||
}
|
||||
|
||||
vfunc_command_line(commandLine) {
|
||||
this.activate();
|
||||
let args = commandLine.get_arguments();
|
||||
|
||||
if (args.length) {
|
||||
let uuid = args[0];
|
||||
|
||||
this._skipMainWindow = true;
|
||||
|
||||
// Strip off "extension:///" prefix which fakes a URI, if it exists
|
||||
uuid = stripPrefix(uuid, "extension:///");
|
||||
|
||||
if (!this._loaded)
|
||||
this._startupUuid = uuid;
|
||||
else if (!this._showPrefs(uuid))
|
||||
this._skipMainWindow = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
var Expander = GObject.registerClass({
|
||||
@@ -444,113 +569,19 @@ var Expander = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var EmptyPlaceholder = GObject.registerClass(
|
||||
class EmptyPlaceholder extends Gtk.Box {
|
||||
_init() {
|
||||
super._init({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 6,
|
||||
margin: 32,
|
||||
});
|
||||
|
||||
let image = new Gtk.Image({
|
||||
icon_name: 'application-x-addon-symbolic',
|
||||
pixel_size: 96,
|
||||
visible: true,
|
||||
vexpand: true,
|
||||
valign: Gtk.Align.END,
|
||||
});
|
||||
image.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
|
||||
this.add(image);
|
||||
|
||||
let label = new Gtk.Label({
|
||||
label: `<b><span size="x-large">${_("No Extensions Installed")}</span></b>`,
|
||||
use_markup: true,
|
||||
visible: true,
|
||||
});
|
||||
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
|
||||
this.add(label);
|
||||
|
||||
let appInfo = Gio.DesktopAppInfo.new('org.gnome.Software.desktop');
|
||||
|
||||
let desc = new Gtk.Label({
|
||||
label: _("Extensions can be installed through Software or <a href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."),
|
||||
use_markup: true,
|
||||
wrap: true,
|
||||
justify: Gtk.Justification.CENTER,
|
||||
visible: true,
|
||||
max_width_chars: 50,
|
||||
hexpand: true,
|
||||
vexpand: appInfo == null,
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.START,
|
||||
});
|
||||
this.add(desc);
|
||||
|
||||
if (appInfo) {
|
||||
let button = new Gtk.Button({
|
||||
label: _("Browse in Software"),
|
||||
image: new Gtk.Image({
|
||||
icon_name: "org.gnome.Software-symbolic",
|
||||
}),
|
||||
always_show_image: true,
|
||||
margin_top: 12,
|
||||
visible: true,
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.START,
|
||||
vexpand: true,
|
||||
});
|
||||
this.add(button);
|
||||
|
||||
button.connect('clicked', w => {
|
||||
let context = w.get_display().get_app_launch_context();
|
||||
appInfo.launch([], context);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var NoShellPlaceholder = GObject.registerClass(
|
||||
class NoShellPlaceholder extends Gtk.Box {
|
||||
_init() {
|
||||
super._init({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 12,
|
||||
margin: 100,
|
||||
margin_bottom: 60,
|
||||
});
|
||||
|
||||
let label = new Gtk.Label({
|
||||
label: '<span size="x-large">%s</span>'.format(
|
||||
_("Something’s gone wrong")),
|
||||
use_markup: true,
|
||||
});
|
||||
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
|
||||
this.add(label);
|
||||
|
||||
label = new Gtk.Label({
|
||||
label: _("We’re very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again."),
|
||||
justify: Gtk.Justification.CENTER,
|
||||
wrap: true,
|
||||
});
|
||||
this.add(label);
|
||||
|
||||
this.show_all();
|
||||
}
|
||||
});
|
||||
|
||||
var DescriptionLabel = GObject.registerClass(
|
||||
class DescriptionLabel extends Gtk.Label {
|
||||
vfunc_get_preferred_height_for_width(width) {
|
||||
// Hack: Request the maximum height allowed by the line limit
|
||||
if (this.lines > 0)
|
||||
return super.vfunc_get_preferred_height_for_width(0);
|
||||
return super.vfunc_get_preferred_height_for_width(width);
|
||||
}
|
||||
});
|
||||
|
||||
var ExtensionRow = GObject.registerClass(
|
||||
class ExtensionRow extends Gtk.ListBoxRow {
|
||||
var ExtensionRow = GObject.registerClass({
|
||||
GTypeName: 'ExtensionRow',
|
||||
Template: 'resource:///org/gnome/shell/ui/extension-row.ui',
|
||||
InternalChildren: [
|
||||
'nameLabel',
|
||||
'descriptionLabel',
|
||||
'versionLabel',
|
||||
'authorLabel',
|
||||
'updatesIcon',
|
||||
'revealButton',
|
||||
'revealer',
|
||||
],
|
||||
}, class ExtensionRow extends Gtk.ListBoxRow {
|
||||
_init(extension) {
|
||||
super._init();
|
||||
|
||||
@@ -558,9 +589,67 @@ class ExtensionRow extends Gtk.ListBoxRow {
|
||||
this._extension = extension;
|
||||
this._prefsModule = null;
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
this._actionGroup = new Gio.SimpleActionGroup();
|
||||
this.insert_action_group('row', this._actionGroup);
|
||||
|
||||
this._buildUI();
|
||||
let action;
|
||||
action = new Gio.SimpleAction({
|
||||
name: 'show-prefs',
|
||||
enabled: this.hasPrefs,
|
||||
});
|
||||
action.connect('activate', () => this.get_toplevel().openPrefs(this.uuid));
|
||||
this._actionGroup.add_action(action);
|
||||
|
||||
action = new Gio.SimpleAction({
|
||||
name: 'show-url',
|
||||
enabled: this.url !== '',
|
||||
});
|
||||
action.connect('activate', () => {
|
||||
Gio.AppInfo.launch_default_for_uri(
|
||||
this.url, this.get_display().get_app_launch_context());
|
||||
});
|
||||
this._actionGroup.add_action(action);
|
||||
|
||||
action = new Gio.SimpleAction({
|
||||
name: 'uninstall',
|
||||
enabled: this.type === ExtensionType.PER_USER,
|
||||
});
|
||||
action.connect('activate', () => this.get_toplevel().uninstall(this.uuid));
|
||||
this._actionGroup.add_action(action);
|
||||
|
||||
action = new Gio.SimpleAction({
|
||||
name: 'enabled',
|
||||
state: new GLib.Variant('b', false),
|
||||
});
|
||||
action.connect('activate', () => {
|
||||
let state = action.get_state();
|
||||
action.change_state(new GLib.Variant('b', !state.get_boolean()));
|
||||
});
|
||||
action.connect('change-state', (a, state) => {
|
||||
if (state.get_boolean())
|
||||
this._app.shellProxy.EnableExtensionRemote(this.uuid);
|
||||
else
|
||||
this._app.shellProxy.DisableExtensionRemote(this.uuid);
|
||||
});
|
||||
this._actionGroup.add_action(action);
|
||||
|
||||
let name = GLib.markup_escape_text(this.name, -1);
|
||||
this._nameLabel.label = name;
|
||||
|
||||
let desc = this._extension.metadata.description.split('\n')[0];
|
||||
this._descriptionLabel.label = desc;
|
||||
|
||||
this._revealButton.connect('clicked', () => {
|
||||
this._revealer.reveal_child = !this._revealer.reveal_child;
|
||||
});
|
||||
this._revealer.connect('notify::reveal-child', () => {
|
||||
if (this._revealer.reveal_child)
|
||||
this._revealButton.get_style_context().add_class('expanded');
|
||||
else
|
||||
this._revealButton.get_style_context().remove_class('expanded');
|
||||
});
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._extensionStateChangedId = this._app.shellProxy.connectSignal(
|
||||
'ExtensionStateChanged', (p, sender, [uuid, newState]) => {
|
||||
@@ -568,14 +657,9 @@ class ExtensionRow extends Gtk.ListBoxRow {
|
||||
return;
|
||||
|
||||
this._extension = ExtensionUtils.deserializeExtension(newState);
|
||||
let state = this._extension.state == ExtensionState.ENABLED;
|
||||
|
||||
this._switch.block_signal_handler(this._notifyActiveId);
|
||||
this._switch.state = state;
|
||||
this._switch.unblock_signal_handler(this._notifyActiveId);
|
||||
|
||||
this._switch.sensitive = this._canToggle();
|
||||
this._updateState();
|
||||
});
|
||||
this._updateState();
|
||||
}
|
||||
|
||||
get uuid() {
|
||||
@@ -590,8 +674,40 @@ class ExtensionRow extends Gtk.ListBoxRow {
|
||||
return this._extension.hasPrefs;
|
||||
}
|
||||
|
||||
get hasUpdate() {
|
||||
return this._extension.hasUpdate || false;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this._extension.type;
|
||||
}
|
||||
|
||||
get creator() {
|
||||
return this._extension.metadata.creator || '';
|
||||
}
|
||||
|
||||
get url() {
|
||||
return this._extension.metadata.url;
|
||||
return this._extension.metadata.url || '';
|
||||
}
|
||||
|
||||
get version() {
|
||||
return this._extension.metadata.version || '';
|
||||
}
|
||||
|
||||
_updateState() {
|
||||
let state = this._extension.state === ExtensionState.ENABLED;
|
||||
|
||||
let action = this._actionGroup.lookup('enabled');
|
||||
action.set_state(new GLib.Variant('b', state));
|
||||
action.enabled = this._canToggle();
|
||||
|
||||
this._updatesIcon.visible = this.hasUpdate;
|
||||
|
||||
this._versionLabel.label = `${this.version}`;
|
||||
this._versionLabel.visible = this.version !== '';
|
||||
|
||||
this._authorLabel.label = `${this.creator}`;
|
||||
this._authorLabel.visible = this.creator !== '';
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
@@ -603,54 +719,6 @@ class ExtensionRow extends Gtk.ListBoxRow {
|
||||
this._extensionStateChangedId = 0;
|
||||
}
|
||||
|
||||
_buildUI() {
|
||||
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||
hexpand: true, margin_end: 24, spacing: 24,
|
||||
margin: 12 });
|
||||
this.add(hbox);
|
||||
|
||||
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 6, hexpand: true });
|
||||
hbox.add(vbox);
|
||||
|
||||
let name = GLib.markup_escape_text(this.name, -1);
|
||||
let label = new Gtk.Label({ label: '<b>' + name + '</b>',
|
||||
use_markup: true,
|
||||
halign: Gtk.Align.START });
|
||||
vbox.add(label);
|
||||
|
||||
let desc = this._extension.metadata.description.split('\n')[0];
|
||||
label = new DescriptionLabel({ label: desc, wrap: true, lines: 2,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
xalign: 0, yalign: 0 });
|
||||
vbox.add(label);
|
||||
|
||||
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
|
||||
visible: this.hasPrefs,
|
||||
no_show_all: true });
|
||||
button.set_image(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
|
||||
icon_size: Gtk.IconSize.BUTTON,
|
||||
visible: true }));
|
||||
button.get_style_context().add_class('circular');
|
||||
hbox.add(button);
|
||||
|
||||
this.prefsButton = button;
|
||||
|
||||
this._switch = new Gtk.Switch({
|
||||
valign: Gtk.Align.CENTER,
|
||||
sensitive: this._canToggle(),
|
||||
state: this._extension.state === ExtensionState.ENABLED,
|
||||
});
|
||||
this._notifyActiveId = this._switch.connect('notify::active', () => {
|
||||
if (this._switch.active)
|
||||
this._app.shellProxy.EnableExtensionRemote(this.uuid);
|
||||
else
|
||||
this._app.shellProxy.DisableExtensionRemote(this.uuid);
|
||||
});
|
||||
this._switch.connect('state-set', () => true);
|
||||
hbox.add(this._switch);
|
||||
}
|
||||
|
||||
_canToggle() {
|
||||
return this._extension.canChange;
|
||||
}
|
||||
|
218
js/extensionPrefs/ui/extension-row.ui
Normal file
218
js/extensionPrefs/ui/extension-row.ui
Normal file
@@ -0,0 +1,218 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<template class="ExtensionRow" parent="GtkListBoxRow">
|
||||
<property name="visible">True</property>
|
||||
<property name="activatable">False</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="nameLabel">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="updatesIcon">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="icon_name">software-update-available-symbolic</property>
|
||||
<style>
|
||||
<class name="warning"/>>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="prefsButton">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="visible"
|
||||
bind-source="prefsButton"
|
||||
bind-property="sensitive"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="action-name">row.show-prefs</property>
|
||||
<style>
|
||||
<class name="circular"/>>
|
||||
<class name="image-button"/>>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">emblem-system-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="action-name">row.enabled</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="revealButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="details-button"/>
|
||||
<class name="image-button"/>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">pan-end-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin_top">12</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Description</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="descriptionLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="max_width_chars">60</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible"
|
||||
bind-source="versionLabel"
|
||||
bind-property="visible"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="label" translatable="yes">Version</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="versionLabel">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible"
|
||||
bind-source="authorLabel"
|
||||
bind-property="visible"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="label" translatable="yes">Author</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="authorLabel">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Website</property>
|
||||
<property name="action_name">row.show-url</property>
|
||||
<property name="valign">end</property>
|
||||
<property name="margin-top">12</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="removeButton">
|
||||
<property name="visible"
|
||||
bind-source="removeButton"
|
||||
bind-property="sensitive"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="label" translatable="yes">Remove…</property>
|
||||
<property name="action_name">row.uninstall</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">end</property>
|
||||
<style>
|
||||
<class name="destructive-action"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
305
js/extensionPrefs/ui/extensions-window.ui
Normal file
305
js/extensionPrefs/ui/extensions-window.ui
Normal file
@@ -0,0 +1,305 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<menu id="primary-menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Help</attribute>
|
||||
<attribute name="action">win.show-help</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">About Extensions</attribute>
|
||||
<attribute name="action">win.show-about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<object class="GtkPopover" id="infoPopover">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">12</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">To find and add extensions, visit <a href="https://extensions.gnome.org">extensions.gnome.org</a>.</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Warning</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin_top">6</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Extensions can cause system issues, including performance problems. If you encounter problems with your system, it is recommended to disable all extensions.</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="max_width_chars">40</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<template class="ExtensionsWindow" parent="GtkApplicationWindow">
|
||||
<property name="default_width">800</property>
|
||||
<property name="default_height">500</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Extensions</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="popover">infoPopover</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">dialog-information-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="menuButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="menu_model">primary-menu</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="killSwitch">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="mainStack">
|
||||
<property name="visible">True</property>
|
||||
<property name="transition_type">crossfade</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="mainBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin">36</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible"
|
||||
bind-source="userList"
|
||||
bind-property="visible"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="halign">start</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Manually Installed</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="userList">
|
||||
<property name="visible">True</property>
|
||||
<property name="selection_mode">none</property>
|
||||
<property name="margin_bottom">24</property>
|
||||
<style>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible"
|
||||
bind-source="systemList"
|
||||
bind-property="visible"
|
||||
bind-flags="sync-create"/>
|
||||
<property name="halign">start</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Built-In</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBox" id="systemList">
|
||||
<property name="visible">True</property>
|
||||
<property name="selection_mode">none</property>
|
||||
<style>
|
||||
<class name="frame"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">main</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">32</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="valign">center</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="pixel_size">96</property>
|
||||
<property name="icon_name">org.gnome.Extensions-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">No Installed Extensions</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
<attribute name="scale" value="1.44"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">placeholder</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="margin_left">100</property>
|
||||
<property name="margin_right">100</property>
|
||||
<property name="margin_top">100</property>
|
||||
<property name="margin_bottom">60</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Something’s gone wrong</property>
|
||||
<attributes>
|
||||
<attribute name="scale" value="1.44"/>
|
||||
</attributes>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">We’re very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again.</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">noshell</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkActionBar" id="updatesBar">
|
||||
<property name="no_show_all">True</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="pixel-size">24</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="icon_name">software-update-available-symbolic</property>
|
||||
<style>
|
||||
<class name="warning"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">Extension Updates Ready</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="updatesLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Log Out…</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="action-name">win.logout</property>
|
||||
<property name="receives_default">True</property>
|
||||
<style>
|
||||
<class name="suggested-action"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@@ -17,10 +17,6 @@ var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
|
||||
|
||||
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
|
||||
|
||||
const WIGGLE_OFFSET = 6;
|
||||
const WIGGLE_DURATION = 65;
|
||||
const N_WIGGLES = 3;
|
||||
|
||||
var AuthPromptMode = {
|
||||
UNLOCK_ONLY: 0,
|
||||
UNLOCK_OR_LOG_IN: 1,
|
||||
@@ -282,11 +278,7 @@ var AuthPrompt = GObject.registerClass({
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
|
||||
|
||||
Util.wiggle(this._entry, {
|
||||
offset: WIGGLE_OFFSET,
|
||||
duration: WIGGLE_DURATION,
|
||||
wiggleCount: N_WIGGLES,
|
||||
});
|
||||
Util.wiggle(this._entry);
|
||||
}
|
||||
|
||||
_onVerificationComplete() {
|
||||
|
@@ -409,7 +409,10 @@ var SessionMenuButton = GObject.registerClass({
|
||||
});
|
||||
|
||||
var LoginDialog = GObject.registerClass({
|
||||
Signals: { 'failed': {} },
|
||||
Signals: {
|
||||
'failed': {},
|
||||
'wake-up-screen': {},
|
||||
},
|
||||
}, class LoginDialog extends St.Widget {
|
||||
_init(parentActor) {
|
||||
super._init({ style_class: 'login-dialog', visible: false });
|
||||
@@ -1225,13 +1228,18 @@ var LoginDialog = GObject.registerClass({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
activate() {
|
||||
this._userList.grab_key_focus();
|
||||
this.show();
|
||||
}
|
||||
|
||||
open() {
|
||||
Main.ctrlAltTabManager.addGroup(this,
|
||||
_("Login Window"),
|
||||
'dialog-password-symbolic',
|
||||
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
|
||||
this._userList.grab_key_focus();
|
||||
this.show();
|
||||
this.activate();
|
||||
|
||||
this.opacity = 0;
|
||||
|
||||
Main.pushModal(this, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
|
||||
|
@@ -31,7 +31,15 @@ var ExtensionState = {
|
||||
UNINSTALLED: 99,
|
||||
};
|
||||
|
||||
const SERIALIZED_PROPERTIES = ['type', 'state', 'path', 'error', 'hasPrefs', 'canChange'];
|
||||
const SERIALIZED_PROPERTIES = [
|
||||
'type',
|
||||
'state',
|
||||
'path',
|
||||
'error',
|
||||
'hasPrefs',
|
||||
'hasUpdate',
|
||||
'canChange',
|
||||
];
|
||||
|
||||
/**
|
||||
* getCurrentExtension:
|
||||
|
@@ -125,11 +125,10 @@ const SystemActions = GObject.registerClass({
|
||||
available: false,
|
||||
});
|
||||
this._actions.set(LOCK_ORIENTATION_ACTION_ID, {
|
||||
// Translators: The name of the lock orientation action in search
|
||||
name: C_("search-result", "Lock Orientation"),
|
||||
name: '',
|
||||
iconName: '',
|
||||
// Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
||||
keywords: _("lock orientation;screen;rotation").split(/[; ]/),
|
||||
keywords: _("lock orientation;unlock orientation;screen;rotation").split(/[; ]/),
|
||||
available: false,
|
||||
});
|
||||
|
||||
@@ -167,11 +166,10 @@ const SystemActions = GObject.registerClass({
|
||||
|
||||
this.forceUpdate();
|
||||
|
||||
this._orientationSettings.connect('changed::orientation-lock',
|
||||
() => {
|
||||
this._updateOrientationLock();
|
||||
this._updateOrientationLockIcon();
|
||||
});
|
||||
this._orientationSettings.connect('changed::orientation-lock', () => {
|
||||
this._updateOrientationLock();
|
||||
this._updateOrientationLockStatus();
|
||||
});
|
||||
Main.layoutManager.connect('monitors-changed',
|
||||
() => this._updateOrientationLock());
|
||||
this._sensorProxy = new SensorProxy(Gio.DBus.system,
|
||||
@@ -190,7 +188,7 @@ const SystemActions = GObject.registerClass({
|
||||
this._updateOrientationLock();
|
||||
});
|
||||
this._updateOrientationLock();
|
||||
this._updateOrientationLockIcon();
|
||||
this._updateOrientationLockStatus();
|
||||
|
||||
Main.sessionMode.connect('updated', () => this._sessionUpdated());
|
||||
this._sessionUpdated();
|
||||
@@ -243,12 +241,21 @@ const SystemActions = GObject.registerClass({
|
||||
this.notify('can-lock-orientation');
|
||||
}
|
||||
|
||||
_updateOrientationLockIcon() {
|
||||
_updateOrientationLockStatus() {
|
||||
let locked = this._orientationSettings.get_boolean('orientation-lock');
|
||||
let action = this._actions.get(LOCK_ORIENTATION_ACTION_ID);
|
||||
|
||||
// Translators: The name of the lock orientation action in search
|
||||
// and in the system status menu
|
||||
let name = locked
|
||||
? C_('search-result', 'Unlock Screen Rotation')
|
||||
: C_('search-result', 'Lock Screen Rotation');
|
||||
let iconName = locked
|
||||
? 'rotation-locked-symbolic'
|
||||
: 'rotation-allowed-symbolic';
|
||||
this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName = iconName;
|
||||
|
||||
action.name = name;
|
||||
action.iconName = iconName;
|
||||
|
||||
this.notify('orientation-lock-icon');
|
||||
}
|
||||
|
@@ -11,6 +11,10 @@ const Params = imports.misc.params;
|
||||
|
||||
var SCROLL_TIME = 100;
|
||||
|
||||
const WIGGLE_OFFSET = 6;
|
||||
const WIGGLE_DURATION = 65;
|
||||
const N_WIGGLES = 3;
|
||||
|
||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
const _balancedParens = '\\([^\\s()<>]+\\)';
|
||||
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
|
||||
@@ -442,9 +446,9 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
|
||||
function wiggle(actor, params) {
|
||||
params = Params.parse(params, {
|
||||
offset: 0,
|
||||
duration: 0,
|
||||
wiggleCount: 0,
|
||||
offset: WIGGLE_OFFSET,
|
||||
duration: WIGGLE_DURATION,
|
||||
wiggleCount: N_WIGGLES,
|
||||
});
|
||||
actor.translation_x = 0;
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
/* exported main */
|
||||
imports.gi.versions.Gtk = '3.0';
|
||||
|
||||
const Format = imports.format;
|
||||
const Gettext = imports.gettext;
|
||||
const { Gio, GLib, GObject, Gtk, Pango, Soup, WebKit2: WebKit } = imports.gi;
|
||||
@@ -116,6 +118,10 @@ class PortalWindow extends Gtk.ApplicationWindow {
|
||||
this._webContext = WebKit.WebContext.new_ephemeral();
|
||||
this._webContext.set_cache_model(WebKit.CacheModel.DOCUMENT_VIEWER);
|
||||
this._webContext.set_network_proxy_settings(WebKit.NetworkProxyMode.NO_PROXY, null);
|
||||
if (this._webContext.set_sandbox_enabled) {
|
||||
// We have WebKitGTK 2.26 or newer.
|
||||
this._webContext.set_sandbox_enabled(true);
|
||||
}
|
||||
|
||||
this._webView = WebKit.WebView.new_with_context(this._webContext);
|
||||
this._webView.connect('decide-policy', this._onDecidePolicy.bind(this));
|
||||
|
@@ -7,5 +7,10 @@
|
||||
<file>misc/extensionUtils.js</file>
|
||||
<file>misc/fileUtils.js</file>
|
||||
<file>misc/params.js</file>
|
||||
|
||||
<file alias="css/application.css">extensionPrefs/css/application.css</file>
|
||||
|
||||
<file alias="ui/extension-row.ui">extensionPrefs/ui/extension-row.ui</file>
|
||||
<file alias="ui/extensions-window.ui">extensionPrefs/ui/extensions-window.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
@@ -12,14 +12,22 @@ var SPINNER_ANIMATION_DELAY = 1000;
|
||||
var Animation = GObject.registerClass(
|
||||
class Animation extends St.Bin {
|
||||
_init(file, width, height, speed) {
|
||||
super._init({ width, height });
|
||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
|
||||
super._init({
|
||||
width: width * themeContext.scale_factor,
|
||||
height: height * themeContext.scale_factor,
|
||||
});
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
this.connect('resource-scale-changed',
|
||||
this._loadFile.bind(this, file, width, height));
|
||||
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
this._scaleChangedId = themeContext.connect('notify::scale-factor',
|
||||
this._loadFile.bind(this, file, width, height));
|
||||
() => {
|
||||
this._loadFile(file, width, height);
|
||||
this.set_size(width * themeContext.scale_factor, height * themeContext.scale_factor);
|
||||
});
|
||||
|
||||
this._speed = speed;
|
||||
|
||||
|
@@ -5,7 +5,6 @@ const { Clutter, Gio, GLib, GObject, Graphene, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const DND = imports.ui.dnd;
|
||||
const GrabHelper = imports.ui.grabHelper;
|
||||
const IconGrid = imports.ui.iconGrid;
|
||||
@@ -41,6 +40,8 @@ var PAGE_SWITCH_TIME = 250;
|
||||
var APP_ICON_SCALE_IN_TIME = 500;
|
||||
var APP_ICON_SCALE_IN_DELAY = 700;
|
||||
|
||||
const FOLDER_DIALOG_ANIMATION_TIME = 200;
|
||||
|
||||
const OVERSHOOT_THRESHOLD = 20;
|
||||
const OVERSHOOT_TIMEOUT = 1000;
|
||||
|
||||
@@ -297,7 +298,6 @@ var BaseAppView = GObject.registerClass({
|
||||
});
|
||||
|
||||
var AllView = GObject.registerClass({
|
||||
Signals: { 'space-ready': {} },
|
||||
}, class AllView extends BaseAppView {
|
||||
_init() {
|
||||
super._init({
|
||||
@@ -364,19 +364,19 @@ var AllView = GObject.registerClass({
|
||||
|
||||
this._clickAction = new Clutter.ClickAction();
|
||||
this._clickAction.connect('clicked', () => {
|
||||
if (!this._currentPopup)
|
||||
if (!this._currentDialog)
|
||||
return;
|
||||
|
||||
let [x, y] = this._clickAction.get_coords();
|
||||
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
|
||||
if (!this._currentPopup.contains(actor))
|
||||
this._currentPopup.popdown();
|
||||
if (!this._currentDialog.contains(actor))
|
||||
this._currentDialog.popdown();
|
||||
});
|
||||
this._eventBlocker.add_action(this._clickAction);
|
||||
|
||||
this._currentPopup = null;
|
||||
this._displayingPopup = false;
|
||||
this._currentPopupDestroyId = 0;
|
||||
this._currentDialog = null;
|
||||
this._displayingDialog = false;
|
||||
this._currentDialogDestroyId = 0;
|
||||
|
||||
this._canScroll = true; // limiting scrolling speed
|
||||
this._scrollTimeoutId = 0;
|
||||
@@ -388,16 +388,6 @@ var AllView = GObject.registerClass({
|
||||
this._lastOvershootTimeoutId = 0;
|
||||
|
||||
Main.overview.connect('hidden', () => this.goToPage(0));
|
||||
this._grid.connect('space-opened', () => {
|
||||
let fadeEffect = this._scrollView.get_effect('fade');
|
||||
if (fadeEffect)
|
||||
fadeEffect.enabled = false;
|
||||
|
||||
this.emit('space-ready');
|
||||
});
|
||||
this._grid.connect('space-closed', () => {
|
||||
this._displayingPopup = false;
|
||||
});
|
||||
|
||||
this._redisplayWorkId = Main.initializeDeferredWork(this, this._redisplay.bind(this));
|
||||
|
||||
@@ -540,15 +530,17 @@ var AllView = GObject.registerClass({
|
||||
// Overridden from BaseAppView
|
||||
animate(animationDirection, onComplete) {
|
||||
this._scrollView.reactive = false;
|
||||
this._swipeTracker.enabled = false;
|
||||
let completionFunc = () => {
|
||||
this._scrollView.reactive = true;
|
||||
this._swipeTracker.enabled = this.mapped;
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
};
|
||||
|
||||
if (animationDirection == IconGrid.AnimationDirection.OUT &&
|
||||
this._displayingPopup && this._currentPopup) {
|
||||
this._currentPopup.popdown();
|
||||
this._displayingDialog && this._currentDialog) {
|
||||
this._currentDialog.popdown();
|
||||
let spaceClosedId = this._grid.connect('space-closed', () => {
|
||||
this._grid.disconnect(spaceClosedId);
|
||||
super.animate(animationDirection, completionFunc);
|
||||
@@ -563,9 +555,9 @@ var AllView = GObject.registerClass({
|
||||
animateSwitch(animationDirection) {
|
||||
super.animateSwitch(animationDirection);
|
||||
|
||||
if (this._currentPopup && this._displayingPopup &&
|
||||
if (this._currentDialog && this._displayingDialog &&
|
||||
animationDirection == IconGrid.AnimationDirection.OUT) {
|
||||
this._currentPopup.ease({
|
||||
this._currentDialog.ease({
|
||||
opacity: 0,
|
||||
duration: VIEWS_SWITCH_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
@@ -577,17 +569,15 @@ var AllView = GObject.registerClass({
|
||||
this._pageIndicators.animateIndicators(animationDirection);
|
||||
}
|
||||
|
||||
getCurrentPageY() {
|
||||
return this._grid.getPageY(this._grid.currentPage);
|
||||
}
|
||||
|
||||
goToPage(pageNumber, animate = true) {
|
||||
pageNumber = clamp(pageNumber, 0, this._grid.nPages() - 1);
|
||||
|
||||
if (this._grid.currentPage == pageNumber && this._displayingPopup && this._currentPopup)
|
||||
if (this._grid.currentPage === pageNumber &&
|
||||
this._displayingDialog &&
|
||||
this._currentDialog)
|
||||
return;
|
||||
if (this._displayingPopup && this._currentPopup)
|
||||
this._currentPopup.popdown();
|
||||
if (this._displayingDialog && this._currentDialog)
|
||||
this._currentDialog.popdown();
|
||||
|
||||
if (!this.mapped) {
|
||||
this._adjustment.value = this._grid.getPageY(pageNumber);
|
||||
@@ -608,24 +598,8 @@ var AllView = GObject.registerClass({
|
||||
});
|
||||
}
|
||||
|
||||
openSpaceForPopup(item, side, nRows) {
|
||||
this._updateIconOpacities(true);
|
||||
this._displayingPopup = true;
|
||||
this._grid.openExtraSpace(item, side, nRows);
|
||||
}
|
||||
|
||||
_closeSpaceForPopup() {
|
||||
this._updateIconOpacities(false);
|
||||
|
||||
let fadeEffect = this._scrollView.get_effect('fade');
|
||||
if (fadeEffect)
|
||||
fadeEffect.enabled = true;
|
||||
|
||||
this._grid.closeExtraSpace();
|
||||
}
|
||||
|
||||
_onScroll(actor, event) {
|
||||
if (this._displayingPopup || !this._scrollView.reactive)
|
||||
if (this._displayingDialog || !this._scrollView.reactive)
|
||||
return Clutter.EVENT_STOP;
|
||||
|
||||
if (this._swipeTracker.canHandleScrollEvent(event))
|
||||
@@ -687,7 +661,7 @@ var AllView = GObject.registerClass({
|
||||
}
|
||||
|
||||
_onKeyPressEvent(actor, event) {
|
||||
if (this._displayingPopup)
|
||||
if (this._displayingDialog)
|
||||
return Clutter.EVENT_STOP;
|
||||
|
||||
if (event.get_key_symbol() === Clutter.KEY_Page_Up) {
|
||||
@@ -701,29 +675,34 @@ var AllView = GObject.registerClass({
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
addFolderPopup(popup) {
|
||||
this._stack.add_actor(popup);
|
||||
popup.connect('open-state-changed', (o, isOpen) => {
|
||||
addFolderDialog(dialog) {
|
||||
this.add_child(dialog);
|
||||
dialog.connect('open-state-changed', (o, isOpen) => {
|
||||
this._eventBlocker.visible = isOpen;
|
||||
|
||||
if (this._currentPopup) {
|
||||
this._currentPopup.disconnect(this._currentPopupDestroyId);
|
||||
this._currentPopupDestroyId = 0;
|
||||
if (this._currentDialog) {
|
||||
this._currentDialog.disconnect(this._currentDialogDestroyId);
|
||||
this._currentDialogDestroyId = 0;
|
||||
}
|
||||
|
||||
this._currentPopup = null;
|
||||
this._currentDialog = null;
|
||||
|
||||
if (isOpen) {
|
||||
this._currentPopup = popup;
|
||||
this._currentPopupDestroyId = popup.connect('destroy', () => {
|
||||
this._currentPopup = null;
|
||||
this._currentPopupDestroyId = 0;
|
||||
this._currentDialog = dialog;
|
||||
this._currentDialogDestroyId = dialog.connect('destroy', () => {
|
||||
this._currentDialog = null;
|
||||
this._currentDialogDestroyId = 0;
|
||||
this._eventBlocker.visible = false;
|
||||
});
|
||||
}
|
||||
this._updateIconOpacities(isOpen);
|
||||
if (!isOpen)
|
||||
this._closeSpaceForPopup();
|
||||
|
||||
// Toggle search entry
|
||||
Main.overview.searchEntry.reactive = !isOpen;
|
||||
Main.overview.searchEntry.clutter_text.reactive = !isOpen;
|
||||
Main.overview.searchEntry.clutter_text.editable = !isOpen;
|
||||
|
||||
this._displayingPopup = isOpen;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -782,9 +761,6 @@ var AllView = GObject.registerClass({
|
||||
|
||||
this._availWidth = availWidth;
|
||||
this._availHeight = availHeight;
|
||||
// Update folder views
|
||||
for (let i = 0; i < this._folderIcons.length; i++)
|
||||
this._folderIcons[i].adaptToSize(availWidth, availHeight);
|
||||
}
|
||||
|
||||
_resetOvershoot() {
|
||||
@@ -871,7 +847,7 @@ var AllView = GObject.registerClass({
|
||||
this._dragMonitor = null;
|
||||
}
|
||||
|
||||
this._eventBlocker.visible = this._currentPopup !== null;
|
||||
this._eventBlocker.visible = this._currentDialog !== null;
|
||||
this._resetOvershoot();
|
||||
}
|
||||
|
||||
@@ -900,8 +876,8 @@ var AllView = GObject.registerClass({
|
||||
let view = _getViewFromIcon(source);
|
||||
view.removeApp(source.app);
|
||||
|
||||
if (this._currentPopup)
|
||||
this._currentPopup.popdown();
|
||||
if (this._currentDialog)
|
||||
this._currentDialog.popdown();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1315,6 +1291,8 @@ class FolderView extends BaseAppView {
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
}, {
|
||||
minRows: 1,
|
||||
});
|
||||
|
||||
// If it not expand, the parent doesn't take into account its preferred_width when allocating
|
||||
@@ -1404,44 +1382,10 @@ class FolderView extends BaseAppView {
|
||||
this._scrollView.update_fade_effect(fadeOffset, 0);
|
||||
|
||||
// Set extra padding to avoid popup or close button being cut off
|
||||
this._grid.topPadding = Math.max(this._grid.topPadding - this._offsetForEachSide, 0);
|
||||
this._grid.bottomPadding = Math.max(this._grid.bottomPadding - this._offsetForEachSide, 0);
|
||||
this._grid.leftPadding = Math.max(this._grid.leftPadding - this._offsetForEachSide, 0);
|
||||
this._grid.rightPadding = Math.max(this._grid.rightPadding - this._offsetForEachSide, 0);
|
||||
|
||||
this.set_width(this.usedWidth());
|
||||
this.set_height(this.usedHeight());
|
||||
}
|
||||
|
||||
_getPageAvailableSize() {
|
||||
let pageBox = new Clutter.ActorBox();
|
||||
pageBox.x1 = pageBox.y1 = 0;
|
||||
pageBox.x2 = this._parentAvailableWidth;
|
||||
pageBox.y2 = this._parentAvailableHeight;
|
||||
|
||||
let contentBox = this.get_theme_node().get_content_box(pageBox);
|
||||
// We only can show icons inside the collection view boxPointer
|
||||
// so we have to subtract the required padding etc of the boxpointer
|
||||
return [(contentBox.x2 - contentBox.x1) - 2 * this._offsetForEachSide, (contentBox.y2 - contentBox.y1) - 2 * this._offsetForEachSide];
|
||||
}
|
||||
|
||||
usedWidth() {
|
||||
let [availWidthPerPage] = this._getPageAvailableSize();
|
||||
return this._grid.usedWidth(availWidthPerPage);
|
||||
}
|
||||
|
||||
usedHeight() {
|
||||
return this._grid.usedHeightForNRows(this.nRowsDisplayedAtOnce());
|
||||
}
|
||||
|
||||
nRowsDisplayedAtOnce() {
|
||||
let [availWidthPerPage, availHeightPerPage] = this._getPageAvailableSize();
|
||||
let maxRows = this._grid.rowsForHeight(availHeightPerPage) - 1;
|
||||
return Math.min(this._grid.nRows(availWidthPerPage), maxRows);
|
||||
}
|
||||
|
||||
setPaddingOffsets(offset) {
|
||||
this._offsetForEachSide = offset;
|
||||
this._grid.topPadding = Math.max(this._grid.topPadding, 0);
|
||||
this._grid.bottomPadding = Math.max(this._grid.bottomPadding, 0);
|
||||
this._grid.leftPadding = Math.max(this._grid.leftPadding, 0);
|
||||
this._grid.rightPadding = Math.max(this._grid.rightPadding, 0);
|
||||
}
|
||||
|
||||
_loadApps() {
|
||||
@@ -1540,8 +1484,6 @@ var FolderIcon = GObject.registerClass({
|
||||
this._folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder',
|
||||
path });
|
||||
this._delegate = this;
|
||||
// whether we need to update arrow side, position etc.
|
||||
this._popupInvalidated = false;
|
||||
|
||||
this.icon = new IconGrid.BaseIcon('', {
|
||||
createIcon: this._createIcon.bind(this),
|
||||
@@ -1557,10 +1499,6 @@ var FolderIcon = GObject.registerClass({
|
||||
this._itemDragEndId = Main.overview.connect(
|
||||
'item-drag-end', this._onDragEnd.bind(this));
|
||||
|
||||
this._popupTimeoutId = 0;
|
||||
|
||||
this.connect('popup-menu', this._popupRenamePopup.bind(this));
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._folder.connect('changed', this._redisplay.bind(this));
|
||||
@@ -1578,10 +1516,8 @@ var FolderIcon = GObject.registerClass({
|
||||
this._spaceReadySignalId = 0;
|
||||
}
|
||||
|
||||
if (this._popup)
|
||||
this._popup.destroy();
|
||||
|
||||
this._removeMenuTimeout();
|
||||
if (this._dialog)
|
||||
this._dialog.destroy();
|
||||
}
|
||||
|
||||
vfunc_clicked() {
|
||||
@@ -1589,17 +1525,16 @@ var FolderIcon = GObject.registerClass({
|
||||
}
|
||||
|
||||
vfunc_unmap() {
|
||||
super.vfunc_unmap();
|
||||
if (this._dialog)
|
||||
this._dialog.popdown();
|
||||
|
||||
if (this._popup)
|
||||
this._popup.popdown();
|
||||
super.vfunc_unmap();
|
||||
}
|
||||
|
||||
open() {
|
||||
this._removeMenuTimeout();
|
||||
this._ensurePopup();
|
||||
this._ensureFolderDialog();
|
||||
this.view._scrollView.vscroll.adjustment.value = 0;
|
||||
this._openSpaceForPopup();
|
||||
this._dialog.popup();
|
||||
}
|
||||
|
||||
getAppIds() {
|
||||
@@ -1693,293 +1628,59 @@ var FolderIcon = GObject.registerClass({
|
||||
return this.view.createFolderIcon(iconSize, this);
|
||||
}
|
||||
|
||||
_popupHeight() {
|
||||
let usedHeight = this.view.usedHeight() + this._popup.getOffset(St.Side.TOP) + this._popup.getOffset(St.Side.BOTTOM);
|
||||
return usedHeight;
|
||||
}
|
||||
|
||||
_openSpaceForPopup() {
|
||||
this._spaceReadySignalId = this._parentView.connect('space-ready', () => {
|
||||
this._parentView.disconnect(this._spaceReadySignalId);
|
||||
this._spaceReadySignalId = 0;
|
||||
this._popup.popup();
|
||||
this._updatePopupPosition();
|
||||
});
|
||||
this._parentView.openSpaceForPopup(this, this._boxPointerArrowside, this.view.nRowsDisplayedAtOnce());
|
||||
}
|
||||
|
||||
_calculateBoxPointerArrowSide() {
|
||||
let spaceTop = this.y - this._parentView.getCurrentPageY();
|
||||
let spaceBottom = this._parentView.height - (spaceTop + this.height);
|
||||
|
||||
return spaceTop > spaceBottom ? St.Side.BOTTOM : St.Side.TOP;
|
||||
}
|
||||
|
||||
_updatePopupSize() {
|
||||
// StWidget delays style calculation until needed, make sure we use the correct values
|
||||
this.view._grid.ensure_style();
|
||||
|
||||
let offsetForEachSide = Math.ceil((this._popup.getOffset(St.Side.TOP) +
|
||||
this._popup.getOffset(St.Side.BOTTOM) -
|
||||
this._popup.getCloseButtonOverlap()) / 2);
|
||||
// Add extra padding to prevent boxpointer decorations and close button being cut off
|
||||
this.view.setPaddingOffsets(offsetForEachSide);
|
||||
this.view.adaptToSize(this._parentAvailableWidth, this._parentAvailableHeight);
|
||||
}
|
||||
|
||||
_updatePopupPosition() {
|
||||
if (!this._popup)
|
||||
_ensureFolderDialog() {
|
||||
if (this._dialog)
|
||||
return;
|
||||
|
||||
if (this._boxPointerArrowside == St.Side.BOTTOM)
|
||||
this._popup.y = this.allocation.y1 + this.translation_y - this._popupHeight();
|
||||
else
|
||||
this._popup.y = this.allocation.y1 + this.translation_y + this.height;
|
||||
}
|
||||
|
||||
_ensurePopup() {
|
||||
if (this._popup && !this._popupInvalidated)
|
||||
return;
|
||||
this._boxPointerArrowside = this._calculateBoxPointerArrowSide();
|
||||
if (!this._popup) {
|
||||
this._popup = new AppFolderPopup(this, this._boxPointerArrowside);
|
||||
this._parentView.addFolderPopup(this._popup);
|
||||
this._popup.connect('open-state-changed', (popup, isOpen) => {
|
||||
if (!this._dialog) {
|
||||
this._dialog = new AppFolderDialog(this, this._folder);
|
||||
this._parentView.addFolderDialog(this._dialog);
|
||||
this._dialog.connect('open-state-changed', (popup, isOpen) => {
|
||||
if (!isOpen)
|
||||
this.checked = false;
|
||||
});
|
||||
} else {
|
||||
this._popup.updateArrowSide(this._boxPointerArrowside);
|
||||
}
|
||||
this._updatePopupSize();
|
||||
this._updatePopupPosition();
|
||||
this._popupInvalidated = false;
|
||||
}
|
||||
|
||||
_removeMenuTimeout() {
|
||||
if (this._popupTimeoutId > 0) {
|
||||
GLib.source_remove(this._popupTimeoutId);
|
||||
this._popupTimeoutId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_setPopupTimeout() {
|
||||
this._removeMenuTimeout();
|
||||
this._popupTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, MENU_POPUP_TIMEOUT, () => {
|
||||
this._popupTimeoutId = 0;
|
||||
this._popupRenamePopup();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._popupTimeoutId,
|
||||
'[gnome-shell] this._popupRenamePopup');
|
||||
}
|
||||
|
||||
vfunc_leave_event(crossingEvent) {
|
||||
let ret = super.vfunc_leave_event(crossingEvent);
|
||||
this.fake_release();
|
||||
this._removeMenuTimeout();
|
||||
return ret;
|
||||
}
|
||||
|
||||
vfunc_button_press_event(buttonEvent) {
|
||||
super.vfunc_button_press_event(buttonEvent);
|
||||
|
||||
if (buttonEvent.button == 1) {
|
||||
this._setPopupTimeout();
|
||||
} else if (buttonEvent.button == 3) {
|
||||
this._popupRenamePopup();
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
vfunc_touch_event(touchEvent) {
|
||||
super.vfunc_touch_event(touchEvent);
|
||||
|
||||
if (touchEvent.type == Clutter.EventType.TOUCH_BEGIN)
|
||||
this._setPopupTimeout();
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_popupRenamePopup() {
|
||||
this._removeMenuTimeout();
|
||||
this.fake_release();
|
||||
|
||||
if (!this._menu) {
|
||||
this._menuManager = new PopupMenu.PopupMenuManager(this);
|
||||
|
||||
this._menu = new RenameFolderMenu(this, this._folder);
|
||||
this._menuManager.addMenu(this._menu);
|
||||
|
||||
this._menu.connect('open-state-changed', (menu, isPoppedUp) => {
|
||||
if (!isPoppedUp)
|
||||
this.sync_hover();
|
||||
});
|
||||
let id = Main.overview.connect('hiding', () => {
|
||||
this._menu.close();
|
||||
});
|
||||
this.connect('destroy', () => {
|
||||
Main.overview.disconnect(id);
|
||||
});
|
||||
}
|
||||
|
||||
this.set_hover(true);
|
||||
this._menu.open();
|
||||
this._menuManager.ignoreRelease();
|
||||
}
|
||||
|
||||
adaptToSize(width, height) {
|
||||
this._parentAvailableWidth = width;
|
||||
this._parentAvailableHeight = height;
|
||||
if (this._popup)
|
||||
this.view.adaptToSize(width, height);
|
||||
this._popupInvalidated = true;
|
||||
}
|
||||
});
|
||||
|
||||
var RenameFolderMenuItem = GObject.registerClass(
|
||||
class RenameFolderMenuItem extends PopupMenu.PopupBaseMenuItem {
|
||||
_init(folder) {
|
||||
super._init({
|
||||
style_class: 'rename-folder-popup-item',
|
||||
reactive: false,
|
||||
});
|
||||
this.setOrnament(PopupMenu.Ornament.HIDDEN);
|
||||
|
||||
this._folder = folder;
|
||||
|
||||
// Entry
|
||||
this._entry = new St.Entry({
|
||||
x_expand: true,
|
||||
width: 200,
|
||||
});
|
||||
this.add_child(this._entry);
|
||||
|
||||
this._entry.clutter_text.connect(
|
||||
'notify::text', this._validate.bind(this));
|
||||
this._entry.clutter_text.connect(
|
||||
'activate', this._updateFolderName.bind(this));
|
||||
|
||||
// Rename button
|
||||
this._button = new St.Button({
|
||||
style_class: 'button',
|
||||
reactive: true,
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
|
||||
can_focus: true,
|
||||
label: _('Rename'),
|
||||
});
|
||||
this.add_child(this._button);
|
||||
|
||||
this._button.connect('clicked', this._updateFolderName.bind(this));
|
||||
}
|
||||
|
||||
vfunc_map() {
|
||||
this._entry.text = _getFolderName(this._folder);
|
||||
this._entry.clutter_text.set_selection(0, -1);
|
||||
super.vfunc_map();
|
||||
}
|
||||
|
||||
vfunc_key_focus_in() {
|
||||
super.vfunc_key_focus_in();
|
||||
this._entry.clutter_text.grab_key_focus();
|
||||
}
|
||||
|
||||
_isValidFolderName() {
|
||||
let folderName = _getFolderName(this._folder);
|
||||
let newFolderName = this._entry.text.trim();
|
||||
|
||||
return newFolderName.length > 0 && newFolderName != folderName;
|
||||
}
|
||||
|
||||
_validate() {
|
||||
let isValid = this._isValidFolderName();
|
||||
|
||||
this._button.reactive = isValid;
|
||||
}
|
||||
|
||||
_updateFolderName() {
|
||||
if (!this._isValidFolderName())
|
||||
return;
|
||||
|
||||
let newFolderName = this._entry.text.trim();
|
||||
this._folder.set_string('name', newFolderName);
|
||||
this._folder.set_boolean('translate', false);
|
||||
this.activate(Clutter.get_current_event());
|
||||
}
|
||||
});
|
||||
|
||||
var RenameFolderMenu = class RenameFolderMenu extends PopupMenu.PopupMenu {
|
||||
constructor(source, folder) {
|
||||
super(source, 0.5, St.Side.BOTTOM);
|
||||
this.actor.add_style_class_name('rename-folder-popup');
|
||||
|
||||
// We want to keep the item hovered while the menu is up
|
||||
this.blockSourceEvents = true;
|
||||
|
||||
let menuItem = new RenameFolderMenuItem(folder);
|
||||
this.addMenuItem(menuItem);
|
||||
|
||||
// Focus the text entry on menu pop-up
|
||||
this.focusActor = menuItem;
|
||||
|
||||
// Chain our visibility and lifecycle to that of the source
|
||||
this._sourceMappedId = source.connect('notify::mapped', () => {
|
||||
if (!source.mapped)
|
||||
this.close();
|
||||
});
|
||||
source.connect('destroy', () => {
|
||||
source.disconnect(this._sourceMappedId);
|
||||
this.destroy();
|
||||
});
|
||||
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(RenameFolderMenu.prototype);
|
||||
|
||||
var AppFolderPopup = GObject.registerClass({
|
||||
var AppFolderDialog = GObject.registerClass({
|
||||
Signals: {
|
||||
'open-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
|
||||
},
|
||||
}, class AppFolderPopup extends St.Widget {
|
||||
_init(source, side) {
|
||||
}, class AppFolderDialog extends St.Widget {
|
||||
_init(source, folder) {
|
||||
super._init({
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
style_class: 'app-folder-dialog-container',
|
||||
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,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
this.add_constraint(new Clutter.BindConstraint({
|
||||
source: Main.overview.viewSelector,
|
||||
coordinate: Clutter.BindCoordinate.ALL,
|
||||
}));
|
||||
|
||||
this._source = source;
|
||||
this._folder = folder;
|
||||
this._view = source.view;
|
||||
this._arrowSide = side;
|
||||
|
||||
this._isOpen = false;
|
||||
this.parentOffset = 0;
|
||||
|
||||
this._boxPointer = new BoxPointer.BoxPointer(this._arrowSide, {
|
||||
style_class: 'app-folder-popup-bin',
|
||||
this._viewBox = new St.BoxLayout({
|
||||
style_class: 'app-folder-dialog',
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
x_align: Clutter.ActorAlign.FILL,
|
||||
y_align: Clutter.ActorAlign.FILL,
|
||||
vertical: true,
|
||||
});
|
||||
this.add_child(this._viewBox);
|
||||
|
||||
this._boxPointer.style_class = 'app-folder-popup';
|
||||
this.add_actor(this._boxPointer);
|
||||
this._boxPointer.bin.set_child(this._view);
|
||||
|
||||
this.closeButton = Util.makeCloseButton(this._boxPointer);
|
||||
this.closeButton.connect('clicked', this.popdown.bind(this));
|
||||
this.add_actor(this.closeButton);
|
||||
|
||||
this._boxPointer.bind_property('opacity', this.closeButton, 'opacity',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
this._addFolderNameEntry();
|
||||
this._viewBox.add_child(this._view);
|
||||
|
||||
global.focus_manager.add_group(this);
|
||||
|
||||
@@ -1988,6 +1689,206 @@ var AppFolderPopup = GObject.registerClass({
|
||||
});
|
||||
this._grabHelper.addActor(Main.layoutManager.overviewGroup);
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._sourceMappedId = 0;
|
||||
this._needsZoomAndFade = false;
|
||||
}
|
||||
|
||||
_addFolderNameEntry() {
|
||||
this._entryBox = new St.BoxLayout({
|
||||
style_class: 'folder-name-container',
|
||||
});
|
||||
this._viewBox.add_child(this._entryBox);
|
||||
|
||||
// Empty actor to center the title
|
||||
let ghostButton = new Clutter.Actor();
|
||||
this._entryBox.add_child(ghostButton);
|
||||
|
||||
let stack = new Shell.Stack({
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
this._entryBox.add_child(stack);
|
||||
|
||||
// Folder name label
|
||||
this._folderNameLabel = new St.Label({
|
||||
style_class: 'folder-name-label',
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
|
||||
stack.add_child(this._folderNameLabel);
|
||||
|
||||
// Folder name entry
|
||||
this._entry = new St.Entry({
|
||||
style_class: 'folder-name-entry',
|
||||
opacity: 0,
|
||||
reactive: false,
|
||||
});
|
||||
this._entry.clutter_text.set({
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
|
||||
this._entry.clutter_text.connect('activate', () => {
|
||||
this._showFolderLabel();
|
||||
});
|
||||
|
||||
stack.add_child(this._entry);
|
||||
|
||||
// Edit button
|
||||
this._editButton = new St.Button({
|
||||
style_class: 'edit-folder-button',
|
||||
button_mask: St.ButtonMask.ONE,
|
||||
toggle_mode: true,
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
x_align: Clutter.ActorAlign.END,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
child: new St.Icon({
|
||||
icon_name: 'document-edit-symbolic',
|
||||
icon_size: 16,
|
||||
}),
|
||||
});
|
||||
|
||||
this._editButton.connect('notify::checked', () => {
|
||||
if (this._editButton.checked)
|
||||
this._showFolderEntry();
|
||||
else
|
||||
this._showFolderLabel();
|
||||
});
|
||||
|
||||
this._entryBox.add_child(this._editButton);
|
||||
|
||||
ghostButton.add_constraint(new Clutter.BindConstraint({
|
||||
source: this._editButton,
|
||||
coordinate: Clutter.BindCoordinate.SIZE,
|
||||
}));
|
||||
|
||||
this._folder.connect('changed::name', () => this._syncFolderName());
|
||||
this._syncFolderName();
|
||||
}
|
||||
|
||||
_syncFolderName() {
|
||||
let newName = _getFolderName(this._folder);
|
||||
|
||||
this._folderNameLabel.text = newName;
|
||||
this._entry.text = newName;
|
||||
}
|
||||
|
||||
_switchActor(from, to) {
|
||||
to.reactive = true;
|
||||
to.ease({
|
||||
opacity: 255,
|
||||
duration: 300,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
|
||||
from.ease({
|
||||
opacity: 0,
|
||||
duration: 300,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
from.reactive = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
_showFolderLabel() {
|
||||
if (this._editButton.checked)
|
||||
this._editButton.checked = false;
|
||||
|
||||
this._maybeUpdateFolderName();
|
||||
this._switchActor(this._entry, this._folderNameLabel);
|
||||
}
|
||||
|
||||
_showFolderEntry() {
|
||||
this._switchActor(this._folderNameLabel, this._entry);
|
||||
|
||||
this._entry.clutter_text.set_selection(0, -1);
|
||||
this._entry.clutter_text.grab_key_focus();
|
||||
}
|
||||
|
||||
_maybeUpdateFolderName() {
|
||||
let folderName = _getFolderName(this._folder);
|
||||
let newFolderName = this._entry.text.trim();
|
||||
|
||||
if (newFolderName.length === 0 || newFolderName === folderName)
|
||||
return;
|
||||
|
||||
this._folder.set_string('name', newFolderName);
|
||||
this._folder.set_boolean('translate', false);
|
||||
}
|
||||
|
||||
_zoomAndFadeIn() {
|
||||
let [sourceX, sourceY] =
|
||||
this._source.get_transformed_position();
|
||||
let [dialogX, dialogY] =
|
||||
this.get_transformed_position();
|
||||
|
||||
this.set({
|
||||
translation_x: sourceX - dialogX,
|
||||
translation_y: sourceY - dialogY,
|
||||
scale_x: this._source.width / this.width,
|
||||
scale_y: this._source.height / this.height,
|
||||
opacity: 0,
|
||||
});
|
||||
|
||||
this.ease({
|
||||
translation_x: 0,
|
||||
translation_y: 0,
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
opacity: 255,
|
||||
duration: FOLDER_DIALOG_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
|
||||
this._needsZoomAndFade = false;
|
||||
|
||||
if (this._sourceMappedId === 0) {
|
||||
this._sourceMappedId = this._source.connect(
|
||||
'notify::mapped', this._zoomAndFadeOut.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
_zoomAndFadeOut() {
|
||||
if (!this._isOpen)
|
||||
return;
|
||||
|
||||
if (!this._source.mapped) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
let [sourceX, sourceY] =
|
||||
this._source.get_transformed_position();
|
||||
let [dialogX, dialogY] =
|
||||
this.get_transformed_position();
|
||||
|
||||
this.ease({
|
||||
translation_x: sourceX - dialogX,
|
||||
translation_y: sourceY - dialogY,
|
||||
scale_x: this._source.width / this.width,
|
||||
scale_y: this._source.height / this.height,
|
||||
opacity: 0,
|
||||
duration: FOLDER_DIALOG_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
this.set({
|
||||
translation_x: 0,
|
||||
translation_y: 0,
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
opacity: 255,
|
||||
});
|
||||
this.hide();
|
||||
},
|
||||
});
|
||||
|
||||
this._needsZoomAndFade = false;
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
@@ -1996,6 +1897,28 @@ var AppFolderPopup = GObject.registerClass({
|
||||
this._grabHelper.ungrab({ actor: this });
|
||||
this._grabHelper = null;
|
||||
}
|
||||
|
||||
if (this._sourceMappedId) {
|
||||
this._source.disconnect(this._sourceMappedId);
|
||||
this._sourceMappedId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
vfunc_allocate(box, flags) {
|
||||
let contentBox = this.get_theme_node().get_content_box(box);
|
||||
|
||||
let [, entryBoxHeight] = this._entryBox.get_size();
|
||||
let spacing = this._viewBox.layout_manager.spacing;
|
||||
|
||||
this._view.adaptToSize(
|
||||
contentBox.get_width(),
|
||||
contentBox.get_height() - entryBoxHeight - spacing);
|
||||
|
||||
super.vfunc_allocate(box, flags);
|
||||
|
||||
// We can only start zooming after receiving an allocation
|
||||
if (this._needsZoomAndFade)
|
||||
this._zoomAndFadeIn();
|
||||
}
|
||||
|
||||
vfunc_key_press_event(keyEvent) {
|
||||
@@ -2061,20 +1984,9 @@ var AppFolderPopup = GObject.registerClass({
|
||||
if (!this._isOpen)
|
||||
return;
|
||||
|
||||
this._needsZoomAndFade = true;
|
||||
this.show();
|
||||
|
||||
this._boxPointer.setArrowActor(this._source);
|
||||
// We need to hide the icons of the view until the boxpointer animation
|
||||
// is completed so we can animate the icons after as we like without
|
||||
// showing them while boxpointer is animating.
|
||||
this._view.opacity = 0;
|
||||
this._boxPointer.open(BoxPointer.PopupAnimation.FADE |
|
||||
BoxPointer.PopupAnimation.SLIDE,
|
||||
() => {
|
||||
this._view.opacity = 255;
|
||||
this._view.animate(IconGrid.AnimationDirection.IN);
|
||||
});
|
||||
|
||||
this.emit('open-state-changed', true);
|
||||
}
|
||||
|
||||
@@ -2082,29 +1994,13 @@ var AppFolderPopup = GObject.registerClass({
|
||||
if (!this._isOpen)
|
||||
return;
|
||||
|
||||
this._grabHelper.ungrab({ actor: this });
|
||||
this._zoomAndFadeOut();
|
||||
this._showFolderLabel();
|
||||
|
||||
this._boxPointer.close(BoxPointer.PopupAnimation.FADE |
|
||||
BoxPointer.PopupAnimation.SLIDE);
|
||||
this._grabHelper.ungrab({ actor: this });
|
||||
this._isOpen = false;
|
||||
this.emit('open-state-changed', false);
|
||||
}
|
||||
|
||||
getCloseButtonOverlap() {
|
||||
return this.closeButton.get_theme_node().get_length('-shell-close-overlap-y');
|
||||
}
|
||||
|
||||
getOffset(side) {
|
||||
let offset = this._boxPointer.getPadding(side);
|
||||
if (this._arrowSide == side)
|
||||
offset += this._boxPointer.getArrowHeight();
|
||||
return offset;
|
||||
}
|
||||
|
||||
updateArrowSide(side) {
|
||||
this._arrowSide = side;
|
||||
this._boxPointer.updateArrowSide(side);
|
||||
}
|
||||
});
|
||||
|
||||
var AppIcon = GObject.registerClass({
|
||||
|
@@ -1,6 +1,7 @@
|
||||
/* exported AudioDeviceSelectionDBus */
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
@@ -36,18 +37,17 @@ var AudioDeviceSelectionDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
_buildLayout() {
|
||||
let title = new St.Label({ style_class: 'audio-selection-title',
|
||||
text: _("Select Audio Device"),
|
||||
x_align: Clutter.ActorAlign.CENTER });
|
||||
|
||||
this.contentLayout.style_class = 'audio-selection-content';
|
||||
this.contentLayout.add(title);
|
||||
let content = new Dialog.MessageDialogContent({
|
||||
title: _('Select Audio Device'),
|
||||
});
|
||||
|
||||
this._selectionBox = new St.BoxLayout({
|
||||
style_class: 'audio-selection-box',
|
||||
x_expand: true,
|
||||
});
|
||||
this.contentLayout.add_child(this._selectionBox);
|
||||
content.add_child(this._selectionBox);
|
||||
|
||||
this.contentLayout.add_child(content);
|
||||
|
||||
if (Main.sessionMode.allowSettings) {
|
||||
this.addButton({ action: this._openSettings.bind(this),
|
||||
|
@@ -504,12 +504,9 @@ var SystemBackground = GObject.registerClass({
|
||||
Signals: { 'loaded': {} },
|
||||
}, class SystemBackground extends Meta.BackgroundActor {
|
||||
_init() {
|
||||
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
|
||||
|
||||
if (_systemBackground == null) {
|
||||
_systemBackground = new Meta.Background({ meta_display: global.display });
|
||||
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
|
||||
_systemBackground.set_file(file, GDesktopEnums.BackgroundStyle.WALLPAPER);
|
||||
}
|
||||
|
||||
super._init({
|
||||
@@ -518,22 +515,11 @@ var SystemBackground = GObject.registerClass({
|
||||
background: _systemBackground,
|
||||
});
|
||||
|
||||
let cache = Meta.BackgroundImageCache.get_default();
|
||||
let image = cache.load(file);
|
||||
if (image.is_loaded()) {
|
||||
image = null;
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this.emit('loaded');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
|
||||
} else {
|
||||
let id = image.connect('loaded', () => {
|
||||
this.emit('loaded');
|
||||
image.disconnect(id);
|
||||
image = null;
|
||||
});
|
||||
}
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this.emit('loaded');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -7,6 +7,7 @@ const Main = imports.ui.main;
|
||||
const MessageList = imports.ui.messageList;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Mpris = imports.ui.mpris;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
@@ -1100,6 +1101,26 @@ class Placeholder extends St.BoxLayout {
|
||||
}
|
||||
});
|
||||
|
||||
const DoNotDisturbSwitch = GObject.registerClass(
|
||||
class DoNotDisturbSwitch extends PopupMenu.Switch {
|
||||
_init() {
|
||||
this._settings = new Gio.Settings({
|
||||
schema_id: 'org.gnome.desktop.notifications',
|
||||
});
|
||||
|
||||
super._init(this._settings.get_boolean('show-banners'));
|
||||
|
||||
this._settings.bind('show-banners',
|
||||
this, 'state',
|
||||
Gio.SettingsBindFlags.INVERT_BOOLEAN);
|
||||
|
||||
this.connect('destroy', () => {
|
||||
this._settings.run_dispose();
|
||||
this._settings = null;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var CalendarMessageList = GObject.registerClass(
|
||||
class CalendarMessageList extends St.Widget {
|
||||
_init() {
|
||||
@@ -1125,16 +1146,33 @@ class CalendarMessageList extends St.Widget {
|
||||
this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
|
||||
box.add_actor(this._scrollView);
|
||||
|
||||
let hbox = new St.BoxLayout({ style_class: 'message-list-controls' });
|
||||
box.add_child(hbox);
|
||||
|
||||
hbox.add_child(new St.Label({
|
||||
text: _('Do Not Disturb'),
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
}));
|
||||
|
||||
this._dndSwitch = new DoNotDisturbSwitch();
|
||||
this._dndButton = new St.Button({
|
||||
can_focus: true,
|
||||
child: this._dndSwitch,
|
||||
});
|
||||
this._dndButton.connect('clicked', () => this._dndSwitch.toggle());
|
||||
hbox.add_child(this._dndButton);
|
||||
|
||||
this._clearButton = new St.Button({
|
||||
style_class: 'message-list-clear-button button',
|
||||
label: _('Clear'),
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.END,
|
||||
});
|
||||
this._clearButton.connect('clicked', () => {
|
||||
this._sectionList.get_children().forEach(s => s.clear());
|
||||
});
|
||||
box.add_actor(this._clearButton);
|
||||
hbox.add_actor(this._clearButton);
|
||||
|
||||
this._placeholder.bind_property('visible',
|
||||
this._clearButton, 'visible',
|
||||
|
@@ -19,7 +19,7 @@ class CheckBox extends St.Button {
|
||||
this._box = new St.Bin({ y_align: Clutter.ActorAlign.START });
|
||||
container.add_actor(this._box);
|
||||
|
||||
this._label = new St.Label();
|
||||
this._label = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
|
||||
this._label.clutter_text.set_line_wrap(true);
|
||||
this._label.clutter_text.set_ellipsize(Pango.EllipsizeMode.NONE);
|
||||
container.add_actor(this._label);
|
||||
|
@@ -3,13 +3,11 @@
|
||||
|
||||
const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
|
||||
var WORK_SPINNER_ICON_SIZE = 16;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
var KeyringDialog = GObject.registerClass(
|
||||
class KeyringDialog extends ModalDialog.ModalDialog {
|
||||
@@ -21,141 +19,97 @@ class KeyringDialog extends ModalDialog.ModalDialog {
|
||||
this.prompt.connect('show-confirm', this._onShowConfirm.bind(this));
|
||||
this.prompt.connect('prompt-close', this._onHidePrompt.bind(this));
|
||||
|
||||
this._content = new Dialog.MessageDialogContent();
|
||||
this.contentLayout.add(this._content);
|
||||
let content = new Dialog.MessageDialogContent();
|
||||
|
||||
this.prompt.bind_property('message', this._content, 'title', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('description', this._content, 'description', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('message',
|
||||
content, 'title', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('description',
|
||||
content, 'description', GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
this._workSpinner = null;
|
||||
this._controlTable = null;
|
||||
let passwordBox = new St.BoxLayout({
|
||||
style_class: 'prompt-dialog-password-layout',
|
||||
vertical: true,
|
||||
});
|
||||
|
||||
this._cancelButton = this.addButton({ label: '',
|
||||
action: this._onCancelButton.bind(this),
|
||||
key: Clutter.KEY_Escape });
|
||||
this._continueButton = this.addButton({ label: '',
|
||||
action: this._onContinueButton.bind(this),
|
||||
default: true });
|
||||
this._passwordEntry = new St.PasswordEntry({
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
can_focus: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
ShellEntry.addContextMenu(this._passwordEntry);
|
||||
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
|
||||
this.prompt.bind_property('password-visible',
|
||||
this._passwordEntry, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
passwordBox.add_child(this._passwordEntry);
|
||||
|
||||
this._confirmEntry = new St.PasswordEntry({
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
can_focus: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
ShellEntry.addContextMenu(this._confirmEntry);
|
||||
this._confirmEntry.clutter_text.connect('activate', this._onConfirmActivate.bind(this));
|
||||
this.prompt.bind_property('confirm-visible',
|
||||
this._confirmEntry, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
passwordBox.add_child(this._confirmEntry);
|
||||
|
||||
this.prompt.set_password_actor(this._passwordEntry.clutter_text);
|
||||
this.prompt.set_confirm_actor(this._confirmEntry.clutter_text);
|
||||
|
||||
let warningBox = new St.BoxLayout({ vertical: true });
|
||||
|
||||
let capsLockWarning = new ShellEntry.CapsLockWarning();
|
||||
let syncCapsLockWarningVisibility = () => {
|
||||
capsLockWarning.visible =
|
||||
this.prompt.password_visible || this.prompt.confirm_visible;
|
||||
};
|
||||
this.prompt.connect('notify::password-visible', syncCapsLockWarningVisibility);
|
||||
this.prompt.connect('notify::confirm-visible', syncCapsLockWarningVisibility);
|
||||
warningBox.add_child(capsLockWarning);
|
||||
|
||||
let warning = new St.Label({ style_class: 'prompt-dialog-error-label' });
|
||||
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
warning.clutter_text.line_wrap = true;
|
||||
this.prompt.bind_property('warning',
|
||||
warning, 'text', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.connect('notify::warning-visible', () => {
|
||||
warning.opacity = this.prompt.warning_visible ? 255 : 0;
|
||||
});
|
||||
this.prompt.connect('notify::warning', () => {
|
||||
if (this._passwordEntry && warning !== '')
|
||||
Util.wiggle(this._passwordEntry);
|
||||
});
|
||||
warningBox.add_child(warning);
|
||||
|
||||
passwordBox.add_child(warningBox);
|
||||
content.add_child(passwordBox);
|
||||
|
||||
this._choice = new CheckBox.CheckBox();
|
||||
this.prompt.bind_property('choice-label', this._choice.getLabelActor(),
|
||||
'text', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('choice-chosen', this._choice,
|
||||
'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
|
||||
this.prompt.bind_property('choice-visible', this._choice,
|
||||
'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
content.add_child(this._choice);
|
||||
|
||||
this.contentLayout.add_child(content);
|
||||
|
||||
this._cancelButton = this.addButton({
|
||||
label: '',
|
||||
action: this._onCancelButton.bind(this),
|
||||
key: Clutter.KEY_Escape,
|
||||
});
|
||||
this._continueButton = this.addButton({
|
||||
label: '',
|
||||
action: this._onContinueButton.bind(this),
|
||||
default: true,
|
||||
});
|
||||
|
||||
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
||||
}
|
||||
|
||||
_setWorking(working) {
|
||||
if (!this._workSpinner)
|
||||
return;
|
||||
|
||||
if (working)
|
||||
this._workSpinner.play();
|
||||
else
|
||||
this._workSpinner.stop();
|
||||
}
|
||||
|
||||
_buildControlTable() {
|
||||
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
||||
let table = new St.Widget({
|
||||
style_class: 'keyring-dialog-control-table',
|
||||
layout_manager: layout,
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
});
|
||||
layout.hookup_style(table);
|
||||
let rtl = table.get_text_direction() == Clutter.TextDirection.RTL;
|
||||
let row = 0;
|
||||
|
||||
if (this.prompt.password_visible) {
|
||||
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
label.set_text(_("Password:"));
|
||||
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._passwordEntry = new St.PasswordEntry({
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
text: '',
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
});
|
||||
ShellEntry.addContextMenu(this._passwordEntry);
|
||||
this._passwordEntry.clutter_text.connect('activate', this._onPasswordActivate.bind(this));
|
||||
|
||||
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, {
|
||||
animate: true,
|
||||
});
|
||||
|
||||
if (rtl) {
|
||||
layout.attach(this._workSpinner, 0, row, 1, 1);
|
||||
layout.attach(this._passwordEntry, 1, row, 1, 1);
|
||||
layout.attach(label, 2, row, 1, 1);
|
||||
} else {
|
||||
layout.attach(label, 0, row, 1, 1);
|
||||
layout.attach(this._passwordEntry, 1, row, 1, 1);
|
||||
layout.attach(this._workSpinner, 2, row, 1, 1);
|
||||
}
|
||||
row++;
|
||||
} else {
|
||||
this._workSpinner = null;
|
||||
this._passwordEntry = null;
|
||||
}
|
||||
|
||||
if (this.prompt.confirm_visible) {
|
||||
var label = new St.Label({ style_class: 'prompt-dialog-password-label',
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
label.set_text(_("Type again:"));
|
||||
this._confirmEntry = new St.PasswordEntry({
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
text: '',
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
});
|
||||
ShellEntry.addContextMenu(this._confirmEntry);
|
||||
this._confirmEntry.clutter_text.connect('activate', this._onConfirmActivate.bind(this));
|
||||
if (rtl) {
|
||||
layout.attach(this._confirmEntry, 0, row, 1, 1);
|
||||
layout.attach(label, 1, row, 1, 1);
|
||||
} else {
|
||||
layout.attach(label, 0, row, 1, 1);
|
||||
layout.attach(this._confirmEntry, 1, row, 1, 1);
|
||||
}
|
||||
row++;
|
||||
} else {
|
||||
this._confirmEntry = null;
|
||||
}
|
||||
|
||||
this.prompt.set_password_actor(this._passwordEntry ? this._passwordEntry.clutter_text : null);
|
||||
this.prompt.set_confirm_actor(this._confirmEntry ? this._confirmEntry.clutter_text : null);
|
||||
|
||||
if (this._passwordEntry || this._confirmEntry) {
|
||||
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
|
||||
layout.attach(this._capsLockWarningLabel, 1, row, 1, 1);
|
||||
row++;
|
||||
}
|
||||
|
||||
if (this.prompt.choice_visible) {
|
||||
let choice = new CheckBox.CheckBox();
|
||||
this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('choice-chosen', choice, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
|
||||
layout.attach(choice, rtl ? 0 : 1, row, 1, 1);
|
||||
row++;
|
||||
}
|
||||
|
||||
let warning = new St.Label({ style_class: 'prompt-dialog-error-label',
|
||||
x_align: Clutter.ActorAlign.START });
|
||||
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
warning.clutter_text.line_wrap = true;
|
||||
layout.attach(warning, rtl ? 0 : 1, row, 1, 1);
|
||||
this.prompt.bind_property('warning-visible', warning, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('warning', warning, 'text', GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
if (this._controlTable) {
|
||||
this._controlTable.destroy_all_children();
|
||||
this._controlTable.destroy();
|
||||
}
|
||||
|
||||
this._controlTable = table;
|
||||
this._content.add_child(table);
|
||||
}
|
||||
|
||||
_updateSensitivity(sensitive) {
|
||||
if (this._passwordEntry) {
|
||||
this._passwordEntry.reactive = sensitive;
|
||||
@@ -169,7 +123,6 @@ class KeyringDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
this._continueButton.can_focus = sensitive;
|
||||
this._continueButton.reactive = sensitive;
|
||||
this._setWorking(!sensitive);
|
||||
}
|
||||
|
||||
_ensureOpen() {
|
||||
@@ -191,16 +144,16 @@ class KeyringDialog extends ModalDialog.ModalDialog {
|
||||
}
|
||||
|
||||
_onShowPassword() {
|
||||
this._buildControlTable();
|
||||
this._ensureOpen();
|
||||
this._updateSensitivity(true);
|
||||
this._passwordEntry.text = '';
|
||||
this._passwordEntry.grab_key_focus();
|
||||
}
|
||||
|
||||
_onShowConfirm() {
|
||||
this._buildControlTable();
|
||||
this._ensureOpen();
|
||||
this._updateSensitivity(true);
|
||||
this._confirmEntry.text = '';
|
||||
this._continueButton.grab_key_focus();
|
||||
}
|
||||
|
||||
|
@@ -33,38 +33,26 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
||||
title: this._content.title,
|
||||
description: this._content.message,
|
||||
});
|
||||
this.contentLayout.add_actor(contentBox);
|
||||
|
||||
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
||||
let secretTable = new St.Widget({ style_class: 'network-dialog-secret-table',
|
||||
layout_manager: layout });
|
||||
layout.hookup_style(secretTable);
|
||||
|
||||
let rtl = secretTable.get_text_direction() == Clutter.TextDirection.RTL;
|
||||
let initialFocusSet = false;
|
||||
let pos = 0;
|
||||
for (let i = 0; i < this._content.secrets.length; i++) {
|
||||
let secret = this._content.secrets[i];
|
||||
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
|
||||
text: secret.label,
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
|
||||
let reactive = secret.key != null;
|
||||
|
||||
let entryParams = {
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
hint_text: secret.label,
|
||||
text: secret.value,
|
||||
can_focus: reactive,
|
||||
reactive,
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
};
|
||||
if (secret.password)
|
||||
secret.entry = new St.PasswordEntry(entryParams);
|
||||
else
|
||||
secret.entry = new St.Entry(entryParams);
|
||||
ShellEntry.addContextMenu(secret.entry);
|
||||
contentBox.add_child(secret.entry);
|
||||
|
||||
if (secret.validate)
|
||||
secret.valid = secret.validate(secret);
|
||||
@@ -89,36 +77,26 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
||||
} else {
|
||||
secret.valid = true;
|
||||
}
|
||||
|
||||
if (rtl) {
|
||||
layout.attach(secret.entry, 0, pos, 1, 1);
|
||||
layout.attach(label, 1, pos, 1, 1);
|
||||
} else {
|
||||
layout.attach(label, 0, pos, 1, 1);
|
||||
layout.attach(secret.entry, 1, pos, 1, 1);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (this._content.secrets.some(s => s.password)) {
|
||||
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
|
||||
if (rtl)
|
||||
layout.attach(this._capsLockWarningLabel, 0, pos, 1, 1);
|
||||
else
|
||||
layout.attach(this._capsLockWarningLabel, 1, pos, 1, 1);
|
||||
let capsLockWarning = new ShellEntry.CapsLockWarning();
|
||||
contentBox.add_child(capsLockWarning);
|
||||
}
|
||||
|
||||
contentBox.add_child(secretTable);
|
||||
|
||||
if (flags & NM.SecretAgentGetSecretsFlags.WPS_PBC_ACTIVE) {
|
||||
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
|
||||
text: _("Alternatively you can connect by pushing the “WPS” button on your router.") });
|
||||
let descriptionLabel = new St.Label({
|
||||
text: _('Alternatively you can connect by pushing the “WPS” button on your router.'),
|
||||
style_class: 'message-dialog-description',
|
||||
});
|
||||
descriptionLabel.clutter_text.line_wrap = true;
|
||||
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
|
||||
contentBox.add_child(descriptionLabel);
|
||||
}
|
||||
|
||||
this.contentLayout.add_child(contentBox);
|
||||
|
||||
this._okButton = {
|
||||
label: _("Connect"),
|
||||
action: this._onOk.bind(this),
|
||||
@@ -325,7 +303,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
||||
case '802-11-wireless':
|
||||
wirelessSetting = this._connection.get_setting_wireless();
|
||||
ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
|
||||
content.title = _("Authentication required by wireless network");
|
||||
content.title = _('Authentication required');
|
||||
content.message = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
|
||||
this._getWirelessSecrets(content.secrets, wirelessSetting);
|
||||
break;
|
||||
@@ -353,7 +331,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
||||
// fall through
|
||||
case 'cdma':
|
||||
case 'bluetooth':
|
||||
content.title = _("Mobile broadband network password");
|
||||
content.title = _('Authentication required');
|
||||
content.message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
|
||||
this._getMobileSecrets(content.secrets, connectionType);
|
||||
break;
|
||||
@@ -700,7 +678,7 @@ var NetworkAgent = class {
|
||||
case '802-11-wireless': {
|
||||
let wirelessSetting = connection.get_setting_wireless();
|
||||
let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
|
||||
title = _("Authentication required by wireless network");
|
||||
title = _('Authentication required');
|
||||
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
|
||||
break;
|
||||
}
|
||||
@@ -721,7 +699,7 @@ var NetworkAgent = class {
|
||||
// fall through
|
||||
case 'cdma':
|
||||
case 'bluetooth':
|
||||
title = _("Mobile broadband network password");
|
||||
title = _('Authentication required');
|
||||
body = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
|
||||
break;
|
||||
case 'vpn':
|
||||
|
@@ -4,21 +4,19 @@
|
||||
const { AccountsService, Clutter, GLib,
|
||||
GObject, Pango, PolkitAgent, Polkit, Shell, St } = imports.gi;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const DialogMode = {
|
||||
AUTH: 0,
|
||||
CONFIRM: 1,
|
||||
};
|
||||
|
||||
var DIALOG_ICON_SIZE = 48;
|
||||
|
||||
var WORK_SPINNER_ICON_SIZE = 16;
|
||||
const DIALOG_ICON_SIZE = 64;
|
||||
|
||||
const DELAYED_RESET_TIMEOUT = 200;
|
||||
|
||||
@@ -40,8 +38,10 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
|
||||
let title = _("Authentication Required");
|
||||
|
||||
let content = new Dialog.MessageDialogContent({ title, description });
|
||||
this.contentLayout.add_actor(content);
|
||||
let headerContent = new Dialog.MessageDialogContent({ title, description });
|
||||
this.contentLayout.add_child(headerContent);
|
||||
|
||||
let bodyContent = new Dialog.MessageDialogContent();
|
||||
|
||||
if (userNames.length > 1) {
|
||||
log(`polkitAuthenticationAgent: Received ${userNames.length} ` +
|
||||
@@ -59,22 +59,21 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
|
||||
let userBox = new St.BoxLayout({
|
||||
style_class: 'polkit-dialog-user-layout',
|
||||
vertical: false,
|
||||
vertical: true,
|
||||
});
|
||||
content.add_child(userBox);
|
||||
bodyContent.add_child(userBox);
|
||||
|
||||
this._userAvatar = new UserWidget.Avatar(this._user, {
|
||||
iconSize: DIALOG_ICON_SIZE,
|
||||
styleClass: 'polkit-dialog-user-icon',
|
||||
});
|
||||
this._userAvatar.x_align = Clutter.ActorAlign.CENTER;
|
||||
userBox.add_child(this._userAvatar);
|
||||
|
||||
this._userLabel = new St.Label({
|
||||
style_class: userName === 'root'
|
||||
? 'polkit-dialog-user-root-label'
|
||||
: 'polkit-dialog-user-label',
|
||||
x_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
|
||||
if (userName === 'root')
|
||||
@@ -82,58 +81,60 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
|
||||
userBox.add_child(this._userLabel);
|
||||
|
||||
this._passwordBox = new St.BoxLayout({ vertical: false, style_class: 'prompt-dialog-password-box' });
|
||||
content.add_child(this._passwordBox);
|
||||
this._passwordLabel = new St.Label({
|
||||
style_class: 'prompt-dialog-password-label',
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
let passwordBox = new St.BoxLayout({
|
||||
style_class: 'prompt-dialog-password-layout',
|
||||
vertical: true,
|
||||
});
|
||||
this._passwordBox.add_child(this._passwordLabel);
|
||||
|
||||
this._passwordEntry = new St.PasswordEntry({
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
text: "",
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
visible: false,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
ShellEntry.addContextMenu(this._passwordEntry);
|
||||
this._passwordEntry.clutter_text.connect('activate', this._onEntryActivate.bind(this));
|
||||
this._passwordEntry.bind_property('reactive',
|
||||
this._passwordEntry.clutter_text, 'editable',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
this._passwordBox.add_child(this._passwordEntry);
|
||||
passwordBox.add_child(this._passwordEntry);
|
||||
|
||||
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, {
|
||||
animate: true,
|
||||
let warningBox = new St.BoxLayout({ vertical: true });
|
||||
|
||||
let capsLockWarning = new ShellEntry.CapsLockWarning();
|
||||
this._passwordEntry.bind_property('visible',
|
||||
capsLockWarning, 'visible',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
warningBox.add_child(capsLockWarning);
|
||||
|
||||
this._errorMessageLabel = new St.Label({
|
||||
style_class: 'prompt-dialog-error-label',
|
||||
visible: false,
|
||||
});
|
||||
this._passwordBox.add(this._workSpinner);
|
||||
|
||||
this._passwordBox.hide();
|
||||
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning({ style_class: 'prompt-dialog-caps-lock-warning' });
|
||||
content.add_child(this._capsLockWarningLabel);
|
||||
|
||||
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label' });
|
||||
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._errorMessageLabel.clutter_text.line_wrap = true;
|
||||
content.add_child(this._errorMessageLabel);
|
||||
this._errorMessageLabel.hide();
|
||||
warningBox.add_child(this._errorMessageLabel);
|
||||
|
||||
this._infoMessageLabel = new St.Label({ style_class: 'prompt-dialog-info-label' });
|
||||
this._infoMessageLabel = new St.Label({
|
||||
style_class: 'prompt-dialog-info-label',
|
||||
visible: false,
|
||||
});
|
||||
this._infoMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._infoMessageLabel.clutter_text.line_wrap = true;
|
||||
content.add_child(this._infoMessageLabel);
|
||||
this._infoMessageLabel.hide();
|
||||
warningBox.add_child(this._infoMessageLabel);
|
||||
|
||||
/* text is intentionally non-blank otherwise the height is not the same as for
|
||||
* infoMessage and errorMessageLabel - but it is still invisible because
|
||||
* gnome-shell.css sets the color to be transparent
|
||||
*/
|
||||
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
|
||||
text: 'abc' });
|
||||
this._nullMessageLabel.add_style_class_name('hidden');
|
||||
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label' });
|
||||
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._nullMessageLabel.clutter_text.line_wrap = true;
|
||||
content.add_child(this._nullMessageLabel);
|
||||
this._nullMessageLabel.show();
|
||||
warningBox.add_child(this._nullMessageLabel);
|
||||
|
||||
passwordBox.add_child(warningBox);
|
||||
bodyContent.add_child(passwordBox);
|
||||
|
||||
this._cancelButton = this.addButton({ label: _("Cancel"),
|
||||
action: this.cancel.bind(this),
|
||||
@@ -149,6 +150,8 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
this._okButton.reactive = text.get_text().length > 0;
|
||||
});
|
||||
|
||||
this.contentLayout.add_child(bodyContent);
|
||||
|
||||
this._doneEmitted = false;
|
||||
|
||||
this._mode = -1;
|
||||
@@ -163,13 +166,6 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
this._onUserChanged();
|
||||
}
|
||||
|
||||
_setWorking(working) {
|
||||
if (working)
|
||||
this._workSpinner.play();
|
||||
else
|
||||
this._workSpinner.stop();
|
||||
}
|
||||
|
||||
_initiateSession() {
|
||||
this._destroySession(DELAYED_RESET_TIMEOUT);
|
||||
|
||||
@@ -218,7 +214,6 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
|
||||
this._passwordEntry.reactive = false;
|
||||
this._okButton.reactive = false;
|
||||
this._setWorking(true);
|
||||
|
||||
this._session.response(response);
|
||||
// When the user responds, dismiss already shown info and
|
||||
@@ -260,6 +255,8 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
this._errorMessageLabel.show();
|
||||
this._infoMessageLabel.hide();
|
||||
this._nullMessageLabel.hide();
|
||||
|
||||
Util.wiggle(this._passwordEntry);
|
||||
}
|
||||
|
||||
/* Try and authenticate again */
|
||||
@@ -273,19 +270,20 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
this._sessionRequestTimeoutId = 0;
|
||||
}
|
||||
|
||||
// Cheap localization trick
|
||||
if (request == 'Password:' || request == 'Password: ')
|
||||
this._passwordLabel.set_text(_("Password:"));
|
||||
// Hack: The request string comes directly from PAM, if it's "Password:"
|
||||
// we replace it with our own, if it's something else we replace the
|
||||
// last colon and any trailing spaces with a "…".
|
||||
if (request === 'Password:' || request === 'Password: ')
|
||||
this._passwordEntry.hint_text = _('Enter Password…');
|
||||
else
|
||||
this._passwordLabel.set_text(request);
|
||||
this._passwordEntry.hint_text = request.replace(/: *$/, '…');
|
||||
|
||||
this._passwordEntry.password_visible = echoOn;
|
||||
|
||||
this._passwordBox.show();
|
||||
this._passwordEntry.show();
|
||||
this._passwordEntry.set_text('');
|
||||
this._passwordEntry.reactive = true;
|
||||
this._okButton.reactive = false;
|
||||
this._setWorking(false);
|
||||
|
||||
this._ensureOpen();
|
||||
this._passwordEntry.grab_key_focus();
|
||||
@@ -332,7 +330,7 @@ var AuthenticationDialog = GObject.registerClass({
|
||||
if (this.state != ModalDialog.State.OPENED)
|
||||
return;
|
||||
|
||||
this._passwordBox.hide();
|
||||
this._passwordEntry.hide();
|
||||
this._cancelButton.grab_key_focus();
|
||||
this._okButton.reactive = false;
|
||||
};
|
||||
|
@@ -432,7 +432,6 @@ var MessagesIndicator = GObject.registerClass(
|
||||
class MessagesIndicator extends St.Icon {
|
||||
_init() {
|
||||
super._init({
|
||||
icon_name: 'message-indicator-symbolic',
|
||||
icon_size: 16,
|
||||
visible: false,
|
||||
y_expand: true,
|
||||
@@ -440,6 +439,13 @@ class MessagesIndicator extends St.Icon {
|
||||
});
|
||||
|
||||
this._sources = [];
|
||||
this._count = 0;
|
||||
this._doNotDisturb = false;
|
||||
|
||||
this._settings = new Gio.Settings({
|
||||
schema_id: 'org.gnome.desktop.notifications',
|
||||
});
|
||||
this._settings.connect('changed::show-banners', this._sync.bind(this));
|
||||
|
||||
Main.messageTray.connect('source-added', this._onSourceAdded.bind(this));
|
||||
Main.messageTray.connect('source-removed', this._onSourceRemoved.bind(this));
|
||||
@@ -447,6 +453,11 @@ class MessagesIndicator extends St.Icon {
|
||||
|
||||
let sources = Main.messageTray.getSources();
|
||||
sources.forEach(source => this._onSourceAdded(null, source));
|
||||
|
||||
this.connect('destroy', () => {
|
||||
this._settings.run_dispose();
|
||||
this._settings = null;
|
||||
});
|
||||
}
|
||||
|
||||
_onSourceAdded(tray, source) {
|
||||
@@ -463,9 +474,17 @@ class MessagesIndicator extends St.Icon {
|
||||
_updateCount() {
|
||||
let count = 0;
|
||||
this._sources.forEach(source => (count += source.unseenCount));
|
||||
count -= Main.messageTray.queueCount;
|
||||
this._count = count - Main.messageTray.queueCount;
|
||||
|
||||
this.visible = count > 0;
|
||||
this._sync();
|
||||
}
|
||||
|
||||
_sync() {
|
||||
let doNotDisturb = !this._settings.get_boolean('show-banners');
|
||||
this.icon_name = doNotDisturb
|
||||
? 'notifications-disabled-symbolic'
|
||||
: 'message-indicator-symbolic';
|
||||
this.visible = doNotDisturb || this._count > 0;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -473,21 +492,19 @@ var IndicatorPad = GObject.registerClass(
|
||||
class IndicatorPad extends St.Widget {
|
||||
_init(actor) {
|
||||
this._source = actor;
|
||||
this._source.connect('notify::visible', () => this.queue_relayout());
|
||||
this._source.connect('notify::size', () => this.queue_relayout());
|
||||
super._init();
|
||||
this._source.bind_property('visible',
|
||||
this, 'visible',
|
||||
GObject.BindingFlags.SYNC_CREATE);
|
||||
}
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
if (this._source.visible)
|
||||
return this._source.get_preferred_width(forHeight);
|
||||
return [0, 0];
|
||||
return this._source.get_preferred_width(forHeight);
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
if (this._source.visible)
|
||||
return this._source.get_preferred_height(forWidth);
|
||||
return [0, 0];
|
||||
return this._source.get_preferred_height(forWidth);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -559,7 +576,7 @@ class DateMenuButton extends PanelMenu.Button {
|
||||
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
|
||||
this._indicator = new MessagesIndicator();
|
||||
|
||||
let box = new St.BoxLayout();
|
||||
let box = new St.BoxLayout({ style_class: 'clock-display-box' });
|
||||
box.add_actor(new IndicatorPad(this._indicator));
|
||||
box.add_actor(this._clockDisplay);
|
||||
box.add_actor(this._indicator);
|
||||
|
16
js/ui/dnd.js
16
js/ui/dnd.js
@@ -313,8 +313,8 @@ var _Draggable = class _Draggable {
|
||||
device = event.get_device();
|
||||
|
||||
if (device == undefined) {
|
||||
let manager = Clutter.DeviceManager.get_default();
|
||||
device = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
device = seat.get_pointer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,14 +411,18 @@ var _Draggable = class _Draggable {
|
||||
this._snapBackY = this._dragStartY + this._dragOffsetY;
|
||||
this._snapBackScale = this._dragActor.scale_x;
|
||||
|
||||
let origDragOffsetX = this._dragOffsetX;
|
||||
let origDragOffsetY = this._dragOffsetY;
|
||||
let [transX, transY] = this._dragActor.get_translation();
|
||||
this._dragOffsetX -= transX;
|
||||
this._dragOffsetY -= transY;
|
||||
|
||||
if (this._dragActorMaxSize != undefined) {
|
||||
let [scaledWidth, scaledHeight] = this._dragActor.get_transformed_size();
|
||||
let currentSize = Math.max(scaledWidth, scaledHeight);
|
||||
if (currentSize > this._dragActorMaxSize) {
|
||||
let scale = this._dragActorMaxSize / currentSize;
|
||||
let origScale = this._dragActor.scale_x;
|
||||
let origDragOffsetX = this._dragOffsetX;
|
||||
let origDragOffsetY = this._dragOffsetY;
|
||||
|
||||
// The position of the actor changes as we scale
|
||||
// around the drag position, but we can't just tween
|
||||
@@ -435,8 +439,8 @@ var _Draggable = class _Draggable {
|
||||
|
||||
this._dragActor.get_transition('scale-x').connect('new-frame', () => {
|
||||
let currentScale = this._dragActor.scale_x / origScale;
|
||||
this._dragOffsetX = currentScale * origDragOffsetX;
|
||||
this._dragOffsetY = currentScale * origDragOffsetY;
|
||||
this._dragOffsetX = currentScale * origDragOffsetX - transX;
|
||||
this._dragOffsetY = currentScale * origDragOffsetY - transY;
|
||||
this._dragActor.set_position(
|
||||
this._dragX + this._dragOffsetX,
|
||||
this._dragY + this._dragOffsetY);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported init, installExtension, uninstallExtension,
|
||||
checkForUpdates, updateExtension */
|
||||
/* exported init, installExtension, uninstallExtension, checkForUpdates */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Soup } = imports.gi;
|
||||
|
||||
@@ -100,13 +99,9 @@ function gotExtensionZipFile(session, message, uuid, dir, callback, errback) {
|
||||
});
|
||||
}
|
||||
|
||||
function updateExtension(uuid) {
|
||||
// This gets a bit tricky. We want the update to be seamless -
|
||||
// if we have any error during downloading or extracting, we
|
||||
// want to not unload the current version.
|
||||
|
||||
let oldExtensionTmpDir = GLib.Dir.make_tmp('XXXXXX-shell-extension');
|
||||
let newExtensionTmpDir = GLib.Dir.make_tmp('XXXXXX-shell-extension');
|
||||
function downloadExtensionUpdate(uuid) {
|
||||
let dir = Gio.File.new_for_path(
|
||||
GLib.build_filenamev([global.userdatadir, 'extension-updates', uuid]));
|
||||
|
||||
let params = { shell_version: Config.PACKAGE_VERSION };
|
||||
|
||||
@@ -114,39 +109,10 @@ function updateExtension(uuid) {
|
||||
let message = Soup.form_request_new_from_hash('GET', url, params);
|
||||
|
||||
_httpSession.queue_message(message, session => {
|
||||
gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, () => {
|
||||
let oldExtension = Main.extensionManager.lookup(uuid);
|
||||
let extensionDir = oldExtension.dir;
|
||||
|
||||
if (!Main.extensionManager.unloadExtension(oldExtension))
|
||||
return;
|
||||
|
||||
FileUtils.recursivelyMoveDir(extensionDir, oldExtensionTmpDir);
|
||||
FileUtils.recursivelyMoveDir(newExtensionTmpDir, extensionDir);
|
||||
|
||||
let extension = null;
|
||||
|
||||
try {
|
||||
extension = Main.extensionManager.createExtensionObject(uuid, extensionDir, ExtensionUtils.ExtensionType.PER_USER);
|
||||
Main.extensionManager.loadExtension(extension);
|
||||
} catch (e) {
|
||||
if (extension)
|
||||
Main.extensionManager.unloadExtension(extension);
|
||||
|
||||
logError(e, 'Error loading extension %s'.format(uuid));
|
||||
|
||||
FileUtils.recursivelyDeleteDir(extensionDir, false);
|
||||
FileUtils.recursivelyMoveDir(oldExtensionTmpDir, extensionDir);
|
||||
|
||||
// Restore what was there before. We can't do much if we
|
||||
// fail here.
|
||||
Main.extensionManager.loadExtension(oldExtension);
|
||||
return;
|
||||
}
|
||||
|
||||
FileUtils.recursivelyDeleteDir(oldExtensionTmpDir, true);
|
||||
gotExtensionZipFile(session, message, uuid, dir, () => {
|
||||
Main.extensionManager.notifyExtensionUpdate(uuid);
|
||||
}, (code, msg) => {
|
||||
log(`Error while updating extension ${uuid}: ${code} (${msg})`);
|
||||
log(`Error while downloading update for extension ${uuid}: ${code} (${msg})`);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -154,11 +120,21 @@ function updateExtension(uuid) {
|
||||
function checkForUpdates() {
|
||||
let metadatas = {};
|
||||
Main.extensionManager.getUuids().forEach(uuid => {
|
||||
metadatas[uuid] = Main.extensionManager.extensions[uuid].metadata;
|
||||
let extension = Main.extensionManager.lookup(uuid);
|
||||
if (extension.type !== ExtensionUtils.ExtensionType.PER_USER)
|
||||
return;
|
||||
if (extension.hasUpdate)
|
||||
return;
|
||||
metadatas[uuid] = extension.metadata;
|
||||
});
|
||||
|
||||
let params = { shell_version: Config.PACKAGE_VERSION,
|
||||
installed: JSON.stringify(metadatas) };
|
||||
let versionCheck = global.settings.get_boolean(
|
||||
'disable-extension-version-validation');
|
||||
let params = {
|
||||
shell_version: Config.PACKAGE_VERSION,
|
||||
installed: JSON.stringify(metadatas),
|
||||
disable_version_validation: `${versionCheck}`,
|
||||
};
|
||||
|
||||
let url = REPOSITORY_URL_UPDATE;
|
||||
let message = Soup.form_request_new_from_hash('GET', url, params);
|
||||
@@ -172,7 +148,7 @@ function checkForUpdates() {
|
||||
if (operation == 'blacklist')
|
||||
uninstallExtension(uuid);
|
||||
else if (operation == 'upgrade' || operation == 'downgrade')
|
||||
updateExtension(uuid);
|
||||
downloadExtensionUpdate(uuid);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -197,7 +173,8 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
|
||||
}]);
|
||||
|
||||
let content = new Dialog.MessageDialogContent({
|
||||
title: _("Download and install “%s” from extensions.gnome.org?").format(info.name),
|
||||
title: _('Install Extension'),
|
||||
description: _('Download and install “%s” from extensions.gnome.org?').format(info.name),
|
||||
});
|
||||
|
||||
this.contentLayout.add(content);
|
||||
|
@@ -1,12 +1,14 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported init connect disconnect */
|
||||
|
||||
const { GLib, Gio, St } = imports.gi;
|
||||
const { GLib, Gio, GObject, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
|
||||
const { ExtensionState, ExtensionType } = ExtensionUtils;
|
||||
|
||||
@@ -15,10 +17,13 @@ const DISABLED_EXTENSIONS_KEY = 'disabled-extensions';
|
||||
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
|
||||
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
|
||||
|
||||
const UPDATE_CHECK_TIMEOUT = 24 * 60 * 60; // 1 day in seconds
|
||||
|
||||
var ExtensionManager = class {
|
||||
constructor() {
|
||||
this._initialized = false;
|
||||
this._enabled = false;
|
||||
this._updateNotified = false;
|
||||
|
||||
this._extensions = new Map();
|
||||
this._enabledExtensions = [];
|
||||
@@ -45,7 +50,14 @@ var ExtensionManager = class {
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
|
||||
this._installExtensionUpdates();
|
||||
this._sessionUpdated();
|
||||
|
||||
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, UPDATE_CHECK_TIMEOUT, () => {
|
||||
ExtensionDownloader.checkForUpdates();
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
});
|
||||
ExtensionDownloader.checkForUpdates();
|
||||
}
|
||||
|
||||
lookup(uuid) {
|
||||
@@ -198,6 +210,27 @@ var ExtensionManager = class {
|
||||
return true;
|
||||
}
|
||||
|
||||
notifyExtensionUpdate(uuid) {
|
||||
let extension = this.lookup(uuid);
|
||||
if (!extension)
|
||||
return;
|
||||
|
||||
extension.hasUpdate = true;
|
||||
this.emit('extension-state-changed', extension);
|
||||
|
||||
if (!this._updateNotified) {
|
||||
this._updateNotified = true;
|
||||
|
||||
let source = new ExtensionUpdateSource();
|
||||
Main.messageTray.add(source);
|
||||
|
||||
let notification = new MessageTray.Notification(source,
|
||||
_('Extension Updates Available'),
|
||||
_('Extension updates are ready to be installed.'));
|
||||
source.showNotification(notification);
|
||||
}
|
||||
}
|
||||
|
||||
logExtensionError(uuid, error) {
|
||||
let extension = this.lookup(uuid);
|
||||
if (!extension)
|
||||
@@ -253,6 +286,7 @@ var ExtensionManager = class {
|
||||
path: dir.get_path(),
|
||||
error: '',
|
||||
hasPrefs: dir.get_child('prefs.js').query_exists(null),
|
||||
hasUpdate: false,
|
||||
canChange: false,
|
||||
};
|
||||
this._extensions.set(uuid, extension);
|
||||
@@ -446,6 +480,21 @@ var ExtensionManager = class {
|
||||
}).forEach(extension => this.reloadExtension(extension));
|
||||
}
|
||||
|
||||
_installExtensionUpdates() {
|
||||
FileUtils.collectFromDatadirs('extension-updates', true, (dir, info) => {
|
||||
let fileType = info.get_file_type();
|
||||
if (fileType !== Gio.FileType.DIRECTORY)
|
||||
return;
|
||||
let uuid = info.get_name();
|
||||
let extensionDir = Gio.File.new_for_path(
|
||||
GLib.build_filenamev([global.userdatadir, 'extensions', uuid]));
|
||||
|
||||
FileUtils.recursivelyDeleteDir(extensionDir, false);
|
||||
FileUtils.recursivelyMoveDir(dir, extensionDir);
|
||||
FileUtils.recursivelyDeleteDir(dir, true);
|
||||
});
|
||||
}
|
||||
|
||||
_loadExtensions() {
|
||||
global.settings.connect(`changed::${ENABLED_EXTENSIONS_KEY}`,
|
||||
this._onEnabledExtensionsChanged.bind(this));
|
||||
@@ -531,3 +580,27 @@ var ExtensionManager = class {
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ExtensionManager.prototype);
|
||||
|
||||
const ExtensionUpdateSource = GObject.registerClass(
|
||||
class ExtensionUpdateSource extends MessageTray.Source {
|
||||
_init() {
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
this._app = appSys.lookup_app('org.gnome.Extensions.desktop');
|
||||
|
||||
super._init(this._app.get_name());
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return this._app.app_info.get_icon();
|
||||
}
|
||||
|
||||
_createPolicy() {
|
||||
return new MessageTray.NotificationApplicationPolicy(this._app.id);
|
||||
}
|
||||
|
||||
open() {
|
||||
this._app.activate();
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
}
|
||||
});
|
||||
|
@@ -9,8 +9,6 @@ const Main = imports.ui.main;
|
||||
var ICON_SIZE = 96;
|
||||
var MIN_ICON_SIZE = 16;
|
||||
|
||||
var EXTRA_SPACE_ANIMATION_TIME = 250;
|
||||
|
||||
var ANIMATION_TIME_IN = 350;
|
||||
var ANIMATION_TIME_OUT = 1 / 2 * ANIMATION_TIME_IN;
|
||||
var ANIMATION_MAX_DELAY_FOR_ITEM = 2 / 3 * ANIMATION_TIME_IN;
|
||||
@@ -197,7 +195,7 @@ function zoomOutActorAtPos(actor, x, y) {
|
||||
}
|
||||
|
||||
function animateIconPosition(icon, box, flags, nChangedIcons) {
|
||||
if (!icon.has_allocation() || icon.allocation.equal(box)) {
|
||||
if (!icon.has_allocation() || icon.allocation.equal(box) || icon.opacity === 0) {
|
||||
icon.allocate(box, flags);
|
||||
return false;
|
||||
}
|
||||
@@ -846,10 +844,8 @@ var IconGrid = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
var PaginatedIconGrid = GObject.registerClass({
|
||||
Signals: { 'space-opened': {},
|
||||
'space-closed': {} },
|
||||
}, class PaginatedIconGrid extends IconGrid {
|
||||
var PaginatedIconGrid = GObject.registerClass(
|
||||
class PaginatedIconGrid extends IconGrid {
|
||||
_init(params) {
|
||||
super._init(params);
|
||||
this._nPages = 0;
|
||||
@@ -981,94 +977,4 @@ var PaginatedIconGrid = GObject.registerClass({
|
||||
throw new Error('Item not found.');
|
||||
return Math.floor(index / this._childrenPerPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* openExtraSpace:
|
||||
* @param {Clutter.Actor} sourceItem: item for which to create extra space
|
||||
* @param {St.Side} side: where @sourceItem should be located relative to
|
||||
* the created space
|
||||
* @param {number} nRows: the amount of space to create
|
||||
*
|
||||
* Pan view to create extra space for @nRows above or below @sourceItem.
|
||||
*/
|
||||
openExtraSpace(sourceItem, side, nRows) {
|
||||
let children = this._getVisibleChildren();
|
||||
let index = children.indexOf(sourceItem);
|
||||
if (index == -1)
|
||||
throw new Error('Item not found.');
|
||||
|
||||
let pageIndex = Math.floor(index / this._childrenPerPage);
|
||||
let pageOffset = pageIndex * this._childrenPerPage;
|
||||
|
||||
let childrenPerRow = this._childrenPerPage / this._rowsPerPage;
|
||||
let sourceRow = Math.floor((index - pageOffset) / childrenPerRow);
|
||||
|
||||
let nRowsAbove = side == St.Side.TOP ? sourceRow + 1 : sourceRow;
|
||||
let nRowsBelow = this._rowsPerPage - nRowsAbove;
|
||||
|
||||
let nRowsUp, nRowsDown;
|
||||
if (side == St.Side.TOP) {
|
||||
nRowsDown = Math.min(nRowsBelow, nRows);
|
||||
nRowsUp = nRows - nRowsDown;
|
||||
} else {
|
||||
nRowsUp = Math.min(nRowsAbove, nRows);
|
||||
nRowsDown = nRows - nRowsUp;
|
||||
}
|
||||
|
||||
let childrenDown = children.splice(pageOffset +
|
||||
nRowsAbove * childrenPerRow,
|
||||
nRowsBelow * childrenPerRow);
|
||||
let childrenUp = children.splice(pageOffset,
|
||||
nRowsAbove * childrenPerRow);
|
||||
|
||||
// Special case: On the last row with no rows below the icon,
|
||||
// there's no need to move any rows either up or down
|
||||
if (childrenDown.length == 0 && nRowsUp == 0) {
|
||||
this._translatedChildren = [];
|
||||
this.emit('space-opened');
|
||||
} else {
|
||||
this._translateChildren(childrenUp, St.DirectionType.UP, nRowsUp);
|
||||
this._translateChildren(childrenDown, St.DirectionType.DOWN, nRowsDown);
|
||||
this._translatedChildren = childrenUp.concat(childrenDown);
|
||||
}
|
||||
}
|
||||
|
||||
_translateChildren(children, direction, nRows) {
|
||||
let translationY = nRows * (this._getVItemSize() + this._getSpacing());
|
||||
if (translationY == 0)
|
||||
return;
|
||||
|
||||
if (direction == St.DirectionType.UP)
|
||||
translationY *= -1;
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
children[i].translation_y = 0;
|
||||
let params = {
|
||||
translation_y: translationY,
|
||||
duration: EXTRA_SPACE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_IN_OUT_QUAD,
|
||||
};
|
||||
if (i == (children.length - 1))
|
||||
params.onComplete = () => this.emit('space-opened');
|
||||
children[i].ease(params);
|
||||
}
|
||||
}
|
||||
|
||||
closeExtraSpace() {
|
||||
if (!this._translatedChildren || !this._translatedChildren.length) {
|
||||
this.emit('space-closed');
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._translatedChildren.length; i++) {
|
||||
if (!this._translatedChildren[i].translation_y)
|
||||
continue;
|
||||
this._translatedChildren[i].ease({
|
||||
translation_y: 0,
|
||||
duration: EXTRA_SPACE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_IN_OUT_QUAD,
|
||||
onComplete: () => this.emit('space-closed'),
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* exported InhibitShortcutsDialog */
|
||||
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell } = imports.gi;
|
||||
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
@@ -75,22 +75,25 @@ var InhibitShortcutsDialog = GObject.registerClass({
|
||||
_buildLayout() {
|
||||
let name = this._app ? this._app.get_name() : this._window.title;
|
||||
|
||||
/* Translators: %s is an application name like "Settings" */
|
||||
let title = name
|
||||
? _("%s wants to inhibit shortcuts").format(name)
|
||||
: _("Application wants to inhibit shortcuts");
|
||||
|
||||
let contentParams = { title };
|
||||
let content = new Dialog.MessageDialogContent({
|
||||
title: _('Allow inhibiting shortcuts'),
|
||||
description: name
|
||||
/* Translators: %s is an application name like "Settings" */
|
||||
? _('The application %s wants to inhibit shortcuts').format(name)
|
||||
: _('An application wants to inhibit shortcuts'),
|
||||
});
|
||||
|
||||
let restoreAccel = this._getRestoreAccel();
|
||||
if (restoreAccel) {
|
||||
contentParams.description =
|
||||
let restoreLabel = new St.Label({
|
||||
/* Translators: %s is a keyboard shortcut like "Super+x" */
|
||||
_("You can restore shortcuts by pressing %s.").format(restoreAccel);
|
||||
text: _('You can restore shortcuts by pressing %s.').format(restoreAccel),
|
||||
style_class: 'message-dialog-description',
|
||||
});
|
||||
content.add_child(restoreLabel);
|
||||
}
|
||||
|
||||
let content = new Dialog.MessageDialogContent(contentParams);
|
||||
this._dialog.contentLayout.add_actor(content);
|
||||
this._dialog.contentLayout.add_child(content);
|
||||
|
||||
this._dialog.addButton({ label: _("Deny"),
|
||||
action: () => {
|
||||
|
@@ -15,12 +15,12 @@ class KbdA11yDialog extends GObject.Object {
|
||||
|
||||
this._a11ySettings = new Gio.Settings({ schema_id: KEYBOARD_A11Y_SCHEMA });
|
||||
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
deviceManager.connect('kbd-a11y-flags-changed',
|
||||
this._showKbdA11yDialog.bind(this));
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
seat.connect('kbd-a11y-flags-changed',
|
||||
this._showKbdA11yDialog.bind(this));
|
||||
}
|
||||
|
||||
_showKbdA11yDialog(deviceManager, newFlags, whatChanged) {
|
||||
_showKbdA11yDialog(seat, newFlags, whatChanged) {
|
||||
let dialog = new ModalDialog.ModalDialog();
|
||||
let title, description;
|
||||
let key, enabled;
|
||||
@@ -49,10 +49,8 @@ class KbdA11yDialog extends GObject.Object {
|
||||
return;
|
||||
}
|
||||
|
||||
let contentParams = { title, description, styleClass: 'access-dialog' };
|
||||
let content = new Dialog.MessageDialogContent(contentParams);
|
||||
|
||||
dialog.contentLayout.add_actor(content);
|
||||
let content = new Dialog.MessageDialogContent({ title, description });
|
||||
dialog.contentLayout.add_child(content);
|
||||
|
||||
dialog.addButton({ label: enabled ? _("Leave On") : _("Turn On"),
|
||||
action: () => {
|
||||
|
@@ -614,6 +614,7 @@ var EmojiPager = GObject.registerClass({
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
reactive: true,
|
||||
clip_to_allocation: true,
|
||||
y_expand: true,
|
||||
});
|
||||
this._sections = sections;
|
||||
this._nCols = nCols;
|
||||
@@ -934,7 +935,6 @@ var EmojiSelection = GObject.registerClass({
|
||||
this.add_child(bottomRow);
|
||||
|
||||
this._curPage = 0;
|
||||
this._emojiPager.setCurrentPage(0);
|
||||
}
|
||||
|
||||
vfunc_map() {
|
||||
@@ -942,11 +942,6 @@ var EmojiSelection = GObject.registerClass({
|
||||
super.vfunc_map();
|
||||
}
|
||||
|
||||
vfunc_unmap() {
|
||||
super.vfunc_unmap();
|
||||
this._emojiPager.setCurrentPage(0);
|
||||
}
|
||||
|
||||
_onPageChanged(sectionLabel, page, nPages) {
|
||||
this._curPage = page;
|
||||
this._pageIndicator.setNPages(nPages);
|
||||
@@ -1107,13 +1102,13 @@ var KeyboardManager = class KeyBoardManager {
|
||||
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
|
||||
this._a11yApplicationsSettings.connect('changed', this._syncEnabled.bind(this));
|
||||
|
||||
this._lastDeviceId = null;
|
||||
Meta.get_backend().connect('last-device-changed', (backend, deviceId) => {
|
||||
let manager = Clutter.DeviceManager.get_default();
|
||||
let device = manager.get_device(deviceId);
|
||||
this._seat = Clutter.get_default_backend().get_default_seat();
|
||||
this._seat.connect('notify::touch-mode', this._syncEnabled.bind(this));
|
||||
|
||||
this._lastDevice = null;
|
||||
Meta.get_backend().connect('last-device-changed', (backend, device) => {
|
||||
if (device.get_device_name().indexOf('XTEST') < 0) {
|
||||
this._lastDeviceId = deviceId;
|
||||
this._lastDevice = device;
|
||||
this._syncEnabled();
|
||||
}
|
||||
});
|
||||
@@ -1121,21 +1116,18 @@ var KeyboardManager = class KeyBoardManager {
|
||||
}
|
||||
|
||||
_lastDeviceIsTouchscreen() {
|
||||
if (!this._lastDeviceId)
|
||||
if (!this._lastDevice)
|
||||
return false;
|
||||
|
||||
let manager = Clutter.DeviceManager.get_default();
|
||||
let device = manager.get_device(this._lastDeviceId);
|
||||
|
||||
if (!device)
|
||||
return false;
|
||||
|
||||
return device.get_device_type() == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
|
||||
let deviceType = this._lastDevice.get_device_type();
|
||||
return deviceType == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
|
||||
}
|
||||
|
||||
_syncEnabled() {
|
||||
let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
|
||||
let enabled = enableKeyboard || this._lastDeviceIsTouchscreen();
|
||||
let autoEnabled = this._seat.get_touch_mode() && this._lastDeviceIsTouchscreen();
|
||||
let enabled = enableKeyboard || autoEnabled;
|
||||
|
||||
if (!enabled && !this._keyboard)
|
||||
return;
|
||||
|
||||
@@ -1290,7 +1282,10 @@ class Keyboard extends St.BoxLayout {
|
||||
this._suggestions = new Suggestions();
|
||||
this.add_child(this._suggestions);
|
||||
|
||||
this._aspectContainer = new AspectContainer({ layout_manager: new Clutter.BinLayout() });
|
||||
this._aspectContainer = new AspectContainer({
|
||||
layout_manager: new Clutter.BinLayout(),
|
||||
y_expand: true,
|
||||
});
|
||||
this.add_child(this._aspectContainer);
|
||||
|
||||
this._emojiSelection = new EmojiSelection();
|
||||
@@ -1590,7 +1585,17 @@ class Keyboard extends St.BoxLayout {
|
||||
|
||||
let maxHeight = monitor.height / 3;
|
||||
this.width = monitor.width;
|
||||
this.height = maxHeight;
|
||||
|
||||
if (monitor.width > monitor.height) {
|
||||
this.height = maxHeight;
|
||||
} else {
|
||||
/* In portrait mode, lack of horizontal space means we won't be
|
||||
* able to make the OSK that big while keeping size ratio, so
|
||||
* we allow the OSK being smaller than 1/3rd of the monitor height
|
||||
* there.
|
||||
*/
|
||||
this.height = Math.min(maxHeight, this.get_preferred_height(monitor.width));
|
||||
}
|
||||
}
|
||||
|
||||
_onGroupChanged() {
|
||||
@@ -1829,8 +1834,8 @@ class Keyboard extends St.BoxLayout {
|
||||
|
||||
var KeyboardController = class {
|
||||
constructor() {
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
this._virtualDevice = seat.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
|
||||
|
||||
this._inputSourceManager = InputSourceManager.getInputSourceManager();
|
||||
this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
|
||||
|
@@ -531,9 +531,9 @@ var Inspector = GObject.registerClass({
|
||||
eventHandler.connect('scroll-event', this._onScrollEvent.bind(this));
|
||||
eventHandler.connect('motion-event', this._onMotionEvent.bind(this));
|
||||
|
||||
let dm = Clutter.DeviceManager.get_default();
|
||||
this._pointerDevice = dm.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
|
||||
this._keyboardDevice = dm.get_core_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
this._pointerDevice = seat.get_pointer();
|
||||
this._keyboardDevice = seat.get_keyboard();
|
||||
|
||||
this._pointerDevice.grab(eventHandler);
|
||||
this._keyboardDevice.grab(eventHandler);
|
||||
|
@@ -430,8 +430,10 @@ var Magnifier = class Magnifier {
|
||||
* lines making up the crosshairs.
|
||||
*/
|
||||
setCrosshairsLength(length) {
|
||||
if (this._crossHairs)
|
||||
this._crossHairs.setLength(length);
|
||||
if (this._crossHairs) {
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._crossHairs.setLength(length / scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -745,7 +747,7 @@ var ZoomRegion = class ZoomRegion {
|
||||
this._xCaret = 0;
|
||||
this._yCaret = 0;
|
||||
|
||||
this._pointerIdleMonitor = Meta.IdleMonitor.get_for_device(Meta.VIRTUAL_CORE_POINTER_ID);
|
||||
this._pointerIdleMonitor = Meta.IdleMonitor.get_core();
|
||||
this._scrollContentsTimerId = 0;
|
||||
}
|
||||
|
||||
@@ -797,9 +799,14 @@ var ZoomRegion = class ZoomRegion {
|
||||
return;
|
||||
}
|
||||
|
||||
[this._xFocus, this._yFocus] = [extents.x + (extents.width / 2),
|
||||
extents.y + (extents.height / 2)];
|
||||
this._centerFromFocusPosition();
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let [xFocus, yFocus] = [(extents.x + (extents.width / 2)) * scaleFactor,
|
||||
(extents.y + (extents.height / 2)) * scaleFactor];
|
||||
|
||||
if (this._xFocus !== xFocus || this._yFocus !== yFocus) {
|
||||
[this._xFocus, this._yFocus] = [xFocus, yFocus];
|
||||
this._centerFromFocusPosition();
|
||||
}
|
||||
}
|
||||
|
||||
_updateCaret(caller, event) {
|
||||
@@ -814,8 +821,13 @@ var ZoomRegion = class ZoomRegion {
|
||||
return;
|
||||
}
|
||||
|
||||
[this._xCaret, this._yCaret] = [extents.x, extents.y];
|
||||
this._centerFromCaretPosition();
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let [xCaret, yCaret] = [extents.x * scaleFactor, extents.y * scaleFactor];
|
||||
|
||||
if (this._xCaret !== xCaret || this._yCaret !== yCaret) {
|
||||
[this._xCaret, this._yCaret] = [xCaret, yCaret];
|
||||
this._centerFromCaretPosition();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -863,7 +875,8 @@ var ZoomRegion = class ZoomRegion {
|
||||
setMagFactor(xMagFactor, yMagFactor) {
|
||||
this._changeROI({ xMagFactor,
|
||||
yMagFactor,
|
||||
redoCursorTracking: this._followingCursor });
|
||||
redoCursorTracking: this._followingCursor,
|
||||
animate: true });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1121,6 +1134,13 @@ var ZoomRegion = class ZoomRegion {
|
||||
return this._screenPosition;
|
||||
}
|
||||
|
||||
_clearScrollContentsTimer() {
|
||||
if (this._scrollContentsTimerId !== 0) {
|
||||
GLib.source_remove(this._scrollContentsTimerId);
|
||||
this._scrollContentsTimerId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* scrollToMousePos:
|
||||
* Set the region of interest based on the position of the system pointer.
|
||||
@@ -1134,28 +1154,29 @@ var ZoomRegion = class ZoomRegion {
|
||||
else
|
||||
this._updateMousePosition();
|
||||
|
||||
this._clearScrollContentsTimer();
|
||||
this._scrollContentsTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, POINTER_REST_TIME, () => {
|
||||
this._followingCursor = false;
|
||||
if (this._xDelayed !== null && this._yDelayed !== null) {
|
||||
this._scrollContentsToDelayed(this._xDelayed, this._yDelayed);
|
||||
this._xDelayed = null;
|
||||
this._yDelayed = null;
|
||||
}
|
||||
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
|
||||
// Determine whether the system mouse pointer is over this zoom region.
|
||||
return this._isMouseOverRegion();
|
||||
}
|
||||
|
||||
_clearScrollContentsTimer() {
|
||||
if (this._scrollContentsTimerId != 0) {
|
||||
GLib.source_remove(this._scrollContentsTimerId);
|
||||
this._scrollContentsTimerId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_scrollContentsToDelayed(x, y) {
|
||||
if (this._pointerIdleMonitor.get_idletime() >= POINTER_REST_TIME) {
|
||||
if (this._followingCursor) {
|
||||
this._xDelayed = x;
|
||||
this._yDelayed = y;
|
||||
} else {
|
||||
this.scrollContentsTo(x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
this._clearScrollContentsTimer();
|
||||
this._scrollContentsTimerId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, POINTER_REST_TIME, () => {
|
||||
this._scrollContentsToDelayed(x, y);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1166,11 +1187,16 @@ var ZoomRegion = class ZoomRegion {
|
||||
* @param {number} y: The y-coord of the point to center on.
|
||||
*/
|
||||
scrollContentsTo(x, y) {
|
||||
if (x < 0 || x > global.screen_width ||
|
||||
y < 0 || y > global.screen_height)
|
||||
return;
|
||||
|
||||
this._clearScrollContentsTimer();
|
||||
|
||||
this._followingCursor = false;
|
||||
this._changeROI({ xCenter: x,
|
||||
yCenter: y });
|
||||
yCenter: y,
|
||||
animate: true });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1322,7 +1348,7 @@ var ZoomRegion = class ZoomRegion {
|
||||
this._crossHairsActor = null;
|
||||
|
||||
// Contrast and brightness effects.
|
||||
this._magShaderEffects = new MagShaderEffects(this._uiGroupClone);
|
||||
this._magShaderEffects = new MagShaderEffects(mainGroup);
|
||||
this._magShaderEffects.setColorSaturation(this._colorSaturation);
|
||||
this._magShaderEffects.setInvertLightness(this._invertLightness);
|
||||
this._magShaderEffects.setBrightness(this._brightness);
|
||||
@@ -1379,7 +1405,8 @@ var ZoomRegion = class ZoomRegion {
|
||||
yMagFactor: this._yMagFactor,
|
||||
xCenter: this._xCenter,
|
||||
yCenter: this._yCenter,
|
||||
redoCursorTracking: false });
|
||||
redoCursorTracking: false,
|
||||
animate: false });
|
||||
|
||||
if (params.xMagFactor <= 0)
|
||||
params.xMagFactor = this._xMagFactor;
|
||||
@@ -1418,8 +1445,7 @@ var ZoomRegion = class ZoomRegion {
|
||||
height: this._viewPortHeight }, true);
|
||||
}
|
||||
|
||||
this._updateCloneGeometry();
|
||||
this._updateMousePosition();
|
||||
this._updateCloneGeometry(params.animate);
|
||||
}
|
||||
|
||||
_isMouseOverRegion() {
|
||||
@@ -1557,38 +1583,64 @@ var ZoomRegion = class ZoomRegion {
|
||||
this._magView.set_position(this._viewPortX, this._viewPortY);
|
||||
}
|
||||
|
||||
_updateCloneGeometry() {
|
||||
_updateCloneGeometry(animate = false) {
|
||||
if (!this.isActive())
|
||||
return;
|
||||
|
||||
this._uiGroupClone.set_scale(this._xMagFactor, this._yMagFactor);
|
||||
this._mouseActor.set_scale(this._xMagFactor, this._yMagFactor);
|
||||
|
||||
let [x, y] = this._screenToViewPort(0, 0);
|
||||
this._uiGroupClone.set_position(Math.round(x), Math.round(y));
|
||||
this._uiGroupClone.ease({
|
||||
x: Math.round(x),
|
||||
y: Math.round(y),
|
||||
scale_x: this._xMagFactor,
|
||||
scale_y: this._yMagFactor,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: animate ? 100 : 0,
|
||||
});
|
||||
|
||||
this._updateMousePosition();
|
||||
let [mouseX, mouseY] = this._getMousePosition();
|
||||
this._mouseActor.ease({
|
||||
x: mouseX,
|
||||
y: mouseY,
|
||||
scale_x: this._xMagFactor,
|
||||
scale_y: this._yMagFactor,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: animate ? 100 : 0,
|
||||
});
|
||||
|
||||
if (this._crossHairsActor) {
|
||||
let [crossX, crossY] = this._getCrossHairsPosition();
|
||||
this._crossHairsActor.ease({
|
||||
x: crossX,
|
||||
y: crossY,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: animate ? 100 : 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_updateMousePosition() {
|
||||
if (!this.isActive())
|
||||
return;
|
||||
|
||||
let [xMagMouse, yMagMouse] = this._screenToViewPort(this._magnifier.xMouse,
|
||||
this._magnifier.yMouse);
|
||||
|
||||
xMagMouse = Math.round(xMagMouse);
|
||||
yMagMouse = Math.round(yMagMouse);
|
||||
|
||||
let [xMagMouse, yMagMouse] = this._getMousePosition();
|
||||
this._mouseActor.set_position(xMagMouse, yMagMouse);
|
||||
|
||||
if (this._crossHairsActor) {
|
||||
let [groupWidth, groupHeight] = this._crossHairsActor.get_size();
|
||||
this._crossHairsActor.set_position(xMagMouse - groupWidth / 2,
|
||||
yMagMouse - groupHeight / 2);
|
||||
let [crossX, crossY] = this._getCrossHairsPosition();
|
||||
this._crossHairsActor.set_position(crossX, crossY);
|
||||
}
|
||||
}
|
||||
|
||||
_getMousePosition() {
|
||||
let [xMagMouse, yMagMouse] = this._screenToViewPort(
|
||||
this._magnifier.xMouse, this._magnifier.yMouse);
|
||||
return [Math.round(xMagMouse), Math.round(yMagMouse)];
|
||||
}
|
||||
|
||||
_getCrossHairsPosition() {
|
||||
let [xMagMouse, yMagMouse] = this._getMousePosition();
|
||||
let [groupWidth, groupHeight] = this._crossHairsActor.get_size();
|
||||
|
||||
return [xMagMouse - groupWidth / 2, yMagMouse - groupHeight / 2];
|
||||
}
|
||||
|
||||
_monitorsChanged() {
|
||||
this._background.set_size(global.screen_width, global.screen_height);
|
||||
this._updateScreenPosition();
|
||||
@@ -1807,12 +1859,10 @@ class Crosshairs extends Clutter.Actor {
|
||||
let clipWidth = this._clipSize[0];
|
||||
let clipHeight = this._clipSize[1];
|
||||
|
||||
// Note that clip, if present, is not centred on the cross hair
|
||||
// intersection, but biased towards the top left.
|
||||
let left = groupWidth / 2 - clipWidth * 0.25 - leftLength;
|
||||
let right = groupWidth / 2 + clipWidth * 0.75;
|
||||
let top = groupHeight / 2 - clipHeight * 0.25 - topLength - thickness / 2;
|
||||
let bottom = groupHeight / 2 + clipHeight * 0.75 + thickness / 2;
|
||||
let left = groupWidth / 2 - clipWidth / 2 - leftLength - thickness / 2;
|
||||
let right = groupWidth / 2 + clipWidth / 2 + thickness / 2;
|
||||
let top = groupHeight / 2 - clipHeight / 2 - topLength - thickness / 2;
|
||||
let bottom = groupHeight / 2 + clipHeight / 2 + thickness / 2;
|
||||
this._horizLeftHair.set_position(left, (groupHeight - thickness) / 2);
|
||||
this._horizRightHair.set_position(right, (groupHeight - thickness) / 2);
|
||||
this._vertTopHair.set_position((groupWidth - thickness) / 2, top);
|
||||
|
@@ -137,6 +137,7 @@ class OverviewActor extends St.BoxLayout {
|
||||
var Overview = class {
|
||||
constructor() {
|
||||
this._initCalled = false;
|
||||
this._visible = false;
|
||||
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
this._sessionUpdated();
|
||||
@@ -689,5 +690,9 @@ var Overview = class {
|
||||
|
||||
return this.dash.showAppsButton;
|
||||
}
|
||||
|
||||
get searchEntry() {
|
||||
return this._overview.searchEntry;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Overview.prototype);
|
||||
|
@@ -31,15 +31,10 @@ var SlideLayout = GObject.registerClass({
|
||||
'slide-x', 'slide-x', 'slide-x',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0, 1, 1),
|
||||
'translation-x': GObject.ParamSpec.double(
|
||||
'translation-x', 'translation-x', 'translation-x',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
-Infinity, Infinity, 0),
|
||||
},
|
||||
}, class SlideLayout extends Clutter.FixedLayout {
|
||||
_init(params) {
|
||||
this._slideX = 1;
|
||||
this._translationX = 0;
|
||||
this._direction = SlideDirection.LEFT;
|
||||
|
||||
super._init(params);
|
||||
@@ -72,7 +67,7 @@ var SlideLayout = GObject.registerClass({
|
||||
: availWidth - natWidth * this._slideX;
|
||||
|
||||
let actorBox = new Clutter.ActorBox();
|
||||
actorBox.x1 = box.x1 + alignX + this._translationX;
|
||||
actorBox.x1 = box.x1 + alignX;
|
||||
actorBox.x2 = actorBox.x1 + (child.x_expand ? availWidth : natWidth);
|
||||
actorBox.y1 = box.y1;
|
||||
actorBox.y2 = actorBox.y1 + availHeight;
|
||||
@@ -102,20 +97,6 @@ var SlideLayout = GObject.registerClass({
|
||||
get slideDirection() {
|
||||
return this._direction;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
set translation_x(value) {
|
||||
if (this._translationX == value)
|
||||
return;
|
||||
this._translationX = value;
|
||||
this.notify('translation-x');
|
||||
this.layout_changed();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get translation_x() {
|
||||
return this._translationX;
|
||||
}
|
||||
});
|
||||
|
||||
var SlidingControl = GObject.registerClass(
|
||||
@@ -184,11 +165,12 @@ class SlidingControl extends St.Widget {
|
||||
else
|
||||
translationEnd = translation;
|
||||
|
||||
if (this.layout.translation_x == translationEnd)
|
||||
if (this.translation_x === translationEnd)
|
||||
return;
|
||||
|
||||
this.layout.translation_x = translationStart;
|
||||
this.ease_property('@layout.translation-x', translationEnd, {
|
||||
this.translation_x = translationStart;
|
||||
this.ease({
|
||||
translation_x: translationEnd,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: SIDE_CONTROLS_ANIMATION_TIME,
|
||||
});
|
||||
|
@@ -648,15 +648,15 @@ var PadOsd = GObject.registerClass({
|
||||
this._capturedEventId = global.stage.connect('captured-event', this._onCapturedEvent.bind(this));
|
||||
this._padChooser = null;
|
||||
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
this._deviceAddedId = deviceManager.connect('device-added', (manager, device) => {
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
this._deviceAddedId = seat.connect('device-added', (_seat, device) => {
|
||||
if (device.get_device_type() == Clutter.InputDeviceType.PAD_DEVICE &&
|
||||
this.padDevice.is_grouped(device)) {
|
||||
this._groupPads.push(device);
|
||||
this._updatePadChooser();
|
||||
}
|
||||
});
|
||||
this._deviceRemovedId = deviceManager.connect('device-removed', (manager, device) => {
|
||||
this._deviceRemovedId = seat.connect('device-removed', (_seat, device) => {
|
||||
// If the device is being removed, destroy the padOsd.
|
||||
if (device == this.padDevice) {
|
||||
this.destroy();
|
||||
@@ -669,7 +669,7 @@ var PadOsd = GObject.registerClass({
|
||||
}
|
||||
});
|
||||
|
||||
deviceManager.list_devices().forEach(device => {
|
||||
seat.list_devices().forEach(device => {
|
||||
if (device != this.padDevice &&
|
||||
device.get_device_type() == Clutter.InputDeviceType.PAD_DEVICE &&
|
||||
this.padDevice.is_grouped(device))
|
||||
@@ -960,13 +960,13 @@ var PadOsd = GObject.registerClass({
|
||||
Main.popModal(this);
|
||||
this._actionEditor.close();
|
||||
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
if (this._deviceRemovedId != 0) {
|
||||
deviceManager.disconnect(this._deviceRemovedId);
|
||||
seat.disconnect(this._deviceRemovedId);
|
||||
this._deviceRemovedId = 0;
|
||||
}
|
||||
if (this._deviceAddedId != 0) {
|
||||
deviceManager.disconnect(this._deviceAddedId);
|
||||
seat.disconnect(this._deviceAddedId);
|
||||
this._deviceAddedId = 0;
|
||||
}
|
||||
|
||||
@@ -990,8 +990,8 @@ var PadOsdService = class {
|
||||
|
||||
ShowAsync(params, invocation) {
|
||||
let [deviceNode, editionMode] = params;
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
let devices = deviceManager.list_devices();
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
let devices = seat.list_devices();
|
||||
let padDevice = null;
|
||||
|
||||
devices.forEach(device => {
|
||||
|
@@ -108,9 +108,9 @@ var PieTimer = GObject.registerClass({
|
||||
|
||||
var PointerA11yTimeout = class PointerA11yTimeout {
|
||||
constructor() {
|
||||
let manager = Clutter.DeviceManager.get_default();
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
|
||||
manager.connect('ptr-a11y-timeout-started', (o, device, type, timeout) => {
|
||||
seat.connect('ptr-a11y-timeout-started', (o, device, type, timeout) => {
|
||||
let [x, y] = global.get_pointer();
|
||||
|
||||
this._pieTimer = new PieTimer();
|
||||
@@ -123,7 +123,7 @@ var PointerA11yTimeout = class PointerA11yTimeout {
|
||||
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
|
||||
});
|
||||
|
||||
manager.connect('ptr-a11y-timeout-stopped', (o, device, type, clicked) => {
|
||||
seat.connect('ptr-a11y-timeout-stopped', (o, device, type, clicked) => {
|
||||
if (!clicked)
|
||||
this._pieTimer.destroy();
|
||||
|
||||
|
@@ -305,25 +305,44 @@ class PopupSeparatorMenuItem extends PopupBaseMenuItem {
|
||||
}
|
||||
});
|
||||
|
||||
var Switch = GObject.registerClass(
|
||||
class Switch extends St.Bin {
|
||||
var Switch = GObject.registerClass({
|
||||
Properties: {
|
||||
'state': GObject.ParamSpec.boolean(
|
||||
'state', 'state', 'state',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
false),
|
||||
},
|
||||
}, class Switch extends St.Bin {
|
||||
_init(state) {
|
||||
super._init({ style_class: 'toggle-switch',
|
||||
accessible_role: Atk.Role.CHECK_BOX,
|
||||
can_focus: true });
|
||||
this.setToggleState(state);
|
||||
this._state = false;
|
||||
|
||||
super._init({
|
||||
style_class: 'toggle-switch',
|
||||
accessible_role: Atk.Role.CHECK_BOX,
|
||||
can_focus: true,
|
||||
state,
|
||||
});
|
||||
}
|
||||
|
||||
setToggleState(state) {
|
||||
get state() {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
set state(state) {
|
||||
if (this._state === state)
|
||||
return;
|
||||
|
||||
if (state)
|
||||
this.add_style_pseudo_class('checked');
|
||||
else
|
||||
this.remove_style_pseudo_class('checked');
|
||||
this.state = state;
|
||||
|
||||
this._state = state;
|
||||
this.notify('state');
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setToggleState(!this.state);
|
||||
this.state = !this.state;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -393,7 +412,7 @@ var PopupSwitchMenuItem = GObject.registerClass({
|
||||
}
|
||||
|
||||
setToggleState(state) {
|
||||
this._switch.setToggleState(state);
|
||||
this._switch.state = state;
|
||||
this.checkAccessibleState();
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
@@ -18,13 +19,13 @@ const TERMINAL_SCHEMA = 'org.gnome.desktop.default-applications.terminal';
|
||||
const EXEC_KEY = 'exec';
|
||||
const EXEC_ARG_KEY = 'exec-arg';
|
||||
|
||||
var DIALOG_GROW_TIME = 100;
|
||||
|
||||
var RunDialog = GObject.registerClass(
|
||||
class RunDialog extends ModalDialog.ModalDialog {
|
||||
_init() {
|
||||
super._init({ styleClass: 'run-dialog',
|
||||
destroyOnClose: false });
|
||||
super._init({
|
||||
styleClass: 'run-dialog',
|
||||
destroyOnClose: false,
|
||||
});
|
||||
|
||||
this._lockdownSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
|
||||
this._terminalSettings = new Gio.Settings({ schema_id: TERMINAL_SCHEMA });
|
||||
@@ -54,58 +55,41 @@ class RunDialog extends ModalDialog.ModalDialog {
|
||||
},
|
||||
};
|
||||
|
||||
let label = new St.Label({ style_class: 'run-dialog-label',
|
||||
text: _("Enter a Command") });
|
||||
let title = _('Run a Command');
|
||||
|
||||
this.contentLayout.add_child(label);
|
||||
let content = new Dialog.MessageDialogContent({ title });
|
||||
this.contentLayout.add_actor(content);
|
||||
|
||||
let entry = new St.Entry({ style_class: 'run-dialog-entry',
|
||||
can_focus: true });
|
||||
let entry = new St.Entry({
|
||||
style_class: 'run-dialog-entry',
|
||||
can_focus: true,
|
||||
});
|
||||
ShellEntry.addContextMenu(entry);
|
||||
|
||||
entry.label_actor = label;
|
||||
|
||||
this._entryText = entry.clutter_text;
|
||||
this.contentLayout.add_child(entry);
|
||||
content.add_child(entry);
|
||||
this.setInitialKeyFocus(this._entryText);
|
||||
|
||||
this._errorBox = new St.BoxLayout({ style_class: 'run-dialog-error-box' });
|
||||
let defaultDescriptionText = _('Press ESC to close');
|
||||
|
||||
this.contentLayout.add_child(this._errorBox);
|
||||
|
||||
let errorIcon = new St.Icon({ icon_name: 'dialog-error-symbolic',
|
||||
icon_size: 24,
|
||||
style_class: 'run-dialog-error-icon',
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
|
||||
this._errorBox.add_child(errorIcon);
|
||||
this._descriptionLabel = new St.Label({
|
||||
style_class: 'run-dialog-description',
|
||||
text: defaultDescriptionText,
|
||||
});
|
||||
content.add_child(this._descriptionLabel);
|
||||
|
||||
this._commandError = false;
|
||||
|
||||
this._errorMessage = new St.Label({
|
||||
style_class: 'run-dialog-error-label',
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
this._errorMessage.clutter_text.line_wrap = true;
|
||||
|
||||
this._errorBox.add_child(this._errorMessage);
|
||||
|
||||
this._errorBox.hide();
|
||||
|
||||
this.setButtons([{
|
||||
action: this.close.bind(this),
|
||||
label: _("Close"),
|
||||
key: Clutter.KEY_Escape,
|
||||
}]);
|
||||
|
||||
this._pathCompleter = new Gio.FilenameCompleter();
|
||||
|
||||
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
|
||||
entry: this._entryText });
|
||||
this._history = new History.HistoryManager({
|
||||
gsettingsKey: HISTORY_KEY,
|
||||
entry: this._entryText,
|
||||
});
|
||||
this._entryText.connect('activate', o => {
|
||||
this.popModal();
|
||||
this._run(o.get_text(),
|
||||
Clutter.get_current_event().get_state() & Clutter.ModifierType.CONTROL_MASK);
|
||||
Clutter.get_current_event().get_state() & Clutter.ModifierType.CONTROL_MASK);
|
||||
if (!this._commandError ||
|
||||
!this.pushModal())
|
||||
this.close();
|
||||
@@ -128,6 +112,18 @@ class RunDialog extends ModalDialog.ModalDialog {
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
this._entryText.connect('text-changed', () => {
|
||||
this._descriptionLabel.set_text(defaultDescriptionText);
|
||||
});
|
||||
}
|
||||
|
||||
vfunc_key_release_event(event) {
|
||||
if (event.keyval === Clutter.KEY_Escape) {
|
||||
this.close();
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_getCommandCompletion(text) {
|
||||
@@ -216,7 +212,7 @@ class RunDialog extends ModalDialog.ModalDialog {
|
||||
let file = Gio.file_new_for_path(path);
|
||||
try {
|
||||
Gio.app_info_launch_default_for_uri(file.get_uri(),
|
||||
global.create_app_launch_context(0, -1));
|
||||
global.create_app_launch_context(0, -1));
|
||||
} catch (err) {
|
||||
// The exception from gjs contains an error string like:
|
||||
// Error invoking Gio.app_info_launch_default_for_uri: No application
|
||||
@@ -234,24 +230,7 @@ class RunDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
_showError(message) {
|
||||
this._commandError = true;
|
||||
|
||||
this._errorMessage.set_text(message);
|
||||
|
||||
if (!this._errorBox.visible) {
|
||||
let [, errorBoxNaturalHeight] = this._errorBox.get_preferred_height(-1);
|
||||
|
||||
let parentActor = this._errorBox.get_parent();
|
||||
let height = parentActor.height + errorBoxNaturalHeight;
|
||||
parentActor.ease({
|
||||
height,
|
||||
duration: DIALOG_GROW_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
parentActor.set_height(-1);
|
||||
this._errorBox.show();
|
||||
},
|
||||
});
|
||||
}
|
||||
this._descriptionLabel.set_text(message);
|
||||
}
|
||||
|
||||
_restart() {
|
||||
@@ -266,7 +245,6 @@ class RunDialog extends ModalDialog.ModalDialog {
|
||||
|
||||
open() {
|
||||
this._history.lastItem();
|
||||
this._errorBox.hide();
|
||||
this._entryText.set_text('');
|
||||
this._commandError = false;
|
||||
|
||||
|
@@ -1,13 +1,10 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const { AccountsService, Clutter, Gio, GLib,
|
||||
GnomeDesktop, GObject, Graphene, Meta, Shell, St } = imports.gi;
|
||||
const Cairo = imports.cairo;
|
||||
const { AccountsService, Clutter, Gio,
|
||||
GLib, Graphene, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Layout = imports.ui.layout;
|
||||
const OVirt = imports.gdm.oVirt;
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
@@ -27,17 +24,6 @@ const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
|
||||
const DISABLE_LOCK_KEY = 'disable-lock-screen';
|
||||
|
||||
const LOCKED_STATE_STR = 'screenShield.locked';
|
||||
// fraction of screen height the arrow must reach before completing
|
||||
// the slide up automatically
|
||||
var ARROW_DRAG_THRESHOLD = 0.1;
|
||||
|
||||
// Parameters for the arrow animation
|
||||
var N_ARROWS = 3;
|
||||
var ARROW_ANIMATION_TIME = 600;
|
||||
var ARROW_ANIMATION_PEAK_OPACITY = 0.4;
|
||||
var ARROW_IDLE_TIME = 30000; // ms
|
||||
|
||||
var SUMMARY_ICON_SIZE = 48;
|
||||
|
||||
// ScreenShield animation time
|
||||
// - STANDARD_FADE_TIME is used when the session goes idle
|
||||
@@ -48,384 +34,6 @@ var STANDARD_FADE_TIME = 10000;
|
||||
var MANUAL_FADE_TIME = 300;
|
||||
var CURTAIN_SLIDE_TIME = 300;
|
||||
|
||||
var Clock = GObject.registerClass(
|
||||
class ScreenShieldClock extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({ style_class: 'screen-shield-clock', vertical: true });
|
||||
|
||||
this._time = new St.Label({
|
||||
style_class: 'screen-shield-clock-time',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
this._date = new St.Label({
|
||||
style_class: 'screen-shield-clock-date',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
|
||||
this.add_child(this._time);
|
||||
this.add_child(this._date);
|
||||
|
||||
this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
|
||||
this._wallClock.connect('notify::clock', this._updateClock.bind(this));
|
||||
|
||||
this._updateClock();
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_updateClock() {
|
||||
this._time.text = this._wallClock.clock;
|
||||
|
||||
let date = new Date();
|
||||
/* Translators: This is a time format for a date in
|
||||
long format */
|
||||
let dateFormat = Shell.util_translate_time_string(N_("%A, %B %d"));
|
||||
this._date.text = date.toLocaleFormat(dateFormat);
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._wallClock.run_dispose();
|
||||
}
|
||||
});
|
||||
|
||||
var NotificationsBox = GObject.registerClass({
|
||||
Signals: { 'wake-up-screen': {} },
|
||||
}, class NotificationsBox extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
vertical: true,
|
||||
name: 'screenShieldNotifications',
|
||||
style_class: 'screen-shield-notifications-container',
|
||||
});
|
||||
|
||||
this._scrollView = new St.ScrollView({ hscrollbar_policy: St.PolicyType.NEVER });
|
||||
this._notificationBox = new St.BoxLayout({ vertical: true,
|
||||
style_class: 'screen-shield-notifications-container' });
|
||||
this._scrollView.add_actor(this._notificationBox);
|
||||
|
||||
this.add_child(this._scrollView);
|
||||
|
||||
this._sources = new Map();
|
||||
Main.messageTray.getSources().forEach(source => {
|
||||
this._sourceAdded(Main.messageTray, source, true);
|
||||
});
|
||||
this._updateVisibility();
|
||||
|
||||
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._sourceAddedId) {
|
||||
Main.messageTray.disconnect(this._sourceAddedId);
|
||||
this._sourceAddedId = 0;
|
||||
}
|
||||
|
||||
let items = this._sources.entries();
|
||||
for (let [source, obj] of items)
|
||||
this._removeSource(source, obj);
|
||||
}
|
||||
|
||||
_updateVisibility() {
|
||||
this._notificationBox.visible =
|
||||
this._notificationBox.get_children().some(a => a.visible);
|
||||
|
||||
this.visible = this._notificationBox.visible;
|
||||
}
|
||||
|
||||
_makeNotificationCountText(count, isChat) {
|
||||
if (isChat)
|
||||
return ngettext("%d new message", "%d new messages", count).format(count);
|
||||
else
|
||||
return ngettext("%d new notification", "%d new notifications", count).format(count);
|
||||
}
|
||||
|
||||
_makeNotificationSource(source, box) {
|
||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||
box.add_child(sourceActor);
|
||||
|
||||
let textBox = new St.BoxLayout({ vertical: true });
|
||||
box.add_child(textBox);
|
||||
|
||||
let title = new St.Label({ text: source.title,
|
||||
style_class: 'screen-shield-notification-label' });
|
||||
textBox.add(title);
|
||||
|
||||
let count = source.unseenCount;
|
||||
let countLabel = new St.Label({ text: this._makeNotificationCountText(count, source.isChat),
|
||||
style_class: 'screen-shield-notification-count-text' });
|
||||
textBox.add(countLabel);
|
||||
|
||||
box.visible = count != 0;
|
||||
return [title, countLabel];
|
||||
}
|
||||
|
||||
_makeNotificationDetailedSource(source, box) {
|
||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||
let sourceBin = new St.Bin({ child: sourceActor });
|
||||
box.add(sourceBin);
|
||||
|
||||
let textBox = new St.BoxLayout({ vertical: true });
|
||||
box.add_child(textBox);
|
||||
|
||||
let title = new St.Label({ text: source.title,
|
||||
style_class: 'screen-shield-notification-label' });
|
||||
textBox.add(title);
|
||||
|
||||
let visible = false;
|
||||
for (let i = 0; i < source.notifications.length; i++) {
|
||||
let n = source.notifications[i];
|
||||
|
||||
if (n.acknowledged)
|
||||
continue;
|
||||
|
||||
let body = '';
|
||||
if (n.bannerBodyText) {
|
||||
body = n.bannerBodyMarkup
|
||||
? n.bannerBodyText
|
||||
: GLib.markup_escape_text(n.bannerBodyText, -1);
|
||||
}
|
||||
|
||||
let label = new St.Label({ style_class: 'screen-shield-notification-count-text' });
|
||||
label.clutter_text.set_markup(`<b>${n.title}</b> ${body}`);
|
||||
textBox.add(label);
|
||||
|
||||
visible = true;
|
||||
}
|
||||
|
||||
box.visible = visible;
|
||||
return [title, null];
|
||||
}
|
||||
|
||||
_shouldShowDetails(source) {
|
||||
return source.policy.detailsInLockScreen ||
|
||||
source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
|
||||
}
|
||||
|
||||
_showSource(source, obj, box) {
|
||||
if (obj.detailed)
|
||||
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
|
||||
else
|
||||
[obj.titleLabel, obj.countLabel] = this._makeNotificationSource(source, box);
|
||||
|
||||
box.visible = obj.visible && (source.unseenCount > 0);
|
||||
}
|
||||
|
||||
_sourceAdded(tray, source, initial) {
|
||||
let obj = {
|
||||
visible: source.policy.showInLockScreen,
|
||||
detailed: this._shouldShowDetails(source),
|
||||
sourceDestroyId: 0,
|
||||
sourceCountChangedId: 0,
|
||||
sourceTitleChangedId: 0,
|
||||
sourceUpdatedId: 0,
|
||||
sourceBox: null,
|
||||
titleLabel: null,
|
||||
countLabel: null,
|
||||
};
|
||||
|
||||
obj.sourceBox = new St.BoxLayout({ style_class: 'screen-shield-notification-source',
|
||||
x_expand: true });
|
||||
this._showSource(source, obj, obj.sourceBox);
|
||||
this._notificationBox.add_child(obj.sourceBox);
|
||||
|
||||
obj.sourceCountChangedId = source.connect('notify::count', () => {
|
||||
this._countChanged(source, obj);
|
||||
});
|
||||
obj.sourceTitleChangedId = source.connect('notify::title', () => {
|
||||
this._titleChanged(source, obj);
|
||||
});
|
||||
obj.policyChangedId = source.policy.connect('notify', (policy, pspec) => {
|
||||
if (pspec.name == 'show-in-lock-screen')
|
||||
this._visibleChanged(source, obj);
|
||||
else
|
||||
this._detailedChanged(source, obj);
|
||||
});
|
||||
obj.sourceDestroyId = source.connect('destroy', () => {
|
||||
this._onSourceDestroy(source, obj);
|
||||
});
|
||||
|
||||
this._sources.set(source, obj);
|
||||
|
||||
if (!initial) {
|
||||
// block scrollbars while animating, if they're not needed now
|
||||
let boxHeight = this._notificationBox.height;
|
||||
if (this._scrollView.height >= boxHeight)
|
||||
this._scrollView.vscrollbar_policy = St.PolicyType.NEVER;
|
||||
|
||||
let widget = obj.sourceBox;
|
||||
let [, natHeight] = widget.get_preferred_height(-1);
|
||||
widget.height = 0;
|
||||
widget.ease({
|
||||
height: natHeight,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: 250,
|
||||
onComplete: () => {
|
||||
this._scrollView.vscrollbar_policy = St.PolicyType.AUTOMATIC;
|
||||
widget.set_height(-1);
|
||||
},
|
||||
});
|
||||
|
||||
this._updateVisibility();
|
||||
if (obj.sourceBox.visible)
|
||||
this.emit('wake-up-screen');
|
||||
}
|
||||
}
|
||||
|
||||
_titleChanged(source, obj) {
|
||||
obj.titleLabel.text = source.title;
|
||||
}
|
||||
|
||||
_countChanged(source, obj) {
|
||||
// A change in the number of notifications may change whether we show
|
||||
// details.
|
||||
let newDetailed = this._shouldShowDetails(source);
|
||||
let oldDetailed = obj.detailed;
|
||||
|
||||
obj.detailed = newDetailed;
|
||||
|
||||
if (obj.detailed || oldDetailed != newDetailed) {
|
||||
// A new notification was pushed, or a previous notification was destroyed.
|
||||
// Give up, and build the list again.
|
||||
|
||||
obj.sourceBox.destroy_all_children();
|
||||
obj.titleLabel = obj.countLabel = null;
|
||||
this._showSource(source, obj, obj.sourceBox);
|
||||
} else {
|
||||
let count = source.unseenCount;
|
||||
obj.countLabel.text = this._makeNotificationCountText(count, source.isChat);
|
||||
}
|
||||
|
||||
obj.sourceBox.visible = obj.visible && (source.unseenCount > 0);
|
||||
|
||||
this._updateVisibility();
|
||||
if (obj.sourceBox.visible)
|
||||
this.emit('wake-up-screen');
|
||||
}
|
||||
|
||||
_visibleChanged(source, obj) {
|
||||
if (obj.visible == source.policy.showInLockScreen)
|
||||
return;
|
||||
|
||||
obj.visible = source.policy.showInLockScreen;
|
||||
obj.sourceBox.visible = obj.visible && source.unseenCount > 0;
|
||||
|
||||
this._updateVisibility();
|
||||
if (obj.sourceBox.visible)
|
||||
this.emit('wake-up-screen');
|
||||
}
|
||||
|
||||
_detailedChanged(source, obj) {
|
||||
let newDetailed = this._shouldShowDetails(source);
|
||||
if (obj.detailed == newDetailed)
|
||||
return;
|
||||
|
||||
obj.detailed = newDetailed;
|
||||
|
||||
obj.sourceBox.destroy_all_children();
|
||||
obj.titleLabel = obj.countLabel = null;
|
||||
this._showSource(source, obj, obj.sourceBox);
|
||||
}
|
||||
|
||||
_onSourceDestroy(source, obj) {
|
||||
this._removeSource(source, obj);
|
||||
this._updateVisibility();
|
||||
}
|
||||
|
||||
_removeSource(source, obj) {
|
||||
obj.sourceBox.destroy();
|
||||
obj.sourceBox = obj.titleLabel = obj.countLabel = null;
|
||||
|
||||
source.disconnect(obj.sourceDestroyId);
|
||||
source.disconnect(obj.sourceCountChangedId);
|
||||
source.disconnect(obj.sourceTitleChangedId);
|
||||
source.policy.disconnect(obj.policyChangedId);
|
||||
|
||||
this._sources.delete(source);
|
||||
}
|
||||
});
|
||||
|
||||
var Arrow = GObject.registerClass(
|
||||
class ScreenShieldArrow extends St.Bin {
|
||||
_init(params) {
|
||||
super._init(params);
|
||||
|
||||
this._drawingArea = new St.DrawingArea({
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
});
|
||||
this._drawingArea.connect('repaint', this._drawArrow.bind(this));
|
||||
this.child = this._drawingArea;
|
||||
|
||||
this._shadowHelper = null;
|
||||
this._shadowWidth = this._shadowHeight = 0;
|
||||
}
|
||||
|
||||
_drawArrow(arrow) {
|
||||
let cr = arrow.get_context();
|
||||
let [w, h] = arrow.get_surface_size();
|
||||
let node = this.get_theme_node();
|
||||
let thickness = node.get_length('-arrow-thickness');
|
||||
|
||||
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
|
||||
|
||||
cr.setLineCap(Cairo.LineCap.ROUND);
|
||||
cr.setLineWidth(thickness);
|
||||
|
||||
cr.moveTo(thickness / 2, h - thickness / 2);
|
||||
cr.lineTo(w / 2, thickness);
|
||||
cr.lineTo(w - thickness / 2, h - thickness / 2);
|
||||
cr.stroke();
|
||||
cr.$dispose();
|
||||
}
|
||||
|
||||
vfunc_get_paint_volume(volume) {
|
||||
if (!super.vfunc_get_paint_volume(volume))
|
||||
return false;
|
||||
|
||||
if (!this._shadow)
|
||||
return true;
|
||||
|
||||
let shadowBox = new Clutter.ActorBox();
|
||||
this._shadow.get_box(this._drawingArea.get_allocation_box(), shadowBox);
|
||||
|
||||
volume.set_width(Math.max(shadowBox.x2 - shadowBox.x1, volume.get_width()));
|
||||
volume.set_height(Math.max(shadowBox.y2 - shadowBox.y1, volume.get_height()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
vfunc_style_changed() {
|
||||
let node = this.get_theme_node();
|
||||
this._shadow = node.get_shadow('-arrow-shadow');
|
||||
if (this._shadow)
|
||||
this._shadowHelper = St.ShadowHelper.new(this._shadow);
|
||||
else
|
||||
this._shadowHelper = null;
|
||||
|
||||
super.vfunc_style_changed();
|
||||
}
|
||||
|
||||
vfunc_paint(paintContext) {
|
||||
if (this._shadowHelper) {
|
||||
this._shadowHelper.update(this._drawingArea);
|
||||
|
||||
let allocation = this._drawingArea.get_allocation_box();
|
||||
let paintOpacity = this._drawingArea.get_paint_opacity();
|
||||
let framebuffer = paintContext.get_framebuffer();
|
||||
|
||||
this._shadowHelper.paint(framebuffer, allocation, paintOpacity);
|
||||
}
|
||||
|
||||
this._drawingArea.paint(paintContext);
|
||||
}
|
||||
});
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* If you are setting org.gnome.desktop.session.idle-delay directly in dconf,
|
||||
* rather than through System Settings, you also need to set
|
||||
@@ -447,59 +55,18 @@ var ScreenShield = class {
|
||||
name: 'lockScreenGroup',
|
||||
visible: false,
|
||||
});
|
||||
this._lockScreenGroup.connect('key-press-event',
|
||||
this._onLockScreenKeyPress.bind(this));
|
||||
this._lockScreenGroup.connect('scroll-event',
|
||||
this._onLockScreenScroll.bind(this));
|
||||
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
|
||||
|
||||
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
||||
name: 'lockScreenContents' });
|
||||
this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||
this._lockDialogGroup = new St.Widget({
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||
name: 'lockDialogGroup',
|
||||
});
|
||||
|
||||
this._lockScreenGroup.add_actor(this._lockScreenContents);
|
||||
|
||||
this._backgroundGroup = new Clutter.Actor();
|
||||
|
||||
this._lockScreenGroup.add_actor(this._backgroundGroup);
|
||||
this._lockScreenGroup.set_child_below_sibling(this._backgroundGroup, null);
|
||||
this._bgManagers = [];
|
||||
|
||||
this._updateBackgrounds();
|
||||
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
|
||||
|
||||
this._arrowAnimationId = 0;
|
||||
this._arrowWatchId = 0;
|
||||
this._arrowActiveWatchId = 0;
|
||||
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
|
||||
vertical: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.END,
|
||||
// HACK: without these, ClutterBinLayout
|
||||
// ignores alignment properties on the actor
|
||||
x_expand: true,
|
||||
y_expand: true });
|
||||
|
||||
for (let i = 0; i < N_ARROWS; i++) {
|
||||
let arrow = new Arrow({ opacity: 0 });
|
||||
this._arrowContainer.add_actor(arrow);
|
||||
}
|
||||
this._lockScreenContents.add_actor(this._arrowContainer);
|
||||
|
||||
this._dragAction = new Clutter.GestureAction();
|
||||
this._dragAction.connect('gesture-begin', this._onDragBegin.bind(this));
|
||||
this._dragAction.connect('gesture-progress', this._onDragMotion.bind(this));
|
||||
this._dragAction.connect('gesture-end', this._onDragEnd.bind(this));
|
||||
this._lockScreenGroup.add_action(this._dragAction);
|
||||
|
||||
this._lockDialogGroup = new St.Widget({ x_expand: true,
|
||||
y_expand: true,
|
||||
reactive: true,
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||
name: 'lockDialogGroup' });
|
||||
|
||||
this.actor.add_actor(this._lockDialogGroup);
|
||||
this.actor.add_actor(this._lockScreenGroup);
|
||||
this.actor.add_actor(this._lockDialogGroup);
|
||||
|
||||
this._presence = new GnomeSession.Presence((proxy, error) => {
|
||||
if (error) {
|
||||
@@ -519,14 +86,14 @@ var ScreenShield = class {
|
||||
this._smartcardManager.connect('smartcard-inserted',
|
||||
(manager, token) => {
|
||||
if (this._isLocked && token.UsedToLogin)
|
||||
this._liftShield(true, 0);
|
||||
this._activateDialog();
|
||||
});
|
||||
|
||||
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
||||
this._oVirtCredentialsManager.connect('user-authenticated',
|
||||
() => {
|
||||
if (this._isLocked)
|
||||
this._liftShield(true, 0);
|
||||
this._activateDialog();
|
||||
});
|
||||
|
||||
this._loginManager = LoginManager.getLoginManager();
|
||||
@@ -551,7 +118,6 @@ var ScreenShield = class {
|
||||
this._lockSettings.connect(`changed::${DISABLE_LOCK_KEY}`, this._syncInhibitor.bind(this));
|
||||
|
||||
this._isModal = false;
|
||||
this._hasLockScreen = false;
|
||||
this._isGreeter = false;
|
||||
this._isActive = false;
|
||||
this._isLocked = false;
|
||||
@@ -591,39 +157,10 @@ var ScreenShield = class {
|
||||
this._syncInhibitor();
|
||||
}
|
||||
|
||||
_createBackground(monitorIndex) {
|
||||
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 bgManager = new Background.BackgroundManager({ container: widget,
|
||||
monitorIndex,
|
||||
controlPosition: false,
|
||||
settingsSchema: SCREENSAVER_SCHEMA });
|
||||
|
||||
this._bgManagers.push(bgManager);
|
||||
|
||||
this._backgroundGroup.add_child(widget);
|
||||
}
|
||||
|
||||
_updateBackgrounds() {
|
||||
for (let i = 0; i < this._bgManagers.length; i++)
|
||||
this._bgManagers[i].destroy();
|
||||
|
||||
this._bgManagers = [];
|
||||
this._backgroundGroup.destroy_all_children();
|
||||
|
||||
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
|
||||
this._createBackground(i);
|
||||
}
|
||||
|
||||
_liftShield(onPrimary, velocity) {
|
||||
_activateDialog() {
|
||||
if (this._isLocked) {
|
||||
if (this._ensureUnlockDialog(onPrimary, true /* allowCancel */))
|
||||
this._hideLockScreen(true /* animate */, velocity);
|
||||
this._ensureUnlockDialog(true /* allowCancel */);
|
||||
this._dialog.activate();
|
||||
} else {
|
||||
this.deactivate(true /* animate */);
|
||||
}
|
||||
@@ -638,9 +175,7 @@ var ScreenShield = class {
|
||||
// LoginDialog.cancel() will grab the key focus
|
||||
// on its own, so ensure it stays on lock screen
|
||||
// instead
|
||||
this._lockScreenGroup.grab_key_focus();
|
||||
} else {
|
||||
this._dialog = null;
|
||||
this._dialog.grab_key_focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,55 +194,6 @@ var ScreenShield = class {
|
||||
return this._isModal;
|
||||
}
|
||||
|
||||
_onLockScreenKeyPress(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
let unichar = event.get_key_unicode();
|
||||
|
||||
// Do nothing if the lock screen is not fully shown.
|
||||
// This avoids reusing the previous (and stale) unlock
|
||||
// dialog if esc is pressed while the curtain is going
|
||||
// down after cancel.
|
||||
|
||||
if (this._lockScreenState != MessageTray.State.SHOWN)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let isEnter = symbol == Clutter.KEY_Return ||
|
||||
symbol == Clutter.KEY_KP_Enter ||
|
||||
symbol == Clutter.KEY_ISO_Enter;
|
||||
let isEscape = symbol == Clutter.KEY_Escape;
|
||||
let isLiftChar = GLib.unichar_isprint(unichar) &&
|
||||
(this._isLocked || !GLib.unichar_isgraph(unichar));
|
||||
if (!isEnter && !isEscape && !isLiftChar)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
if (this._isLocked &&
|
||||
this._ensureUnlockDialog(true, true) &&
|
||||
GLib.unichar_isgraph(unichar))
|
||||
this._dialog.addCharacter(unichar);
|
||||
|
||||
this._liftShield(true, 0);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_onLockScreenScroll(actor, event) {
|
||||
if (this._lockScreenState != MessageTray.State.SHOWN)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let delta = 0;
|
||||
if (event.get_scroll_direction() == Clutter.ScrollDirection.SMOOTH)
|
||||
delta = Math.abs(event.get_scroll_delta()[0]);
|
||||
else
|
||||
delta = 5;
|
||||
|
||||
this._lockScreenScrollCounter += delta;
|
||||
|
||||
// 7 standard scrolls to lift up
|
||||
if (this._lockScreenScrollCounter > 35)
|
||||
this._liftShield(true, 0);
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
_syncInhibitor() {
|
||||
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
|
||||
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
|
||||
@@ -736,78 +222,6 @@ var ScreenShield = class {
|
||||
}
|
||||
}
|
||||
|
||||
_animateArrows() {
|
||||
let arrows = this._arrowContainer.get_children();
|
||||
let unitaryDelay = ARROW_ANIMATION_TIME / (arrows.length + 1);
|
||||
let maxOpacity = 255 * ARROW_ANIMATION_PEAK_OPACITY;
|
||||
for (let i = 0; i < arrows.length; i++) {
|
||||
arrows[i].opacity = 0;
|
||||
arrows[i].ease({
|
||||
opacity: maxOpacity,
|
||||
delay: unitaryDelay * (N_ARROWS - (i + 1)),
|
||||
duration: ARROW_ANIMATION_TIME / 2,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
arrows[i].ease({
|
||||
opacity: 0,
|
||||
duration: ARROW_ANIMATION_TIME / 2,
|
||||
mode: Clutter.AnimationMode.EASE_IN_QUAD,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
_onDragBegin() {
|
||||
this._lockScreenGroup.remove_all_transitions();
|
||||
this._lockScreenState = MessageTray.State.HIDING;
|
||||
|
||||
if (this._isLocked)
|
||||
this._ensureUnlockDialog(false, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_onDragMotion() {
|
||||
let [, origY] = this._dragAction.get_press_coords(0);
|
||||
let [, currentY] = this._dragAction.get_motion_coords(0);
|
||||
|
||||
let newY = currentY - origY;
|
||||
newY = clamp(newY, -global.stage.height, 0);
|
||||
|
||||
this._lockScreenGroup.translation_y = newY;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_onDragEnd(_action, _actor, _eventX, _eventY, _modifiers) {
|
||||
if (this._lockScreenState != MessageTray.State.HIDING)
|
||||
return;
|
||||
if (this._lockScreenGroup.translation_y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
|
||||
// Complete motion automatically
|
||||
let [velocity_, velocityX_, velocityY] = this._dragAction.get_velocity(0);
|
||||
this._liftShield(true, -velocityY);
|
||||
} else {
|
||||
// restore the lock screen to its original place
|
||||
// try to use the same speed as the normal animation
|
||||
let h = global.stage.height;
|
||||
let duration = MANUAL_FADE_TIME * -this._lockScreenGroup.translation_y / h;
|
||||
this._lockScreenGroup.remove_all_transitions();
|
||||
this._lockScreenGroup.ease({
|
||||
translation_y: 0,
|
||||
duration,
|
||||
mode: Clutter.AnimationMode.EASE_IN_QUAD,
|
||||
onComplete: () => {
|
||||
this._lockScreenState = MessageTray.State.SHOWN;
|
||||
},
|
||||
});
|
||||
|
||||
this._maybeCancelDialog();
|
||||
}
|
||||
}
|
||||
|
||||
_onStatusChanged(status) {
|
||||
if (status != GnomeSession.PresenceStatus.IDLE)
|
||||
return;
|
||||
@@ -913,14 +327,10 @@ var ScreenShield = class {
|
||||
this.actor.show();
|
||||
this._isGreeter = Main.sessionMode.isGreeter;
|
||||
this._isLocked = true;
|
||||
if (this._ensureUnlockDialog(true, true))
|
||||
this._hideLockScreen(false, 0);
|
||||
this._ensureUnlockDialog(true);
|
||||
}
|
||||
|
||||
_hideLockScreenComplete() {
|
||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
||||
Main.sessionMode.popMode('lock-screen');
|
||||
|
||||
this._lockScreenState = MessageTray.State.HIDDEN;
|
||||
this._lockScreenGroup.hide();
|
||||
|
||||
@@ -930,13 +340,13 @@ var ScreenShield = class {
|
||||
}
|
||||
}
|
||||
|
||||
_hideLockScreen(animate, velocity) {
|
||||
_hideLockScreen(animate) {
|
||||
if (this._lockScreenState == MessageTray.State.HIDDEN)
|
||||
return;
|
||||
|
||||
this._lockScreenState = MessageTray.State.HIDING;
|
||||
|
||||
this._lockScreenGroup.remove_all_transitions();
|
||||
this._lockDialogGroup.remove_all_transitions();
|
||||
|
||||
if (animate) {
|
||||
// Tween the lock screen out of screen
|
||||
@@ -944,16 +354,14 @@ var ScreenShield = class {
|
||||
// use the same speed regardless of original position
|
||||
// if velocity is specified, it's in pixels per milliseconds
|
||||
let h = global.stage.height;
|
||||
let delta = h + this._lockScreenGroup.translation_y;
|
||||
let minVelocity = global.stage.height / CURTAIN_SLIDE_TIME;
|
||||
|
||||
velocity = Math.max(minVelocity, velocity);
|
||||
let delta = h + this._lockDialogGroup.translation_y;
|
||||
let velocity = global.stage.height / CURTAIN_SLIDE_TIME;
|
||||
let duration = delta / velocity;
|
||||
|
||||
this._lockScreenGroup.ease({
|
||||
this._lockDialogGroup.ease({
|
||||
translation_y: -h,
|
||||
duration,
|
||||
mode: Clutter.AnimationMode.EASE_IN_QUAD,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => this._hideLockScreenComplete(),
|
||||
});
|
||||
} else {
|
||||
@@ -963,7 +371,7 @@ var ScreenShield = class {
|
||||
this._cursorTracker.set_pointer_visible(true);
|
||||
}
|
||||
|
||||
_ensureUnlockDialog(onPrimary, allowCancel) {
|
||||
_ensureUnlockDialog(allowCancel) {
|
||||
if (!this._dialog) {
|
||||
let constructor = Main.sessionMode.unlockDialog;
|
||||
if (!constructor) {
|
||||
@@ -975,7 +383,7 @@ var ScreenShield = class {
|
||||
this._dialog = new constructor(this._lockDialogGroup);
|
||||
|
||||
let time = global.get_current_time();
|
||||
if (!this._dialog.open(time, onPrimary)) {
|
||||
if (!this._dialog.open(time)) {
|
||||
// This is kind of an impossible error: we're already modal
|
||||
// by the time we reach this...
|
||||
log('Could not open login dialog: failed to acquire grab');
|
||||
@@ -984,9 +392,12 @@ var ScreenShield = class {
|
||||
}
|
||||
|
||||
this._dialog.connect('failed', this._onUnlockFailed.bind(this));
|
||||
this._wakeUpScreenId = this._dialog.connect(
|
||||
'wake-up-screen', this._wakeUpScreen.bind(this));
|
||||
}
|
||||
|
||||
this._dialog.allowCancel = allowCancel;
|
||||
this._dialog.grab_key_focus();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1003,21 +414,17 @@ var ScreenShield = class {
|
||||
if (this._lockScreenState != MessageTray.State.HIDDEN)
|
||||
return;
|
||||
|
||||
this._ensureLockScreen();
|
||||
this._lockDialogGroup.scale_x = 1;
|
||||
this._lockDialogGroup.scale_y = 1;
|
||||
|
||||
this._lockScreenGroup.show();
|
||||
this._lockScreenState = MessageTray.State.SHOWING;
|
||||
|
||||
let fadeToBlack = params.fadeToBlack;
|
||||
|
||||
if (params.animateLockScreen) {
|
||||
this._lockScreenGroup.translation_y = -global.screen_height;
|
||||
this._lockScreenGroup.remove_all_transitions();
|
||||
this._lockScreenGroup.ease({
|
||||
this._lockDialogGroup.translation_y = -global.screen_height;
|
||||
this._lockDialogGroup.remove_all_transitions();
|
||||
this._lockDialogGroup.ease({
|
||||
translation_y: 0,
|
||||
duration: MANUAL_FADE_TIME,
|
||||
duration: Overview.ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
this._lockScreenShown({ fadeToBlack, animateFade: true });
|
||||
@@ -1028,69 +435,10 @@ var ScreenShield = class {
|
||||
this._lockScreenShown({ fadeToBlack, animateFade: false });
|
||||
}
|
||||
|
||||
this._lockScreenGroup.grab_key_focus();
|
||||
|
||||
if (Main.sessionMode.currentMode != 'lock-screen')
|
||||
Main.sessionMode.pushMode('lock-screen');
|
||||
}
|
||||
|
||||
_startArrowAnimation() {
|
||||
this._arrowActiveWatchId = 0;
|
||||
|
||||
if (!this._arrowAnimationId) {
|
||||
this._arrowAnimationId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 6000, this._animateArrows.bind(this));
|
||||
GLib.Source.set_name_by_id(this._arrowAnimationId, '[gnome-shell] this._animateArrows');
|
||||
this._animateArrows();
|
||||
}
|
||||
|
||||
if (!this._arrowWatchId) {
|
||||
this._arrowWatchId = this.idleMonitor.add_idle_watch(ARROW_IDLE_TIME,
|
||||
this._pauseArrowAnimation.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
_pauseArrowAnimation() {
|
||||
if (this._arrowAnimationId) {
|
||||
GLib.source_remove(this._arrowAnimationId);
|
||||
this._arrowAnimationId = 0;
|
||||
}
|
||||
|
||||
if (!this._arrowActiveWatchId)
|
||||
this._arrowActiveWatchId = this.idleMonitor.add_user_active_watch(this._startArrowAnimation.bind(this));
|
||||
}
|
||||
|
||||
_stopArrowAnimation() {
|
||||
if (this._arrowAnimationId) {
|
||||
GLib.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() {
|
||||
let idleTime = this.idleMonitor.get_idletime();
|
||||
|
||||
if (idleTime < ARROW_IDLE_TIME)
|
||||
this._startArrowAnimation();
|
||||
else
|
||||
this._pauseArrowAnimation();
|
||||
this._dialog.grab_key_focus();
|
||||
}
|
||||
|
||||
_lockScreenShown(params) {
|
||||
if (this._dialog && !this._isGreeter) {
|
||||
this._dialog.destroy();
|
||||
this._dialog = null;
|
||||
}
|
||||
|
||||
this._checkArrowAnimation();
|
||||
|
||||
let motionId = global.stage.connect('captured-event', (stage, event) => {
|
||||
if (event.type() == Clutter.EventType.MOTION) {
|
||||
this._cursorTracker.set_pointer_visible(true);
|
||||
@@ -1102,7 +450,6 @@ var ScreenShield = class {
|
||||
this._cursorTracker.set_pointer_visible(false);
|
||||
|
||||
this._lockScreenState = MessageTray.State.SHOWN;
|
||||
this._lockScreenScrollCounter = 0;
|
||||
|
||||
if (params.fadeToBlack && params.animateFade) {
|
||||
// Take a beat
|
||||
@@ -1125,52 +472,11 @@ var ScreenShield = class {
|
||||
this.emit('lock-screen-shown');
|
||||
}
|
||||
|
||||
// Some of the actors in the lock screen are heavy in
|
||||
// resources, so we only create them when needed
|
||||
_ensureLockScreen() {
|
||||
if (this._hasLockScreen)
|
||||
return;
|
||||
|
||||
this._lockScreenContentsBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
vertical: true,
|
||||
style_class: 'screen-shield-contents-box' });
|
||||
this._clock = new Clock();
|
||||
this._lockScreenContentsBox.add_child(this._clock);
|
||||
|
||||
this._lockScreenContents.add_actor(this._lockScreenContentsBox);
|
||||
|
||||
this._notificationsBox = new NotificationsBox();
|
||||
this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', this._wakeUpScreen.bind(this));
|
||||
this._lockScreenContentsBox.add_child(this._notificationsBox);
|
||||
|
||||
this._hasLockScreen = true;
|
||||
}
|
||||
|
||||
_wakeUpScreen() {
|
||||
this._onUserBecameActive();
|
||||
this.emit('wake-up-screen');
|
||||
}
|
||||
|
||||
_clearLockScreen() {
|
||||
this._clock.destroy();
|
||||
this._clock = null;
|
||||
|
||||
if (this._notificationsBox) {
|
||||
this._notificationsBox.disconnect(this._wakeUpScreenId);
|
||||
this._notificationsBox.destroy();
|
||||
this._notificationsBox = null;
|
||||
}
|
||||
|
||||
this._stopArrowAnimation();
|
||||
|
||||
this._lockScreenContentsBox.destroy();
|
||||
|
||||
this._hasLockScreen = false;
|
||||
}
|
||||
|
||||
get locked() {
|
||||
return this._isLocked;
|
||||
}
|
||||
@@ -1191,13 +497,8 @@ var ScreenShield = class {
|
||||
}
|
||||
|
||||
_continueDeactivate(animate) {
|
||||
this._hideLockScreen(animate, 0);
|
||||
this._hideLockScreen(animate);
|
||||
|
||||
if (this._hasLockScreen)
|
||||
this._clearLockScreen();
|
||||
|
||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
||||
Main.sessionMode.popMode('lock-screen');
|
||||
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
||||
Main.sessionMode.popMode('unlock-dialog');
|
||||
|
||||
@@ -1223,9 +524,8 @@ var ScreenShield = class {
|
||||
}
|
||||
|
||||
this._lockDialogGroup.ease({
|
||||
scale_x: 0,
|
||||
scale_y: 0,
|
||||
duration: animate ? Overview.ANIMATION_TIME : 0,
|
||||
translation_y: -global.screen_height,
|
||||
duration: Overview.ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => this._completeDeactivate(),
|
||||
});
|
||||
@@ -1262,10 +562,11 @@ var ScreenShield = class {
|
||||
if (this._activationTime == 0)
|
||||
this._activationTime = GLib.get_monotonic_time();
|
||||
|
||||
this._ensureUnlockDialog(true);
|
||||
|
||||
this.actor.show();
|
||||
|
||||
if (Main.sessionMode.currentMode != 'unlock-dialog' &&
|
||||
Main.sessionMode.currentMode != 'lock-screen') {
|
||||
if (Main.sessionMode.currentMode !== 'unlock-dialog') {
|
||||
this._isGreeter = Main.sessionMode.isGreeter;
|
||||
if (!this._isGreeter)
|
||||
Main.sessionMode.pushMode('unlock-dialog');
|
||||
|
@@ -5,8 +5,10 @@
|
||||
|
||||
const { Gio, GLib, Meta, Shell } = imports.gi;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
@@ -77,6 +79,12 @@ function _getPerfHelper() {
|
||||
return _perfHelper;
|
||||
}
|
||||
|
||||
function _spawnPerfHelper() {
|
||||
let path = Config.LIBEXECDIR;
|
||||
let command = `${path}/gnome-shell-perf-helper`;
|
||||
Util.trySpawnCommandLine(command);
|
||||
}
|
||||
|
||||
function _callRemote(obj, method, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
args.push((result, excp) => {
|
||||
@@ -276,6 +284,25 @@ function _collect(scriptModule, outputFile) {
|
||||
}
|
||||
}
|
||||
|
||||
async function _runPerfScript(scriptModule, outputFile) {
|
||||
for (let step of scriptModule.run()) {
|
||||
try {
|
||||
await step; // eslint-disable-line no-await-in-loop
|
||||
} catch (err) {
|
||||
log(`Script failed: ${err}\n${err.stack}`);
|
||||
Meta.exit(Meta.ExitCode.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
_collect(scriptModule, outputFile);
|
||||
} catch (err) {
|
||||
log(`Script failed: ${err}\n${err.stack}`);
|
||||
Meta.exit(Meta.ExitCode.ERROR);
|
||||
}
|
||||
Meta.exit(Meta.ExitCode.SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* runPerfScript
|
||||
* @param {Object} scriptModule: module object with run and finish
|
||||
@@ -317,23 +344,13 @@ function _collect(scriptModule, outputFile) {
|
||||
* After running the script and collecting statistics from the
|
||||
* event log, GNOME Shell will exit.
|
||||
**/
|
||||
async function runPerfScript(scriptModule, outputFile) {
|
||||
function runPerfScript(scriptModule, outputFile) {
|
||||
Shell.PerfLog.get_default().set_enabled(true);
|
||||
_spawnPerfHelper();
|
||||
|
||||
for (let step of scriptModule.run()) {
|
||||
try {
|
||||
await step; // eslint-disable-line no-await-in-loop
|
||||
} catch (err) {
|
||||
log(`Script failed: ${err}\n${err.stack}`);
|
||||
Meta.exit(Meta.ExitCode.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
_collect(scriptModule, outputFile);
|
||||
} catch (err) {
|
||||
log(`Script failed: ${err}\n${err.stack}`);
|
||||
Meta.exit(Meta.ExitCode.ERROR);
|
||||
}
|
||||
Meta.exit(Meta.ExitCode.SUCCESS);
|
||||
Gio.bus_watch_name(Gio.BusType.SESSION,
|
||||
'org.gnome.Shell.PerfHelper',
|
||||
Gio.BusNameWatcherFlags.NONE,
|
||||
() => _runPerfScript(scriptModule, outputFile),
|
||||
null);
|
||||
}
|
||||
|
@@ -53,19 +53,6 @@ const _modes = {
|
||||
panelStyle: 'login-screen',
|
||||
},
|
||||
|
||||
'lock-screen': {
|
||||
isLocked: true,
|
||||
isGreeter: undefined,
|
||||
unlockDialog: undefined,
|
||||
components: ['polkitAgent', 'telepathyClient'],
|
||||
panel: {
|
||||
left: [],
|
||||
center: [],
|
||||
right: ['aggregateMenu'],
|
||||
},
|
||||
panelStyle: 'lock-screen',
|
||||
},
|
||||
|
||||
'unlock-dialog': {
|
||||
isLocked: true,
|
||||
unlockDialog: undefined,
|
||||
|
@@ -302,7 +302,7 @@ var GnomeShellExtensions = class {
|
||||
|
||||
LaunchExtensionPrefs(uuid) {
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
let app = appSys.lookup_app('gnome-shell-extension-prefs.desktop');
|
||||
let app = appSys.lookup_app('org.gnome.Extensions.desktop');
|
||||
let info = app.get_app_info();
|
||||
let timestamp = global.display.get_current_time_roundtrip();
|
||||
info.launch_uris([`extension:///${uuid}`],
|
||||
|
@@ -156,36 +156,53 @@ function addContextMenu(entry, params) {
|
||||
var CapsLockWarning = GObject.registerClass(
|
||||
class CapsLockWarning extends St.Label {
|
||||
_init(params) {
|
||||
let defaultParams = { style_class: 'prompt-dialog-error-label' };
|
||||
let defaultParams = { style_class: 'caps-lock-warning-label' };
|
||||
super._init(Object.assign(defaultParams, params));
|
||||
|
||||
this.text = _('Caps lock is on.');
|
||||
|
||||
this._keymap = Clutter.get_default_backend().get_keymap();
|
||||
this.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this.clutter_text.line_wrap = true;
|
||||
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
this._keymap = seat.get_keymap();
|
||||
this._stateChangedId = 0;
|
||||
|
||||
this.connect('notify::mapped', () => {
|
||||
if (this.is_mapped()) {
|
||||
this.stateChangedId = this._keymap.connect('state-changed',
|
||||
this._updateCapsLockWarningOpacity.bind(this));
|
||||
this._stateChangedId = this._keymap.connect('state-changed',
|
||||
() => this._sync(true));
|
||||
} else {
|
||||
this._keymap.disconnect(this.stateChangedId);
|
||||
this.stateChangedId = 0;
|
||||
this._keymap.disconnect(this._stateChangedId);
|
||||
this._stateChangedId = 0;
|
||||
}
|
||||
|
||||
this._updateCapsLockWarningOpacity();
|
||||
this._sync(false);
|
||||
});
|
||||
|
||||
this.connect('destroy', () => {
|
||||
if (this.stateChangedId > 0)
|
||||
this._keymap.disconnect(this.stateChangedId);
|
||||
if (this._stateChangedId)
|
||||
this._keymap.disconnect(this._stateChangedId);
|
||||
});
|
||||
|
||||
this.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this.clutter_text.line_wrap = true;
|
||||
}
|
||||
|
||||
_updateCapsLockWarningOpacity() {
|
||||
_sync(animate) {
|
||||
let capsLockOn = this._keymap.get_caps_lock_state();
|
||||
this.opacity = capsLockOn ? 255 : 0;
|
||||
|
||||
this.remove_all_transitions();
|
||||
|
||||
this.natural_height_set = false;
|
||||
let [, height] = this.get_preferred_height(-1);
|
||||
this.natural_height_set = true;
|
||||
|
||||
this.ease({
|
||||
height: capsLockOn ? height : 0,
|
||||
opacity: capsLockOn ? 255 : 0,
|
||||
duration: animate ? 200 : 0,
|
||||
onComplete: () => {
|
||||
if (capsLockOn)
|
||||
this.height = -1;
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@@ -13,6 +13,7 @@ const Params = imports.misc.params;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
var LIST_ITEM_ICON_SIZE = 48;
|
||||
var WORK_SPINNER_ICON_SIZE = 16;
|
||||
@@ -20,18 +21,23 @@ var WORK_SPINNER_ICON_SIZE = 16;
|
||||
const REMEMBER_MOUNT_PASSWORD_KEY = 'remember-mount-password';
|
||||
|
||||
/* ------ Common Utils ------- */
|
||||
function _setButtonsForChoices(dialog, choices) {
|
||||
function _setButtonsForChoices(dialog, oldChoices, choices) {
|
||||
let buttons = [];
|
||||
let buttonsChanged = oldChoices.length !== choices.length;
|
||||
|
||||
for (let idx = 0; idx < choices.length; idx++) {
|
||||
let button = idx;
|
||||
|
||||
buttonsChanged = buttonsChanged || oldChoices[idx] !== choices[idx];
|
||||
|
||||
buttons.unshift({
|
||||
label: choices[idx],
|
||||
action: () => dialog.emit('response', button),
|
||||
});
|
||||
}
|
||||
|
||||
dialog.setButtons(buttons);
|
||||
if (buttonsChanged)
|
||||
dialog.setButtons(buttons);
|
||||
}
|
||||
|
||||
function _setLabelsForMessage(content, message) {
|
||||
@@ -43,41 +49,6 @@ function _setLabelsForMessage(content, message) {
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
var ListItem = GObject.registerClass({
|
||||
Signals: { 'activate': {} },
|
||||
}, class ListItem extends St.Button {
|
||||
_init(app) {
|
||||
let layout = new St.BoxLayout({ vertical: false });
|
||||
super._init({
|
||||
style_class: 'mount-dialog-app-list-item',
|
||||
can_focus: true,
|
||||
child: layout,
|
||||
reactive: true,
|
||||
});
|
||||
|
||||
this._app = app;
|
||||
|
||||
this._icon = this._app.create_icon_texture(LIST_ITEM_ICON_SIZE);
|
||||
|
||||
let iconBin = new St.Bin({ style_class: 'mount-dialog-app-list-item-icon',
|
||||
child: this._icon });
|
||||
layout.add(iconBin);
|
||||
|
||||
this._nameLabel = new St.Label({
|
||||
text: this._app.get_name(),
|
||||
style_class: 'mount-dialog-app-list-item-name',
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
let labelBin = new St.Bin({ child: this._nameLabel });
|
||||
layout.add(labelBin);
|
||||
}
|
||||
|
||||
vfunc_clicked() {
|
||||
this.emit('activate');
|
||||
this._app.activate();
|
||||
}
|
||||
});
|
||||
|
||||
var ShellMountOperation = class {
|
||||
constructor(source, params) {
|
||||
params = Params.parse(params, { existingDialog: null });
|
||||
@@ -258,15 +229,27 @@ var ShellMountQuestionDialog = GObject.registerClass({
|
||||
Signals: { 'response': { param_types: [GObject.TYPE_INT] } },
|
||||
}, class ShellMountQuestionDialog extends ModalDialog.ModalDialog {
|
||||
_init() {
|
||||
super._init({ styleClass: 'mount-dialog' });
|
||||
super._init({ styleClass: 'mount-question-dialog' });
|
||||
|
||||
this._oldChoices = [];
|
||||
|
||||
this._content = new Dialog.MessageDialogContent();
|
||||
this.contentLayout.add_child(this._content);
|
||||
}
|
||||
|
||||
vfunc_key_release_event(event) {
|
||||
if (event.keyval === Clutter.KEY_Escape) {
|
||||
this.emit('response', -1);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
update(message, choices) {
|
||||
_setLabelsForMessage(this._content, message);
|
||||
_setButtonsForChoices(this, choices);
|
||||
_setButtonsForChoices(this, this._oldChoices, choices);
|
||||
this._oldChoices = choices;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -287,21 +270,18 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
let disksApp = Shell.AppSystem.get_default().lookup_app('org.gnome.DiskUtility.desktop');
|
||||
|
||||
let content = new Dialog.MessageDialogContent({ title, description });
|
||||
this.contentLayout.add_actor(content);
|
||||
|
||||
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
||||
let grid = new St.Widget({ style_class: 'prompt-dialog-grid',
|
||||
layout_manager: layout });
|
||||
layout.hookup_style(grid);
|
||||
let rtl = grid.get_text_direction() === Clutter.TextDirection.RTL;
|
||||
let passwordGridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
||||
let passwordGrid = new St.Widget({
|
||||
style_class: 'prompt-dialog-password-grid',
|
||||
layout_manager: passwordGridLayout,
|
||||
});
|
||||
passwordGridLayout.hookup_style(passwordGrid);
|
||||
|
||||
let rtl = passwordGrid.get_text_direction() === Clutter.TextDirection.RTL;
|
||||
let curGridRow = 0;
|
||||
|
||||
if (flags & Gio.AskPasswordFlags.TCRYPT) {
|
||||
this._keyfilesLabel = new St.Label({
|
||||
style_class: 'prompt-dialog-keyfiles-label',
|
||||
visible: false,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
|
||||
this._hiddenVolume = new CheckBox.CheckBox(_("Hidden Volume"));
|
||||
content.add_child(this._hiddenVolume);
|
||||
|
||||
@@ -312,6 +292,7 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
this._keyfilesCheckbox.connect("clicked", this._onKeyfilesCheckboxClicked.bind(this));
|
||||
content.add_child(this._keyfilesCheckbox);
|
||||
|
||||
this._keyfilesLabel = new St.Label({ visible: false });
|
||||
this._keyfilesLabel.clutter_text.set_markup(
|
||||
/* Translators: %s is the Disks application */
|
||||
_("To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead.").format(disksApp.get_name())
|
||||
@@ -320,71 +301,65 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
this._keyfilesLabel.clutter_text.line_wrap = true;
|
||||
content.add_child(this._keyfilesLabel);
|
||||
|
||||
this._pimLabel = new St.Label({ style_class: 'prompt-dialog-password-label',
|
||||
text: _("PIM Number"),
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
this._pimEntry = new St.PasswordEntry({
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
hint_text: _('Enter PIM Number…'),
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
});
|
||||
this._pimEntry.clutter_text.connect('activate', this._onEntryActivate.bind(this));
|
||||
ShellEntry.addContextMenu(this._pimEntry);
|
||||
|
||||
if (rtl) {
|
||||
layout.attach(this._pimEntry, 0, 0, 1, 1);
|
||||
layout.attach(this._pimLabel, 1, 0, 1, 1);
|
||||
} else {
|
||||
layout.attach(this._pimLabel, 0, 0, 1, 1);
|
||||
layout.attach(this._pimEntry, 1, 0, 1, 1);
|
||||
}
|
||||
|
||||
this._pimErrorMessageLabel = new St.Label({ style_class: 'prompt-dialog-password-entry',
|
||||
text: _("The PIM must be a number or empty."),
|
||||
visible: false });
|
||||
layout.attach(this._pimErrorMessageLabel, 0, 2, 2, 1);
|
||||
if (rtl)
|
||||
passwordGridLayout.attach(this._pimEntry, 1, curGridRow, 1, 1);
|
||||
else
|
||||
passwordGridLayout.attach(this._pimEntry, 0, curGridRow, 1, 1);
|
||||
curGridRow += 1;
|
||||
} else {
|
||||
this._hiddenVolume = null;
|
||||
this._systemVolume = null;
|
||||
this._pimEntry = null;
|
||||
this._pimErrorMessageLabel = null;
|
||||
}
|
||||
|
||||
this._passwordLabel = new St.Label({ style_class: 'prompt-dialog-password-label',
|
||||
text: _("Password"),
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
this._passwordEntry = new St.PasswordEntry({
|
||||
style_class: 'prompt-dialog-password-entry',
|
||||
hint_text: _('Enter Password…'),
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
});
|
||||
this._passwordEntry.clutter_text.connect('activate', this._onEntryActivate.bind(this));
|
||||
ShellEntry.addContextMenu(this._passwordEntry);
|
||||
this.setInitialKeyFocus(this._passwordEntry);
|
||||
ShellEntry.addContextMenu(this._passwordEntry);
|
||||
|
||||
this._workSpinner = new Animation.Spinner(WORK_SPINNER_ICON_SIZE, {
|
||||
animate: true,
|
||||
});
|
||||
this._passwordEntry.secondary_icon = this._workSpinner;
|
||||
this._capsLockWarningLabel = new ShellEntry.CapsLockWarning();
|
||||
|
||||
if (rtl) {
|
||||
layout.attach(this._passwordEntry, 0, 1, 1, 1);
|
||||
layout.attach(this._passwordLabel, 1, 1, 1, 1);
|
||||
layout.attach(this._capsLockWarningLabel, 0, 2, 1, 1);
|
||||
passwordGridLayout.attach(this._workSpinner, 0, curGridRow, 1, 1);
|
||||
passwordGridLayout.attach(this._passwordEntry, 1, curGridRow, 1, 1);
|
||||
} else {
|
||||
layout.attach(this._passwordLabel, 0, 1, 1, 1);
|
||||
layout.attach(this._passwordEntry, 1, 1, 1, 1);
|
||||
layout.attach(this._capsLockWarningLabel, 1, 2, 1, 1);
|
||||
passwordGridLayout.attach(this._passwordEntry, 0, curGridRow, 1, 1);
|
||||
passwordGridLayout.attach(this._workSpinner, 1, curGridRow, 1, 1);
|
||||
}
|
||||
curGridRow += 1;
|
||||
|
||||
content.add_child(grid);
|
||||
let warningBox = new St.BoxLayout({ vertical: true });
|
||||
|
||||
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label',
|
||||
text: _("Sorry, that didn’t work. Please try again.") });
|
||||
let capsLockWarning = new ShellEntry.CapsLockWarning();
|
||||
warningBox.add_child(capsLockWarning);
|
||||
|
||||
this._errorMessageLabel = new St.Label({
|
||||
style_class: 'prompt-dialog-error-label',
|
||||
opacity: 0,
|
||||
});
|
||||
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._errorMessageLabel.clutter_text.line_wrap = true;
|
||||
this._errorMessageLabel.hide();
|
||||
content.add_child(this._errorMessageLabel);
|
||||
warningBox.add_child(this._errorMessageLabel);
|
||||
|
||||
passwordGridLayout.attach(warningBox, 0, curGridRow, 2, 1);
|
||||
|
||||
content.add_child(passwordGrid);
|
||||
|
||||
if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) {
|
||||
this._rememberChoice = new CheckBox.CheckBox(_("Remember Password"));
|
||||
@@ -395,6 +370,8 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
this._rememberChoice = null;
|
||||
}
|
||||
|
||||
this.contentLayout.add_child(content);
|
||||
|
||||
this._defaultButtons = [{
|
||||
label: _("Cancel"),
|
||||
action: this._onCancelButton.bind(this),
|
||||
@@ -420,9 +397,12 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
}
|
||||
|
||||
reaskPassword() {
|
||||
this._passwordEntry.set_text('');
|
||||
this._errorMessageLabel.show();
|
||||
this._workSpinner.stop();
|
||||
this._passwordEntry.set_text('');
|
||||
this._errorMessageLabel.text = _('Sorry, that didn’t work. Please try again.');
|
||||
this._errorMessageLabel.opacity = 255;
|
||||
|
||||
Util.wiggle(this._passwordEntry);
|
||||
}
|
||||
|
||||
_onCancelButton() {
|
||||
@@ -435,14 +415,17 @@ var ShellMountPasswordDialog = GObject.registerClass({
|
||||
|
||||
_onEntryActivate() {
|
||||
let pim = 0;
|
||||
if (this._pimEntry !== null)
|
||||
if (this._pimEntry !== null) {
|
||||
pim = this._pimEntry.get_text();
|
||||
if (isNaN(pim)) {
|
||||
this._pimEntry.set_text('');
|
||||
this._pimErrorMessageLabel.show();
|
||||
return;
|
||||
} else if (this._pimErrorMessageLabel !== null) {
|
||||
this._pimErrorMessageLabel.hide();
|
||||
|
||||
if (isNaN(pim)) {
|
||||
this._pimEntry.set_text('');
|
||||
this._errorMessageLabel.text = _('The PIM must be a number or empty.');
|
||||
this._errorMessageLabel.opacity = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
this._errorMessageLabel.opacity = 0;
|
||||
}
|
||||
|
||||
global.settings.set_boolean(REMEMBER_MOUNT_PASSWORD_KEY,
|
||||
@@ -496,38 +479,30 @@ var ShellProcessesDialog = GObject.registerClass({
|
||||
Signals: { 'response': { param_types: [GObject.TYPE_INT] } },
|
||||
}, class ShellProcessesDialog extends ModalDialog.ModalDialog {
|
||||
_init() {
|
||||
super._init({ styleClass: 'mount-dialog' });
|
||||
super._init({ styleClass: 'processes-dialog' });
|
||||
|
||||
this._oldChoices = [];
|
||||
|
||||
this._content = new Dialog.MessageDialogContent();
|
||||
this.contentLayout.add_child(this._content);
|
||||
|
||||
let scrollView = new St.ScrollView({
|
||||
style_class: 'mount-dialog-app-list',
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
});
|
||||
scrollView.set_policy(St.PolicyType.NEVER,
|
||||
St.PolicyType.AUTOMATIC);
|
||||
this.contentLayout.add_child(scrollView);
|
||||
scrollView.hide();
|
||||
this._applicationSection = new Dialog.ListSection();
|
||||
this._applicationSection.hide();
|
||||
this.contentLayout.add_child(this._applicationSection);
|
||||
}
|
||||
|
||||
this._applicationList = new St.BoxLayout({ vertical: true });
|
||||
scrollView.add_actor(this._applicationList);
|
||||
vfunc_key_release_event(event) {
|
||||
if (event.keyval === Clutter.KEY_Escape) {
|
||||
this.emit('response', -1);
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
|
||||
this._applicationList.connect('actor-added', () => {
|
||||
if (this._applicationList.get_n_children() == 1)
|
||||
scrollView.show();
|
||||
});
|
||||
|
||||
this._applicationList.connect('actor-removed', () => {
|
||||
if (this._applicationList.get_n_children() == 0)
|
||||
scrollView.hide();
|
||||
});
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_setAppsForPids(pids) {
|
||||
// remove all the items
|
||||
this._applicationList.destroy_all_children();
|
||||
this._applicationSection.list.destroy_all_children();
|
||||
|
||||
pids.forEach(pid => {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
@@ -536,20 +511,22 @@ var ShellProcessesDialog = GObject.registerClass({
|
||||
if (!app)
|
||||
return;
|
||||
|
||||
let item = new ListItem(app);
|
||||
this._applicationList.add_child(item);
|
||||
|
||||
item.connect('activate', () => {
|
||||
// use -1 to indicate Cancel
|
||||
this.emit('response', -1);
|
||||
let listItem = new Dialog.ListSectionItem({
|
||||
icon_actor: app.create_icon_texture(LIST_ITEM_ICON_SIZE),
|
||||
title: app.get_name(),
|
||||
});
|
||||
this._applicationSection.list.add_child(listItem);
|
||||
});
|
||||
|
||||
this._applicationSection.visible =
|
||||
this._applicationSection.list.get_n_children() > 0;
|
||||
}
|
||||
|
||||
update(message, processes, choices) {
|
||||
this._setAppsForPids(processes);
|
||||
_setLabelsForMessage(this._content, message);
|
||||
_setButtonsForChoices(this, choices);
|
||||
_setButtonsForChoices(this, this._oldChoices, choices);
|
||||
this._oldChoices = choices;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -701,8 +678,17 @@ var GnomeShellMountOpHandler = class {
|
||||
|
||||
this._dialog = new ShellMountQuestionDialog(message);
|
||||
this._dialog.connect('response', (object, choice) => {
|
||||
this._clearCurrentRequest(Gio.MountOperationResult.HANDLED,
|
||||
{ choice: GLib.Variant.new('i', choice) });
|
||||
let response;
|
||||
let details = {};
|
||||
|
||||
if (choice == -1) {
|
||||
response = Gio.MountOperationResult.ABORTED;
|
||||
} else {
|
||||
response = Gio.MountOperationResult.HANDLED;
|
||||
details['choice'] = GLib.Variant.new('i', choice);
|
||||
}
|
||||
|
||||
this._clearCurrentRequest(response, details);
|
||||
});
|
||||
|
||||
this._dialog.update(message, choices);
|
||||
|
@@ -48,8 +48,8 @@ class DwellClickIndicator extends PanelMenu.Button {
|
||||
this._a11ySettings.connect(`changed::${KEY_DWELL_CLICK_ENABLED}`, this._syncMenuVisibility.bind(this));
|
||||
this._a11ySettings.connect(`changed::${KEY_DWELL_MODE}`, this._syncMenuVisibility.bind(this));
|
||||
|
||||
this._deviceManager = Clutter.DeviceManager.get_default();
|
||||
this._deviceManager.connect('ptr-a11y-dwell-click-type-changed', this._updateClickType.bind(this));
|
||||
this._seat = Clutter.get_default_backend().get_default_seat();
|
||||
this._seat.connect('ptr-a11y-dwell-click-type-changed', this._updateClickType.bind(this));
|
||||
|
||||
this._addDwellAction(DWELL_CLICK_MODES.primary);
|
||||
this._addDwellAction(DWELL_CLICK_MODES.double);
|
||||
@@ -80,7 +80,7 @@ class DwellClickIndicator extends PanelMenu.Button {
|
||||
}
|
||||
|
||||
_setClickType(mode) {
|
||||
this._deviceManager.set_pointer_a11y_dwell_click_type(mode.type);
|
||||
this._seat.set_pointer_a11y_dwell_click_type(mode.type);
|
||||
this._icon.icon_name = mode.icon;
|
||||
}
|
||||
});
|
||||
|
@@ -347,22 +347,30 @@ var AppAuthorizer = class {
|
||||
var GeolocationDialog = GObject.registerClass({
|
||||
Signals: { 'response': { param_types: [GObject.TYPE_UINT] } },
|
||||
}, class GeolocationDialog extends ModalDialog.ModalDialog {
|
||||
_init(name, description, reqAccuracyLevel) {
|
||||
_init(name, reason, reqAccuracyLevel) {
|
||||
super._init({ styleClass: 'geolocation-dialog' });
|
||||
this.reqAccuracyLevel = reqAccuracyLevel;
|
||||
|
||||
/* Translators: %s is an application name */
|
||||
let title = _("Give %s access to your location?").format(name);
|
||||
let content = new Dialog.MessageDialogContent({
|
||||
title: _('Allow location access'),
|
||||
/* Translators: %s is an application name */
|
||||
description: _('The app %s wants to access your location').format(name),
|
||||
});
|
||||
|
||||
let content = new Dialog.MessageDialogContent({ title, description });
|
||||
this.contentLayout.add_actor(content);
|
||||
let reasonLabel = new St.Label({
|
||||
text: reason,
|
||||
style_class: 'message-dialog-description',
|
||||
});
|
||||
content.add_child(reasonLabel);
|
||||
|
||||
let infoLabel = new St.Label({
|
||||
text: _('Location access can be changed at any time from the privacy settings.'),
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
style_class: 'message-dialog-description',
|
||||
});
|
||||
content.add_child(infoLabel);
|
||||
|
||||
this.contentLayout.add_child(content);
|
||||
|
||||
let button = this.addButton({ label: _("Deny Access"),
|
||||
action: this._onDenyClicked.bind(this),
|
||||
key: Clutter.KEY_Escape });
|
||||
|
@@ -20,9 +20,13 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this._createSubMenu();
|
||||
|
||||
this._loginScreenItem.connect('notify::visible',
|
||||
() => this._updateMultiUser());
|
||||
() => this._updateSessionSubMenu());
|
||||
this._logoutItem.connect('notify::visible',
|
||||
() => this._updateMultiUser());
|
||||
() => this._updateSessionSubMenu());
|
||||
this._suspendItem.connect('notify::visible',
|
||||
() => this._updateSessionSubMenu());
|
||||
this._powerOffItem.connect('notify::visible',
|
||||
() => this._updateSessionSubMenu());
|
||||
// Whether shutdown is available or not depends on both lockdown
|
||||
// settings (disable-log-out) and Polkit policy - the latter doesn't
|
||||
// notify, so we update the menu item each time the menu opens or
|
||||
@@ -33,7 +37,7 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
|
||||
this._systemActions.forceUpdate();
|
||||
});
|
||||
this._updateMultiUser();
|
||||
this._updateSessionSubMenu();
|
||||
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
this._sessionUpdated();
|
||||
@@ -43,19 +47,22 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
this._settingsItem.visible = Main.sessionMode.allowSettings;
|
||||
}
|
||||
|
||||
_updateMultiUser() {
|
||||
let hasSwitchUser = this._loginScreenItem.visible;
|
||||
let hasLogout = this._logoutItem.visible;
|
||||
|
||||
this._sessionSubMenu.visible = hasSwitchUser || hasLogout;
|
||||
_updateSessionSubMenu() {
|
||||
this._sessionSubMenu.visible =
|
||||
this._loginScreenItem.visible ||
|
||||
this._logoutItem.visible ||
|
||||
this._suspendItem.visible ||
|
||||
this._powerOffItem.visible;
|
||||
}
|
||||
|
||||
_createSubMenu() {
|
||||
let bindFlags = GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE;
|
||||
let item;
|
||||
|
||||
item = new PopupMenu.PopupImageMenuItem(_('Lock Screen Rotation'),
|
||||
item = new PopupMenu.PopupImageMenuItem(
|
||||
this._systemActions.getName('lock-orientation'),
|
||||
this._systemActions.orientation_lock_icon);
|
||||
|
||||
item.connect('activate', () => {
|
||||
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
||||
this._systemActions.activateLockOrientation();
|
||||
@@ -68,7 +75,10 @@ class Indicator extends PanelMenu.SystemIndicator {
|
||||
bindFlags);
|
||||
this._systemActions.connect('notify::orientation-lock-icon', () => {
|
||||
let iconName = this._systemActions.orientation_lock_icon;
|
||||
let labelText = this._systemActions.getName("lock-orientation");
|
||||
|
||||
this._orientationLockItem.setIcon(iconName);
|
||||
this._orientationLockItem.label.text = labelText;
|
||||
});
|
||||
|
||||
let app = this._settingsApp = Shell.AppSystem.get_default().lookup_app(
|
||||
|
@@ -270,6 +270,8 @@ const ScrollGesture = GObject.registerClass({
|
||||
return;
|
||||
|
||||
this._enabled = enabled;
|
||||
this._began = false;
|
||||
|
||||
this.notify('enabled');
|
||||
}
|
||||
|
||||
|
@@ -1,41 +1,539 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported UnlockDialog */
|
||||
|
||||
const { AccountsService, Atk, Clutter,
|
||||
Gdm, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const { AccountsService, Atk, Clutter, Gdm, Gio,
|
||||
GnomeDesktop, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
|
||||
const AuthPrompt = imports.gdm.authPrompt;
|
||||
|
||||
// The timeout before going back automatically to the lock screen (in seconds)
|
||||
const IDLE_TIMEOUT = 2 * 60;
|
||||
|
||||
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
||||
|
||||
const CROSSFADE_TIME = 300;
|
||||
|
||||
const BLUR_BRIGHTNESS = 0.55;
|
||||
const BLUR_RADIUS = 200;
|
||||
|
||||
const SUMMARY_ICON_SIZE = 32;
|
||||
|
||||
var NotificationsBox = GObject.registerClass({
|
||||
Signals: { 'wake-up-screen': {} },
|
||||
}, class NotificationsBox extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
vertical: true,
|
||||
name: 'unlockDialogNotifications',
|
||||
style_class: 'unlock-dialog-notifications-container',
|
||||
});
|
||||
|
||||
this._scrollView = new St.ScrollView({ hscrollbar_policy: St.PolicyType.NEVER });
|
||||
this._notificationBox = new St.BoxLayout({
|
||||
vertical: true,
|
||||
style_class: 'unlock-dialog-notifications-container',
|
||||
});
|
||||
this._scrollView.add_actor(this._notificationBox);
|
||||
|
||||
this.add_child(this._scrollView);
|
||||
|
||||
this._sources = new Map();
|
||||
Main.messageTray.getSources().forEach(source => {
|
||||
this._sourceAdded(Main.messageTray, source, true);
|
||||
});
|
||||
this._updateVisibility();
|
||||
|
||||
this._sourceAddedId = Main.messageTray.connect('source-added', this._sourceAdded.bind(this));
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._sourceAddedId) {
|
||||
Main.messageTray.disconnect(this._sourceAddedId);
|
||||
this._sourceAddedId = 0;
|
||||
}
|
||||
|
||||
let items = this._sources.entries();
|
||||
for (let [source, obj] of items)
|
||||
this._removeSource(source, obj);
|
||||
}
|
||||
|
||||
_updateVisibility() {
|
||||
this._notificationBox.visible =
|
||||
this._notificationBox.get_children().some(a => a.visible);
|
||||
|
||||
this.visible = this._notificationBox.visible;
|
||||
}
|
||||
|
||||
_makeNotificationSource(source, box) {
|
||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||
box.add_child(sourceActor);
|
||||
|
||||
let textBox = new St.BoxLayout({
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
box.add_child(textBox);
|
||||
|
||||
let title = new St.Label({
|
||||
text: source.title,
|
||||
style_class: 'unlock-dialog-notification-label',
|
||||
x_expand: true,
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
});
|
||||
textBox.add(title);
|
||||
|
||||
let count = source.unseenCount;
|
||||
let countLabel = new St.Label({
|
||||
text: `${count}`,
|
||||
style_class: 'unlock-dialog-notification-count-text',
|
||||
});
|
||||
textBox.add(countLabel);
|
||||
|
||||
box.visible = count !== 0;
|
||||
return [title, countLabel];
|
||||
}
|
||||
|
||||
_makeNotificationDetailedSource(source, box) {
|
||||
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
|
||||
let sourceBin = new St.Bin({ child: sourceActor });
|
||||
box.add(sourceBin);
|
||||
|
||||
let textBox = new St.BoxLayout({ vertical: true });
|
||||
box.add_child(textBox);
|
||||
|
||||
let title = new St.Label({
|
||||
text: source.title,
|
||||
style_class: 'unlock-dialog-notification-label',
|
||||
});
|
||||
textBox.add(title);
|
||||
|
||||
let visible = false;
|
||||
for (let i = 0; i < source.notifications.length; i++) {
|
||||
let n = source.notifications[i];
|
||||
|
||||
if (n.acknowledged)
|
||||
continue;
|
||||
|
||||
let body = '';
|
||||
if (n.bannerBodyText) {
|
||||
body = n.bannerBodyMarkup
|
||||
? n.bannerBodyText
|
||||
: GLib.markup_escape_text(n.bannerBodyText, -1);
|
||||
}
|
||||
|
||||
let label = new St.Label({ style_class: 'unlock-dialog-notification-count-text' });
|
||||
label.clutter_text.set_markup(`<b>${n.title}</b> ${body}`);
|
||||
textBox.add(label);
|
||||
|
||||
visible = true;
|
||||
}
|
||||
|
||||
box.visible = visible;
|
||||
return [title, null];
|
||||
}
|
||||
|
||||
_shouldShowDetails(source) {
|
||||
return source.policy.detailsInLockScreen ||
|
||||
source.narrowestPrivacyScope === MessageTray.PrivacyScope.SYSTEM;
|
||||
}
|
||||
|
||||
_updateSourceBoxStyle(source, obj, box) {
|
||||
let hasCriticalNotification =
|
||||
source.notifications.some(n => n.urgency === MessageTray.Urgency.CRITICAL);
|
||||
|
||||
if (hasCriticalNotification !== obj.hasCriticalNotification) {
|
||||
obj.hasCriticalNotification = hasCriticalNotification;
|
||||
|
||||
if (hasCriticalNotification)
|
||||
box.add_style_class_name('critical');
|
||||
else
|
||||
box.remove_style_class_name('critical');
|
||||
}
|
||||
}
|
||||
|
||||
_showSource(source, obj, box) {
|
||||
if (obj.detailed)
|
||||
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
|
||||
else
|
||||
[obj.titleLabel, obj.countLabel] = this._makeNotificationSource(source, box);
|
||||
|
||||
box.visible = obj.visible && (source.unseenCount > 0);
|
||||
|
||||
this._updateSourceBoxStyle(source, obj, box);
|
||||
}
|
||||
|
||||
_sourceAdded(tray, source, initial) {
|
||||
let obj = {
|
||||
visible: source.policy.showInLockScreen,
|
||||
detailed: this._shouldShowDetails(source),
|
||||
sourceDestroyId: 0,
|
||||
sourceCountChangedId: 0,
|
||||
sourceTitleChangedId: 0,
|
||||
sourceUpdatedId: 0,
|
||||
sourceBox: null,
|
||||
titleLabel: null,
|
||||
countLabel: null,
|
||||
hasCriticalNotification: false,
|
||||
};
|
||||
|
||||
obj.sourceBox = new St.BoxLayout({
|
||||
style_class: 'unlock-dialog-notification-source',
|
||||
x_expand: true,
|
||||
});
|
||||
this._showSource(source, obj, obj.sourceBox);
|
||||
this._notificationBox.add_child(obj.sourceBox);
|
||||
|
||||
obj.sourceCountChangedId = source.connect('notify::count', () => {
|
||||
this._countChanged(source, obj);
|
||||
});
|
||||
obj.sourceTitleChangedId = source.connect('notify::title', () => {
|
||||
this._titleChanged(source, obj);
|
||||
});
|
||||
obj.policyChangedId = source.policy.connect('notify', (policy, pspec) => {
|
||||
if (pspec.name === 'show-in-lock-screen')
|
||||
this._visibleChanged(source, obj);
|
||||
else
|
||||
this._detailedChanged(source, obj);
|
||||
});
|
||||
obj.sourceDestroyId = source.connect('destroy', () => {
|
||||
this._onSourceDestroy(source, obj);
|
||||
});
|
||||
|
||||
this._sources.set(source, obj);
|
||||
|
||||
if (!initial) {
|
||||
// block scrollbars while animating, if they're not needed now
|
||||
let boxHeight = this._notificationBox.height;
|
||||
if (this._scrollView.height >= boxHeight)
|
||||
this._scrollView.vscrollbar_policy = St.PolicyType.NEVER;
|
||||
|
||||
let widget = obj.sourceBox;
|
||||
let [, natHeight] = widget.get_preferred_height(-1);
|
||||
widget.height = 0;
|
||||
widget.ease({
|
||||
height: natHeight,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: 250,
|
||||
onComplete: () => {
|
||||
this._scrollView.vscrollbar_policy = St.PolicyType.AUTOMATIC;
|
||||
widget.set_height(-1);
|
||||
},
|
||||
});
|
||||
|
||||
this._updateVisibility();
|
||||
if (obj.sourceBox.visible)
|
||||
this.emit('wake-up-screen');
|
||||
}
|
||||
}
|
||||
|
||||
_titleChanged(source, obj) {
|
||||
obj.titleLabel.text = source.title;
|
||||
}
|
||||
|
||||
_countChanged(source, obj) {
|
||||
// A change in the number of notifications may change whether we show
|
||||
// details.
|
||||
let newDetailed = this._shouldShowDetails(source);
|
||||
let oldDetailed = obj.detailed;
|
||||
|
||||
obj.detailed = newDetailed;
|
||||
|
||||
if (obj.detailed || oldDetailed !== newDetailed) {
|
||||
// A new notification was pushed, or a previous notification was destroyed.
|
||||
// Give up, and build the list again.
|
||||
|
||||
obj.sourceBox.destroy_all_children();
|
||||
obj.titleLabel = obj.countLabel = null;
|
||||
this._showSource(source, obj, obj.sourceBox);
|
||||
} else {
|
||||
let count = source.unseenCount;
|
||||
obj.countLabel.text = `${count}`;
|
||||
}
|
||||
|
||||
obj.sourceBox.visible = obj.visible && (source.unseenCount > 0);
|
||||
|
||||
this._updateVisibility();
|
||||
if (obj.sourceBox.visible)
|
||||
this.emit('wake-up-screen');
|
||||
}
|
||||
|
||||
_visibleChanged(source, obj) {
|
||||
if (obj.visible === source.policy.showInLockScreen)
|
||||
return;
|
||||
|
||||
obj.visible = source.policy.showInLockScreen;
|
||||
obj.sourceBox.visible = obj.visible && source.unseenCount > 0;
|
||||
|
||||
this._updateVisibility();
|
||||
if (obj.sourceBox.visible)
|
||||
this.emit('wake-up-screen');
|
||||
}
|
||||
|
||||
_detailedChanged(source, obj) {
|
||||
let newDetailed = this._shouldShowDetails(source);
|
||||
if (obj.detailed === newDetailed)
|
||||
return;
|
||||
|
||||
obj.detailed = newDetailed;
|
||||
|
||||
obj.sourceBox.destroy_all_children();
|
||||
obj.titleLabel = obj.countLabel = null;
|
||||
this._showSource(source, obj, obj.sourceBox);
|
||||
}
|
||||
|
||||
_onSourceDestroy(source, obj) {
|
||||
this._removeSource(source, obj);
|
||||
this._updateVisibility();
|
||||
}
|
||||
|
||||
_removeSource(source, obj) {
|
||||
obj.sourceBox.destroy();
|
||||
obj.sourceBox = obj.titleLabel = obj.countLabel = null;
|
||||
|
||||
source.disconnect(obj.sourceDestroyId);
|
||||
source.disconnect(obj.sourceCountChangedId);
|
||||
source.disconnect(obj.sourceTitleChangedId);
|
||||
source.policy.disconnect(obj.policyChangedId);
|
||||
|
||||
this._sources.delete(source);
|
||||
}
|
||||
});
|
||||
|
||||
var Clock = GObject.registerClass(
|
||||
class UnlockDialogClock extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({ style_class: 'unlock-dialog-clock', vertical: true });
|
||||
|
||||
this._time = new St.Label({
|
||||
style_class: 'unlock-dialog-clock-time',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
this._date = new St.Label({
|
||||
style_class: 'unlock-dialog-clock-date',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
|
||||
this.add_child(this._time);
|
||||
this.add_child(this._date);
|
||||
|
||||
this._wallClock = new GnomeDesktop.WallClock({ time_only: true });
|
||||
this._wallClock.connect('notify::clock', this._updateClock.bind(this));
|
||||
|
||||
this._updateClock();
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_updateClock() {
|
||||
this._time.text = this._wallClock.clock;
|
||||
|
||||
let date = new Date();
|
||||
/* Translators: This is a time format for a date in
|
||||
long format */
|
||||
let dateFormat = Shell.util_translate_time_string(N_('%A %B %-d'));
|
||||
this._date.text = date.toLocaleFormat(dateFormat);
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._wallClock.run_dispose();
|
||||
}
|
||||
});
|
||||
|
||||
var UnlockDialogLayout = GObject.registerClass(
|
||||
class UnlockDialogLayout extends Clutter.LayoutManager {
|
||||
_init(stack, notifications) {
|
||||
super._init();
|
||||
|
||||
this._stack = stack;
|
||||
this._notifications = notifications;
|
||||
}
|
||||
|
||||
vfunc_get_preferred_width(container, forHeight) {
|
||||
return this._stack.get_preferred_width(forHeight);
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(container, forWidth) {
|
||||
return this._stack.get_preferred_height(forWidth);
|
||||
}
|
||||
|
||||
vfunc_allocate(container, box, flags) {
|
||||
let [width, height] = box.get_size();
|
||||
|
||||
let tenthOfHeight = height / 10.0;
|
||||
let thirdOfHeight = height / 3.0;
|
||||
|
||||
let [, , stackWidth, stackHeight] =
|
||||
this._stack.get_preferred_size();
|
||||
|
||||
let [, , notificationsWidth, notificationsHeight] =
|
||||
this._notifications.get_preferred_size();
|
||||
|
||||
let columnWidth = Math.max(stackWidth, notificationsWidth);
|
||||
|
||||
let columnX1 = Math.floor((width - columnWidth) / 2.0);
|
||||
let actorBox = new Clutter.ActorBox();
|
||||
|
||||
// Notifications
|
||||
let maxNotificationsHeight = Math.min(
|
||||
notificationsHeight,
|
||||
height - tenthOfHeight - stackHeight);
|
||||
|
||||
actorBox.x1 = columnX1;
|
||||
actorBox.y1 = height - maxNotificationsHeight;
|
||||
actorBox.x2 = columnX1 + columnWidth;
|
||||
actorBox.y2 = actorBox.y1 + maxNotificationsHeight;
|
||||
|
||||
this._notifications.allocate(actorBox, flags);
|
||||
|
||||
// Authentication Box
|
||||
let stackY = Math.min(
|
||||
thirdOfHeight,
|
||||
height - stackHeight - maxNotificationsHeight);
|
||||
|
||||
actorBox.x1 = columnX1;
|
||||
actorBox.y1 = stackY;
|
||||
actorBox.x2 = columnX1 + columnWidth;
|
||||
actorBox.y2 = stackY + stackHeight;
|
||||
|
||||
this._stack.allocate(actorBox, flags);
|
||||
}
|
||||
});
|
||||
|
||||
var UnlockDialog = GObject.registerClass({
|
||||
Signals: { 'failed': {} },
|
||||
Signals: {
|
||||
'failed': {},
|
||||
'wake-up-screen': {},
|
||||
},
|
||||
}, class UnlockDialog extends St.Widget {
|
||||
_init(parentActor) {
|
||||
super._init({
|
||||
accessible_role: Atk.Role.WINDOW,
|
||||
style_class: 'login-dialog',
|
||||
layout_manager: new Clutter.BoxLayout(),
|
||||
visible: false,
|
||||
can_focus: true,
|
||||
reactive: true,
|
||||
});
|
||||
|
||||
this.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||
parentActor.add_child(this);
|
||||
|
||||
this._activePage = null;
|
||||
|
||||
let tapAction = new Clutter.TapAction();
|
||||
tapAction.connect('tap', this._showPrompt.bind(this));
|
||||
this.add_action(tapAction);
|
||||
|
||||
// Background
|
||||
this._backgroundGroup = new Clutter.Actor();
|
||||
this.add_child(this._backgroundGroup);
|
||||
|
||||
this._bgManagers = [];
|
||||
|
||||
this._updateBackgrounds();
|
||||
this._monitorsChangedId =
|
||||
Main.layoutManager.connect('monitors-changed', this._updateBackgrounds.bind(this));
|
||||
|
||||
this._userManager = AccountsService.UserManager.get_default();
|
||||
this._userName = GLib.get_user_name();
|
||||
this._user = this._userManager.get_user(this._userName);
|
||||
|
||||
this._promptBox = new St.BoxLayout({ vertical: true,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
x_expand: true,
|
||||
y_expand: true });
|
||||
this.add_child(this._promptBox);
|
||||
// Authentication & Clock stack
|
||||
let stack = new Shell.Stack();
|
||||
|
||||
this._promptBox = new St.BoxLayout({ vertical: true });
|
||||
stack.add_child(this._promptBox);
|
||||
|
||||
this._clock = new Clock();
|
||||
stack.add_child(this._clock);
|
||||
this._showClock();
|
||||
|
||||
this.allowCancel = false;
|
||||
|
||||
Main.ctrlAltTabManager.addGroup(this, _('Unlock Window'), 'dialog-password-symbolic');
|
||||
|
||||
// Notifications
|
||||
this._notificationsBox = new NotificationsBox();
|
||||
this._notificationsBox.connect('wake-up-screen', () => this.emit('wake-up-screen'));
|
||||
|
||||
// Main Box
|
||||
let mainBox = new Clutter.Actor();
|
||||
mainBox.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||
mainBox.add_child(stack);
|
||||
mainBox.add_child(this._notificationsBox);
|
||||
mainBox.layout_manager = new UnlockDialogLayout(
|
||||
stack,
|
||||
this._notificationsBox);
|
||||
this.add_child(mainBox);
|
||||
|
||||
this._idleMonitor = Meta.IdleMonitor.get_core();
|
||||
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, this._escape.bind(this));
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
vfunc_key_press_event(keyEvent) {
|
||||
if (this._activePage === this._promptBox ||
|
||||
(this._promptBox && this._promptBox.visible))
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let unichar = keyEvent.unicode_value;
|
||||
|
||||
this._showPrompt();
|
||||
|
||||
if (GLib.unichar_isgraph(unichar))
|
||||
this.addCharacter(unichar);
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
_createBackground(monitorIndex) {
|
||||
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 bgManager = new Background.BackgroundManager({
|
||||
container: widget,
|
||||
monitorIndex,
|
||||
controlPosition: false,
|
||||
settingsSchema: SCREENSAVER_SCHEMA,
|
||||
});
|
||||
|
||||
this._bgManagers.push(bgManager);
|
||||
|
||||
this._backgroundGroup.add_child(widget);
|
||||
|
||||
widget.add_effect(new Shell.BlurEffect({
|
||||
brightness: BLUR_BRIGHTNESS,
|
||||
blur_radius: BLUR_RADIUS,
|
||||
}));
|
||||
}
|
||||
|
||||
_updateBackgrounds() {
|
||||
for (let i = 0; i < this._bgManagers.length; i++)
|
||||
this._bgManagers[i].destroy();
|
||||
|
||||
this._bgManagers = [];
|
||||
this._backgroundGroup.destroy_all_children();
|
||||
|
||||
for (let i = 0; i < Main.layoutManager.monitors.length; i++)
|
||||
this._createBackground(i);
|
||||
}
|
||||
|
||||
_ensureAuthPrompt() {
|
||||
if (this._authPrompt)
|
||||
return;
|
||||
|
||||
this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
|
||||
this._authPrompt.connect('failed', this._fail.bind(this));
|
||||
@@ -45,16 +543,18 @@ var UnlockDialog = GObject.registerClass({
|
||||
|
||||
this._promptBox.add_child(this._authPrompt);
|
||||
|
||||
this.allowCancel = false;
|
||||
|
||||
let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
|
||||
if (screenSaverSettings.get_boolean('user-switch-enabled')) {
|
||||
let otherUserLabel = new St.Label({ text: _("Log in as another user"),
|
||||
style_class: 'login-dialog-not-listed-label' });
|
||||
this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
||||
can_focus: true,
|
||||
child: otherUserLabel,
|
||||
reactive: true });
|
||||
let otherUserLabel = new St.Label({
|
||||
text: _('Log in as another user'),
|
||||
style_class: 'login-dialog-not-listed-label',
|
||||
});
|
||||
this._otherUserButton = new St.Button({
|
||||
style_class: 'login-dialog-not-listed-button',
|
||||
can_focus: true,
|
||||
child: otherUserLabel,
|
||||
reactive: true,
|
||||
});
|
||||
this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this));
|
||||
this._promptBox.add_child(this._otherUserButton);
|
||||
} else {
|
||||
@@ -63,13 +563,24 @@ var UnlockDialog = GObject.registerClass({
|
||||
|
||||
this._authPrompt.reset();
|
||||
this._updateSensitivity(true);
|
||||
}
|
||||
|
||||
Main.ctrlAltTabManager.addGroup(this, _("Unlock Window"), 'dialog-password-symbolic');
|
||||
_maybeDestroyAuthPrompt() {
|
||||
let focus = global.stage.key_focus;
|
||||
if (focus === null ||
|
||||
(this._authPrompt && this._authPrompt.contains(focus)) ||
|
||||
(this._otherUserButton && focus === this._otherUserButton))
|
||||
this.grab_key_focus();
|
||||
|
||||
this._idleMonitor = Meta.IdleMonitor.get_core();
|
||||
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, this._escape.bind(this));
|
||||
if (this._authPrompt) {
|
||||
this._authPrompt.destroy();
|
||||
this._authPrompt = null;
|
||||
}
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
if (this._otherUserButton) {
|
||||
this._otherUserButton.destroy();
|
||||
this._otherUserButton = null;
|
||||
}
|
||||
}
|
||||
|
||||
_updateSensitivity(sensitive) {
|
||||
@@ -81,7 +592,55 @@ var UnlockDialog = GObject.registerClass({
|
||||
}
|
||||
}
|
||||
|
||||
_showClock() {
|
||||
if (this._activePage === this._clock)
|
||||
return;
|
||||
|
||||
this._activePage = this._clock;
|
||||
this._clock.show();
|
||||
|
||||
this._promptBox.ease({
|
||||
opacity: 0,
|
||||
duration: CROSSFADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
this._promptBox.hide();
|
||||
this._maybeDestroyAuthPrompt();
|
||||
},
|
||||
});
|
||||
|
||||
this._clock.ease({
|
||||
opacity: 255,
|
||||
duration: CROSSFADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
}
|
||||
|
||||
_showPrompt() {
|
||||
this._ensureAuthPrompt();
|
||||
|
||||
if (this._activePage === this._promptBox)
|
||||
return;
|
||||
|
||||
this._activePage = this._promptBox;
|
||||
this._promptBox.show();
|
||||
|
||||
this._clock.ease({
|
||||
opacity: 0,
|
||||
duration: CROSSFADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => this._clock.hide(),
|
||||
});
|
||||
|
||||
this._promptBox.ease({
|
||||
opacity: 255,
|
||||
duration: CROSSFADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
});
|
||||
}
|
||||
|
||||
_fail() {
|
||||
this._showClock();
|
||||
this.emit('failed');
|
||||
}
|
||||
|
||||
@@ -115,19 +674,25 @@ var UnlockDialog = GObject.registerClass({
|
||||
this._idleMonitor.remove_watch(this._idleWatchId);
|
||||
this._idleWatchId = 0;
|
||||
}
|
||||
|
||||
if (this._monitorsChangedId) {
|
||||
Main.layoutManager.disconnect(this._monitorsChangedId);
|
||||
delete this._monitorsChangedId;
|
||||
}
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this._authPrompt.cancel();
|
||||
|
||||
this.destroy();
|
||||
if (this._authPrompt)
|
||||
this._authPrompt.cancel();
|
||||
}
|
||||
|
||||
addCharacter(unichar) {
|
||||
this._showPrompt();
|
||||
this._authPrompt.addCharacter(unichar);
|
||||
}
|
||||
|
||||
finish(onComplete) {
|
||||
this._ensureAuthPrompt();
|
||||
this._authPrompt.finish(onComplete);
|
||||
}
|
||||
|
||||
@@ -149,6 +714,10 @@ var UnlockDialog = GObject.registerClass({
|
||||
return true;
|
||||
}
|
||||
|
||||
activate() {
|
||||
this._showPrompt();
|
||||
}
|
||||
|
||||
popModal(timestamp) {
|
||||
if (this._isModal) {
|
||||
Main.popModal(this, timestamp);
|
||||
|
@@ -45,21 +45,17 @@ const WINDOW_DIMMER_EFFECT_NAME = "gnome-shell-window-dimmer";
|
||||
var DisplayChangeDialog = GObject.registerClass(
|
||||
class DisplayChangeDialog extends ModalDialog.ModalDialog {
|
||||
_init(wm) {
|
||||
super._init({ styleClass: 'prompt-dialog' });
|
||||
super._init();
|
||||
|
||||
this._wm = wm;
|
||||
|
||||
this._countDown = Meta.MonitorManager.get_display_configuration_timeout();
|
||||
|
||||
let title = _("Do you want to keep these display settings?");
|
||||
// Translators: This string should be shorter than 30 characters
|
||||
let title = _('Keep these display settings?');
|
||||
let description = this._formatCountDown();
|
||||
|
||||
this._content = new Dialog.MessageDialogContent({
|
||||
title, description,
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
});
|
||||
|
||||
this._content = new Dialog.MessageDialogContent({ title, description });
|
||||
this.contentLayout.add_child(this._content);
|
||||
|
||||
/* Translators: this and the following message should be limited in length,
|
||||
|
@@ -155,8 +155,7 @@ var WindowClone = GObject.registerClass({
|
||||
|
||||
this._updateAttachedDialogs();
|
||||
this._computeBoundingBox();
|
||||
this.x = this._boundingBox.x;
|
||||
this.y = this._boundingBox.y;
|
||||
this.set_translation(this._boundingBox.x, this._boundingBox.y, 0);
|
||||
|
||||
this._computeWindowCenter();
|
||||
|
||||
@@ -1364,8 +1363,8 @@ class Workspace extends St.Widget {
|
||||
if (!clone.positioned) {
|
||||
// This window appeared after the overview was already up
|
||||
// Grow the clone from the center of the slot
|
||||
clone.x = x + cloneWidth / 2;
|
||||
clone.y = y + cloneHeight / 2;
|
||||
clone.translation_x = x + cloneWidth / 2;
|
||||
clone.translation_y = y + cloneHeight / 2;
|
||||
clone.scale_x = 0;
|
||||
clone.scale_y = 0;
|
||||
clone.positioned = true;
|
||||
@@ -1380,8 +1379,8 @@ class Workspace extends St.Widget {
|
||||
clone.opacity = 0;
|
||||
clone.scale_x = 0;
|
||||
clone.scale_y = 0;
|
||||
clone.x = x;
|
||||
clone.y = y;
|
||||
clone.translation_x = x;
|
||||
clone.translation_y = y;
|
||||
}
|
||||
|
||||
clone.ease({
|
||||
@@ -1395,7 +1394,7 @@ class Workspace extends St.Widget {
|
||||
} else {
|
||||
// cancel any active tweens (otherwise they might override our changes)
|
||||
clone.remove_all_transitions();
|
||||
clone.set_position(x, y);
|
||||
clone.set_translation(x, y, 0);
|
||||
clone.set_scale(scale, scale);
|
||||
clone.set_opacity(255);
|
||||
clone.overlay.relayout(false);
|
||||
@@ -1425,7 +1424,8 @@ class Workspace extends St.Widget {
|
||||
|
||||
_animateClone(clone, overlay, x, y, scale) {
|
||||
clone.ease({
|
||||
x, y,
|
||||
translation_x: x,
|
||||
translation_y: y,
|
||||
scale_x: scale,
|
||||
scale_y: scale,
|
||||
duration: Overview.ANIMATION_TIME,
|
||||
@@ -1570,7 +1570,7 @@ class Workspace extends St.Widget {
|
||||
clone.slot = [x, y, clone.width * scale, clone.height * scale];
|
||||
clone.positioned = true;
|
||||
|
||||
clone.set_position(x, y);
|
||||
clone.set_translation(x, y, 0);
|
||||
clone.set_scale(scale, scale);
|
||||
clone.overlay.relayout(false);
|
||||
}
|
||||
@@ -1725,8 +1725,8 @@ class Workspace extends St.Widget {
|
||||
let [origX, origY] = clone.getOriginalPosition();
|
||||
clone.scale_x = 1;
|
||||
clone.scale_y = 1;
|
||||
clone.x = origX;
|
||||
clone.y = origY;
|
||||
clone.translation_x = origX;
|
||||
clone.translation_y = origY;
|
||||
clone.ease({
|
||||
opacity,
|
||||
duration,
|
||||
@@ -1776,8 +1776,8 @@ class Workspace extends St.Widget {
|
||||
if (clone.metaWindow.showing_on_its_workspace()) {
|
||||
let [origX, origY] = clone.getOriginalPosition();
|
||||
clone.ease({
|
||||
x: origX,
|
||||
y: origY,
|
||||
translation_x: origX,
|
||||
translation_y: origY,
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
opacity: 255,
|
||||
|
@@ -426,7 +426,14 @@ class WorkspacesDisplay extends St.Widget {
|
||||
this._swipeTracker.connect('begin', this._switchWorkspaceBegin.bind(this));
|
||||
this._swipeTracker.connect('update', this._switchWorkspaceUpdate.bind(this));
|
||||
this._swipeTracker.connect('end', this._switchWorkspaceEnd.bind(this));
|
||||
this.bind_property('mapped', this._swipeTracker, 'enabled', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.connect('notify::mapped', this._updateSwipeTracker.bind(this));
|
||||
|
||||
this._windowDragBeginId =
|
||||
Main.overview.connect('window-drag-begin',
|
||||
this._windowDragBegin.bind(this));
|
||||
this._windowDragEndId =
|
||||
Main.overview.connect('window-drag-begin',
|
||||
this._windowDragEnd.bind(this));
|
||||
|
||||
this._primaryIndex = Main.layoutManager.primaryIndex;
|
||||
this._workspacesViews = [];
|
||||
@@ -443,6 +450,7 @@ class WorkspacesDisplay extends St.Widget {
|
||||
this._scrollTimeoutId = 0;
|
||||
|
||||
this._fullGeometry = null;
|
||||
this._inWindowDrag = false;
|
||||
|
||||
this._gestureActive = false; // touch(pad) gestures
|
||||
this._canScroll = true; // limiting scrolling speed
|
||||
@@ -470,6 +478,22 @@ class WorkspacesDisplay extends St.Widget {
|
||||
|
||||
global.window_manager.disconnect(this._switchWorkspaceId);
|
||||
global.workspace_manager.disconnect(this._reorderWorkspacesdId);
|
||||
Main.overview.disconnect(this._windowDragBeginId);
|
||||
Main.overview.disconnect(this._windowDragEndId);
|
||||
}
|
||||
|
||||
_windowDragBegin() {
|
||||
this._inWindowDrag = true;
|
||||
this._updateSwipeTracker();
|
||||
}
|
||||
|
||||
_windowDragEnd() {
|
||||
this._inWindowDrag = false;
|
||||
this._updateSwipeTracker();
|
||||
}
|
||||
|
||||
_updateSwipeTracker() {
|
||||
this._swipeTracker.enabled = this.mapped && !this._inWindowDrag;
|
||||
}
|
||||
|
||||
_workspacesReordered() {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('gnome-shell', 'c',
|
||||
version: '3.35.3',
|
||||
version: '3.35.90',
|
||||
meson_version: '>= 0.47.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
@@ -25,7 +25,7 @@ gio_req = '>= 2.56.0'
|
||||
gi_req = '>= 1.49.1'
|
||||
gjs_req = '>= 1.63.2'
|
||||
gtk_req = '>= 3.15.0'
|
||||
mutter_req = '>= 3.35.3'
|
||||
mutter_req = '>= 3.35.90'
|
||||
polkit_req = '>= 0.100'
|
||||
schemas_req = '>= 3.33.1'
|
||||
startup_req = '>= 0.11'
|
||||
@@ -55,6 +55,7 @@ pkglibdir = join_paths(libdir, meson.project_name())
|
||||
autostartdir = join_paths(sysconfdir, 'xdg', 'autostart')
|
||||
convertdir = join_paths(datadir, 'GConf', 'gsettings')
|
||||
desktopdir = join_paths(datadir, 'applications')
|
||||
icondir = join_paths(datadir, 'icons')
|
||||
ifacedir = join_paths(datadir, 'dbus-1', 'interfaces')
|
||||
localedir = join_paths(datadir, 'locale')
|
||||
portaldir = join_paths(datadir, 'xdg-desktop-portal', 'portals')
|
||||
|
@@ -8,6 +8,12 @@ datadir = os.path.join(prefix, 'share')
|
||||
|
||||
# Packaging tools define DESTDIR and this isn't needed for them
|
||||
if 'DESTDIR' not in os.environ:
|
||||
print('Updating icon cache...')
|
||||
icon_cache_dir = os.path.join(datadir, 'icons', 'hicolor')
|
||||
if not os.path.exists(icon_cache_dir):
|
||||
os.makedirs(icon_cache_dir)
|
||||
subprocess.call(['gtk-update-icon-cache', '-qtf', icon_cache_dir])
|
||||
|
||||
print('Updating desktop database...')
|
||||
desktop_database_dir = os.path.join(datadir, 'applications')
|
||||
if not os.path.exists(desktop_database_dir):
|
||||
|
@@ -1,11 +1,13 @@
|
||||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
data/50-gnome-shell-system.xml
|
||||
data/gnome-shell-extension-prefs.desktop.in.in
|
||||
data/org.gnome.Extensions.desktop.in.in
|
||||
data/org.gnome.Shell.desktop.in.in
|
||||
data/org.gnome.shell.gschema.xml.in
|
||||
data/org.gnome.Shell.PortalHelper.desktop.in.in
|
||||
js/extensionPrefs/main.js
|
||||
js/extensionPrefs/ui/extension-row.ui
|
||||
js/extensionPrefs/ui/extensions-window.ui
|
||||
js/gdm/authPrompt.js
|
||||
js/gdm/loginDialog.js
|
||||
js/gdm/util.js
|
||||
|
306
po/ca.po
306
po/ca.po
@@ -10,8 +10,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||
"POT-Creation-Date: 2019-12-27 13:16+0000\n"
|
||||
"PO-Revision-Date: 2020-01-03 22:58+0100\n"
|
||||
"POT-Creation-Date: 2020-01-25 01:15+0000\n"
|
||||
"PO-Revision-Date: 2020-01-26 10:07+0100\n"
|
||||
"Last-Translator: Robert Antoni Buj Gelonch <rbuj@fedoraproject.org>\n"
|
||||
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
|
||||
"Language: ca\n"
|
||||
@@ -46,7 +46,7 @@ msgid "Open the application menu"
|
||||
msgstr "Obre el menú d'aplicació"
|
||||
|
||||
#: data/gnome-shell-extension-prefs.desktop.in.in:4
|
||||
#: js/extensionPrefs/main.js:210
|
||||
#: js/extensionPrefs/main.js:209
|
||||
msgid "Shell Extensions"
|
||||
msgstr "Extensions del Shell"
|
||||
|
||||
@@ -415,11 +415,11 @@ msgstr ""
|
||||
msgid "Network Login"
|
||||
msgstr "Inici de sessió de xarxa"
|
||||
|
||||
#: js/extensionPrefs/main.js:103 js/extensionPrefs/main.js:526
|
||||
#: js/extensionPrefs/main.js:102 js/extensionPrefs/main.js:525
|
||||
msgid "Something’s gone wrong"
|
||||
msgstr "Alguna cosa ha anat malament"
|
||||
|
||||
#: js/extensionPrefs/main.js:110
|
||||
#: js/extensionPrefs/main.js:109
|
||||
msgid ""
|
||||
"We’re very sorry, but there’s been a problem: the settings for this "
|
||||
"extension can’t be displayed. We recommend that you report the issue to the "
|
||||
@@ -428,27 +428,27 @@ msgstr ""
|
||||
"Hi ha un problema: no es poden mostrar els paràmetres per a aquesta "
|
||||
"extensió. Us recomanem que informeu del problema als autors de l'extensió."
|
||||
|
||||
#: js/extensionPrefs/main.js:117
|
||||
#: js/extensionPrefs/main.js:116
|
||||
msgid "Technical Details"
|
||||
msgstr "Detalls tècnics"
|
||||
|
||||
#: js/extensionPrefs/main.js:152
|
||||
#: js/extensionPrefs/main.js:151
|
||||
msgid "Copy Error"
|
||||
msgstr "Copia l'error"
|
||||
|
||||
#: js/extensionPrefs/main.js:179
|
||||
#: js/extensionPrefs/main.js:178
|
||||
msgid "Homepage"
|
||||
msgstr "Pàgina d'inici"
|
||||
|
||||
#: js/extensionPrefs/main.js:180
|
||||
#: js/extensionPrefs/main.js:179
|
||||
msgid "Visit extension homepage"
|
||||
msgstr "Visiteu la pàgina d'inici de l'extensió"
|
||||
|
||||
#: js/extensionPrefs/main.js:468
|
||||
#: js/extensionPrefs/main.js:467
|
||||
msgid "No Extensions Installed"
|
||||
msgstr "No hi ha cap extensió instal·lada"
|
||||
|
||||
#: js/extensionPrefs/main.js:478
|
||||
#: js/extensionPrefs/main.js:477
|
||||
msgid ""
|
||||
"Extensions can be installed through Software or <a href=\"https://extensions."
|
||||
"gnome.org\">extensions.gnome.org</a>."
|
||||
@@ -456,11 +456,11 @@ msgstr ""
|
||||
"Les extensions es poden instal·lar amb el Programari o a <a href=\"https://"
|
||||
"extensions.gnome.org\">extensions.gnome.org</a>."
|
||||
|
||||
#: js/extensionPrefs/main.js:493
|
||||
#: js/extensionPrefs/main.js:492
|
||||
msgid "Browse in Software"
|
||||
msgstr "Navega al Programari"
|
||||
|
||||
#: js/extensionPrefs/main.js:533
|
||||
#: js/extensionPrefs/main.js:532
|
||||
msgid ""
|
||||
"We’re very sorry, but it was not possible to get the list of installed "
|
||||
"extensions. Make sure you are logged into GNOME and try again."
|
||||
@@ -469,9 +469,9 @@ msgstr ""
|
||||
"heu entrat al GNOME i torneu a provar-ho."
|
||||
|
||||
#: js/gdm/authPrompt.js:174 js/ui/audioDeviceSelection.js:57
|
||||
#: js/ui/components/networkAgent.js:130 js/ui/components/polkitAgent.js:139
|
||||
#: js/ui/endSessionDialog.js:445 js/ui/extensionDownloader.js:190
|
||||
#: js/ui/shellMountOperation.js:402 js/ui/shellMountOperation.js:412
|
||||
#: js/ui/components/networkAgent.js:129 js/ui/components/polkitAgent.js:138
|
||||
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:190
|
||||
#: js/ui/shellMountOperation.js:399 js/ui/shellMountOperation.js:409
|
||||
#: js/ui/status/network.js:910
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel·la"
|
||||
@@ -480,7 +480,7 @@ msgstr "Cancel·la"
|
||||
msgid "Next"
|
||||
msgstr "Següent"
|
||||
|
||||
#: js/gdm/authPrompt.js:237 js/ui/shellMountOperation.js:406
|
||||
#: js/gdm/authPrompt.js:237 js/ui/shellMountOperation.js:403
|
||||
#: js/ui/unlockDialog.js:44
|
||||
msgid "Unlock"
|
||||
msgstr "Desbloqueja"
|
||||
@@ -508,8 +508,8 @@ msgstr "(p. ex. l'usuari o %s)"
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: js/gdm/loginDialog.js:899 js/ui/components/networkAgent.js:257
|
||||
#: js/ui/components/networkAgent.js:280 js/ui/components/networkAgent.js:298
|
||||
#: js/gdm/loginDialog.js:899 js/ui/components/networkAgent.js:256
|
||||
#: js/ui/components/networkAgent.js:279 js/ui/components/networkAgent.js:297
|
||||
msgid "Username: "
|
||||
msgstr "Nom d'usuari:"
|
||||
|
||||
@@ -538,7 +538,7 @@ msgstr "Apaga"
|
||||
|
||||
#. Translators: A list of keywords that match the power-off action, separated by semicolons
|
||||
#: js/misc/systemActions.js:92
|
||||
msgid "power off;shutdown;reboot;restart"
|
||||
msgid "power off;shutdown;reboot;restart;halt;stop"
|
||||
msgstr "apaga;atura;reinicia"
|
||||
|
||||
#. Translators: The name of the lock screen action in search
|
||||
@@ -749,56 +749,52 @@ msgstr ""
|
||||
|
||||
#. No support for non-modal system dialogs, so ignore the option
|
||||
#. let modal = options['modal'] || true;
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:364
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:366
|
||||
msgid "Deny Access"
|
||||
msgstr "Denega l'accés"
|
||||
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:367
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:369
|
||||
msgid "Grant Access"
|
||||
msgstr "Permet l'accés"
|
||||
|
||||
#: js/ui/appDisplay.js:921
|
||||
#: js/ui/appDisplay.js:904
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "Carpeta sense nom"
|
||||
|
||||
#: js/ui/appDisplay.js:944
|
||||
#: js/ui/appDisplay.js:927
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "Les aplicacions utilitzades freqüentment apareixeran aquí"
|
||||
|
||||
#: js/ui/appDisplay.js:1079
|
||||
#: js/ui/appDisplay.js:1062
|
||||
msgid "Frequent"
|
||||
msgstr "Freqüent"
|
||||
|
||||
#: js/ui/appDisplay.js:1086
|
||||
#: js/ui/appDisplay.js:1069
|
||||
msgid "All"
|
||||
msgstr "Totes"
|
||||
|
||||
#: js/ui/appDisplay.js:1861
|
||||
msgid "Rename"
|
||||
msgstr "Canvia el nom"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2549 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2452 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Obre finestres"
|
||||
|
||||
#: js/ui/appDisplay.js:2569 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2472 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Finestra nova"
|
||||
|
||||
#: js/ui/appDisplay.js:2580
|
||||
#: js/ui/appDisplay.js:2483
|
||||
msgid "Launch using Dedicated Graphics Card"
|
||||
msgstr "Inicia usant una targeta gràfica dedicada"
|
||||
|
||||
#: js/ui/appDisplay.js:2608 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2511 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Suprimeix dels preferits"
|
||||
|
||||
#: js/ui/appDisplay.js:2614
|
||||
#: js/ui/appDisplay.js:2517
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Afegeix als preferits"
|
||||
|
||||
#: js/ui/appDisplay.js:2624 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2527 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Mostra els detalls"
|
||||
|
||||
@@ -845,7 +841,7 @@ msgid "Settings"
|
||||
msgstr "Paràmetres"
|
||||
|
||||
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
|
||||
#: js/ui/calendar.js:40
|
||||
#: js/ui/calendar.js:41
|
||||
msgctxt "calendar-no-work"
|
||||
msgid "06"
|
||||
msgstr "06"
|
||||
@@ -855,43 +851,43 @@ msgstr "06"
|
||||
#. * NOTE: These grid abbreviations are always shown together
|
||||
#. * and in order, e.g. "S M T W T F S".
|
||||
#.
|
||||
#: js/ui/calendar.js:69
|
||||
#: js/ui/calendar.js:70
|
||||
msgctxt "grid sunday"
|
||||
msgid "S"
|
||||
msgstr "Dg"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Monday
|
||||
#: js/ui/calendar.js:71
|
||||
#: js/ui/calendar.js:72
|
||||
msgctxt "grid monday"
|
||||
msgid "M"
|
||||
msgstr "Dl"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Tuesday
|
||||
#: js/ui/calendar.js:73
|
||||
#: js/ui/calendar.js:74
|
||||
msgctxt "grid tuesday"
|
||||
msgid "T"
|
||||
msgstr "Dt"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Wednesday
|
||||
#: js/ui/calendar.js:75
|
||||
#: js/ui/calendar.js:76
|
||||
msgctxt "grid wednesday"
|
||||
msgid "W"
|
||||
msgstr "Dc"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Thursday
|
||||
#: js/ui/calendar.js:77
|
||||
#: js/ui/calendar.js:78
|
||||
msgctxt "grid thursday"
|
||||
msgid "T"
|
||||
msgstr "Dj"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Friday
|
||||
#: js/ui/calendar.js:79
|
||||
#: js/ui/calendar.js:80
|
||||
msgctxt "grid friday"
|
||||
msgid "F"
|
||||
msgstr "Dv"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Saturday
|
||||
#: js/ui/calendar.js:81
|
||||
#: js/ui/calendar.js:82
|
||||
msgctxt "grid saturday"
|
||||
msgid "S"
|
||||
msgstr "Ds"
|
||||
@@ -902,7 +898,7 @@ msgstr "Ds"
|
||||
#. * "%OB" is the new format specifier introduced in glibc 2.27,
|
||||
#. * in most cases you should not change it.
|
||||
#.
|
||||
#: js/ui/calendar.js:370
|
||||
#: js/ui/calendar.js:371
|
||||
msgid "%OB"
|
||||
msgstr "%OB"
|
||||
|
||||
@@ -915,55 +911,61 @@ msgstr "%OB"
|
||||
#. * in most cases you should not use the old "%B" here unless you
|
||||
#. * absolutely know what you are doing.
|
||||
#.
|
||||
#: js/ui/calendar.js:380
|
||||
#: js/ui/calendar.js:381
|
||||
msgid "%OB %Y"
|
||||
msgstr "%OB de %Y"
|
||||
|
||||
#: js/ui/calendar.js:439
|
||||
#: js/ui/calendar.js:440
|
||||
msgid "Previous month"
|
||||
msgstr "Mes anterior"
|
||||
|
||||
#: js/ui/calendar.js:454
|
||||
#: js/ui/calendar.js:455
|
||||
msgid "Next month"
|
||||
msgstr "Mes següent"
|
||||
|
||||
#: js/ui/calendar.js:604
|
||||
#: js/ui/calendar.js:605
|
||||
#, no-javascript-format
|
||||
msgctxt "date day number format"
|
||||
msgid "%d"
|
||||
msgstr "%-d"
|
||||
|
||||
#: js/ui/calendar.js:660
|
||||
#: js/ui/calendar.js:661
|
||||
msgid "Week %V"
|
||||
msgstr "Setmana %-V"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/calendar.js:729
|
||||
#: js/ui/calendar.js:730
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Tot el dia"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/calendar.js:867
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d"
|
||||
msgstr "%A %-d %B"
|
||||
|
||||
#: js/ui/calendar.js:871
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/calendar.js:870
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d, %Y"
|
||||
msgstr "%A %d %B de %Y"
|
||||
|
||||
#: js/ui/calendar.js:1097
|
||||
#: js/ui/calendar.js:1096
|
||||
msgid "No Notifications"
|
||||
msgstr "Cap notificació"
|
||||
|
||||
#: js/ui/calendar.js:1100
|
||||
#: js/ui/calendar.js:1099
|
||||
msgid "No Events"
|
||||
msgstr "Cap cita"
|
||||
|
||||
#: js/ui/calendar.js:1132
|
||||
#: js/ui/calendar.js:1153
|
||||
msgid "Do Not Disturb"
|
||||
msgstr "No molesteu"
|
||||
|
||||
#: js/ui/calendar.js:1167
|
||||
msgid "Clear"
|
||||
msgstr "Neteja-ho"
|
||||
|
||||
@@ -981,11 +983,11 @@ msgstr ""
|
||||
"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida "
|
||||
"completa."
|
||||
|
||||
#: js/ui/closeDialog.js:71
|
||||
#: js/ui/closeDialog.js:70
|
||||
msgid "Force Quit"
|
||||
msgstr "Força la sortida"
|
||||
|
||||
#: js/ui/closeDialog.js:74
|
||||
#: js/ui/closeDialog.js:73
|
||||
msgid "Wait"
|
||||
msgstr "Espera"
|
||||
|
||||
@@ -1011,53 +1013,53 @@ msgstr ""
|
||||
msgid "Open with %s"
|
||||
msgstr "Obre amb %s"
|
||||
|
||||
#: js/ui/components/keyring.js:71 js/ui/components/polkitAgent.js:279
|
||||
#: js/ui/components/keyring.js:70 js/ui/components/polkitAgent.js:278
|
||||
msgid "Password:"
|
||||
msgstr "Contrasenya:"
|
||||
|
||||
#: js/ui/components/keyring.js:105
|
||||
#: js/ui/components/keyring.js:104
|
||||
msgid "Type again:"
|
||||
msgstr "Torneu a escriure-la:"
|
||||
|
||||
#: js/ui/components/networkAgent.js:116
|
||||
#: js/ui/components/networkAgent.js:115
|
||||
msgid ""
|
||||
"Alternatively you can connect by pushing the “WPS” button on your router."
|
||||
msgstr "També us podeu connectar prement el botó «WPS» del vostre encaminador."
|
||||
|
||||
#: js/ui/components/networkAgent.js:124 js/ui/status/network.js:223
|
||||
#: js/ui/components/networkAgent.js:123 js/ui/status/network.js:223
|
||||
#: js/ui/status/network.js:314 js/ui/status/network.js:913
|
||||
msgid "Connect"
|
||||
msgstr "Connecta"
|
||||
|
||||
#. Cisco LEAP
|
||||
#: js/ui/components/networkAgent.js:225 js/ui/components/networkAgent.js:237
|
||||
#: js/ui/components/networkAgent.js:261 js/ui/components/networkAgent.js:282
|
||||
#: js/ui/components/networkAgent.js:302 js/ui/components/networkAgent.js:312
|
||||
#: js/ui/components/networkAgent.js:224 js/ui/components/networkAgent.js:236
|
||||
#: js/ui/components/networkAgent.js:260 js/ui/components/networkAgent.js:281
|
||||
#: js/ui/components/networkAgent.js:301 js/ui/components/networkAgent.js:311
|
||||
msgid "Password: "
|
||||
msgstr "Contrasenya:"
|
||||
|
||||
#. static WEP
|
||||
#: js/ui/components/networkAgent.js:230
|
||||
#: js/ui/components/networkAgent.js:229
|
||||
msgid "Key: "
|
||||
msgstr "Clau:"
|
||||
|
||||
#: js/ui/components/networkAgent.js:265 js/ui/components/networkAgent.js:288
|
||||
#: js/ui/components/networkAgent.js:264 js/ui/components/networkAgent.js:287
|
||||
msgid "Private key password: "
|
||||
msgstr "Contrasenya de la clau privada:"
|
||||
|
||||
#: js/ui/components/networkAgent.js:286
|
||||
#: js/ui/components/networkAgent.js:285
|
||||
msgid "Identity: "
|
||||
msgstr "Identitat:"
|
||||
|
||||
#: js/ui/components/networkAgent.js:300
|
||||
#: js/ui/components/networkAgent.js:299
|
||||
msgid "Service: "
|
||||
msgstr "Servei:"
|
||||
|
||||
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:704
|
||||
#: js/ui/components/networkAgent.js:328 js/ui/components/networkAgent.js:703
|
||||
msgid "Authentication required by wireless network"
|
||||
msgstr "La xarxa sense fil requereix autenticació"
|
||||
|
||||
#: js/ui/components/networkAgent.js:330 js/ui/components/networkAgent.js:705
|
||||
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:704
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Passwords or encryption keys are required to access the wireless network "
|
||||
@@ -1066,53 +1068,58 @@ msgstr ""
|
||||
"Per accedir a la xarxa sense fil «%s» calen les contrasenyes o les claus "
|
||||
"d'encriptació."
|
||||
|
||||
#: js/ui/components/networkAgent.js:334 js/ui/components/networkAgent.js:709
|
||||
#: js/ui/components/networkAgent.js:333 js/ui/components/networkAgent.js:708
|
||||
msgid "Wired 802.1X authentication"
|
||||
msgstr "Autenticació 802.1X amb fil"
|
||||
|
||||
#: js/ui/components/networkAgent.js:336
|
||||
#: js/ui/components/networkAgent.js:335
|
||||
msgid "Network name: "
|
||||
msgstr "Nom de la xarxa: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:341 js/ui/components/networkAgent.js:713
|
||||
#: js/ui/components/networkAgent.js:340 js/ui/components/networkAgent.js:712
|
||||
msgid "DSL authentication"
|
||||
msgstr "Autenticació DSL"
|
||||
|
||||
#: js/ui/components/networkAgent.js:348 js/ui/components/networkAgent.js:718
|
||||
#: js/ui/components/networkAgent.js:347 js/ui/components/networkAgent.js:717
|
||||
msgid "PIN code required"
|
||||
msgstr "Cal que introduïu el codi PIN"
|
||||
|
||||
#: js/ui/components/networkAgent.js:349 js/ui/components/networkAgent.js:719
|
||||
#: js/ui/components/networkAgent.js:348 js/ui/components/networkAgent.js:718
|
||||
msgid "PIN code is needed for the mobile broadband device"
|
||||
msgstr "Cal que introduïu el codi PIN del dispositiu de banda ampla mòbil"
|
||||
|
||||
#: js/ui/components/networkAgent.js:350
|
||||
#: js/ui/components/networkAgent.js:349
|
||||
msgid "PIN: "
|
||||
msgstr "PIN: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:357 js/ui/components/networkAgent.js:725
|
||||
#: js/ui/components/networkAgent.js:356 js/ui/components/networkAgent.js:724
|
||||
msgid "Mobile broadband network password"
|
||||
msgstr "Contrasenya de la xarxa de banda ampla mòbil"
|
||||
|
||||
#: js/ui/components/networkAgent.js:358 js/ui/components/networkAgent.js:710
|
||||
#: js/ui/components/networkAgent.js:714 js/ui/components/networkAgent.js:726
|
||||
#: js/ui/components/networkAgent.js:357 js/ui/components/networkAgent.js:709
|
||||
#: js/ui/components/networkAgent.js:713 js/ui/components/networkAgent.js:725
|
||||
#: js/ui/components/networkAgent.js:729
|
||||
#, javascript-format
|
||||
msgid "A password is required to connect to “%s”."
|
||||
msgstr "Cal introduir una contrasenya per connectar-vos a «%s»."
|
||||
|
||||
#: js/ui/components/networkAgent.js:693 js/ui/status/network.js:1688
|
||||
#: js/ui/components/networkAgent.js:692 js/ui/status/network.js:1688
|
||||
msgid "Network Manager"
|
||||
msgstr "Gestor de connexions de xarxa"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:42
|
||||
#: js/ui/components/networkAgent.js:728
|
||||
msgid "VPN password"
|
||||
msgstr "Contrasenya VPN"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:41
|
||||
msgid "Authentication Required"
|
||||
msgstr "Cal autenticació"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:82
|
||||
#: js/ui/components/polkitAgent.js:81
|
||||
msgid "Administrator"
|
||||
msgstr "Administrador"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:142
|
||||
#: js/ui/components/polkitAgent.js:141
|
||||
msgid "Authenticate"
|
||||
msgstr "Autentica"
|
||||
|
||||
@@ -1120,7 +1127,7 @@ msgstr "Autentica"
|
||||
#. * requested authentication was not gained; this can happen
|
||||
#. * because of an authentication error (like invalid password),
|
||||
#. * for instance.
|
||||
#: js/ui/components/polkitAgent.js:260 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/components/polkitAgent.js:259 js/ui/shellMountOperation.js:383
|
||||
msgid "Sorry, that didn’t work. Please try again."
|
||||
msgstr "No ha funcionat. Torneu-ho a provar."
|
||||
|
||||
@@ -1131,7 +1138,7 @@ msgstr "No ha funcionat. Torneu-ho a provar."
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "En/na %s ara es diu %s"
|
||||
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:176
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
|
||||
msgid "Windows"
|
||||
msgstr "Finestres"
|
||||
|
||||
@@ -1174,19 +1181,19 @@ msgstr "Rellotges del món"
|
||||
msgid "Weather"
|
||||
msgstr "El temps"
|
||||
|
||||
#: js/ui/dateMenu.js:389
|
||||
#: js/ui/dateMenu.js:391
|
||||
msgid "Select a location…"
|
||||
msgstr "Trieu una ubicació…"
|
||||
|
||||
#: js/ui/dateMenu.js:402
|
||||
#: js/ui/dateMenu.js:404
|
||||
msgid "Loading…"
|
||||
msgstr "S'està carregant…"
|
||||
|
||||
#: js/ui/dateMenu.js:412
|
||||
#: js/ui/dateMenu.js:414
|
||||
msgid "Go online for weather information"
|
||||
msgstr "Vés en línia per a informació sobre el temps"
|
||||
|
||||
#: js/ui/dateMenu.js:414
|
||||
#: js/ui/dateMenu.js:416
|
||||
msgid "Weather information is currently unavailable"
|
||||
msgstr "La informació sobre el temps no està disponible"
|
||||
|
||||
@@ -1220,56 +1227,56 @@ msgctxt "button"
|
||||
msgid "Log Out"
|
||||
msgstr "Surt"
|
||||
|
||||
#: js/ui/endSessionDialog.js:57
|
||||
#: js/ui/endSessionDialog.js:56
|
||||
msgctxt "title"
|
||||
msgid "Power Off"
|
||||
msgstr "Apagada"
|
||||
|
||||
#: js/ui/endSessionDialog.js:58
|
||||
#: js/ui/endSessionDialog.js:57
|
||||
msgctxt "title"
|
||||
msgid "Install Updates & Power Off"
|
||||
msgstr "Instal·la les actualitzacions i apaga"
|
||||
|
||||
#: js/ui/endSessionDialog.js:60
|
||||
#: js/ui/endSessionDialog.js:59
|
||||
#, javascript-format
|
||||
msgid "The system will power off automatically in %d second."
|
||||
msgid_plural "The system will power off automatically in %d seconds."
|
||||
msgstr[0] "S'apagarà l'ordinador automàticament d'aquí %d segon."
|
||||
msgstr[1] "S'apagarà l'ordinador automàticament d'aquí %d segons."
|
||||
|
||||
#: js/ui/endSessionDialog.js:64
|
||||
#: js/ui/endSessionDialog.js:63
|
||||
msgctxt "checkbox"
|
||||
msgid "Install pending software updates"
|
||||
msgstr "Instal·la les actualitzacions pendents"
|
||||
|
||||
#: js/ui/endSessionDialog.js:67 js/ui/endSessionDialog.js:84
|
||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Reinicia"
|
||||
|
||||
#: js/ui/endSessionDialog.js:69
|
||||
#: js/ui/endSessionDialog.js:68
|
||||
msgctxt "button"
|
||||
msgid "Power Off"
|
||||
msgstr "Apaga"
|
||||
|
||||
#: js/ui/endSessionDialog.js:76
|
||||
#: js/ui/endSessionDialog.js:74
|
||||
msgctxt "title"
|
||||
msgid "Restart"
|
||||
msgstr "Reinici"
|
||||
|
||||
#: js/ui/endSessionDialog.js:78
|
||||
#: js/ui/endSessionDialog.js:76
|
||||
#, javascript-format
|
||||
msgid "The system will restart automatically in %d second."
|
||||
msgid_plural "The system will restart automatically in %d seconds."
|
||||
msgstr[0] "Es reiniciarà l'ordinador automàticament d'aquí %d segon."
|
||||
msgstr[1] "Es reiniciarà l'ordinador automàticament d'aquí %d segons."
|
||||
|
||||
#: js/ui/endSessionDialog.js:92
|
||||
#: js/ui/endSessionDialog.js:89
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Updates"
|
||||
msgstr "Reinicia i instal·la les actualitzacions"
|
||||
|
||||
#: js/ui/endSessionDialog.js:94
|
||||
#: js/ui/endSessionDialog.js:91
|
||||
#, javascript-format
|
||||
msgid "The system will automatically restart and install updates in %d second."
|
||||
msgid_plural ""
|
||||
@@ -1281,22 +1288,22 @@ msgstr[1] ""
|
||||
"Es reiniciarà l'ordinador automàticament i s'instal·laran les "
|
||||
"actualitzacions d'aquí %d segons."
|
||||
|
||||
#: js/ui/endSessionDialog.js:100 js/ui/endSessionDialog.js:120
|
||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
||||
msgctxt "button"
|
||||
msgid "Restart & Install"
|
||||
msgstr "Reinicia i instal·la"
|
||||
|
||||
#: js/ui/endSessionDialog.js:101
|
||||
#: js/ui/endSessionDialog.js:98
|
||||
msgctxt "button"
|
||||
msgid "Install & Power Off"
|
||||
msgstr "Instal·la i apaga"
|
||||
|
||||
#: js/ui/endSessionDialog.js:102
|
||||
#: js/ui/endSessionDialog.js:99
|
||||
msgctxt "checkbox"
|
||||
msgid "Power off after updates are installed"
|
||||
msgstr "Apaga després d'instal·lar les actualitzacions"
|
||||
|
||||
#: js/ui/endSessionDialog.js:110
|
||||
#: js/ui/endSessionDialog.js:106
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Upgrade"
|
||||
msgstr "Reinicia i instal·la l'actualització"
|
||||
@@ -1304,7 +1311,7 @@ msgstr "Reinicia i instal·la l'actualització"
|
||||
#. Translators: This is the text displayed for system upgrades in the
|
||||
#. shut down dialog. First %s gets replaced with the distro name and
|
||||
#. second %s with the distro version to upgrade to
|
||||
#: js/ui/endSessionDialog.js:115
|
||||
#: js/ui/endSessionDialog.js:111
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||
@@ -1314,30 +1321,30 @@ msgstr ""
|
||||
"instal·lació pot trigar força temps. Assegureu-vos que heu fet còpia de "
|
||||
"seguretat i que l'ordinador està connectat al corrent."
|
||||
|
||||
#: js/ui/endSessionDialog.js:301
|
||||
msgid "Running on battery power: please plug in before installing updates."
|
||||
#: js/ui/endSessionDialog.js:259
|
||||
msgid "Running on battery power: Please plug in before installing updates."
|
||||
msgstr ""
|
||||
"S'està utilitzant la bateria: connecteu l'ordinador a la xarxa elèctrica "
|
||||
"S'està utilitzant la bateria. Connecteu l'ordinador a la xarxa elèctrica "
|
||||
"abans d'instal·lar les actualitzacions."
|
||||
|
||||
#: js/ui/endSessionDialog.js:320
|
||||
msgid "Some applications are busy or have unsaved work."
|
||||
#: js/ui/endSessionDialog.js:268
|
||||
msgid "Some applications are busy or have unsaved work"
|
||||
msgstr ""
|
||||
"Hi ha algunes aplicacions que estan ocupades o que tenen documents sense "
|
||||
"desar."
|
||||
|
||||
#: js/ui/endSessionDialog.js:327
|
||||
msgid "Other users are logged in."
|
||||
msgstr "Altres usuaris tenen la sessió oberta."
|
||||
#: js/ui/endSessionDialog.js:273
|
||||
msgid "Other users are logged in"
|
||||
msgstr "Altres usuaris tenen la sessió oberta"
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: js/ui/endSessionDialog.js:649
|
||||
#: js/ui/endSessionDialog.js:588
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (remot)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: js/ui/endSessionDialog.js:652
|
||||
#: js/ui/endSessionDialog.js:591
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (consola)"
|
||||
@@ -1361,16 +1368,16 @@ msgid "Application wants to inhibit shortcuts"
|
||||
msgstr "L'aplicació vol inhabilitar les dreceres"
|
||||
|
||||
#. Translators: %s is a keyboard shortcut like "Super+x"
|
||||
#: js/ui/inhibitShortcutsDialog.js:90
|
||||
#: js/ui/inhibitShortcutsDialog.js:89
|
||||
#, javascript-format
|
||||
msgid "You can restore shortcuts by pressing %s."
|
||||
msgstr "Podeu restaurar les dreceres si premeu %s."
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:96
|
||||
#: js/ui/inhibitShortcutsDialog.js:95
|
||||
msgid "Deny"
|
||||
msgstr "Denega"
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:103
|
||||
#: js/ui/inhibitShortcutsDialog.js:102
|
||||
msgid "Allow"
|
||||
msgstr "Permet"
|
||||
|
||||
@@ -1418,16 +1425,16 @@ msgstr ""
|
||||
"Això desactiva la funcionalitat de les tecles enganxoses, que afecta la "
|
||||
"manera en què funciona el teclat."
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:58
|
||||
#: js/ui/kbdA11yDialog.js:57
|
||||
msgid "Leave On"
|
||||
msgstr "Deixa-ho actiu"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:58 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/kbdA11yDialog.js:57 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/status/network.js:1285
|
||||
msgid "Turn On"
|
||||
msgstr "Activa"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:66 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/kbdA11yDialog.js:65 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/status/network.js:131 js/ui/status/network.js:315
|
||||
#: js/ui/status/network.js:1285 js/ui/status/network.js:1397
|
||||
#: js/ui/status/nightLight.js:41 js/ui/status/rfkill.js:81
|
||||
@@ -1435,7 +1442,7 @@ msgstr "Activa"
|
||||
msgid "Turn Off"
|
||||
msgstr "Desactiva"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:66
|
||||
#: js/ui/kbdA11yDialog.js:65
|
||||
msgid "Leave Off"
|
||||
msgstr "Deixa-ho desactivat"
|
||||
|
||||
@@ -1655,11 +1662,11 @@ msgstr "El GNOME necessita bloquejar la pantalla"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: js/ui/screenShield.js:831 js/ui/screenShield.js:1303
|
||||
#: js/ui/screenShield.js:830 js/ui/screenShield.js:1301
|
||||
msgid "Unable to lock"
|
||||
msgstr "No es pot blocar"
|
||||
|
||||
#: js/ui/screenShield.js:832 js/ui/screenShield.js:1304
|
||||
#: js/ui/screenShield.js:831 js/ui/screenShield.js:1302
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Una aplicació està bloquejant el bloqueig"
|
||||
|
||||
@@ -1694,60 +1701,60 @@ msgstr "Mostra el text"
|
||||
msgid "Hide Text"
|
||||
msgstr "Oculta el text"
|
||||
|
||||
#: js/ui/shellEntry.js:161
|
||||
#: js/ui/shellEntry.js:162
|
||||
msgid "Caps lock is on."
|
||||
msgstr "Bloq Maj està activat."
|
||||
|
||||
#: js/ui/shellMountOperation.js:308
|
||||
#: js/ui/shellMountOperation.js:305
|
||||
msgid "Hidden Volume"
|
||||
msgstr "Volum ocult"
|
||||
|
||||
#: js/ui/shellMountOperation.js:311
|
||||
#: js/ui/shellMountOperation.js:308
|
||||
msgid "Windows System Volume"
|
||||
msgstr "Volum del sistema del Windows"
|
||||
|
||||
#: js/ui/shellMountOperation.js:314
|
||||
#: js/ui/shellMountOperation.js:311
|
||||
msgid "Uses Keyfiles"
|
||||
msgstr "Usa fitxers de claus"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:320
|
||||
#: js/ui/shellMountOperation.js:317
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead."
|
||||
msgstr ""
|
||||
"Per a desbloquejar un volum que usa fitxers de claus, useu l'eina <i>%s</i>."
|
||||
|
||||
#: js/ui/shellMountOperation.js:327
|
||||
#: js/ui/shellMountOperation.js:324
|
||||
msgid "PIM Number"
|
||||
msgstr "Número PIM"
|
||||
|
||||
#: js/ui/shellMountOperation.js:346
|
||||
#: js/ui/shellMountOperation.js:343
|
||||
msgid "The PIM must be a number or empty."
|
||||
msgstr "El PIM ha de ser un nombre o estar buit."
|
||||
|
||||
#: js/ui/shellMountOperation.js:357
|
||||
#: js/ui/shellMountOperation.js:354
|
||||
msgid "Password"
|
||||
msgstr "Contrasenya"
|
||||
|
||||
#: js/ui/shellMountOperation.js:393
|
||||
#: js/ui/shellMountOperation.js:390
|
||||
msgid "Remember Password"
|
||||
msgstr "Recorda la contrasenya"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:417
|
||||
#: js/ui/shellMountOperation.js:414
|
||||
#, javascript-format
|
||||
msgid "Open %s"
|
||||
msgstr "Obre %s"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:489
|
||||
#: js/ui/shellMountOperation.js:486
|
||||
#, javascript-format
|
||||
msgid "Unable to start %s"
|
||||
msgstr "No es pot iniciar %s"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:491
|
||||
#: js/ui/shellMountOperation.js:488
|
||||
#, javascript-format
|
||||
msgid "Couldn’t find the %s application"
|
||||
msgstr "No s'ha pogut trobar l'aplicació %s"
|
||||
@@ -1844,11 +1851,11 @@ msgstr "Clic secundari"
|
||||
msgid "Dwell Click"
|
||||
msgstr "Clic en passar per sobre"
|
||||
|
||||
#: js/ui/status/keyboard.js:818
|
||||
#: js/ui/status/keyboard.js:825
|
||||
msgid "Keyboard"
|
||||
msgstr "Teclat"
|
||||
|
||||
#: js/ui/status/keyboard.js:840
|
||||
#: js/ui/status/keyboard.js:847
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "Mostra la disposició del teclat"
|
||||
|
||||
@@ -1877,12 +1884,12 @@ msgid "Enable"
|
||||
msgstr "Habilita"
|
||||
|
||||
#. Translators: %s is an application name
|
||||
#: js/ui/status/location.js:357
|
||||
#: js/ui/status/location.js:355
|
||||
#, javascript-format
|
||||
msgid "Give %s access to your location?"
|
||||
msgstr "Voleu donar a %s accés a la vostra ubicació?"
|
||||
|
||||
#: js/ui/status/location.js:358
|
||||
#: js/ui/status/location.js:361
|
||||
msgid "Location access can be changed at any time from the privacy settings."
|
||||
msgstr ""
|
||||
"Podeu canviar la configuració de l'accés a la ubicació sempre que vulgueu "
|
||||
@@ -2264,11 +2271,11 @@ msgstr "Entra amb un altre usuari"
|
||||
msgid "Unlock Window"
|
||||
msgstr "Desbloqueja la finestra"
|
||||
|
||||
#: js/ui/viewSelector.js:180
|
||||
#: js/ui/viewSelector.js:181
|
||||
msgid "Applications"
|
||||
msgstr "Aplicacions"
|
||||
|
||||
#: js/ui/viewSelector.js:184
|
||||
#: js/ui/viewSelector.js:185
|
||||
msgid "Search"
|
||||
msgstr "Cerca"
|
||||
|
||||
@@ -2277,22 +2284,22 @@ msgstr "Cerca"
|
||||
msgid "“%s” is ready"
|
||||
msgstr "«%s» ja està a punt"
|
||||
|
||||
#: js/ui/windowManager.js:57
|
||||
#: js/ui/windowManager.js:54
|
||||
msgid "Do you want to keep these display settings?"
|
||||
msgstr "Voleu mantenir aquesta configuració de la pantalla?"
|
||||
|
||||
#. Translators: this and the following message should be limited in length,
|
||||
#. to avoid ellipsizing the labels.
|
||||
#.
|
||||
#: js/ui/windowManager.js:71
|
||||
#: js/ui/windowManager.js:68
|
||||
msgid "Revert Settings"
|
||||
msgstr "Descarta els canvis"
|
||||
|
||||
#: js/ui/windowManager.js:74
|
||||
#: js/ui/windowManager.js:71
|
||||
msgid "Keep Changes"
|
||||
msgstr "Mantén els canvis"
|
||||
|
||||
#: js/ui/windowManager.js:92
|
||||
#: js/ui/windowManager.js:89
|
||||
#, javascript-format
|
||||
msgid "Settings changes will revert in %d second"
|
||||
msgid_plural "Settings changes will revert in %d seconds"
|
||||
@@ -2301,7 +2308,7 @@ msgstr[1] "Es descartaran els canvis d'aquí %d segons"
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#: js/ui/windowManager.js:690
|
||||
#: js/ui/windowManager.js:546
|
||||
#, javascript-format
|
||||
msgid "%d × %d"
|
||||
msgstr "%d × %d"
|
||||
@@ -2390,12 +2397,12 @@ msgstr "Utilitza un mode específic, p. ex. «gdm» per la pantalla d'entrada"
|
||||
msgid "List possible modes"
|
||||
msgstr "Llista els modes possibles"
|
||||
|
||||
#: src/shell-app.c:265
|
||||
#: src/shell-app.c:279
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Desconegut"
|
||||
|
||||
#: src/shell-app.c:516
|
||||
#: src/shell-app.c:530
|
||||
#, c-format
|
||||
msgid "Failed to launch “%s”"
|
||||
msgstr "No s'ha pogut iniciar «%s»"
|
||||
@@ -2753,6 +2760,9 @@ msgstr[1] "%u entrades"
|
||||
msgid "System Sounds"
|
||||
msgstr "Sons del sistema"
|
||||
|
||||
#~ msgid "Rename"
|
||||
#~ msgstr "Canvia el nom"
|
||||
|
||||
#~ msgid "Account Settings"
|
||||
#~ msgstr "Paràmetres del compte"
|
||||
|
||||
|
1736
po/en_GB.po
1736
po/en_GB.po
File diff suppressed because it is too large
Load Diff
308
po/fur.po
308
po/fur.po
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: video-subtitles master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
|
||||
"POT-Creation-Date: 2019-12-20 22:04+0000\n"
|
||||
"PO-Revision-Date: 2019-12-22 19:58+0100\n"
|
||||
"POT-Creation-Date: 2020-01-26 09:11+0000\n"
|
||||
"PO-Revision-Date: 2020-01-26 20:08+0100\n"
|
||||
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
|
||||
"Language-Team: Friulian <fur@li.org>\n"
|
||||
"Language: fur\n"
|
||||
@@ -43,7 +43,7 @@ msgid "Open the application menu"
|
||||
msgstr "Vierç il menù aplicazions"
|
||||
|
||||
#: data/gnome-shell-extension-prefs.desktop.in.in:4
|
||||
#: js/extensionPrefs/main.js:210
|
||||
#: js/extensionPrefs/main.js:209
|
||||
msgid "Shell Extensions"
|
||||
msgstr "Estensions Shell"
|
||||
|
||||
@@ -400,11 +400,11 @@ msgstr ""
|
||||
msgid "Network Login"
|
||||
msgstr "Acès di rêt"
|
||||
|
||||
#: js/extensionPrefs/main.js:103 js/extensionPrefs/main.js:526
|
||||
#: js/extensionPrefs/main.js:102 js/extensionPrefs/main.js:525
|
||||
msgid "Something’s gone wrong"
|
||||
msgstr "Alc al è lât stuart"
|
||||
|
||||
#: js/extensionPrefs/main.js:110
|
||||
#: js/extensionPrefs/main.js:109
|
||||
msgid ""
|
||||
"We’re very sorry, but there’s been a problem: the settings for this "
|
||||
"extension can’t be displayed. We recommend that you report the issue to the "
|
||||
@@ -414,27 +414,27 @@ msgstr ""
|
||||
"puedin jessi mostradis. Si consee di segnalâ il probleme ai autôrs de "
|
||||
"estension."
|
||||
|
||||
#: js/extensionPrefs/main.js:117
|
||||
#: js/extensionPrefs/main.js:116
|
||||
msgid "Technical Details"
|
||||
msgstr "Detais tecnics"
|
||||
|
||||
#: js/extensionPrefs/main.js:152
|
||||
#: js/extensionPrefs/main.js:151
|
||||
msgid "Copy Error"
|
||||
msgstr "Copie erôr"
|
||||
|
||||
#: js/extensionPrefs/main.js:179
|
||||
#: js/extensionPrefs/main.js:178
|
||||
msgid "Homepage"
|
||||
msgstr "Pagjine principâl"
|
||||
|
||||
#: js/extensionPrefs/main.js:180
|
||||
#: js/extensionPrefs/main.js:179
|
||||
msgid "Visit extension homepage"
|
||||
msgstr "Visite la pagjine principâl de estension"
|
||||
|
||||
#: js/extensionPrefs/main.js:468
|
||||
#: js/extensionPrefs/main.js:467
|
||||
msgid "No Extensions Installed"
|
||||
msgstr "Nissune estension instalade"
|
||||
|
||||
#: js/extensionPrefs/main.js:478
|
||||
#: js/extensionPrefs/main.js:477
|
||||
msgid ""
|
||||
"Extensions can be installed through Software or <a href=\"https://extensions."
|
||||
"gnome.org\">extensions.gnome.org</a>."
|
||||
@@ -442,11 +442,11 @@ msgstr ""
|
||||
"Si puedin instalâ lis estension cun Software o cun <a href=\"https://"
|
||||
"extensions.gnome.org\">extensions.gnome.org</a>."
|
||||
|
||||
#: js/extensionPrefs/main.js:493
|
||||
#: js/extensionPrefs/main.js:492
|
||||
msgid "Browse in Software"
|
||||
msgstr "Esplore in Software"
|
||||
|
||||
#: js/extensionPrefs/main.js:533
|
||||
#: js/extensionPrefs/main.js:532
|
||||
msgid ""
|
||||
"We’re very sorry, but it was not possible to get the list of installed "
|
||||
"extensions. Make sure you are logged into GNOME and try again."
|
||||
@@ -455,9 +455,9 @@ msgstr ""
|
||||
"instaladis. Controle di jessi jentrât in GNOME e torne prove."
|
||||
|
||||
#: js/gdm/authPrompt.js:174 js/ui/audioDeviceSelection.js:57
|
||||
#: js/ui/components/networkAgent.js:130 js/ui/components/polkitAgent.js:139
|
||||
#: js/ui/endSessionDialog.js:445 js/ui/extensionDownloader.js:190
|
||||
#: js/ui/shellMountOperation.js:402 js/ui/shellMountOperation.js:412
|
||||
#: js/ui/components/networkAgent.js:129 js/ui/components/polkitAgent.js:138
|
||||
#: js/ui/endSessionDialog.js:374 js/ui/extensionDownloader.js:190
|
||||
#: js/ui/shellMountOperation.js:399 js/ui/shellMountOperation.js:409
|
||||
#: js/ui/status/network.js:910
|
||||
msgid "Cancel"
|
||||
msgstr "Anule"
|
||||
@@ -466,7 +466,7 @@ msgstr "Anule"
|
||||
msgid "Next"
|
||||
msgstr "Indenant"
|
||||
|
||||
#: js/gdm/authPrompt.js:237 js/ui/shellMountOperation.js:406
|
||||
#: js/gdm/authPrompt.js:237 js/ui/shellMountOperation.js:403
|
||||
#: js/ui/unlockDialog.js:44
|
||||
msgid "Unlock"
|
||||
msgstr "Sbloche"
|
||||
@@ -494,8 +494,8 @@ msgstr "(p.e., utent o %s)"
|
||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||
#. is not visible here since we only care about phase2 authentication
|
||||
#. (and don't even care of which one)
|
||||
#: js/gdm/loginDialog.js:899 js/ui/components/networkAgent.js:257
|
||||
#: js/ui/components/networkAgent.js:280 js/ui/components/networkAgent.js:298
|
||||
#: js/gdm/loginDialog.js:899 js/ui/components/networkAgent.js:256
|
||||
#: js/ui/components/networkAgent.js:279 js/ui/components/networkAgent.js:297
|
||||
msgid "Username: "
|
||||
msgstr "Non utent: "
|
||||
|
||||
@@ -524,8 +524,8 @@ msgstr "Distudâ"
|
||||
|
||||
#. Translators: A list of keywords that match the power-off action, separated by semicolons
|
||||
#: js/misc/systemActions.js:92
|
||||
msgid "power off;shutdown;reboot;restart"
|
||||
msgstr "distudâ;studâ;tornâ a inviâ"
|
||||
msgid "power off;shutdown;reboot;restart;halt;stop"
|
||||
msgstr "distudâ;studâ;tornâ a inviâ;fermâ"
|
||||
|
||||
#. Translators: The name of the lock screen action in search
|
||||
#: js/misc/systemActions.js:97
|
||||
@@ -735,56 +735,52 @@ msgstr ""
|
||||
|
||||
#. No support for non-modal system dialogs, so ignore the option
|
||||
#. let modal = options['modal'] || true;
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:364
|
||||
#: js/ui/accessDialog.js:39 js/ui/status/location.js:366
|
||||
msgid "Deny Access"
|
||||
msgstr "Dinee acès"
|
||||
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:367
|
||||
#: js/ui/accessDialog.js:40 js/ui/status/location.js:369
|
||||
msgid "Grant Access"
|
||||
msgstr "Garantìs l'acès"
|
||||
|
||||
#: js/ui/appDisplay.js:921
|
||||
#: js/ui/appDisplay.js:904
|
||||
msgid "Unnamed Folder"
|
||||
msgstr "Cartele cence non"
|
||||
|
||||
#: js/ui/appDisplay.js:944
|
||||
#: js/ui/appDisplay.js:927
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "Lis aplicazions dopradis dispès a vignaran mostradis culì"
|
||||
|
||||
#: js/ui/appDisplay.js:1079
|
||||
#: js/ui/appDisplay.js:1062
|
||||
msgid "Frequent"
|
||||
msgstr "Dispès"
|
||||
|
||||
#: js/ui/appDisplay.js:1086
|
||||
#: js/ui/appDisplay.js:1069
|
||||
msgid "All"
|
||||
msgstr "Dutis"
|
||||
|
||||
#: js/ui/appDisplay.js:1861
|
||||
msgid "Rename"
|
||||
msgstr "Cambie non"
|
||||
|
||||
#. Translators: This is the heading of a list of open windows
|
||||
#: js/ui/appDisplay.js:2549 js/ui/panel.js:75
|
||||
#: js/ui/appDisplay.js:2452 js/ui/panel.js:75
|
||||
msgid "Open Windows"
|
||||
msgstr "Barcons vierts"
|
||||
|
||||
#: js/ui/appDisplay.js:2569 js/ui/panel.js:82
|
||||
#: js/ui/appDisplay.js:2472 js/ui/panel.js:82
|
||||
msgid "New Window"
|
||||
msgstr "Gnûf barcon"
|
||||
|
||||
#: js/ui/appDisplay.js:2580
|
||||
#: js/ui/appDisplay.js:2483
|
||||
msgid "Launch using Dedicated Graphics Card"
|
||||
msgstr "Invie doprant une schede grafiche dedicade"
|
||||
|
||||
#: js/ui/appDisplay.js:2608 js/ui/dash.js:239
|
||||
#: js/ui/appDisplay.js:2511 js/ui/dash.js:239
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Gjave dai preferîts"
|
||||
|
||||
#: js/ui/appDisplay.js:2614
|
||||
#: js/ui/appDisplay.js:2517
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Zonte tai preferîts"
|
||||
|
||||
#: js/ui/appDisplay.js:2624 js/ui/panel.js:93
|
||||
#: js/ui/appDisplay.js:2527 js/ui/panel.js:93
|
||||
msgid "Show Details"
|
||||
msgstr "Mostre Detais"
|
||||
|
||||
@@ -831,7 +827,7 @@ msgid "Settings"
|
||||
msgstr "Impostazions"
|
||||
|
||||
#. Translators: Enter 0-6 (Sunday-Saturday) for non-work days. Examples: "0" (Sunday) "6" (Saturday) "06" (Sunday and Saturday).
|
||||
#: js/ui/calendar.js:40
|
||||
#: js/ui/calendar.js:41
|
||||
msgctxt "calendar-no-work"
|
||||
msgid "06"
|
||||
msgstr "06"
|
||||
@@ -841,43 +837,43 @@ msgstr "06"
|
||||
#. * NOTE: These grid abbreviations are always shown together
|
||||
#. * and in order, e.g. "S M T W T F S".
|
||||
#.
|
||||
#: js/ui/calendar.js:69
|
||||
#: js/ui/calendar.js:70
|
||||
msgctxt "grid sunday"
|
||||
msgid "S"
|
||||
msgstr "D"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Monday
|
||||
#: js/ui/calendar.js:71
|
||||
#: js/ui/calendar.js:72
|
||||
msgctxt "grid monday"
|
||||
msgid "M"
|
||||
msgstr "L"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Tuesday
|
||||
#: js/ui/calendar.js:73
|
||||
#: js/ui/calendar.js:74
|
||||
msgctxt "grid tuesday"
|
||||
msgid "T"
|
||||
msgstr "M"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Wednesday
|
||||
#: js/ui/calendar.js:75
|
||||
#: js/ui/calendar.js:76
|
||||
msgctxt "grid wednesday"
|
||||
msgid "W"
|
||||
msgstr "M"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Thursday
|
||||
#: js/ui/calendar.js:77
|
||||
#: js/ui/calendar.js:78
|
||||
msgctxt "grid thursday"
|
||||
msgid "T"
|
||||
msgstr "J"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Friday
|
||||
#: js/ui/calendar.js:79
|
||||
#: js/ui/calendar.js:80
|
||||
msgctxt "grid friday"
|
||||
msgid "F"
|
||||
msgstr "V"
|
||||
|
||||
#. Translators: Calendar grid abbreviation for Saturday
|
||||
#: js/ui/calendar.js:81
|
||||
#: js/ui/calendar.js:82
|
||||
msgctxt "grid saturday"
|
||||
msgid "S"
|
||||
msgstr "S"
|
||||
@@ -888,7 +884,7 @@ msgstr "S"
|
||||
#. * "%OB" is the new format specifier introduced in glibc 2.27,
|
||||
#. * in most cases you should not change it.
|
||||
#.
|
||||
#: js/ui/calendar.js:370
|
||||
#: js/ui/calendar.js:371
|
||||
msgid "%OB"
|
||||
msgstr "%OB"
|
||||
|
||||
@@ -901,55 +897,61 @@ msgstr "%OB"
|
||||
#. * in most cases you should not use the old "%B" here unless you
|
||||
#. * absolutely know what you are doing.
|
||||
#.
|
||||
#: js/ui/calendar.js:380
|
||||
#: js/ui/calendar.js:381
|
||||
msgid "%OB %Y"
|
||||
msgstr "%OB dal %Y"
|
||||
|
||||
#: js/ui/calendar.js:439
|
||||
#: js/ui/calendar.js:440
|
||||
msgid "Previous month"
|
||||
msgstr "Mês indaûr"
|
||||
|
||||
#: js/ui/calendar.js:454
|
||||
#: js/ui/calendar.js:455
|
||||
msgid "Next month"
|
||||
msgstr "Prossim mês"
|
||||
|
||||
#: js/ui/calendar.js:604
|
||||
#: js/ui/calendar.js:605
|
||||
#, no-javascript-format
|
||||
msgctxt "date day number format"
|
||||
msgid "%d"
|
||||
msgstr "%d"
|
||||
|
||||
#: js/ui/calendar.js:660
|
||||
#: js/ui/calendar.js:661
|
||||
msgid "Week %V"
|
||||
msgstr "Setemane %V"
|
||||
|
||||
#. Translators: Shown in calendar event list for all day events
|
||||
#. * Keep it short, best if you can use less then 10 characters
|
||||
#.
|
||||
#: js/ui/calendar.js:729
|
||||
#: js/ui/calendar.js:730
|
||||
msgctxt "event list time"
|
||||
msgid "All Day"
|
||||
msgstr "Dut il dì"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year
|
||||
#: js/ui/calendar.js:867
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d"
|
||||
msgstr "%A, %-d di %B"
|
||||
|
||||
#: js/ui/calendar.js:871
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year
|
||||
#: js/ui/calendar.js:870
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %-d, %Y"
|
||||
msgstr "%A, %-d di %B dal %Y"
|
||||
|
||||
#: js/ui/calendar.js:1097
|
||||
#: js/ui/calendar.js:1096
|
||||
msgid "No Notifications"
|
||||
msgstr "Nissune notifiche"
|
||||
|
||||
#: js/ui/calendar.js:1100
|
||||
#: js/ui/calendar.js:1099
|
||||
msgid "No Events"
|
||||
msgstr "Nissun event"
|
||||
|
||||
#: js/ui/calendar.js:1132
|
||||
#: js/ui/calendar.js:1153
|
||||
msgid "Do Not Disturb"
|
||||
msgstr "No sta disturbâ"
|
||||
|
||||
#: js/ui/calendar.js:1167
|
||||
msgid "Clear"
|
||||
msgstr "Nete"
|
||||
|
||||
@@ -967,11 +969,11 @@ msgstr ""
|
||||
"Si pues sielzi di spietâ un tic che al continui o sfuarçâ la aplicazion a "
|
||||
"jessî dal dut."
|
||||
|
||||
#: js/ui/closeDialog.js:71
|
||||
#: js/ui/closeDialog.js:70
|
||||
msgid "Force Quit"
|
||||
msgstr "Sfuarce jessude"
|
||||
|
||||
#: js/ui/closeDialog.js:74
|
||||
#: js/ui/closeDialog.js:73
|
||||
msgid "Wait"
|
||||
msgstr "Spiete"
|
||||
|
||||
@@ -996,54 +998,54 @@ msgstr "La version di udisks instalade no supuarte la impostazion PIM"
|
||||
msgid "Open with %s"
|
||||
msgstr "Vierç cun %s"
|
||||
|
||||
#: js/ui/components/keyring.js:71 js/ui/components/polkitAgent.js:279
|
||||
#: js/ui/components/keyring.js:70 js/ui/components/polkitAgent.js:278
|
||||
msgid "Password:"
|
||||
msgstr "Password:"
|
||||
|
||||
#: js/ui/components/keyring.js:105
|
||||
#: js/ui/components/keyring.js:104
|
||||
msgid "Type again:"
|
||||
msgstr "Scîf di gnûf:"
|
||||
|
||||
#: js/ui/components/networkAgent.js:116
|
||||
#: js/ui/components/networkAgent.js:115
|
||||
msgid ""
|
||||
"Alternatively you can connect by pushing the “WPS” button on your router."
|
||||
msgstr ""
|
||||
"In alternative al è pussibil conetisi fracant il boton “WPS” sul router."
|
||||
|
||||
#: js/ui/components/networkAgent.js:124 js/ui/status/network.js:223
|
||||
#: js/ui/components/networkAgent.js:123 js/ui/status/network.js:223
|
||||
#: js/ui/status/network.js:314 js/ui/status/network.js:913
|
||||
msgid "Connect"
|
||||
msgstr "Conet"
|
||||
|
||||
#. Cisco LEAP
|
||||
#: js/ui/components/networkAgent.js:225 js/ui/components/networkAgent.js:237
|
||||
#: js/ui/components/networkAgent.js:261 js/ui/components/networkAgent.js:282
|
||||
#: js/ui/components/networkAgent.js:302 js/ui/components/networkAgent.js:312
|
||||
#: js/ui/components/networkAgent.js:224 js/ui/components/networkAgent.js:236
|
||||
#: js/ui/components/networkAgent.js:260 js/ui/components/networkAgent.js:281
|
||||
#: js/ui/components/networkAgent.js:301 js/ui/components/networkAgent.js:311
|
||||
msgid "Password: "
|
||||
msgstr "Password: "
|
||||
|
||||
#. static WEP
|
||||
#: js/ui/components/networkAgent.js:230
|
||||
#: js/ui/components/networkAgent.js:229
|
||||
msgid "Key: "
|
||||
msgstr "Clâf: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:265 js/ui/components/networkAgent.js:288
|
||||
#: js/ui/components/networkAgent.js:264 js/ui/components/networkAgent.js:287
|
||||
msgid "Private key password: "
|
||||
msgstr "Password di clâf privade: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:286
|
||||
#: js/ui/components/networkAgent.js:285
|
||||
msgid "Identity: "
|
||||
msgstr "Identitât: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:300
|
||||
#: js/ui/components/networkAgent.js:299
|
||||
msgid "Service: "
|
||||
msgstr "Servizi: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:704
|
||||
#: js/ui/components/networkAgent.js:328 js/ui/components/networkAgent.js:703
|
||||
msgid "Authentication required by wireless network"
|
||||
msgstr "La rêt cence fîl e domande autenticazion"
|
||||
|
||||
#: js/ui/components/networkAgent.js:330 js/ui/components/networkAgent.js:705
|
||||
#: js/ui/components/networkAgent.js:329 js/ui/components/networkAgent.js:704
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Passwords or encryption keys are required to access the wireless network "
|
||||
@@ -1052,53 +1054,58 @@ msgstr ""
|
||||
"Si scugne meti une password o une clâf di cifradure par jentrâ te rêt cence "
|
||||
"fîl \"%s\"."
|
||||
|
||||
#: js/ui/components/networkAgent.js:334 js/ui/components/networkAgent.js:709
|
||||
#: js/ui/components/networkAgent.js:333 js/ui/components/networkAgent.js:708
|
||||
msgid "Wired 802.1X authentication"
|
||||
msgstr "Autenticazion vie fîl 802.1X"
|
||||
|
||||
#: js/ui/components/networkAgent.js:336
|
||||
#: js/ui/components/networkAgent.js:335
|
||||
msgid "Network name: "
|
||||
msgstr "Non rêt: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:341 js/ui/components/networkAgent.js:713
|
||||
#: js/ui/components/networkAgent.js:340 js/ui/components/networkAgent.js:712
|
||||
msgid "DSL authentication"
|
||||
msgstr "Autenticazion DSL"
|
||||
|
||||
#: js/ui/components/networkAgent.js:348 js/ui/components/networkAgent.js:718
|
||||
#: js/ui/components/networkAgent.js:347 js/ui/components/networkAgent.js:717
|
||||
msgid "PIN code required"
|
||||
msgstr "Si pretint un codiç PIN"
|
||||
|
||||
#: js/ui/components/networkAgent.js:349 js/ui/components/networkAgent.js:719
|
||||
#: js/ui/components/networkAgent.js:348 js/ui/components/networkAgent.js:718
|
||||
msgid "PIN code is needed for the mobile broadband device"
|
||||
msgstr "Si scugne meti un codiç PIN pal dispositîf a bande largje mobil"
|
||||
|
||||
#: js/ui/components/networkAgent.js:350
|
||||
#: js/ui/components/networkAgent.js:349
|
||||
msgid "PIN: "
|
||||
msgstr "PIN: "
|
||||
|
||||
#: js/ui/components/networkAgent.js:357 js/ui/components/networkAgent.js:725
|
||||
#: js/ui/components/networkAgent.js:356 js/ui/components/networkAgent.js:724
|
||||
msgid "Mobile broadband network password"
|
||||
msgstr "Passowrd rêt mobil a bande largje"
|
||||
|
||||
#: js/ui/components/networkAgent.js:358 js/ui/components/networkAgent.js:710
|
||||
#: js/ui/components/networkAgent.js:714 js/ui/components/networkAgent.js:726
|
||||
#: js/ui/components/networkAgent.js:357 js/ui/components/networkAgent.js:709
|
||||
#: js/ui/components/networkAgent.js:713 js/ui/components/networkAgent.js:725
|
||||
#: js/ui/components/networkAgent.js:729
|
||||
#, javascript-format
|
||||
msgid "A password is required to connect to “%s”."
|
||||
msgstr "A covente une password par tacâsi a '%s'."
|
||||
|
||||
#: js/ui/components/networkAgent.js:693 js/ui/status/network.js:1688
|
||||
#: js/ui/components/networkAgent.js:692 js/ui/status/network.js:1688
|
||||
msgid "Network Manager"
|
||||
msgstr "Ministradôr di rêt"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:42
|
||||
#: js/ui/components/networkAgent.js:728
|
||||
msgid "VPN password"
|
||||
msgstr "Password VPN"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:41
|
||||
msgid "Authentication Required"
|
||||
msgstr "Autenticazion Necessarie"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:82
|
||||
#: js/ui/components/polkitAgent.js:81
|
||||
msgid "Administrator"
|
||||
msgstr "Aministradôr"
|
||||
|
||||
#: js/ui/components/polkitAgent.js:142
|
||||
#: js/ui/components/polkitAgent.js:141
|
||||
msgid "Authenticate"
|
||||
msgstr "Autentiche"
|
||||
|
||||
@@ -1106,7 +1113,7 @@ msgstr "Autentiche"
|
||||
#. * requested authentication was not gained; this can happen
|
||||
#. * because of an authentication error (like invalid password),
|
||||
#. * for instance.
|
||||
#: js/ui/components/polkitAgent.js:260 js/ui/shellMountOperation.js:386
|
||||
#: js/ui/components/polkitAgent.js:259 js/ui/shellMountOperation.js:383
|
||||
msgid "Sorry, that didn’t work. Please try again."
|
||||
msgstr "Mi displâs, no je lade drete. Prove di gnûf."
|
||||
|
||||
@@ -1117,7 +1124,7 @@ msgstr "Mi displâs, no je lade drete. Prove di gnûf."
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "L'utent %s al è cognossût cumò come %s"
|
||||
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:176
|
||||
#: js/ui/ctrlAltTab.js:21 js/ui/viewSelector.js:177
|
||||
msgid "Windows"
|
||||
msgstr "Barcons"
|
||||
|
||||
@@ -1160,19 +1167,19 @@ msgstr "Orlois mondiâi"
|
||||
msgid "Weather"
|
||||
msgstr "Timp"
|
||||
|
||||
#: js/ui/dateMenu.js:389
|
||||
#: js/ui/dateMenu.js:391
|
||||
msgid "Select a location…"
|
||||
msgstr "Selezione une posizion…"
|
||||
|
||||
#: js/ui/dateMenu.js:402
|
||||
#: js/ui/dateMenu.js:404
|
||||
msgid "Loading…"
|
||||
msgstr "Daûr a cjariâ…"
|
||||
|
||||
#: js/ui/dateMenu.js:412
|
||||
#: js/ui/dateMenu.js:414
|
||||
msgid "Go online for weather information"
|
||||
msgstr "Va in rêt pes informazions sul timp"
|
||||
|
||||
#: js/ui/dateMenu.js:414
|
||||
#: js/ui/dateMenu.js:416
|
||||
msgid "Weather information is currently unavailable"
|
||||
msgstr "Lis informazions sul timp al moment no son disponibilis"
|
||||
|
||||
@@ -1206,56 +1213,56 @@ msgctxt "button"
|
||||
msgid "Log Out"
|
||||
msgstr "Jes"
|
||||
|
||||
#: js/ui/endSessionDialog.js:57
|
||||
#: js/ui/endSessionDialog.js:56
|
||||
msgctxt "title"
|
||||
msgid "Power Off"
|
||||
msgstr "Distude"
|
||||
|
||||
#: js/ui/endSessionDialog.js:58
|
||||
#: js/ui/endSessionDialog.js:57
|
||||
msgctxt "title"
|
||||
msgid "Install Updates & Power Off"
|
||||
msgstr "Instale inzornaments e distude"
|
||||
|
||||
#: js/ui/endSessionDialog.js:60
|
||||
#: js/ui/endSessionDialog.js:59
|
||||
#, javascript-format
|
||||
msgid "The system will power off automatically in %d second."
|
||||
msgid_plural "The system will power off automatically in %d seconds."
|
||||
msgstr[0] "Il sisteme si distudarà in automatic chi di %d secont."
|
||||
msgstr[1] "Il sisteme si studarà in automatic chi di %d seconts."
|
||||
|
||||
#: js/ui/endSessionDialog.js:64
|
||||
#: js/ui/endSessionDialog.js:63
|
||||
msgctxt "checkbox"
|
||||
msgid "Install pending software updates"
|
||||
msgstr "Instale i inzornaments software in spiete"
|
||||
|
||||
#: js/ui/endSessionDialog.js:67 js/ui/endSessionDialog.js:84
|
||||
#: js/ui/endSessionDialog.js:66 js/ui/endSessionDialog.js:82
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Torne invie"
|
||||
|
||||
#: js/ui/endSessionDialog.js:69
|
||||
#: js/ui/endSessionDialog.js:68
|
||||
msgctxt "button"
|
||||
msgid "Power Off"
|
||||
msgstr "Distude"
|
||||
|
||||
#: js/ui/endSessionDialog.js:76
|
||||
#: js/ui/endSessionDialog.js:74
|
||||
msgctxt "title"
|
||||
msgid "Restart"
|
||||
msgstr "Torne invie"
|
||||
|
||||
#: js/ui/endSessionDialog.js:78
|
||||
#: js/ui/endSessionDialog.js:76
|
||||
#, javascript-format
|
||||
msgid "The system will restart automatically in %d second."
|
||||
msgid_plural "The system will restart automatically in %d seconds."
|
||||
msgstr[0] "Il sisteme si tornarà a inviâ in automatic chi di %d secont."
|
||||
msgstr[1] "Il sisteme si tornarà a inviâ in automatic chi di %d secont."
|
||||
|
||||
#: js/ui/endSessionDialog.js:92
|
||||
#: js/ui/endSessionDialog.js:89
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Updates"
|
||||
msgstr "Torne a inviâ e instale inzornaments"
|
||||
|
||||
#: js/ui/endSessionDialog.js:94
|
||||
#: js/ui/endSessionDialog.js:91
|
||||
#, javascript-format
|
||||
msgid "The system will automatically restart and install updates in %d second."
|
||||
msgid_plural ""
|
||||
@@ -1267,22 +1274,22 @@ msgstr[1] ""
|
||||
"Il sisteme al tornarà a inviâsi in automatic instalant i inzornaments chi di "
|
||||
"%d seconts."
|
||||
|
||||
#: js/ui/endSessionDialog.js:100 js/ui/endSessionDialog.js:120
|
||||
#: js/ui/endSessionDialog.js:97 js/ui/endSessionDialog.js:116
|
||||
msgctxt "button"
|
||||
msgid "Restart & Install"
|
||||
msgstr "Torne invie e instale"
|
||||
|
||||
#: js/ui/endSessionDialog.js:101
|
||||
#: js/ui/endSessionDialog.js:98
|
||||
msgctxt "button"
|
||||
msgid "Install & Power Off"
|
||||
msgstr "Instale e distude"
|
||||
|
||||
#: js/ui/endSessionDialog.js:102
|
||||
#: js/ui/endSessionDialog.js:99
|
||||
msgctxt "checkbox"
|
||||
msgid "Power off after updates are installed"
|
||||
msgstr "Distude dopo vê instalât i inzornaments"
|
||||
|
||||
#: js/ui/endSessionDialog.js:110
|
||||
#: js/ui/endSessionDialog.js:106
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Upgrade"
|
||||
msgstr "Torne invie e instale avanzament"
|
||||
@@ -1290,7 +1297,7 @@ msgstr "Torne invie e instale avanzament"
|
||||
#. Translators: This is the text displayed for system upgrades in the
|
||||
#. shut down dialog. First %s gets replaced with the distro name and
|
||||
#. second %s with the distro version to upgrade to
|
||||
#: js/ui/endSessionDialog.js:115
|
||||
#: js/ui/endSessionDialog.js:111
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"%s %s will be installed after restart. Upgrade installation can take a long "
|
||||
@@ -1300,28 +1307,28 @@ msgstr ""
|
||||
"dal avanzament e pues tirâ a dilunc: siguriti di vê fat i backup e che il to "
|
||||
"computer al sedi tacât."
|
||||
|
||||
#: js/ui/endSessionDialog.js:301
|
||||
msgid "Running on battery power: please plug in before installing updates."
|
||||
#: js/ui/endSessionDialog.js:259
|
||||
msgid "Running on battery power: Please plug in before installing updates."
|
||||
msgstr ""
|
||||
"Funzionament su batarie: par plasê tache la spine prime di instalâ i "
|
||||
"inzornaments."
|
||||
|
||||
#: js/ui/endSessionDialog.js:320
|
||||
msgid "Some applications are busy or have unsaved work."
|
||||
msgstr "Cualchi aplicazion e je impegnade opûr e à lavôrs no salvâts."
|
||||
#: js/ui/endSessionDialog.js:268
|
||||
msgid "Some applications are busy or have unsaved work"
|
||||
msgstr "Cualchi aplicazion e je impegnade opûr e à lavôrs no salvâts"
|
||||
|
||||
#: js/ui/endSessionDialog.js:327
|
||||
msgid "Other users are logged in."
|
||||
msgstr "Altris utents a son jentrâts."
|
||||
#: js/ui/endSessionDialog.js:273
|
||||
msgid "Other users are logged in"
|
||||
msgstr "Altris utents a son jentrâts"
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||
#: js/ui/endSessionDialog.js:649
|
||||
#: js/ui/endSessionDialog.js:588
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (rimot)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console
|
||||
#: js/ui/endSessionDialog.js:652
|
||||
#: js/ui/endSessionDialog.js:591
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (locâl vie tastiere)"
|
||||
@@ -1345,16 +1352,16 @@ msgid "Application wants to inhibit shortcuts"
|
||||
msgstr "Une aplicazion e desidere inibî lis scurtis"
|
||||
|
||||
#. Translators: %s is a keyboard shortcut like "Super+x"
|
||||
#: js/ui/inhibitShortcutsDialog.js:90
|
||||
#: js/ui/inhibitShortcutsDialog.js:89
|
||||
#, javascript-format
|
||||
msgid "You can restore shortcuts by pressing %s."
|
||||
msgstr "Si pues ripristinâ lis scurtis fracant %s."
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:96
|
||||
#: js/ui/inhibitShortcutsDialog.js:95
|
||||
msgid "Deny"
|
||||
msgstr "Dinee"
|
||||
|
||||
#: js/ui/inhibitShortcutsDialog.js:103
|
||||
#: js/ui/inhibitShortcutsDialog.js:102
|
||||
msgid "Allow"
|
||||
msgstr "Pemet"
|
||||
|
||||
@@ -1401,16 +1408,16 @@ msgstr ""
|
||||
"Chest al disative la funzion tascj singui/tacadiçs, che al determine il mût "
|
||||
"di lavorâ de tastiere."
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:58
|
||||
#: js/ui/kbdA11yDialog.js:57
|
||||
msgid "Leave On"
|
||||
msgstr "Lasse ativât"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:58 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/kbdA11yDialog.js:57 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/status/network.js:1285
|
||||
msgid "Turn On"
|
||||
msgstr "Impie"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:66 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/kbdA11yDialog.js:65 js/ui/status/bluetooth.js:135
|
||||
#: js/ui/status/network.js:131 js/ui/status/network.js:315
|
||||
#: js/ui/status/network.js:1285 js/ui/status/network.js:1397
|
||||
#: js/ui/status/nightLight.js:41 js/ui/status/rfkill.js:81
|
||||
@@ -1418,7 +1425,7 @@ msgstr "Impie"
|
||||
msgid "Turn Off"
|
||||
msgstr "Distude"
|
||||
|
||||
#: js/ui/kbdA11yDialog.js:66
|
||||
#: js/ui/kbdA11yDialog.js:65
|
||||
msgid "Leave Off"
|
||||
msgstr "Lasse disativât"
|
||||
|
||||
@@ -1640,11 +1647,11 @@ msgstr "GNOME al à di blocâ il visôr"
|
||||
#.
|
||||
#. XXX: another option is to kick the user into the gdm login
|
||||
#. screen, where we're not affected by grabs
|
||||
#: js/ui/screenShield.js:831 js/ui/screenShield.js:1303
|
||||
#: js/ui/screenShield.js:830 js/ui/screenShield.js:1301
|
||||
msgid "Unable to lock"
|
||||
msgstr "Impussibil blocâ"
|
||||
|
||||
#: js/ui/screenShield.js:832 js/ui/screenShield.js:1304
|
||||
#: js/ui/screenShield.js:831 js/ui/screenShield.js:1302
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Il bloc al è stât dineât di une aplicazion"
|
||||
|
||||
@@ -1680,24 +1687,24 @@ msgstr "Mostre Test"
|
||||
msgid "Hide Text"
|
||||
msgstr "Plate Test"
|
||||
|
||||
#: js/ui/shellEntry.js:161
|
||||
#: js/ui/shellEntry.js:162
|
||||
msgid "Caps lock is on."
|
||||
msgstr "BlocMaiusc al è atîf."
|
||||
|
||||
#: js/ui/shellMountOperation.js:308
|
||||
#: js/ui/shellMountOperation.js:305
|
||||
msgid "Hidden Volume"
|
||||
msgstr "Volum platât"
|
||||
|
||||
#: js/ui/shellMountOperation.js:311
|
||||
#: js/ui/shellMountOperation.js:308
|
||||
msgid "Windows System Volume"
|
||||
msgstr "Volum di sisteme Windows"
|
||||
|
||||
#: js/ui/shellMountOperation.js:314
|
||||
#: js/ui/shellMountOperation.js:311
|
||||
msgid "Uses Keyfiles"
|
||||
msgstr "Al dopre i File-clâf"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:320
|
||||
#: js/ui/shellMountOperation.js:317
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"To unlock a volume that uses keyfiles, use the <i>%s</i> utility instead."
|
||||
@@ -1705,36 +1712,36 @@ msgstr ""
|
||||
"Par sblocâ un volum che al dopre i file-clâf dopre invezit il program di "
|
||||
"utilitât <i>%s</i>."
|
||||
|
||||
#: js/ui/shellMountOperation.js:327
|
||||
#: js/ui/shellMountOperation.js:324
|
||||
msgid "PIM Number"
|
||||
msgstr "Numar PIM"
|
||||
|
||||
#: js/ui/shellMountOperation.js:346
|
||||
#: js/ui/shellMountOperation.js:343
|
||||
msgid "The PIM must be a number or empty."
|
||||
msgstr "Il PIM al scugne jessi un numar o vueit."
|
||||
|
||||
#: js/ui/shellMountOperation.js:357
|
||||
#: js/ui/shellMountOperation.js:354
|
||||
msgid "Password"
|
||||
msgstr "Password"
|
||||
|
||||
#: js/ui/shellMountOperation.js:393
|
||||
#: js/ui/shellMountOperation.js:390
|
||||
msgid "Remember Password"
|
||||
msgstr "Visâsi Password"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:417
|
||||
#: js/ui/shellMountOperation.js:414
|
||||
#, javascript-format
|
||||
msgid "Open %s"
|
||||
msgstr "Vierç %s"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:489
|
||||
#: js/ui/shellMountOperation.js:486
|
||||
#, javascript-format
|
||||
msgid "Unable to start %s"
|
||||
msgstr "Impussibil inviâ %s"
|
||||
|
||||
#. Translators: %s is the Disks application
|
||||
#: js/ui/shellMountOperation.js:491
|
||||
#: js/ui/shellMountOperation.js:488
|
||||
#, javascript-format
|
||||
msgid "Couldn’t find the %s application"
|
||||
msgstr "Impussibil cjatâ la aplicazion %s"
|
||||
@@ -1831,11 +1838,11 @@ msgstr "Clic secondari"
|
||||
msgid "Dwell Click"
|
||||
msgstr "Clic in polse"
|
||||
|
||||
#: js/ui/status/keyboard.js:818
|
||||
#: js/ui/status/keyboard.js:825
|
||||
msgid "Keyboard"
|
||||
msgstr "Tastiere"
|
||||
|
||||
#: js/ui/status/keyboard.js:840
|
||||
#: js/ui/status/keyboard.js:847
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "Mostre la disposizion de tastiere"
|
||||
|
||||
@@ -1864,12 +1871,12 @@ msgid "Enable"
|
||||
msgstr "Abilite"
|
||||
|
||||
#. Translators: %s is an application name
|
||||
#: js/ui/status/location.js:357
|
||||
#: js/ui/status/location.js:355
|
||||
#, javascript-format
|
||||
msgid "Give %s access to your location?"
|
||||
msgstr "Permeti a %s di cognossi la tô posizion?"
|
||||
|
||||
#: js/ui/status/location.js:358
|
||||
#: js/ui/status/location.js:361
|
||||
msgid "Location access can be changed at any time from the privacy settings."
|
||||
msgstr ""
|
||||
"L'acès ae posizion al pues jessi cambiât cuant che tu vuelis su impostazions "
|
||||
@@ -2250,11 +2257,11 @@ msgstr "Jentre come altri utent"
|
||||
msgid "Unlock Window"
|
||||
msgstr "Sbloche barcon"
|
||||
|
||||
#: js/ui/viewSelector.js:180
|
||||
#: js/ui/viewSelector.js:181
|
||||
msgid "Applications"
|
||||
msgstr "Aplicazions"
|
||||
|
||||
#: js/ui/viewSelector.js:184
|
||||
#: js/ui/viewSelector.js:185
|
||||
msgid "Search"
|
||||
msgstr "Cîr"
|
||||
|
||||
@@ -2263,22 +2270,22 @@ msgstr "Cîr"
|
||||
msgid "“%s” is ready"
|
||||
msgstr "“%s” al è pront"
|
||||
|
||||
#: js/ui/windowManager.js:57
|
||||
#: js/ui/windowManager.js:54
|
||||
msgid "Do you want to keep these display settings?"
|
||||
msgstr "Vûstu tignî chestis impostazions di visôr?"
|
||||
|
||||
#. Translators: this and the following message should be limited in length,
|
||||
#. to avoid ellipsizing the labels.
|
||||
#.
|
||||
#: js/ui/windowManager.js:71
|
||||
#: js/ui/windowManager.js:68
|
||||
msgid "Revert Settings"
|
||||
msgstr "Ripristine impostazions"
|
||||
|
||||
#: js/ui/windowManager.js:74
|
||||
#: js/ui/windowManager.js:71
|
||||
msgid "Keep Changes"
|
||||
msgstr "Ten lis modifichis"
|
||||
|
||||
#: js/ui/windowManager.js:92
|
||||
#: js/ui/windowManager.js:89
|
||||
#, javascript-format
|
||||
msgid "Settings changes will revert in %d second"
|
||||
msgid_plural "Settings changes will revert in %d seconds"
|
||||
@@ -2289,7 +2296,7 @@ msgstr[1] ""
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#: js/ui/windowManager.js:690
|
||||
#: js/ui/windowManager.js:546
|
||||
#, javascript-format
|
||||
msgid "%d × %d"
|
||||
msgstr "%d × %d"
|
||||
@@ -2378,12 +2385,12 @@ msgstr "Dopre une modalitât specifiche, par esempli “gdm” pe videade di ac
|
||||
msgid "List possible modes"
|
||||
msgstr "Liste modalitâts pussibilis"
|
||||
|
||||
#: src/shell-app.c:265
|
||||
#: src/shell-app.c:279
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "No cognossût"
|
||||
|
||||
#: src/shell-app.c:516
|
||||
#: src/shell-app.c:530
|
||||
#, c-format
|
||||
msgid "Failed to launch “%s”"
|
||||
msgstr "No soi rivât a eseguî '%s'"
|
||||
@@ -2743,6 +2750,9 @@ msgstr[1] "%u jentradis"
|
||||
msgid "System Sounds"
|
||||
msgstr "Suns di sisteme"
|
||||
|
||||
#~ msgid "Rename"
|
||||
#~ msgstr "Cambie non"
|
||||
|
||||
#~ msgid "Account Settings"
|
||||
#~ msgstr "Impostazions account"
|
||||
|
||||
|
1415
po/pt_BR.po
1415
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1422
po/zh_TW.po
1422
po/zh_TW.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