Compare commits
265 Commits
Author | SHA1 | Date | |
---|---|---|---|
58ed983b65 | |||
6f2fc9fe14 | |||
185f003363 | |||
6734746707 | |||
65b9369aaf | |||
e1e4ce7049 | |||
812aa10119 | |||
b0fa5e5696 | |||
c7a8c372a1 | |||
73b7d9ace4 | |||
45c2627d4d | |||
635bdea284 | |||
22131d99ad | |||
4e22388089 | |||
c526413119 | |||
1336b197d8 | |||
4b99415215 | |||
1ed107a2bf | |||
cad5e06041 | |||
65d93eacd3 | |||
8369dc6b64 | |||
a0c31478c0 | |||
647c8df12f | |||
6ab045b9ad | |||
2ebac8c186 | |||
06478f242a | |||
6557ae0a2b | |||
adbec80596 | |||
2369ef1296 | |||
ce0ea0434e | |||
ede6ec2a28 | |||
b4b19b551d | |||
dc295927ed | |||
539cbf3593 | |||
b477d215a8 | |||
5de85c708f | |||
ad80cc8950 | |||
bc3a506e68 | |||
92d740ba21 | |||
d65199d2ac | |||
257b99ebd1 | |||
c8be854365 | |||
436b764952 | |||
86063f15ed | |||
716f209537 | |||
7bba7fbf37 | |||
a102c99c07 | |||
5761db5981 | |||
5d33820bd6 | |||
301acc920d | |||
495f9cba72 | |||
726fc1d4f7 | |||
dd6452fe2a | |||
19aa57454b | |||
c9555a3537 | |||
6f473a4f29 | |||
f785f4ad02 | |||
35d0ba4454 | |||
c3428f1efa | |||
9cc1e6b85c | |||
74e1058183 | |||
7c9f76944b | |||
d393ca4f09 | |||
a786f0bcd2 | |||
199bc85bce | |||
d15b46f5cb | |||
c0861b1227 | |||
f97a3522e5 | |||
577e261d1a | |||
33fcff8a1a | |||
cd30572b70 | |||
bc711b6dec | |||
01f5065b87 | |||
9c2bf17ad7 | |||
5385b36a81 | |||
72ed9da1fc | |||
d79924bdd1 | |||
3b7a4b08e2 | |||
09af4433b0 | |||
50df3084f7 | |||
e90734913d | |||
af18a0cf40 | |||
3d399796a6 | |||
60a2794c8b | |||
e039871298 | |||
e057333bf3 | |||
e0c0d9223e | |||
ada21c975f | |||
b4df747464 | |||
9a38011e1e | |||
e0f1fc2694 | |||
da5390340e | |||
3a6b41495a | |||
ce5875f365 | |||
4373d390dc | |||
9ed512e5c5 | |||
c5856196a7 | |||
afc3a8a7e7 | |||
4714c73f0f | |||
742155c384 | |||
2d814bfc5e | |||
8f8e512b37 | |||
3c828c8387 | |||
7c96b39bef | |||
64dbc8aa7f | |||
5649b9c64a | |||
3d0aab3b66 | |||
ce419da6ec | |||
63b49c65ab | |||
ff5bd0b925 | |||
0892220f63 | |||
1c95c9e3ff | |||
4b80cbe1cd | |||
46f3712421 | |||
18aa4ff30c | |||
8a75143a6e | |||
384a6e8684 | |||
a0008f7471 | |||
b53f95a9a0 | |||
1af88e52dd | |||
535028c9a7 | |||
df816368a5 | |||
f34202c3c8 | |||
28c61754a1 | |||
6e46166df4 | |||
15feaa1074 | |||
d7c532daee | |||
427ec6834d | |||
e594b30ead | |||
f43a8a75e4 | |||
645aa01efd | |||
252dce1ec2 | |||
da0066eb84 | |||
adc811ff8f | |||
5117ccdeef | |||
19816523c7 | |||
846e3f8243 | |||
d3c050b88d | |||
f3d1c78c7d | |||
c4f2bb5fe0 | |||
fec511c786 | |||
8a6157c7c1 | |||
d3bb7903e2 | |||
239b67eff6 | |||
0e0caee6ba | |||
62606c68b9 | |||
da831e894c | |||
4b166dcc79 | |||
796fdca5c5 | |||
c6f22826cf | |||
4e491b6f75 | |||
0569bb18f5 | |||
0353ebde5d | |||
b5130c5943 | |||
d54db8ffb3 | |||
0ff5fc8dbb | |||
32ec9959ef | |||
838721fc31 | |||
63e9c98248 | |||
6df30cbb64 | |||
c102a89962 | |||
ff5e39ab79 | |||
607b2efcce | |||
27d010110a | |||
e13602b896 | |||
6777670f0d | |||
b05739fa7e | |||
38854fb06a | |||
b091cfea80 | |||
a8955ffe05 | |||
475fd72ae1 | |||
31675d1812 | |||
cbb0c1c091 | |||
c1234f7793 | |||
1e6c44cb6b | |||
2202b9330f | |||
0b332fc019 | |||
4f4163eb05 | |||
649d360289 | |||
9bcdd9c274 | |||
fbc60199bc | |||
785c813771 | |||
75f8279a19 | |||
5d07832e96 | |||
7395aaf9b4 | |||
2c070d38fb | |||
2c5bc4a1a9 | |||
fa82af251f | |||
e08f2a4a04 | |||
30e17036e8 | |||
c75785efff | |||
3bf89055e3 | |||
a76869216a | |||
a9fd8bfa5e | |||
02a7b0dcfd | |||
dd8c06f2c5 | |||
c63b7f0c3f | |||
a46ea3f8a0 | |||
93071d9167 | |||
2b2e9d4098 | |||
0429aad8bf | |||
2e74920a64 | |||
b5bf82b5db | |||
98cdd44543 | |||
304b68eff9 | |||
18074951b9 | |||
0008ef70e1 | |||
c3cdbd0dac | |||
aefd61c3db | |||
f7752ac699 | |||
d017e6749c | |||
ddfdfaed78 | |||
a870a4d6de | |||
e6e786a19c | |||
01975b61f5 | |||
3c61bef92d | |||
050f2090fb | |||
7746f1a5c4 | |||
97a1cdbe7a | |||
b1dcea7cf1 | |||
9f6f48025d | |||
5e66ac2674 | |||
93c66b3537 | |||
e0d7d28c20 | |||
a82c564a73 | |||
6a40e72329 | |||
3737a9950c | |||
7784bc0905 | |||
49607e1313 | |||
a81f18592a | |||
2ff988ef37 | |||
5136369c18 | |||
7557207b47 | |||
f9d1e2fec0 | |||
f9a03f212c | |||
d200fb1d14 | |||
eb844b095a | |||
dc638c04a6 | |||
b3cbce97ed | |||
14a32c128d | |||
2e332ffd12 | |||
71d9d483f2 | |||
1ef6262139 | |||
da7db509e7 | |||
2a525bd8e8 | |||
51da2bf363 | |||
d2c0ade880 | |||
bcc3eccdab | |||
e581e249ad | |||
c131c44ef6 | |||
cdd23d9cc7 | |||
dc110db4e0 | |||
678670bf1b | |||
07fc15a1eb | |||
83005e27da | |||
56b20ef779 | |||
04adeec8f5 | |||
62d640cd9e | |||
9d7ad6748c | |||
accd24e379 | |||
75d797a0ac | |||
e1e321d3a7 | |||
f14f238150 | |||
ab3200019a | |||
28c028f7ac |
140
NEWS
140
NEWS
@ -1,3 +1,143 @@
|
|||||||
|
3.24.2
|
||||||
|
======
|
||||||
|
* Only fetch weather information when there's a valid location [Rares; #780404]
|
||||||
|
* Handle extension errors during reload due to settings change [Emilio; #781728]
|
||||||
|
* Fix StEntry::primary-icon-clicked emission [Florian; #782190]
|
||||||
|
* Allow search providers to provide clipboard text for results [Daiki; #775099]
|
||||||
|
* Misc. bug fixes [Florian; #781545]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Florian Müllner, Emilio Pozuelo Monfort, Daiki Ueno, Rares Visalom
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Milo Casagrande [it], Милош Поповић [sr], Khaled Hosny [ar]
|
||||||
|
|
||||||
|
3.24.1
|
||||||
|
======
|
||||||
|
* Close Wifi selection dialog on lock [Florian; #780054]
|
||||||
|
* Fix DND over window previews in overview [Florian; #737166]
|
||||||
|
* Do not lock the screen when disabled by lockdown settings [Florian; #780212]
|
||||||
|
* Follow GNOME Weather's location permissions [Florian; #780252]
|
||||||
|
* Fix portals that require a new window to be loaded [Catalin; #759044]
|
||||||
|
* Fix restricting menus to screen height on HiDPI displays [Cosimo; #753305]
|
||||||
|
* Misc. bug fixes and cleanups [Florian, Cosimo, Bastien, Catalin, Carlos;
|
||||||
|
#780063, #780321, #780381, #780453, #758873, #780606, #642652]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Cosimo Cecchi, Carlos Garnacho, Catalin Iacob, Florian Müllner, Bastien Nocera
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Marek Cernocky [cs], Piotr Drąg [pl], Anders Jonsson [sv], Stas Solovey [ru],
|
||||||
|
Rafael Fontenelle [pt_BR], Baurzhan Muftakhidinov [kk], Daniel Korostil [uk],
|
||||||
|
Kukuh Syafaat [id], Milo Casagrande [it], Jiri Grönroos [fi],
|
||||||
|
Daniel Mustieles [es], Balázs Úr [hu], Guillaume Bernard [fr],
|
||||||
|
Changwoo Ryu [ko], Mario Blättermann [de], Fran Dieguez [gl],
|
||||||
|
Dušan Kazik [sk], Yuras Shumovich [be], Fabio Tomat [fur],
|
||||||
|
Kjartan Maraas [nb], Aurimas Černius [lt], Trần Ngọc Quân [vi],
|
||||||
|
Rūdolfs Mazurs [lv], Ask Hjorth Larsen [da], Tom Tryfonidis [el], gogo [hr]
|
||||||
|
|
||||||
|
3.24.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
GNOME Translation Robot [tg], Мирослав Николић [sr, sr@latin],
|
||||||
|
Guillaume Bernard [fr], Rūdolfs Mazurs [lv], Emin Tufan Çetin [tr],
|
||||||
|
sujiniku [ja], Daniel Korostil [uk]
|
||||||
|
|
||||||
|
3.23.92
|
||||||
|
=======
|
||||||
|
* Implement DND to overview on wayland [Hyungwon; #765003]
|
||||||
|
* Make telepathy optional at runtime [Florian; #771721, #779878]
|
||||||
|
* Don't show forecasts for NYC when geoclue gets stuck [Sebastian; #779898]
|
||||||
|
* Add bottom edge drag gesture to bring up the OSK [Jan-Michael; #757712]
|
||||||
|
* Allow switching between pads in the same group [Carlos; #779986]
|
||||||
|
* Ignore showBanners policy for critical notifications [Florian; #779974]
|
||||||
|
* Misc. bug fixes [Florian; #779435, #779819, #779820]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jan-Michael Brummer, Allan Day, Carlos Garnacho, Hyungwon Hwang,
|
||||||
|
Sebastian Keller, Florian Müllner
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Enrico Nicoletto [pt_BR], Jiri Grönroos [fi], Chao-Hsiung Liao [zh_TW],
|
||||||
|
Piotr Drąg [pl], Piotr Drąg [he], Balázs Meskó [hu], Kris Thomsen [da],
|
||||||
|
Yuras Shumovich [be], Sveinn í Felli [is], Inaki Larranaga Murgoitio [eu],
|
||||||
|
Changwoo Ryu [ko], Jordi Mas [ca], Aurimas Černius [lt],
|
||||||
|
Мирослав Николић [sr, sr@latin], Christian Kirbach [de], Anders Jonsson [sv],
|
||||||
|
Fabio Tomat [fur], GNOME Translation Robot [gd], Dušan Kazik [sk],
|
||||||
|
Kukuh Syafaat [id], Marek Černocký [cs], Stas Solovey [ru],
|
||||||
|
Milo Casagrande [it], Fran Dieguez [gl], Daniel Boles [gl], A S Alam [pa],
|
||||||
|
Daniel Mustieles [es]
|
||||||
|
|
||||||
|
3.23.91
|
||||||
|
=======
|
||||||
|
* Use the original timestamps for restored notifications [Florian; #766410]
|
||||||
|
* Add weather information to date+time drop-down [Florian; #754031]
|
||||||
|
* Refine message list layout in date+time drop-down [Florian; #775763]
|
||||||
|
* Make next/prev media controls insensitive when unavailable [Florian; #773884]
|
||||||
|
* Misc. bug fixes [Piotr, Bastien, Florian; #772210, #769546, #775799]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Piotr Drąg, Carlos Garnacho, Florian Müllner, Bastien Nocera
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Baurzhan Muftakhidinov [kk], Jordi Mas [ca], Ask Hjorth Larsen [da],
|
||||||
|
Inaki Larranaga Murgoitio [eu], Daniel Mustieles [es], Dušan Kazik [sk],
|
||||||
|
Aurimas Černius [lt], Jiri Grönroos [fi], Kjartan Maraas [nb],
|
||||||
|
Piotr Drąg [pl], Daniel Korostil [uk], Kukuh Syafaat [id],
|
||||||
|
Milo Casagrande [it], Fabio Tomat [fur], Rafael Fontenelle [pt_BR],
|
||||||
|
Fran Dieguez [gl], Мирослав Николић [sr, sr@latin], Balázs Meskó [hu],
|
||||||
|
Chao-Hsiung Liao [zh_TW]
|
||||||
|
|
||||||
|
3.23.90
|
||||||
|
=======
|
||||||
|
* Handle Ctrl+Q and Ctrl+W in portal window [Bastien; #764133]
|
||||||
|
* Allow to scroll through ibus candidates with mouse [Peng; #776032]
|
||||||
|
* Reload apps on .desktop file content changes [Adrian; #773636]
|
||||||
|
* Use private data/cache directories in portal helper [Bastien; #775639]
|
||||||
|
* Fix subsurfaces not showing up in previews [Rui; #756715]
|
||||||
|
* Fix theme node transitions [Florian; #778145]
|
||||||
|
* Update pad (o)leds on mode switches [Carlos; #776543]
|
||||||
|
* Add security indicators to defend against malicious portals [Bastien; #749197]
|
||||||
|
* Don't allow type ahead at the login screen [Ray; #766139]
|
||||||
|
* Don't fail to load because of TLS errors [Bastien; #778253]
|
||||||
|
* Ensure the network lists remains sorted on rename [Benjamin; #778686]
|
||||||
|
* Toggle power-off/suspend button on long-press [Florian; #721173]
|
||||||
|
* Add "kill-switch" for user extensions [Florian; #778664]
|
||||||
|
* Add night light indicator to status area [Florian; #741224]
|
||||||
|
* Misc. bug fixes [Michael, Bastien, Carlos, Rui, Florian, Alan, Philip, Jonas;
|
||||||
|
#759793, #735233, #762444, #777784, #777934, #778158, #776199, #778425,
|
||||||
|
#771098, #778552, #777317, #778660, #778661, #745626, #778672]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jonas Ådahl, Benjamin Berg, Michael Catanzaro, Philip Chimento,
|
||||||
|
Alan Coopersmith, Piotr Drąg, Carlos Garnacho, Yuri Konotopov,
|
||||||
|
Lionel Landwerlin, Rui Matos, Florian Müllner, Bastien Nocera,
|
||||||
|
Adrian Perez de Castro, Robert Roth, Ray Strode, Peng Wu
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Jiri Grönroos [fi], Balázs Meskó [hu], Gábor Kelemen [hu],
|
||||||
|
Daniel Mustieles [es], Dušan Kazik [sk],
|
||||||
|
Piotr Drąg [ar, eu, fa, hr, pa, pt, sr, sr@latin], Rafael Fontenelle [pt_BR],
|
||||||
|
Jordi Mas [ca], Piotr Drąg [pl], Alexandre Franke [fr],
|
||||||
|
Baurzhan Muftakhidinov [kk], Yuras Shumovich [be], Mandy Wang [zh_CN],
|
||||||
|
Marek Černocký [cs], Kukuh Syafaat [id], Kjartan Maraas [nb],
|
||||||
|
Daniel Korostil [uk]
|
||||||
|
|
||||||
|
3.23.3
|
||||||
|
======
|
||||||
|
* Fix replacing of GNotifications [Florian; #775149]
|
||||||
|
* Prepare for mozjs31 GJS [Philip; #775374]
|
||||||
|
* Misc. bug fixes [Niels, Jonas; #775507, #776130]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jonas Ådahl, Michael Catanzaro, Philip Chimento, Niels De Graef,
|
||||||
|
Carlos Garnacho, Florian Müllner
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Muhammet Kara [tr], Christian Kirbach [de], Baurzhan Muftakhidinov [kk],
|
||||||
|
Cheng-Chia Tseng [zh_TW], A S Alam [pa], Gianvito Cavasoli [it]
|
||||||
|
|
||||||
3.23.2
|
3.23.2
|
||||||
======
|
======
|
||||||
* Implement Pad configuration OSD [Carlos; #771067]
|
* Implement Pad configuration OSD [Carlos; #771067]
|
||||||
|
22
autogen.sh
22
autogen.sh
@ -4,15 +4,15 @@
|
|||||||
srcdir=`dirname $0`
|
srcdir=`dirname $0`
|
||||||
test -z "$srcdir" && srcdir=.
|
test -z "$srcdir" && srcdir=.
|
||||||
|
|
||||||
(test -f $srcdir/configure.ac \
|
pushd $srcdir
|
||||||
&& test -d $srcdir/src) || {
|
|
||||||
|
(test -f configure.ac \
|
||||||
|
&& test -d src) || {
|
||||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||||
echo " top-level gnome-shell directory"
|
echo " top-level gnome-shell directory"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pushd $srcdir
|
|
||||||
|
|
||||||
# Fetch submodules if needed
|
# Fetch submodules if needed
|
||||||
if test ! -f src/gvc/Makefile.am || test ! -f data/theme/gnome-shell-sass/COPYING;
|
if test ! -f src/gvc/Makefile.am || test ! -f data/theme/gnome-shell-sass/COPYING;
|
||||||
then
|
then
|
||||||
@ -21,11 +21,13 @@ then
|
|||||||
fi
|
fi
|
||||||
git submodule update
|
git submodule update
|
||||||
|
|
||||||
|
aclocal --install || exit 1
|
||||||
|
gtkdocize --copy || exit 1
|
||||||
|
intltoolize --force --copy --automake || exit 1
|
||||||
|
autoreconf --verbose --force --install || exit 1
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
which gnome-autogen.sh || {
|
if [ "$NOCONFIGURE" = "" ]; then
|
||||||
echo "You need to install gnome-common from GNOME Git (or from"
|
$srcdir/configure "$@" || exit 1
|
||||||
echo "your OS vendor's package manager)."
|
fi
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
. gnome-autogen.sh
|
|
||||||
|
35
configure.ac
35
configure.ac
@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.23.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.24.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
AX_IS_RELEASE([git-directory])
|
AX_IS_RELEASE([git-directory])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
@ -17,7 +17,6 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
|||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AC_PROG_CXX
|
|
||||||
|
|
||||||
# Initialize libtool
|
# Initialize libtool
|
||||||
LT_PREREQ([2.2.6])
|
LT_PREREQ([2.2.6])
|
||||||
@ -42,6 +41,15 @@ GLIB_GSETTINGS
|
|||||||
AM_PATH_PYTHON([3])
|
AM_PATH_PYTHON([3])
|
||||||
AC_SUBST(PYTHON)
|
AC_SUBST(PYTHON)
|
||||||
|
|
||||||
|
# We depend on a specific version of the libmutter API. The mutter variants of
|
||||||
|
# the Cogl and Clutter libraries also use this API version.
|
||||||
|
LIBMUTTER_API_VERSION=0
|
||||||
|
|
||||||
|
LIBMUTTER=libmutter-$LIBMUTTER_API_VERSION
|
||||||
|
LIBMUTTER_COGL=mutter-cogl-$LIBMUTTER_API_VERSION
|
||||||
|
LIBMUTTER_COGL_PANGO=mutter-cogl-pango-$LIBMUTTER_API_VERSION
|
||||||
|
LIBMUTTER_CLUTTER=mutter-clutter-$LIBMUTTER_API_VERSION
|
||||||
|
|
||||||
# We need at least this, since gst_plugin_register_static() was added
|
# We need at least this, since gst_plugin_register_static() was added
|
||||||
# in 0.10.16, but nothing older than 0.10.21 has been tested.
|
# in 0.10.16, but nothing older than 0.10.21 has been tested.
|
||||||
GSTREAMER_MIN_VERSION=0.11.92
|
GSTREAMER_MIN_VERSION=0.11.92
|
||||||
@ -53,7 +61,7 @@ if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then
|
|||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
build_recorder=true
|
build_recorder=true
|
||||||
recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11 gtk+-3.0"
|
recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11 gtk+-3.0"
|
||||||
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules mutter-clutter-1.0)
|
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules $LIBMUTTER_CLUTTER)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
@ -75,15 +83,13 @@ AS_IF([test x$enable_systemd != xno], [
|
|||||||
|
|
||||||
AC_MSG_RESULT($enable_systemd)
|
AC_MSG_RESULT($enable_systemd)
|
||||||
|
|
||||||
CLUTTER_MIN_VERSION=1.21.5
|
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1
|
||||||
GJS_MIN_VERSION=1.47.0
|
GJS_MIN_VERSION=1.47.0
|
||||||
MUTTER_MIN_VERSION=3.23.2
|
MUTTER_MIN_VERSION=3.24.0
|
||||||
GTK_MIN_VERSION=3.15.0
|
GTK_MIN_VERSION=3.15.0
|
||||||
GIO_MIN_VERSION=2.45.3
|
GIO_MIN_VERSION=2.45.3
|
||||||
LIBECAL_MIN_VERSION=3.5.3
|
LIBECAL_MIN_VERSION=3.5.3
|
||||||
LIBEDATASERVER_MIN_VERSION=3.17.2
|
LIBEDATASERVER_MIN_VERSION=3.17.2
|
||||||
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
|
||||||
POLKIT_MIN_VERSION=0.100
|
POLKIT_MIN_VERSION=0.100
|
||||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||||
GCR_MIN_VERSION=3.7.5
|
GCR_MIN_VERSION=3.7.5
|
||||||
@ -99,12 +105,11 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
|
|||||||
gjs-1.0 >= $GJS_MIN_VERSION
|
gjs-1.0 >= $GJS_MIN_VERSION
|
||||||
$recorder_modules
|
$recorder_modules
|
||||||
gdk-x11-3.0 libsoup-2.4
|
gdk-x11-3.0 libsoup-2.4
|
||||||
mutter-clutter-1.0 >= $CLUTTER_MIN_VERSION
|
$LIBMUTTER_CLUTTER >= $MUTTER_MIN_VERSION
|
||||||
mutter-cogl-pango-1.0
|
$LIBMUTTER_COGL_PANGO
|
||||||
libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION
|
libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION
|
||||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
||||||
libcanberra libcanberra-gtk3
|
libcanberra libcanberra-gtk3
|
||||||
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
|
||||||
polkit-agent-1 >= $POLKIT_MIN_VERSION
|
polkit-agent-1 >= $POLKIT_MIN_VERSION
|
||||||
gcr-base-3 >= $GCR_MIN_VERSION"
|
gcr-base-3 >= $GCR_MIN_VERSION"
|
||||||
if test x$have_systemd = xyes; then
|
if test x$have_systemd = xyes; then
|
||||||
@ -112,16 +117,18 @@ if test x$have_systemd = xyes; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS)
|
PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS)
|
||||||
PKG_CHECK_MODULES(MUTTER, libmutter >= $MUTTER_MIN_VERSION)
|
PKG_CHECK_MODULES(MUTTER, $LIBMUTTER >= $MUTTER_MIN_VERSION)
|
||||||
|
|
||||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-1.0 >= $GJS_MIN_VERSION)
|
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-1.0 >= $GJS_MIN_VERSION)
|
||||||
PKG_CHECK_MODULES(ST, mutter-clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
PKG_CHECK_MODULES(ST, $LIBMUTTER_CLUTTER gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
||||||
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||||
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
||||||
PKG_CHECK_MODULES(TRAY, mutter-clutter-1.0 gtk+-3.0)
|
PKG_CHECK_MODULES(TRAY, $LIBMUTTER_CLUTTER gtk+-3.0)
|
||||||
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
|
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
|
||||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.21.3)
|
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.21.3)
|
||||||
|
|
||||||
|
AC_SUBST(LIBMUTTER_API_VERSION)
|
||||||
|
|
||||||
AC_ARG_ENABLE(browser-plugin,
|
AC_ARG_ENABLE(browser-plugin,
|
||||||
[AS_HELP_STRING([--enable-browser-plugin],
|
[AS_HELP_STRING([--enable-browser-plugin],
|
||||||
[Enable browser plugin [default=yes]])],,
|
[Enable browser plugin [default=yes]])],,
|
||||||
@ -146,10 +153,10 @@ AC_SUBST([GNOME_KEYBINDINGS_KEYSDIR])
|
|||||||
|
|
||||||
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
||||||
|
|
||||||
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter`
|
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir $LIBMUTTER`
|
||||||
AC_SUBST(MUTTER_GIR_DIR)
|
AC_SUBST(MUTTER_GIR_DIR)
|
||||||
|
|
||||||
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter`
|
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir $LIBMUTTER`
|
||||||
AC_SUBST(MUTTER_TYPELIB_DIR)
|
AC_SUBST(MUTTER_TYPELIB_DIR)
|
||||||
|
|
||||||
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=GNOME Shell Extension Preferences
|
Name=Shell Extensions
|
||||||
Comment=Configure GNOME Shell Extensions
|
Comment=Configure GNOME Shell Extensions
|
||||||
Exec=@bindir@/gnome-shell-extension-prefs %u
|
Exec=@bindir@/gnome-shell-extension-prefs %u
|
||||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||||
|
@ -21,6 +21,14 @@
|
|||||||
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
|
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
|
||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="disable-user-extensions" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Disable user extensions</summary>
|
||||||
|
<description>
|
||||||
|
Disable all extensions the user has enabled without affecting
|
||||||
|
the “enabled-extension” setting.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
<key name="disable-extension-version-validation" type="b">
|
<key name="disable-extension-version-validation" type="b">
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
<summary>Disables the validation of extension version compatibility</summary>
|
<summary>Disables the validation of extension version compatibility</summary>
|
||||||
@ -56,9 +64,9 @@
|
|||||||
</key>
|
</key>
|
||||||
<key name="always-show-log-out" type="b">
|
<key name="always-show-log-out" type="b">
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
<summary>Always show the 'Log out' menu item in the user menu.</summary>
|
<summary>Always show the “Log out” menu item in the user menu.</summary>
|
||||||
<description>
|
<description>
|
||||||
This key overrides the automatic hiding of the 'Log out'
|
This key overrides the automatic hiding of the “Log out”
|
||||||
menu item in single-user, single-session situations.
|
menu item in single-user, single-session situations.
|
||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
@ -68,7 +76,7 @@
|
|||||||
<description>
|
<description>
|
||||||
The shell will request a password when an encrypted device or a
|
The shell will request a password when an encrypted device or a
|
||||||
remote filesystem is mounted. If the password can be saved for
|
remote filesystem is mounted. If the password can be saved for
|
||||||
future use a 'Remember Password' checkbox will be present.
|
future use a “Remember Password” checkbox will be present.
|
||||||
This key sets the default state of the checkbox.
|
This key sets the default state of the checkbox.
|
||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
@ -97,9 +105,9 @@
|
|||||||
</key>
|
</key>
|
||||||
<key name="toggle-application-view" type="as">
|
<key name="toggle-application-view" type="as">
|
||||||
<default>["<Super>a"]</default>
|
<default>["<Super>a"]</default>
|
||||||
<summary>Keybinding to open the "Show Applications" view</summary>
|
<summary>Keybinding to open the “Show Applications” view</summary>
|
||||||
<description>
|
<description>
|
||||||
Keybinding to open the "Show Applications" view of the Activities
|
Keybinding to open the “Show Applications” view of the Activities
|
||||||
Overview.
|
Overview.
|
||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
@ -168,8 +176,8 @@
|
|||||||
<summary>The application icon mode.</summary>
|
<summary>The application icon mode.</summary>
|
||||||
<description>
|
<description>
|
||||||
Configures how the windows are shown in the switcher. Valid possibilities
|
Configures how the windows are shown in the switcher. Valid possibilities
|
||||||
are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-only'
|
are “thumbnail-only” (shows a thumbnail of the window), “app-icon-only”
|
||||||
(shows only the application icon) or 'both'.
|
(shows only the application icon) or “both”.
|
||||||
</description>
|
</description>
|
||||||
</key>
|
</key>
|
||||||
<key type="b" name="current-workspace-only">
|
<key type="b" name="current-workspace-only">
|
||||||
|
@ -566,6 +566,10 @@ StScrollBar {
|
|||||||
.pad-osd-window {
|
.pad-osd-window {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
background-color: rgba(0, 0, 0, 0.8); }
|
background-color: rgba(0, 0, 0, 0.8); }
|
||||||
|
.pad-osd-window .pad-osd-title-box {
|
||||||
|
spacing: 12px; }
|
||||||
|
.pad-osd-window .pad-osd-title-menu-box {
|
||||||
|
spacing: 6px; }
|
||||||
|
|
||||||
.combo-box-label {
|
.combo-box-label {
|
||||||
width: 15em; }
|
width: 15em; }
|
||||||
@ -734,9 +738,20 @@ StScrollBar {
|
|||||||
.datemenu-displays-section {
|
.datemenu-displays-section {
|
||||||
padding-bottom: 3em; }
|
padding-bottom: 3em; }
|
||||||
|
|
||||||
|
.datemenu-displays-box {
|
||||||
|
spacing: 1em; }
|
||||||
|
|
||||||
|
.datemenu-calendar-column {
|
||||||
|
border: 0 solid #0d0d0d; }
|
||||||
|
.datemenu-calendar-column:ltr {
|
||||||
|
border-left-width: 1px; }
|
||||||
|
.datemenu-calendar-column:rtl {
|
||||||
|
border-right-width: 1px; }
|
||||||
|
|
||||||
.datemenu-today-button,
|
.datemenu-today-button,
|
||||||
.world-clocks-button,
|
.world-clocks-button,
|
||||||
.message-list-section-title {
|
.weather-button,
|
||||||
|
.events-section-title {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: .4em; }
|
padding: .4em; }
|
||||||
|
|
||||||
@ -749,12 +764,15 @@ StScrollBar {
|
|||||||
.datemenu-today-button:hover, .datemenu-today-button:focus,
|
.datemenu-today-button:hover, .datemenu-today-button:focus,
|
||||||
.world-clocks-button:hover,
|
.world-clocks-button:hover,
|
||||||
.world-clocks-button:focus,
|
.world-clocks-button:focus,
|
||||||
.message-list-section-title:hover,
|
.weather-button:hover,
|
||||||
.message-list-section-title:focus {
|
.weather-button:focus,
|
||||||
|
.events-section-title:hover,
|
||||||
|
.events-section-title:focus {
|
||||||
background-color: #0d0d0d; }
|
background-color: #0d0d0d; }
|
||||||
.datemenu-today-button:active,
|
.datemenu-today-button:active,
|
||||||
.world-clocks-button:active,
|
.world-clocks-button:active,
|
||||||
.message-list-section-title:active {
|
.weather-button:active,
|
||||||
|
.events-section-title:active {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #215d9c; }
|
background-color: #215d9c; }
|
||||||
|
|
||||||
@ -762,13 +780,17 @@ StScrollBar {
|
|||||||
font-size: 1.5em; }
|
font-size: 1.5em; }
|
||||||
|
|
||||||
.world-clocks-header,
|
.world-clocks-header,
|
||||||
.message-list-section-title {
|
.weather-header,
|
||||||
|
.events-section-title {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
|
|
||||||
.world-clocks-grid {
|
.world-clocks-grid {
|
||||||
spacing-rows: 0.4em; }
|
spacing-rows: 0.4em; }
|
||||||
|
|
||||||
|
.weather-box {
|
||||||
|
spacing: 0.4em; }
|
||||||
|
|
||||||
.calendar-month-label {
|
.calendar-month-label {
|
||||||
color: #f2f2f2;
|
color: #f2f2f2;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -853,69 +875,68 @@ StScrollBar {
|
|||||||
.message-list {
|
.message-list {
|
||||||
width: 31.5em; }
|
width: 31.5em; }
|
||||||
|
|
||||||
|
.message-list-clear-button.button {
|
||||||
|
background-color: transparent;
|
||||||
|
margin: 1.5em 1.5em 0; }
|
||||||
|
.message-list-clear-button.button:hover, .message-list-clear-button.button:focus {
|
||||||
|
background-color: #0d0d0d; }
|
||||||
|
|
||||||
.message-list-sections {
|
.message-list-sections {
|
||||||
spacing: 1.5em; }
|
spacing: 1em; }
|
||||||
|
|
||||||
.message-list-section,
|
.message-list-section,
|
||||||
.message-list-section-list {
|
.message-list-section-list {
|
||||||
spacing: 0.7em; }
|
|
||||||
|
|
||||||
.message-list-section-title-box {
|
|
||||||
spacing: 0.4em; }
|
spacing: 0.4em; }
|
||||||
|
|
||||||
.message-list-section-close > StIcon {
|
|
||||||
icon-size: 16px;
|
|
||||||
border-radius: 8px;
|
|
||||||
color: #000;
|
|
||||||
background-color: #666666; }
|
|
||||||
|
|
||||||
/* FIXME: how do you do this in sass? */
|
|
||||||
.message-list-section-close:hover > StIcon,
|
|
||||||
.message-list-section-close:focus > StIcon {
|
|
||||||
background-color: #999999; }
|
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
background-color: #0d0d0d;
|
|
||||||
border-radius: 3px; }
|
border-radius: 3px; }
|
||||||
.message:hover, .message:focus {
|
.message:hover, .message:focus {
|
||||||
background-color: #262626; }
|
background-color: #0d0d0d; }
|
||||||
|
|
||||||
.message-icon-bin {
|
.message-icon-bin {
|
||||||
padding: 8px 0px 8px 8px; }
|
padding: 10px 3px 10px 10px; }
|
||||||
.message-icon-bin:rtl {
|
.message-icon-bin:rtl {
|
||||||
padding: 8px 8px 8px 0px; }
|
padding: 10px 10px 10px 3px; }
|
||||||
|
|
||||||
.message-icon-bin > StIcon {
|
.message-icon-bin > StIcon {
|
||||||
icon-size: 32px; }
|
color: #cccccc;
|
||||||
|
icon-size: 16px;
|
||||||
.message-secondary-bin:ltr {
|
-st-icon-style: symbolic; }
|
||||||
padding-left: 8px; }
|
|
||||||
.message-secondary-bin:rtl {
|
|
||||||
padding-right: 8px; }
|
|
||||||
|
|
||||||
.message-secondary-bin {
|
.message-secondary-bin {
|
||||||
color: #999999; }
|
padding: 0 12px; }
|
||||||
|
|
||||||
|
.message-secondary-bin > .event-time {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 0.7em;
|
||||||
|
/* HACK: the label should be baseline-aligned with a 1em label,
|
||||||
|
fake this with some bottom padding */
|
||||||
|
padding-bottom: 0.13em; }
|
||||||
|
|
||||||
.message-secondary-bin > StIcon {
|
.message-secondary-bin > StIcon {
|
||||||
icon-size: 16px; }
|
icon-size: 16px; }
|
||||||
|
|
||||||
.message-title {
|
.message-title {
|
||||||
font-weight: bold;
|
color: #f2f2f2; }
|
||||||
font-size: 1.1em; }
|
|
||||||
|
|
||||||
.message-content {
|
.message-content {
|
||||||
padding: 8px;
|
color: #cccccc;
|
||||||
font-size: .9em; }
|
padding: 10px; }
|
||||||
|
|
||||||
.message-media-control {
|
.message-media-control {
|
||||||
padding: 6px; }
|
padding: 12px;
|
||||||
|
color: #cccccc; }
|
||||||
.message-media-control:last-child:ltr {
|
.message-media-control:last-child:ltr {
|
||||||
padding-right: 18px; }
|
padding-right: 18px; }
|
||||||
.message-media-control:last-child:rtl {
|
.message-media-control:last-child:rtl {
|
||||||
padding-left: 18px; }
|
padding-left: 18px; }
|
||||||
|
.message-media-control:hover {
|
||||||
|
color: #fff; }
|
||||||
|
.message-media-control:insensitive {
|
||||||
|
color: #999999; }
|
||||||
|
|
||||||
.media-message-cover-icon {
|
.media-message-cover-icon {
|
||||||
icon-size: 32px; }
|
icon-size: 48px !important; }
|
||||||
.media-message-cover-icon.fallback {
|
.media-message-cover-icon.fallback {
|
||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
Submodule data/theme/gnome-shell-sass updated: 50bbd0b50f...e94bce1fcf
@ -566,6 +566,10 @@ StScrollBar {
|
|||||||
.pad-osd-window {
|
.pad-osd-window {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
background-color: rgba(0, 0, 0, 0.8); }
|
background-color: rgba(0, 0, 0, 0.8); }
|
||||||
|
.pad-osd-window .pad-osd-title-box {
|
||||||
|
spacing: 12px; }
|
||||||
|
.pad-osd-window .pad-osd-title-menu-box {
|
||||||
|
spacing: 6px; }
|
||||||
|
|
||||||
.combo-box-label {
|
.combo-box-label {
|
||||||
width: 15em; }
|
width: 15em; }
|
||||||
@ -734,9 +738,20 @@ StScrollBar {
|
|||||||
.datemenu-displays-section {
|
.datemenu-displays-section {
|
||||||
padding-bottom: 3em; }
|
padding-bottom: 3em; }
|
||||||
|
|
||||||
|
.datemenu-displays-box {
|
||||||
|
spacing: 1em; }
|
||||||
|
|
||||||
|
.datemenu-calendar-column {
|
||||||
|
border: 0 solid #454c4c; }
|
||||||
|
.datemenu-calendar-column:ltr {
|
||||||
|
border-left-width: 1px; }
|
||||||
|
.datemenu-calendar-column:rtl {
|
||||||
|
border-right-width: 1px; }
|
||||||
|
|
||||||
.datemenu-today-button,
|
.datemenu-today-button,
|
||||||
.world-clocks-button,
|
.world-clocks-button,
|
||||||
.message-list-section-title {
|
.weather-button,
|
||||||
|
.events-section-title {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: .4em; }
|
padding: .4em; }
|
||||||
|
|
||||||
@ -749,12 +764,15 @@ StScrollBar {
|
|||||||
.datemenu-today-button:hover, .datemenu-today-button:focus,
|
.datemenu-today-button:hover, .datemenu-today-button:focus,
|
||||||
.world-clocks-button:hover,
|
.world-clocks-button:hover,
|
||||||
.world-clocks-button:focus,
|
.world-clocks-button:focus,
|
||||||
.message-list-section-title:hover,
|
.weather-button:hover,
|
||||||
.message-list-section-title:focus {
|
.weather-button:focus,
|
||||||
|
.events-section-title:hover,
|
||||||
|
.events-section-title:focus {
|
||||||
background-color: #454c4c; }
|
background-color: #454c4c; }
|
||||||
.datemenu-today-button:active,
|
.datemenu-today-button:active,
|
||||||
.world-clocks-button:active,
|
.world-clocks-button:active,
|
||||||
.message-list-section-title:active {
|
.weather-button:active,
|
||||||
|
.events-section-title:active {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #215d9c; }
|
background-color: #215d9c; }
|
||||||
|
|
||||||
@ -762,13 +780,17 @@ StScrollBar {
|
|||||||
font-size: 1.5em; }
|
font-size: 1.5em; }
|
||||||
|
|
||||||
.world-clocks-header,
|
.world-clocks-header,
|
||||||
.message-list-section-title {
|
.weather-header,
|
||||||
|
.events-section-title {
|
||||||
color: #8e8e80;
|
color: #8e8e80;
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
|
|
||||||
.world-clocks-grid {
|
.world-clocks-grid {
|
||||||
spacing-rows: 0.4em; }
|
spacing-rows: 0.4em; }
|
||||||
|
|
||||||
|
.weather-box {
|
||||||
|
spacing: 0.4em; }
|
||||||
|
|
||||||
.calendar-month-label {
|
.calendar-month-label {
|
||||||
color: #e2e2df;
|
color: #e2e2df;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -853,69 +875,68 @@ StScrollBar {
|
|||||||
.message-list {
|
.message-list {
|
||||||
width: 31.5em; }
|
width: 31.5em; }
|
||||||
|
|
||||||
|
.message-list-clear-button.button {
|
||||||
|
background-color: transparent;
|
||||||
|
margin: 1.5em 1.5em 0; }
|
||||||
|
.message-list-clear-button.button:hover, .message-list-clear-button.button:focus {
|
||||||
|
background-color: #454c4c; }
|
||||||
|
|
||||||
.message-list-sections {
|
.message-list-sections {
|
||||||
spacing: 1.5em; }
|
spacing: 1em; }
|
||||||
|
|
||||||
.message-list-section,
|
.message-list-section,
|
||||||
.message-list-section-list {
|
.message-list-section-list {
|
||||||
spacing: 0.7em; }
|
|
||||||
|
|
||||||
.message-list-section-title-box {
|
|
||||||
spacing: 0.4em; }
|
spacing: 0.4em; }
|
||||||
|
|
||||||
.message-list-section-close > StIcon {
|
|
||||||
icon-size: 16px;
|
|
||||||
border-radius: 8px;
|
|
||||||
color: #393f3f;
|
|
||||||
background-color: #59594f; }
|
|
||||||
|
|
||||||
/* FIXME: how do you do this in sass? */
|
|
||||||
.message-list-section-close:hover > StIcon,
|
|
||||||
.message-list-section-close:focus > StIcon {
|
|
||||||
background-color: #8e8e80; }
|
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
background-color: #454c4c;
|
|
||||||
border-radius: 3px; }
|
border-radius: 3px; }
|
||||||
.message:hover, .message:focus {
|
.message:hover, .message:focus {
|
||||||
background-color: #5d6767; }
|
background-color: #454c4c; }
|
||||||
|
|
||||||
.message-icon-bin {
|
.message-icon-bin {
|
||||||
padding: 8px 0px 8px 8px; }
|
padding: 10px 3px 10px 10px; }
|
||||||
.message-icon-bin:rtl {
|
.message-icon-bin:rtl {
|
||||||
padding: 8px 8px 8px 0px; }
|
padding: 10px 10px 10px 3px; }
|
||||||
|
|
||||||
.message-icon-bin > StIcon {
|
.message-icon-bin > StIcon {
|
||||||
icon-size: 32px; }
|
color: #bebeb6;
|
||||||
|
icon-size: 16px;
|
||||||
.message-secondary-bin:ltr {
|
-st-icon-style: symbolic; }
|
||||||
padding-left: 8px; }
|
|
||||||
.message-secondary-bin:rtl {
|
|
||||||
padding-right: 8px; }
|
|
||||||
|
|
||||||
.message-secondary-bin {
|
.message-secondary-bin {
|
||||||
color: #8e8e80; }
|
padding: 0 12px; }
|
||||||
|
|
||||||
|
.message-secondary-bin > .event-time {
|
||||||
|
color: #8e8e80;
|
||||||
|
font-size: 0.7em;
|
||||||
|
/* HACK: the label should be baseline-aligned with a 1em label,
|
||||||
|
fake this with some bottom padding */
|
||||||
|
padding-bottom: 0.13em; }
|
||||||
|
|
||||||
.message-secondary-bin > StIcon {
|
.message-secondary-bin > StIcon {
|
||||||
icon-size: 16px; }
|
icon-size: 16px; }
|
||||||
|
|
||||||
.message-title {
|
.message-title {
|
||||||
font-weight: bold;
|
color: #e2e2df; }
|
||||||
font-size: 1.1em; }
|
|
||||||
|
|
||||||
.message-content {
|
.message-content {
|
||||||
padding: 8px;
|
color: #bebeb6;
|
||||||
font-size: .9em; }
|
padding: 10px; }
|
||||||
|
|
||||||
.message-media-control {
|
.message-media-control {
|
||||||
padding: 6px; }
|
padding: 12px;
|
||||||
|
color: #bebeb6; }
|
||||||
.message-media-control:last-child:ltr {
|
.message-media-control:last-child:ltr {
|
||||||
padding-right: 18px; }
|
padding-right: 18px; }
|
||||||
.message-media-control:last-child:rtl {
|
.message-media-control:last-child:rtl {
|
||||||
padding-left: 18px; }
|
padding-left: 18px; }
|
||||||
|
.message-media-control:hover {
|
||||||
|
color: #eeeeec; }
|
||||||
|
.message-media-control:insensitive {
|
||||||
|
color: #8e8e80; }
|
||||||
|
|
||||||
.media-message-cover-icon {
|
.media-message-cover-icon {
|
||||||
icon-size: 32px; }
|
icon-size: 48px !important; }
|
||||||
.media-message-cover-icon.fallback {
|
.media-message-cover-icon.fallback {
|
||||||
color: #515a5a;
|
color: #515a5a;
|
||||||
background-color: #393f3f;
|
background-color: #393f3f;
|
||||||
|
@ -125,7 +125,7 @@ EXTRA_DIST +=
|
|||||||
# Files not to distribute
|
# Files not to distribute
|
||||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||||
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
||||||
DISTCLEANFILES = $(DOC_MODULES).types
|
DISTCLEANFILES = $(DOC_MODULE).types
|
||||||
|
|
||||||
# Comment this out if you want 'make check' to test you doc status
|
# Comment this out if you want 'make check' to test you doc status
|
||||||
# and run some sanity checks
|
# and run some sanity checks
|
||||||
|
@ -50,7 +50,6 @@
|
|||||||
<xi:include href="xml/shell-util.xml"/>
|
<xi:include href="xml/shell-util.xml"/>
|
||||||
<xi:include href="xml/shell-mount-operation.xml"/>
|
<xi:include href="xml/shell-mount-operation.xml"/>
|
||||||
<xi:include href="xml/shell-polkit-authentication-agent.xml"/>
|
<xi:include href="xml/shell-polkit-authentication-agent.xml"/>
|
||||||
<xi:include href="xml/shell-tp-client.xml"/>
|
|
||||||
</chapter>
|
</chapter>
|
||||||
<chapter id="object-tree">
|
<chapter id="object-tree">
|
||||||
<title>Object Hierarchy</title>
|
<title>Object Hierarchy</title>
|
||||||
|
@ -11,6 +11,7 @@ misc/config.js: misc/config.js.in Makefile
|
|||||||
-e "s|[@]datadir@|$(datadir)|g" \
|
-e "s|[@]datadir@|$(datadir)|g" \
|
||||||
-e "s|[@]libexecdir@|$(libexecdir)|g" \
|
-e "s|[@]libexecdir@|$(libexecdir)|g" \
|
||||||
-e "s|[@]sysconfdir@|$(sysconfdir)|g" \
|
-e "s|[@]sysconfdir@|$(sysconfdir)|g" \
|
||||||
|
-e "s|[@]LIBMUTTER_API_VERSION@|$(LIBMUTTER_API_VERSION)|g" \
|
||||||
$< > $@
|
$< > $@
|
||||||
|
|
||||||
js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate-dependencies $(srcdir)/js-resources.gresource.xml)
|
js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate-dependencies $(srcdir)/js-resources.gresource.xml)
|
||||||
|
@ -5,6 +5,7 @@ const GLib = imports.gi.GLib;
|
|||||||
const GObject = imports.gi.GObject;
|
const GObject = imports.gi.GObject;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const Gdk = imports.gi.Gdk;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const Format = imports.format;
|
const Format = imports.format;
|
||||||
|
|
||||||
@ -92,9 +93,11 @@ const Application = new Lang.Class({
|
|||||||
widget = this._buildErrorUI(extension, e);
|
widget = this._buildErrorUI(extension, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dialog = new Gtk.Dialog({ use_header_bar: true,
|
let dialog = new Gtk.Window({ modal: !this._skipMainWindow,
|
||||||
modal: true,
|
type_hint: Gdk.WindowTypeHint.DIALOG });
|
||||||
title: extension.metadata.name });
|
dialog.set_titlebar(new Gtk.HeaderBar({ show_close_button: true,
|
||||||
|
title: extension.metadata.name,
|
||||||
|
visible: true }));
|
||||||
|
|
||||||
if (this._skipMainWindow) {
|
if (this._skipMainWindow) {
|
||||||
this.application.add_window(dialog);
|
this.application.add_window(dialog);
|
||||||
@ -107,7 +110,7 @@ const Application = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
dialog.set_default_size(600, 400);
|
dialog.set_default_size(600, 400);
|
||||||
dialog.get_content_area().add(widget);
|
dialog.add(widget);
|
||||||
dialog.show();
|
dialog.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -143,17 +146,21 @@ const Application = new Lang.Class({
|
|||||||
this._window = new Gtk.ApplicationWindow({ application: app,
|
this._window = new Gtk.ApplicationWindow({ application: app,
|
||||||
window_position: Gtk.WindowPosition.CENTER });
|
window_position: Gtk.WindowPosition.CENTER });
|
||||||
|
|
||||||
this._window.set_size_request(800, 500);
|
this._window.set_default_size(800, 500);
|
||||||
|
|
||||||
this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
|
this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
|
||||||
title: _("GNOME Shell Extensions") });
|
title: _("Shell Extensions") });
|
||||||
this._window.set_titlebar(this._titlebar);
|
this._window.set_titlebar(this._titlebar);
|
||||||
|
|
||||||
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER,
|
let killSwitch = new Gtk.Switch({ valign: Gtk.Align.CENTER });
|
||||||
shadow_type: Gtk.ShadowType.IN,
|
this._titlebar.pack_end(killSwitch);
|
||||||
halign: Gtk.Align.CENTER,
|
|
||||||
propagate_natural_width: true,
|
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
|
||||||
margin: 18 });
|
this._settings.bind('disable-user-extensions', killSwitch, 'active',
|
||||||
|
Gio.SettingsBindFlags.DEFAULT |
|
||||||
|
Gio.SettingsBindFlags.INVERT_BOOLEAN);
|
||||||
|
|
||||||
|
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||||
this._window.add(scroll);
|
this._window.add(scroll);
|
||||||
|
|
||||||
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
|
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
|
||||||
@ -246,6 +253,18 @@ const Application = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DescriptionLabel = new Lang.Class({
|
||||||
|
Name: 'DescriptionLabel',
|
||||||
|
Extends: Gtk.Label,
|
||||||
|
|
||||||
|
vfunc_get_preferred_height_for_width: function(width) {
|
||||||
|
// Hack: Request the maximum height allowed by the line limit
|
||||||
|
if (this.lines > 0)
|
||||||
|
return this.parent(0);
|
||||||
|
return this.parent(width);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const ExtensionRow = new Lang.Class({
|
const ExtensionRow = new Lang.Class({
|
||||||
Name: 'ExtensionRow',
|
Name: 'ExtensionRow',
|
||||||
Extends: Gtk.ListBoxRow,
|
Extends: Gtk.ListBoxRow,
|
||||||
@ -264,6 +283,10 @@ const ExtensionRow = new Lang.Class({
|
|||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._switch.sensitive = this._canEnable();
|
this._switch.sensitive = this._canEnable();
|
||||||
}));
|
}));
|
||||||
|
this._settings.connect('changed::disable-user-extensions',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._switch.sensitive = this._canEnable();
|
||||||
|
}));
|
||||||
|
|
||||||
this._buildUI();
|
this._buildUI();
|
||||||
},
|
},
|
||||||
@ -272,7 +295,8 @@ const ExtensionRow = new Lang.Class({
|
|||||||
let extension = ExtensionUtils.extensions[this.uuid];
|
let extension = ExtensionUtils.extensions[this.uuid];
|
||||||
|
|
||||||
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
hexpand: true, margin: 12, spacing: 6 });
|
hexpand: true, margin_end: 24, spacing: 24,
|
||||||
|
margin: 12 });
|
||||||
this.add(hbox);
|
this.add(hbox);
|
||||||
|
|
||||||
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
||||||
@ -286,9 +310,9 @@ const ExtensionRow = new Lang.Class({
|
|||||||
vbox.add(label);
|
vbox.add(label);
|
||||||
|
|
||||||
let desc = extension.metadata.description.split('\n')[0];
|
let desc = extension.metadata.description.split('\n')[0];
|
||||||
label = new Gtk.Label({ label: desc,
|
label = new DescriptionLabel({ label: desc, wrap: true, lines: 2,
|
||||||
ellipsize: Pango.EllipsizeMode.END,
|
ellipsize: Pango.EllipsizeMode.END,
|
||||||
halign: Gtk.Align.START });
|
xalign: 0, yalign: 0 });
|
||||||
vbox.add(label);
|
vbox.add(label);
|
||||||
|
|
||||||
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
|
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
|
||||||
@ -319,7 +343,8 @@ const ExtensionRow = new Lang.Class({
|
|||||||
let extension = ExtensionUtils.extensions[this.uuid];
|
let extension = ExtensionUtils.extensions[this.uuid];
|
||||||
let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
|
let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
|
||||||
|
|
||||||
return !(checkVersion && ExtensionUtils.isOutOfDate(extension));
|
return !this._settings.get_boolean('disable-user-extensions') &&
|
||||||
|
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
|
||||||
},
|
},
|
||||||
|
|
||||||
_isEnabled: function() {
|
_isEnabled: function() {
|
||||||
|
@ -23,6 +23,12 @@ function FprintManager() {
|
|||||||
g_object_path: '/net/reactivated/Fprint/Manager',
|
g_object_path: '/net/reactivated/Fprint/Manager',
|
||||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
|
||||||
self.init(null);
|
try {
|
||||||
|
self.init(null);
|
||||||
|
} catch(e) {
|
||||||
|
log('Failed to connect to Fprint service: ' + e.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -1225,7 +1225,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addCharacter: function(unichar) {
|
addCharacter: function(unichar) {
|
||||||
this._authPrompt.addCharacter(unichar);
|
// Don't allow type ahead at the login screen
|
||||||
},
|
},
|
||||||
|
|
||||||
finish: function(onComplete) {
|
finish: function(onComplete) {
|
||||||
|
@ -133,7 +133,7 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
Lang.bind(this, this._updateDefaultService));
|
Lang.bind(this, this._updateDefaultService));
|
||||||
this._updateDefaultService();
|
this._updateDefaultService();
|
||||||
|
|
||||||
this._fprintManager = new Fprint.FprintManager();
|
this._fprintManager = Fprint.FprintManager();
|
||||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
||||||
|
|
||||||
// We check for smartcards right away, since an inserted smartcard
|
// We check for smartcards right away, since an inserted smartcard
|
||||||
@ -293,7 +293,8 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
_checkForFingerprintReader: function() {
|
_checkForFingerprintReader: function() {
|
||||||
this._haveFingerprintReader = false;
|
this._haveFingerprintReader = false;
|
||||||
|
|
||||||
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) {
|
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY) ||
|
||||||
|
this._fprintManager == null) {
|
||||||
this._updateDefaultService();
|
this._updateDefaultService();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,10 @@
|
|||||||
<file>misc/modemManager.js</file>
|
<file>misc/modemManager.js</file>
|
||||||
<file>misc/objectManager.js</file>
|
<file>misc/objectManager.js</file>
|
||||||
<file>misc/params.js</file>
|
<file>misc/params.js</file>
|
||||||
|
<file>misc/permissionStore.js</file>
|
||||||
<file>misc/smartcardManager.js</file>
|
<file>misc/smartcardManager.js</file>
|
||||||
<file>misc/util.js</file>
|
<file>misc/util.js</file>
|
||||||
|
<file>misc/weather.js</file>
|
||||||
|
|
||||||
<file>perf/core.js</file>
|
<file>perf/core.js</file>
|
||||||
<file>perf/hwtest.js</file>
|
<file>perf/hwtest.js</file>
|
||||||
@ -117,6 +119,7 @@
|
|||||||
<file>ui/status/brightness.js</file>
|
<file>ui/status/brightness.js</file>
|
||||||
<file>ui/status/location.js</file>
|
<file>ui/status/location.js</file>
|
||||||
<file>ui/status/keyboard.js</file>
|
<file>ui/status/keyboard.js</file>
|
||||||
|
<file>ui/status/nightLight.js</file>
|
||||||
<file>ui/status/network.js</file>
|
<file>ui/status/network.js</file>
|
||||||
<file>ui/status/power.js</file>
|
<file>ui/status/power.js</file>
|
||||||
<file>ui/status/rfkill.js</file>
|
<file>ui/status/rfkill.js</file>
|
||||||
|
@ -15,3 +15,5 @@ const LOCALEDIR = '@datadir@/locale';
|
|||||||
/* other standard directories */
|
/* other standard directories */
|
||||||
const LIBEXECDIR = '@libexecdir@';
|
const LIBEXECDIR = '@libexecdir@';
|
||||||
const SYSCONFDIR = '@sysconfdir@';
|
const SYSCONFDIR = '@sysconfdir@';
|
||||||
|
/* g-i package versions */
|
||||||
|
const LIBMUTTER_API_VERSION = '@LIBMUTTER_API_VERSION@'
|
||||||
|
@ -6,10 +6,11 @@ const Lang = imports.lang;
|
|||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
let IBusCandidatePopup;
|
||||||
try {
|
try {
|
||||||
var IBus = imports.gi.IBus;
|
var IBus = imports.gi.IBus;
|
||||||
_checkIBusVersion(1, 5, 2);
|
_checkIBusVersion(1, 5, 2);
|
||||||
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var IBus = null;
|
var IBus = null;
|
||||||
log(e);
|
log(e);
|
||||||
|
@ -128,7 +128,8 @@ const KeyboardManager = new Lang.Class({
|
|||||||
if (!found)
|
if (!found)
|
||||||
[, , id] = GnomeDesktop.get_input_source_from_locale(DEFAULT_LOCALE);
|
[, , id] = GnomeDesktop.get_input_source_from_locale(DEFAULT_LOCALE);
|
||||||
|
|
||||||
let [found, , , _layout, _variant] = this._xkbInfo.get_layout_info(id);
|
let _layout, _variant;
|
||||||
|
[found, , , _layout, _variant] = this._xkbInfo.get_layout_info(id);
|
||||||
if (found)
|
if (found)
|
||||||
return { layout: _layout, variant: _variant };
|
return { layout: _layout, variant: _variant };
|
||||||
else
|
else
|
||||||
|
37
js/misc/permissionStore.js
Normal file
37
js/misc/permissionStore.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
|
||||||
|
const PermissionStoreIface = '<node> \
|
||||||
|
<interface name="org.freedesktop.impl.portal.PermissionStore"> \
|
||||||
|
<method name="Lookup"> \
|
||||||
|
<arg name="table" type="s" direction="in"/> \
|
||||||
|
<arg name="id" type="s" direction="in"/> \
|
||||||
|
<arg name="permissions" type="a{sas}" direction="out"/> \
|
||||||
|
<arg name="data" type="v" direction="out"/> \
|
||||||
|
</method> \
|
||||||
|
<method name="Set"> \
|
||||||
|
<arg name="table" type="s" direction="in"/> \
|
||||||
|
<arg name="create" type="b" direction="in"/> \
|
||||||
|
<arg name="id" type="s" direction="in"/> \
|
||||||
|
<arg name="app_permissions" type="a{sas}" direction="in"/> \
|
||||||
|
<arg name="data" type="v" direction="in"/> \
|
||||||
|
</method> \
|
||||||
|
<signal name="Changed"> \
|
||||||
|
<arg name="table" type="s" direction="out"/> \
|
||||||
|
<arg name="id" type="s" direction="out"/> \
|
||||||
|
<arg name="deleted" type="b" direction="out"/> \
|
||||||
|
<arg name="data" type="v" direction="out"/> \
|
||||||
|
<arg name="permissions" type="a{sas}" direction="out"/> \
|
||||||
|
</signal> \
|
||||||
|
</interface> \
|
||||||
|
</node>';
|
||||||
|
|
||||||
|
const PermissionStoreProxy = Gio.DBusProxy.makeProxyWrapper(PermissionStoreIface);
|
||||||
|
|
||||||
|
function PermissionStore(initCallback, cancellable) {
|
||||||
|
return new PermissionStoreProxy(Gio.DBus.session,
|
||||||
|
'org.freedesktop.impl.portal.PermissionStore',
|
||||||
|
'/org/freedesktop/impl/portal/PermissionStore',
|
||||||
|
initCallback, cancellable);
|
||||||
|
};
|
129
js/misc/util.js
129
js/misc/util.js
@ -1,9 +1,12 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gettext = imports.gettext;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
const Signals = imports.signals;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
@ -161,6 +164,41 @@ function _handleSpawnError(command, err) {
|
|||||||
Main.notifyError(title, err.message);
|
Main.notifyError(title, err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatTimeSpan(date) {
|
||||||
|
let now = GLib.DateTime.new_now_local();
|
||||||
|
|
||||||
|
let timespan = now.difference(date);
|
||||||
|
|
||||||
|
let minutesAgo = timespan / GLib.TIME_SPAN_MINUTE;
|
||||||
|
let hoursAgo = timespan / GLib.TIME_SPAN_HOUR;
|
||||||
|
let daysAgo = timespan / GLib.TIME_SPAN_DAY;
|
||||||
|
let weeksAgo = daysAgo / 7;
|
||||||
|
let monthsAgo = daysAgo / 30;
|
||||||
|
let yearsAgo = weeksAgo / 52;
|
||||||
|
|
||||||
|
if (minutesAgo < 5)
|
||||||
|
return _("Just now");
|
||||||
|
if (hoursAgo < 1)
|
||||||
|
return Gettext.ngettext("%d minute ago",
|
||||||
|
"%d minutes ago", minutesAgo).format(minutesAgo);
|
||||||
|
if (daysAgo < 1)
|
||||||
|
return Gettext.ngettext("%d hour ago",
|
||||||
|
"%d hours ago", hoursAgo).format(hoursAgo);
|
||||||
|
if (daysAgo < 2)
|
||||||
|
return _("Yesterday");
|
||||||
|
if (daysAgo < 15)
|
||||||
|
return Gettext.ngettext("%d day ago",
|
||||||
|
"%d days ago", daysAgo).format(daysAgo);
|
||||||
|
if (weeksAgo < 8)
|
||||||
|
return Gettext.ngettext("%d week ago",
|
||||||
|
"%d weeks ago", weeksAgo).format(weeksAgo);
|
||||||
|
if (yearsAgo < 1)
|
||||||
|
return Gettext.ngettext("%d month ago",
|
||||||
|
"%d months ago", monthsAgo).format(monthsAgo);
|
||||||
|
return Gettext.ngettext("%d year ago",
|
||||||
|
"%d years ago", yearsAgo).format(yearsAgo);
|
||||||
|
}
|
||||||
|
|
||||||
function formatTime(time, params) {
|
function formatTime(time, params) {
|
||||||
let date;
|
let date;
|
||||||
// HACK: The built-in Date type sucks at timezones, which we need for the
|
// HACK: The built-in Date type sucks at timezones, which we need for the
|
||||||
@ -398,3 +436,94 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
|
|||||||
time: SCROLL_TIME,
|
time: SCROLL_TIME,
|
||||||
transition: 'easeOutQuad' });
|
transition: 'easeOutQuad' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AppSettingsMonitor = new Lang.Class({
|
||||||
|
Name: 'AppSettingsMonitor',
|
||||||
|
|
||||||
|
_init: function(appId, schemaId) {
|
||||||
|
this._appId = appId;
|
||||||
|
this._schemaId = schemaId;
|
||||||
|
|
||||||
|
this._app = null;
|
||||||
|
this._settings = null;
|
||||||
|
this._handlers = [];
|
||||||
|
|
||||||
|
this._schemaSource = Gio.SettingsSchemaSource.get_default();
|
||||||
|
|
||||||
|
this._appSystem = Shell.AppSystem.get_default();
|
||||||
|
this._appSystem.connect('installed-changed',
|
||||||
|
Lang.bind(this, this._onInstalledChanged));
|
||||||
|
this._onInstalledChanged();
|
||||||
|
},
|
||||||
|
|
||||||
|
get available() {
|
||||||
|
return this._app != null && this._settings != null;
|
||||||
|
},
|
||||||
|
|
||||||
|
activateApp: function() {
|
||||||
|
if (this._app)
|
||||||
|
this._app.activate();
|
||||||
|
},
|
||||||
|
|
||||||
|
watchSetting: function(key, callback) {
|
||||||
|
let handler = { id: 0, key: key, callback: callback };
|
||||||
|
this._handlers.push(handler);
|
||||||
|
|
||||||
|
this._connectHandler(handler);
|
||||||
|
},
|
||||||
|
|
||||||
|
_connectHandler: function(handler) {
|
||||||
|
if (!this._settings || handler.id > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
handler.id = this._settings.connect('changed::' + handler.key,
|
||||||
|
handler.callback);
|
||||||
|
handler.callback(this._settings, handler.key);
|
||||||
|
},
|
||||||
|
|
||||||
|
_disconnectHandler: function(handler) {
|
||||||
|
if (this._settings && handler.id > 0)
|
||||||
|
this._settings.disconnect(handler.id);
|
||||||
|
handler.id = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInstalledChanged: function() {
|
||||||
|
let hadApp = (this._app != null);
|
||||||
|
this._app = this._appSystem.lookup_app(this._appId);
|
||||||
|
let haveApp = (this._app != null);
|
||||||
|
|
||||||
|
if (hadApp == haveApp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (haveApp)
|
||||||
|
this._checkSettings();
|
||||||
|
else
|
||||||
|
this._setSettings(null);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setSettings: function(settings) {
|
||||||
|
this._handlers.forEach((handler) => { this._disconnectHandler(handler); });
|
||||||
|
|
||||||
|
let hadSettings = (this._settings != null);
|
||||||
|
this._settings = settings;
|
||||||
|
let haveSettings = (this._settings != null);
|
||||||
|
|
||||||
|
this._handlers.forEach((handler) => { this._connectHandler(handler); });
|
||||||
|
|
||||||
|
if (hadSettings != haveSettings)
|
||||||
|
this.emit('available-changed');
|
||||||
|
},
|
||||||
|
|
||||||
|
_checkSettings: function() {
|
||||||
|
let schema = this._schemaSource.lookup(this._schemaId, true);
|
||||||
|
if (schema) {
|
||||||
|
this._setSettings(new Gio.Settings({ settings_schema: schema }));
|
||||||
|
} else if (this._app) {
|
||||||
|
Mainloop.timeout_add_seconds(1, () => {
|
||||||
|
this._checkSettings();
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(AppSettingsMonitor.prototype);
|
||||||
|
247
js/misc/weather.js
Normal file
247
js/misc/weather.js
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Geoclue = imports.gi.Geoclue;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const GWeather = imports.gi.GWeather;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const PermissionStore = imports.misc.permissionStore;
|
||||||
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
|
// Minimum time between updates to show loading indication
|
||||||
|
const UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
|
||||||
|
|
||||||
|
const WeatherClient = new Lang.Class({
|
||||||
|
Name: 'WeatherClient',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._loading = false;
|
||||||
|
this._locationValid = false;
|
||||||
|
this._lastUpdate = GLib.DateTime.new_from_unix_local(0);
|
||||||
|
|
||||||
|
this._autoLocationRequested = false;
|
||||||
|
this._mostRecentLocation = null;
|
||||||
|
|
||||||
|
this._gclueService = null;
|
||||||
|
this._gclueStarted = false;
|
||||||
|
this._gclueStarting = false;
|
||||||
|
this._gclueLocationChangedId = 0;
|
||||||
|
|
||||||
|
this._weatherAuthorized = false;
|
||||||
|
this._permStore = new PermissionStore.PermissionStore((proxy, error) => {
|
||||||
|
if (error) {
|
||||||
|
log('Failed to connect to permissionStore: ' + error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._permStore.LookupRemote('gnome', 'geolocation', (res, error) => {
|
||||||
|
if (error)
|
||||||
|
log('Error looking up permission: ' + error.message);
|
||||||
|
|
||||||
|
let [perms, data] = error ? [{}, null] : res;
|
||||||
|
let params = ['gnome', 'geolocation', false, data, perms];
|
||||||
|
this._onPermStoreChanged(this._permStore, '', params);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this._permStore.connectSignal('Changed',
|
||||||
|
Lang.bind(this, this._onPermStoreChanged));
|
||||||
|
|
||||||
|
this._locationSettings = new Gio.Settings({ schema_id: 'org.gnome.system.location' });
|
||||||
|
this._locationSettings.connect('changed::enabled',
|
||||||
|
Lang.bind(this, this._updateAutoLocation));
|
||||||
|
|
||||||
|
this._world = GWeather.Location.get_world();
|
||||||
|
|
||||||
|
this._providers = GWeather.Provider.METAR |
|
||||||
|
GWeather.Provider.YR_NO |
|
||||||
|
GWeather.Provider.OWM;
|
||||||
|
|
||||||
|
this._weatherInfo = new GWeather.Info({ enabled_providers: 0 });
|
||||||
|
this._weatherInfo.connect_after('updated', () => {
|
||||||
|
this._lastUpdate = GLib.DateTime.new_now_local();
|
||||||
|
this.emit('changed');
|
||||||
|
});
|
||||||
|
|
||||||
|
this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.Application.desktop',
|
||||||
|
'org.gnome.Weather.Application');
|
||||||
|
this._weatherAppMon.connect('available-changed', () => { this.emit('changed'); });
|
||||||
|
this._weatherAppMon.watchSetting('automatic-location',
|
||||||
|
Lang.bind(this, this._onAutomaticLocationChanged));
|
||||||
|
this._weatherAppMon.watchSetting('locations',
|
||||||
|
Lang.bind(this, this._onLocationsChanged));
|
||||||
|
},
|
||||||
|
|
||||||
|
get available() {
|
||||||
|
return this._weatherAppMon.available;
|
||||||
|
},
|
||||||
|
|
||||||
|
get loading() {
|
||||||
|
return this._loading;
|
||||||
|
},
|
||||||
|
|
||||||
|
get hasLocation() {
|
||||||
|
return this._locationValid;
|
||||||
|
},
|
||||||
|
|
||||||
|
get info() {
|
||||||
|
return this._weatherInfo;
|
||||||
|
},
|
||||||
|
|
||||||
|
activateApp: function() {
|
||||||
|
this._weatherAppMon.activateApp();
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function() {
|
||||||
|
if (!this._locationValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let now = GLib.DateTime.new_now_local();
|
||||||
|
// Update without loading indication if the current info is recent enough
|
||||||
|
if (this._weatherInfo.is_valid() &&
|
||||||
|
now.difference(this._lastUpdate) < UPDATE_THRESHOLD)
|
||||||
|
this._weatherInfo.update();
|
||||||
|
else
|
||||||
|
this._loadInfo();
|
||||||
|
},
|
||||||
|
|
||||||
|
get _useAutoLocation() {
|
||||||
|
return this._autoLocationRequested &&
|
||||||
|
this._locationSettings.get_boolean('enabled') &&
|
||||||
|
this._weatherAuthorized;
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadInfo: function() {
|
||||||
|
let id = this._weatherInfo.connect('updated', () => {
|
||||||
|
this._weatherInfo.disconnect(id);
|
||||||
|
this._loading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._loading = true;
|
||||||
|
this.emit('changed');
|
||||||
|
|
||||||
|
this._weatherInfo.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
_locationsEqual: function(loc1, loc2) {
|
||||||
|
if (loc1 == loc2)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (loc1 == null || loc2 == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return loc1.equal(loc2);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setLocation: function(location) {
|
||||||
|
if (this._locationsEqual(this._weatherInfo.location, location))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._weatherInfo.abort();
|
||||||
|
this._weatherInfo.set_location(location);
|
||||||
|
this._locationValid = (location != null);
|
||||||
|
|
||||||
|
this._weatherInfo.set_enabled_providers(location ? this._providers : 0);
|
||||||
|
|
||||||
|
if (location)
|
||||||
|
this._loadInfo();
|
||||||
|
else
|
||||||
|
this.emit('changed');
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateLocationMonitoring: function() {
|
||||||
|
if (this._useAutoLocation) {
|
||||||
|
if (this._gclueLocationChangedId != 0 || this._gclueService == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._gclueLocationChangedId =
|
||||||
|
this._gclueService.connect('notify::location',
|
||||||
|
Lang.bind(this, this._onGClueLocationChanged));
|
||||||
|
this._onGClueLocationChanged();
|
||||||
|
} else {
|
||||||
|
if (this._gclueLocationChangedId)
|
||||||
|
this._gclueService.disconnect(this._gclueLocationChangedId);
|
||||||
|
this._gclueLocationChangedId = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_startGClueService: function() {
|
||||||
|
if (this._gclueStarting)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._gclueStarting = true;
|
||||||
|
|
||||||
|
Geoclue.Simple.new('org.gnome.Shell', Geoclue.AccuracyLevel.CITY, null,
|
||||||
|
(o, res) => {
|
||||||
|
try {
|
||||||
|
this._gclueService = Geoclue.Simple.new_finish(res);
|
||||||
|
} catch(e) {
|
||||||
|
log('Failed to connect to Geoclue2 service: ' + e.message);
|
||||||
|
this._setLocation(this._mostRecentLocation);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._gclueStarted = true;
|
||||||
|
this._gclueService.get_client().distance_threshold = 100;
|
||||||
|
this._updateLocationMonitoring();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onGClueLocationChanged: function() {
|
||||||
|
let geoLocation = this._gclueService.location;
|
||||||
|
let location = GWeather.Location.new_detached(geoLocation.description,
|
||||||
|
null,
|
||||||
|
geoLocation.latitude,
|
||||||
|
geoLocation.longitude);
|
||||||
|
this._setLocation(location);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAutomaticLocationChanged: function(settings, key) {
|
||||||
|
let useAutoLocation = settings.get_boolean(key);
|
||||||
|
if (this._autoLocationRequested == useAutoLocation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._autoLocationRequested = useAutoLocation;
|
||||||
|
|
||||||
|
this._updateAutoLocation();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateAutoLocation: function() {
|
||||||
|
this._updateLocationMonitoring();
|
||||||
|
|
||||||
|
if (this._useAutoLocation)
|
||||||
|
this._startGClueService();
|
||||||
|
else
|
||||||
|
this._setLocation(this._mostRecentLocation);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onLocationsChanged: function(settings, key) {
|
||||||
|
let serialized = settings.get_value(key).deep_unpack().shift();
|
||||||
|
let mostRecentLocation = null;
|
||||||
|
|
||||||
|
if (serialized)
|
||||||
|
mostRecentLocation = this._world.deserialize(serialized);
|
||||||
|
|
||||||
|
if (this._locationsEqual(this._mostRecentLocation, mostRecentLocation))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._mostRecentLocation = mostRecentLocation;
|
||||||
|
|
||||||
|
if (!this._useAutoLocation || !this._gclueStarted)
|
||||||
|
this._setLocation(this._mostRecentLocation);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onPermStoreChanged: function(proxy, sender, params) {
|
||||||
|
let [table, id, deleted, data, perms] = params;
|
||||||
|
|
||||||
|
if (table != 'gnome' || id != 'geolocation')
|
||||||
|
return;
|
||||||
|
|
||||||
|
let permission = perms['org.gnome.Weather.Application'] || ['NONE'];
|
||||||
|
let [accuracy] = permission;
|
||||||
|
this._weatherAuthorized = accuracy != 'NONE';
|
||||||
|
|
||||||
|
this._updateAutoLocation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(WeatherClient.prototype);
|
@ -19,6 +19,12 @@ const PortalHelperResult = {
|
|||||||
RECHECK: 2
|
RECHECK: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PortalHelperSecurityLevel = {
|
||||||
|
NOT_YET_DETERMINED: 0,
|
||||||
|
SECURE: 1,
|
||||||
|
INSECURE: 2
|
||||||
|
};
|
||||||
|
|
||||||
const INACTIVITY_TIMEOUT = 30000; //ms
|
const INACTIVITY_TIMEOUT = 30000; //ms
|
||||||
const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
|
const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
|
||||||
const CONNECTIVITY_CHECK_URI = 'http://' + CONNECTIVITY_CHECK_HOST;
|
const CONNECTIVITY_CHECK_URI = 'http://' + CONNECTIVITY_CHECK_HOST;
|
||||||
@ -44,6 +50,71 @@ const HelperDBusInterface = '<node> \
|
|||||||
</interface> \
|
</interface> \
|
||||||
</node>';
|
</node>';
|
||||||
|
|
||||||
|
const PortalHeaderBar = new Lang.Class({
|
||||||
|
Name: 'PortalHeaderBar',
|
||||||
|
Extends: Gtk.HeaderBar,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent({ show_close_button: true });
|
||||||
|
|
||||||
|
// See ephy-title-box.c in epiphany for the layout
|
||||||
|
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
spacing: 0 });
|
||||||
|
this.set_custom_title(vbox);
|
||||||
|
|
||||||
|
/* TRANSLATORS: this is the title of the wifi captive portal login window */
|
||||||
|
let titleLabel = new Gtk.Label({ label: _("Hotspot Login"),
|
||||||
|
wrap: false,
|
||||||
|
single_line_mode: true,
|
||||||
|
ellipsize: Pango.EllipsizeMode.END });
|
||||||
|
titleLabel.get_style_context().add_class('title');
|
||||||
|
vbox.add(titleLabel);
|
||||||
|
|
||||||
|
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
spacing: 4,
|
||||||
|
halign: Gtk.Align.CENTER,
|
||||||
|
valign: Gtk.Align.BASELINE });
|
||||||
|
hbox.get_style_context().add_class('subtitle');
|
||||||
|
vbox.add(hbox);
|
||||||
|
|
||||||
|
this._lockImage = new Gtk.Image({ icon_size: Gtk.IconSize.MENU,
|
||||||
|
valign: Gtk.Align.BASELINE });
|
||||||
|
hbox.add(this._lockImage);
|
||||||
|
|
||||||
|
this.subtitleLabel = new Gtk.Label({ wrap: false,
|
||||||
|
single_line_mode: true,
|
||||||
|
ellipsize: Pango.EllipsizeMode.END,
|
||||||
|
valign: Gtk.Align.BASELINE,
|
||||||
|
selectable: true});
|
||||||
|
this.subtitleLabel.get_style_context().add_class('subtitle');
|
||||||
|
hbox.add(this.subtitleLabel);
|
||||||
|
|
||||||
|
vbox.show_all();
|
||||||
|
},
|
||||||
|
|
||||||
|
setSubtitle: function(label) {
|
||||||
|
this.subtitleLabel.set_text(label);
|
||||||
|
},
|
||||||
|
|
||||||
|
setSecurityIcon: function(securityLevel) {
|
||||||
|
switch (securityLevel) {
|
||||||
|
case PortalHelperSecurityLevel.NOT_YET_DETERMINED:
|
||||||
|
this._lockImage.hide();
|
||||||
|
break;
|
||||||
|
case PortalHelperSecurityLevel.SECURE:
|
||||||
|
this._lockImage.show();
|
||||||
|
this._lockImage.set_from_icon_name("channel-secure-symbolic", Gtk.IconSize.MENU);
|
||||||
|
this._lockImage.set_tooltip_text(null);
|
||||||
|
break;
|
||||||
|
case PortalHelperSecurityLevel.INSECURE:
|
||||||
|
this._lockImage.show();
|
||||||
|
this._lockImage.set_from_icon_name("channel-insecure-symbolic", Gtk.IconSize.MENU);
|
||||||
|
this._lockImage.set_tooltip_text(_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const PortalWindow = new Lang.Class({
|
const PortalWindow = new Lang.Class({
|
||||||
Name: 'PortalWindow',
|
Name: 'PortalWindow',
|
||||||
Extends: Gtk.ApplicationWindow,
|
Extends: Gtk.ApplicationWindow,
|
||||||
@ -51,6 +122,12 @@ const PortalWindow = new Lang.Class({
|
|||||||
_init: function(application, url, timestamp, doneCallback) {
|
_init: function(application, url, timestamp, doneCallback) {
|
||||||
this.parent({ application: application });
|
this.parent({ application: application });
|
||||||
|
|
||||||
|
this.connect('delete-event', Lang.bind(this, this.destroyWindow));
|
||||||
|
this._headerBar = new PortalHeaderBar();
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||||
|
this.set_titlebar(this._headerBar);
|
||||||
|
this._headerBar.show();
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
url = CONNECTIVITY_CHECK_URI;
|
url = CONNECTIVITY_CHECK_URI;
|
||||||
this._originalUrlWasGnome = true;
|
this._originalUrlWasGnome = true;
|
||||||
@ -64,28 +141,37 @@ const PortalWindow = new Lang.Class({
|
|||||||
this._lastRecheck = 0;
|
this._lastRecheck = 0;
|
||||||
this._recheckAtExit = false;
|
this._recheckAtExit = false;
|
||||||
|
|
||||||
this._webView = new WebKit.WebView();
|
this._webContext = WebKit.WebContext.new_ephemeral();
|
||||||
|
this._webContext.set_cache_model(WebKit.CacheModel.DOCUMENT_VIEWER);
|
||||||
|
|
||||||
|
this._webView = WebKit.WebView.new_with_context(this._webContext);
|
||||||
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy));
|
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy));
|
||||||
|
this._webView.connect('load-changed', Lang.bind(this, this._onLoadChanged));
|
||||||
|
this._webView.connect('insecure-content-detected', Lang.bind(this, this._onInsecureContentDetected));
|
||||||
|
this._webView.connect('load-failed-with-tls-errors', Lang.bind(this, this._onLoadFailedWithTlsErrors));
|
||||||
this._webView.load_uri(url);
|
this._webView.load_uri(url);
|
||||||
this._webView.connect('notify::title', Lang.bind(this, this._syncTitle));
|
this._webView.connect('notify::uri', Lang.bind(this, this._syncUri));
|
||||||
this._syncTitle();
|
this._syncUri();
|
||||||
|
|
||||||
this.add(this._webView);
|
this.add(this._webView);
|
||||||
this._webView.show();
|
this._webView.show();
|
||||||
|
this.set_size_request(600, 450);
|
||||||
this.maximize();
|
this.maximize();
|
||||||
this.present_with_time(timestamp);
|
this.present_with_time(timestamp);
|
||||||
|
|
||||||
|
this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
|
||||||
},
|
},
|
||||||
|
|
||||||
_syncTitle: function() {
|
destroyWindow: function() {
|
||||||
let title = this._webView.title;
|
this.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
if (title) {
|
_syncUri: function() {
|
||||||
this.title = title;
|
let uri = this._webView.uri;
|
||||||
} else {
|
if (uri)
|
||||||
/* TRANSLATORS: this is the title of the wifi captive portal login
|
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
|
||||||
* window, until we know the title of the actual login page */
|
else
|
||||||
this.title = _("Web Authentication Redirect");
|
this._headerBar.setSubtitle('');
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
@ -101,8 +187,46 @@ const PortalWindow = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onLoadChanged: function(view, loadEvent) {
|
||||||
|
if (loadEvent == WebKit.LoadEvent.STARTED) {
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||||
|
} else if (loadEvent == WebKit.LoadEvent.COMMITTED) {
|
||||||
|
let tlsInfo = this._webView.get_tls_info();
|
||||||
|
let ret = tlsInfo[0];
|
||||||
|
let flags = tlsInfo[2];
|
||||||
|
if (ret && flags == 0)
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.SECURE);
|
||||||
|
else
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInsecureContentDetected: function () {
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onLoadFailedWithTlsErrors: function (view, failingURI, certificate, errors) {
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
|
let uri = new Soup.URI(failingURI);
|
||||||
|
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
|
||||||
|
this._webView.load_uri(failingURI);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
_onDecidePolicy: function(view, decision, type) {
|
_onDecidePolicy: function(view, decision, type) {
|
||||||
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
|
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
|
||||||
|
let navigationAction = decision.get_navigation_action();
|
||||||
|
if (navigationAction.is_user_gesture()) {
|
||||||
|
// Even though the portal asks for a new window,
|
||||||
|
// perform the navigation in the current one. Some
|
||||||
|
// portals open a window as their last login step and
|
||||||
|
// ignoring that window causes them to not let the
|
||||||
|
// user go through. We don't risk popups taking over
|
||||||
|
// the page because we check that the navigation is
|
||||||
|
// user initiated.
|
||||||
|
this._webView.load_request(navigationAction.get_request());
|
||||||
|
}
|
||||||
|
|
||||||
decision.ignore();
|
decision.ignore();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -168,6 +292,10 @@ const WebPortalHelper = new Lang.Class({
|
|||||||
|
|
||||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(HelperDBusInterface, this);
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(HelperDBusInterface, this);
|
||||||
this._queue = [];
|
this._queue = [];
|
||||||
|
|
||||||
|
let action = new Gio.SimpleAction({ name: 'quit' });
|
||||||
|
action.connect('activate', () => { this.active_window.destroyWindow(); });
|
||||||
|
this.add_action(action);
|
||||||
},
|
},
|
||||||
|
|
||||||
vfunc_dbus_register: function(connection, path) {
|
vfunc_dbus_register: function(connection, path) {
|
||||||
@ -199,7 +327,7 @@ const WebPortalHelper = new Lang.Class({
|
|||||||
|
|
||||||
if (obj.connection == connection) {
|
if (obj.connection == connection) {
|
||||||
if (obj.window)
|
if (obj.window)
|
||||||
obj.window.destroy();
|
obj.window.destroyWindow();
|
||||||
this._queue.splice(i, 1);
|
this._queue.splice(i, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -241,6 +369,11 @@ function initEnvironment() {
|
|||||||
function main(argv) {
|
function main(argv) {
|
||||||
initEnvironment();
|
initEnvironment();
|
||||||
|
|
||||||
|
if (!WebKit.WebContext.new_ephemeral) {
|
||||||
|
log('WebKitGTK 2.16 is required for the portal-helper, see https://bugzilla.gnome.org/show_bug.cgi?id=780453');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
||||||
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
||||||
|
|
||||||
|
@ -33,10 +33,9 @@ const AppIconMode = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function _createWindowClone(window, size) {
|
function _createWindowClone(window, size) {
|
||||||
let windowTexture = window.get_texture();
|
let [width, height] = window.get_size();
|
||||||
let [width, height] = windowTexture.get_size();
|
|
||||||
let scale = Math.min(1.0, size / width, size / height);
|
let scale = Math.min(1.0, size / width, size / height);
|
||||||
return new Clutter.Clone({ source: windowTexture,
|
return new Clutter.Clone({ source: window,
|
||||||
width: width * scale,
|
width: width * scale,
|
||||||
height: height * scale,
|
height: height * scale,
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
|
@ -899,6 +899,8 @@ const ControlsBoxLayout = Lang.Class({
|
|||||||
const ViewStackLayout = new Lang.Class({
|
const ViewStackLayout = new Lang.Class({
|
||||||
Name: 'ViewStackLayout',
|
Name: 'ViewStackLayout',
|
||||||
Extends: Clutter.BinLayout,
|
Extends: Clutter.BinLayout,
|
||||||
|
Signals: { 'allocated-size-changed': { param_types: [GObject.TYPE_INT,
|
||||||
|
GObject.TYPE_INT] } },
|
||||||
|
|
||||||
vfunc_allocate: function (actor, box, flags) {
|
vfunc_allocate: function (actor, box, flags) {
|
||||||
let availWidth = box.x2 - box.x1;
|
let availWidth = box.x2 - box.x1;
|
||||||
@ -909,7 +911,6 @@ const ViewStackLayout = new Lang.Class({
|
|||||||
this.parent(actor, box, flags);
|
this.parent(actor, box, flags);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ViewStackLayout.prototype);
|
|
||||||
|
|
||||||
const AppDisplay = new Lang.Class({
|
const AppDisplay = new Lang.Class({
|
||||||
Name: 'AppDisplay',
|
Name: 'AppDisplay',
|
||||||
|
@ -10,8 +10,10 @@ const RENAMED_DESKTOP_IDS = {
|
|||||||
'baobab.desktop': 'org.gnome.baobab.desktop',
|
'baobab.desktop': 'org.gnome.baobab.desktop',
|
||||||
'cheese.desktop': 'org.gnome.Cheese.desktop',
|
'cheese.desktop': 'org.gnome.Cheese.desktop',
|
||||||
'dconf-editor.desktop': 'ca.desrt.dconf-editor.desktop',
|
'dconf-editor.desktop': 'ca.desrt.dconf-editor.desktop',
|
||||||
|
'epiphany.desktop': 'org.gnome.Epiphany.desktop',
|
||||||
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
|
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
|
||||||
'gcalctool.desktop': 'gnome-calculator.desktop',
|
'gcalctool.desktop': 'org.gnome.Calculator.desktop',
|
||||||
|
'geary.desktop': 'org.gnome.Geary.desktop',
|
||||||
'gedit.desktop': 'org.gnome.gedit.desktop',
|
'gedit.desktop': 'org.gnome.gedit.desktop',
|
||||||
'glchess.desktop': 'gnome-chess.desktop',
|
'glchess.desktop': 'gnome-chess.desktop',
|
||||||
'glines.desktop': 'five-or-more.desktop',
|
'glines.desktop': 'five-or-more.desktop',
|
||||||
@ -19,6 +21,7 @@ const RENAMED_DESKTOP_IDS = {
|
|||||||
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
|
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
|
||||||
'gnobots2.desktop': 'gnome-robots.desktop',
|
'gnobots2.desktop': 'gnome-robots.desktop',
|
||||||
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
|
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
|
||||||
|
'gnome-calculator.desktop': 'org.gnome.Calculator.desktop',
|
||||||
'gnome-clocks.desktop': 'org.gnome.clocks.desktop',
|
'gnome-clocks.desktop': 'org.gnome.clocks.desktop',
|
||||||
'gnome-contacts.desktop': 'org.gnome.Contacts.desktop',
|
'gnome-contacts.desktop': 'org.gnome.Contacts.desktop',
|
||||||
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
|
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
|
||||||
@ -56,12 +59,14 @@ const AppFavorites = new Lang.Class({
|
|||||||
|
|
||||||
reload: function() {
|
reload: function() {
|
||||||
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
|
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
|
||||||
|
let appSys = Shell.AppSystem.get_default();
|
||||||
|
|
||||||
// Map old desktop file names to the current ones
|
// Map old desktop file names to the current ones
|
||||||
let updated = false;
|
let updated = false;
|
||||||
ids = ids.map(function (id) {
|
ids = ids.map(function (id) {
|
||||||
let newId = RENAMED_DESKTOP_IDS[id];
|
let newId = RENAMED_DESKTOP_IDS[id];
|
||||||
if (newId !== undefined) {
|
if (newId !== undefined &&
|
||||||
|
appSys.lookup_app(newId) != null) {
|
||||||
updated = true;
|
updated = true;
|
||||||
return newId;
|
return newId;
|
||||||
}
|
}
|
||||||
@ -71,7 +76,6 @@ const AppFavorites = new Lang.Class({
|
|||||||
if (updated)
|
if (updated)
|
||||||
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||||
|
|
||||||
let appSys = Shell.AppSystem.get_default();
|
|
||||||
let apps = ids.map(function (id) {
|
let apps = ids.map(function (id) {
|
||||||
return appSys.lookup_app(id);
|
return appSys.lookup_app(id);
|
||||||
}).filter(function (app) {
|
}).filter(function (app) {
|
||||||
|
@ -142,7 +142,6 @@ const BackgroundCache = new Lang.Class({
|
|||||||
Name: 'BackgroundCache',
|
Name: 'BackgroundCache',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._pendingFileLoads = [];
|
|
||||||
this._fileMonitors = {};
|
this._fileMonitors = {};
|
||||||
this._backgroundSources = {};
|
this._backgroundSources = {};
|
||||||
this._animations = {};
|
this._animations = {};
|
||||||
@ -167,7 +166,8 @@ const BackgroundCache = new Lang.Class({
|
|||||||
settingsSchema: null,
|
settingsSchema: null,
|
||||||
onLoaded: null });
|
onLoaded: null });
|
||||||
|
|
||||||
if (this._animations[params.settingsSchema] && _fileEqual0(this._animationFile, params.file)) {
|
let animation = this._animations[params.settingsSchema];
|
||||||
|
if (animation && _fileEqual0(animation.file, params.file)) {
|
||||||
if (params.onLoaded) {
|
if (params.onLoaded) {
|
||||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
||||||
params.onLoaded(this._animations[params.settingsSchema]);
|
params.onLoaded(this._animations[params.settingsSchema]);
|
||||||
@ -178,7 +178,7 @@ const BackgroundCache = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let animation = new Animation({ file: params.file });
|
animation = new Animation({ file: params.file });
|
||||||
|
|
||||||
animation.load(Lang.bind(this, function() {
|
animation.load(Lang.bind(this, function() {
|
||||||
this._animations[params.settingsSchema] = animation;
|
this._animations[params.settingsSchema] = animation;
|
||||||
@ -255,7 +255,8 @@ const Background = new Lang.Class({
|
|||||||
this._loadAnimation(this._animation.file);
|
this._loadAnimation(this._animation.file);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
LoginManager.getLoginManager().connect('prepare-for-sleep',
|
let loginManager = LoginManager.getLoginManager();
|
||||||
|
this._prepareForSleepId = loginManager.connect('prepare-for-sleep',
|
||||||
(lm, aboutToSuspend) => {
|
(lm, aboutToSuspend) => {
|
||||||
if (aboutToSuspend)
|
if (aboutToSuspend)
|
||||||
return;
|
return;
|
||||||
@ -284,6 +285,10 @@ const Background = new Lang.Class({
|
|||||||
this._clock.disconnect(this._timezoneChangedId);
|
this._clock.disconnect(this._timezoneChangedId);
|
||||||
this._timezoneChangedId = 0;
|
this._timezoneChangedId = 0;
|
||||||
|
|
||||||
|
if (this._prepareForSleepId != 0)
|
||||||
|
LoginManager.getLoginManager().disconnect(this._prepareForSleepId);
|
||||||
|
this._prepareForSleepId = 0;
|
||||||
|
|
||||||
if (this._settingsChangedSignalId != 0)
|
if (this._settingsChangedSignalId != 0)
|
||||||
this._settings.disconnect(this._settingsChangedSignalId);
|
this._settings.disconnect(this._settingsChangedSignalId);
|
||||||
this._settingsChangedSignalId = 0;
|
this._settingsChangedSignalId = 0;
|
||||||
@ -377,11 +382,9 @@ const Background = new Lang.Class({
|
|||||||
|
|
||||||
let cache = Meta.BackgroundImageCache.get_default();
|
let cache = Meta.BackgroundImageCache.get_default();
|
||||||
let numPendingImages = files.length;
|
let numPendingImages = files.length;
|
||||||
let images = [];
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
this._watchFile(files[i]);
|
this._watchFile(files[i]);
|
||||||
let image = cache.load(files[i]);
|
let image = cache.load(files[i]);
|
||||||
images.push(image);
|
|
||||||
if (image.is_loaded()) {
|
if (image.is_loaded()) {
|
||||||
numPendingImages--;
|
numPendingImages--;
|
||||||
if (numPendingImages == 0)
|
if (numPendingImages == 0)
|
||||||
|
@ -20,7 +20,7 @@ const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
|||||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||||
const ELLIPSIS_CHAR = '\u2026';
|
const ELLIPSIS_CHAR = '\u2026';
|
||||||
|
|
||||||
const MESSAGE_ICON_SIZE = 32;
|
const MESSAGE_ICON_SIZE = 16;
|
||||||
|
|
||||||
// alias to prevent xgettext from picking up strings translated in GTK+
|
// alias to prevent xgettext from picking up strings translated in GTK+
|
||||||
const gtk30_ = Gettext_gtk30.gettext;
|
const gtk30_ = Gettext_gtk30.gettext;
|
||||||
@ -706,6 +706,14 @@ const EventMessage = new Lang.Class({
|
|||||||
this._date = date;
|
this._date = date;
|
||||||
|
|
||||||
this.parent(this._formatEventTime(), event.summary);
|
this.parent(this._formatEventTime(), event.summary);
|
||||||
|
|
||||||
|
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
|
||||||
|
this.setIcon(this._icon);
|
||||||
|
|
||||||
|
this.actor.connect('style-changed', () => {
|
||||||
|
let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
|
||||||
|
this._icon.opacity = (iconVisible ? 255 : 0);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_formatEventTime: function() {
|
_formatEventTime: function() {
|
||||||
@ -811,7 +819,16 @@ const EventsSection = new Lang.Class({
|
|||||||
this._desktopSettings.connect('changed', Lang.bind(this, this._reloadEvents));
|
this._desktopSettings.connect('changed', Lang.bind(this, this._reloadEvents));
|
||||||
this._eventSource = new EmptyEventSource();
|
this._eventSource = new EmptyEventSource();
|
||||||
|
|
||||||
this.parent('');
|
this.parent();
|
||||||
|
|
||||||
|
this._title = new St.Button({ style_class: 'events-section-title',
|
||||||
|
label: '',
|
||||||
|
x_align: St.Align.START,
|
||||||
|
can_focus: true });
|
||||||
|
this.actor.insert_child_below(this._title, null);
|
||||||
|
|
||||||
|
this._title.connect('clicked', Lang.bind(this, this._onTitleClicked));
|
||||||
|
this._title.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
|
||||||
|
|
||||||
Shell.AppSystem.get_default().connect('installed-changed',
|
Shell.AppSystem.get_default().connect('installed-changed',
|
||||||
Lang.bind(this, this._appInstalledChanged));
|
Lang.bind(this, this._appInstalledChanged));
|
||||||
@ -832,10 +849,10 @@ const EventsSection = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateTitle: function() {
|
_updateTitle: function() {
|
||||||
if (isToday(this._date)) {
|
this._title.visible = !isToday(this._date);
|
||||||
this._title.label = _("Events");
|
|
||||||
|
if (!this._title.visible)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
let dayFormat;
|
let dayFormat;
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
@ -897,7 +914,8 @@ const EventsSection = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTitleClicked: function() {
|
_onTitleClicked: function() {
|
||||||
this.parent();
|
Main.overview.hide();
|
||||||
|
Main.panel.closeCalendar();
|
||||||
|
|
||||||
let app = this._getCalendarApp();
|
let app = this._getCalendarApp();
|
||||||
if (app.get_id() == 'evolution.desktop')
|
if (app.get_id() == 'evolution.desktop')
|
||||||
@ -928,7 +946,7 @@ const NotificationSection = new Lang.Class({
|
|||||||
Extends: MessageList.MessageListSection,
|
Extends: MessageList.MessageListSection,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("Notifications"));
|
this.parent();
|
||||||
|
|
||||||
this._sources = new Map();
|
this._sources = new Map();
|
||||||
this._nUrgent = 0;
|
this._nUrgent = 0;
|
||||||
@ -946,10 +964,14 @@ const NotificationSection = new Lang.Class({
|
|||||||
!Main.sessionMode.isGreeter;
|
!Main.sessionMode.isGreeter;
|
||||||
},
|
},
|
||||||
|
|
||||||
_createTimeLabel: function() {
|
_createTimeLabel: function(datetime) {
|
||||||
let label = Util.createTimeLabel(new Date());
|
let label = new St.Label({ style_class: 'event-time',
|
||||||
label.style_class = 'event-time',
|
x_align: Clutter.ActorAlign.START,
|
||||||
label.x_align = Clutter.ActorAlign.END;
|
y_align: Clutter.ActorAlign.END });
|
||||||
|
label.connect('notify::mapped', () => {
|
||||||
|
if (label.mapped)
|
||||||
|
label.text = Util.formatTimeSpan(datetime);
|
||||||
|
});
|
||||||
return label;
|
return label;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -970,13 +992,13 @@ const NotificationSection = new Lang.Class({
|
|||||||
|
|
||||||
_onNotificationAdded: function(source, notification) {
|
_onNotificationAdded: function(source, notification) {
|
||||||
let message = new NotificationMessage(notification);
|
let message = new NotificationMessage(notification);
|
||||||
message.setSecondaryActor(this._createTimeLabel());
|
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||||
|
|
||||||
let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
|
let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
|
||||||
|
|
||||||
let updatedId = notification.connect('updated', Lang.bind(this,
|
let updatedId = notification.connect('updated', Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
message.setSecondaryActor(this._createTimeLabel());
|
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||||
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
|
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
|
||||||
}));
|
}));
|
||||||
let destroyId = notification.connect('destroy', Lang.bind(this,
|
let destroyId = notification.connect('destroy', Lang.bind(this,
|
||||||
@ -1017,26 +1039,8 @@ const NotificationSection = new Lang.Class({
|
|||||||
message.notification.acknowledged = true;
|
message.notification.acknowledged = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTitleClicked: function() {
|
|
||||||
this.parent();
|
|
||||||
|
|
||||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-notifications-panel.desktop');
|
|
||||||
|
|
||||||
if (!app) {
|
|
||||||
log('Settings panel for desktop file ' + desktopFile + ' could not be loaded!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.activate();
|
|
||||||
},
|
|
||||||
|
|
||||||
_shouldShow: function() {
|
_shouldShow: function() {
|
||||||
return !this.empty && isToday(this._date);
|
return !this.empty && isToday(this._date);
|
||||||
},
|
|
||||||
|
|
||||||
_sync: function() {
|
|
||||||
this.parent();
|
|
||||||
this._title.reactive = Main.sessionMode.allowSettings;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1098,12 +1102,26 @@ const CalendarMessageList = new Lang.Class({
|
|||||||
this._placeholder = new Placeholder();
|
this._placeholder = new Placeholder();
|
||||||
this.actor.add_actor(this._placeholder.actor);
|
this.actor.add_actor(this._placeholder.actor);
|
||||||
|
|
||||||
|
let box = new St.BoxLayout({ vertical: true,
|
||||||
|
x_expand: true, y_expand: true });
|
||||||
|
this.actor.add_actor(box);
|
||||||
|
|
||||||
this._scrollView = new St.ScrollView({ style_class: 'vfade',
|
this._scrollView = new St.ScrollView({ style_class: 'vfade',
|
||||||
overlay_scrollbars: true,
|
overlay_scrollbars: true,
|
||||||
x_expand: true, y_expand: true,
|
x_expand: true, y_expand: true,
|
||||||
x_fill: true, y_fill: true });
|
x_fill: true, y_fill: true });
|
||||||
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||||
this.actor.add_actor(this._scrollView);
|
box.add_actor(this._scrollView);
|
||||||
|
|
||||||
|
this._clearButton = new St.Button({ style_class: 'message-list-clear-button button',
|
||||||
|
label: _("Clear All"),
|
||||||
|
can_focus: true });
|
||||||
|
this._clearButton.set_x_align(Clutter.ActorAlign.END);
|
||||||
|
this._clearButton.connect('clicked', () => {
|
||||||
|
let sections = [...this._sections.keys()];
|
||||||
|
sections.forEach((s) => { s.clear(); });
|
||||||
|
});
|
||||||
|
box.add_actor(this._clearButton);
|
||||||
|
|
||||||
this._sectionList = new St.BoxLayout({ style_class: 'message-list-sections',
|
this._sectionList = new St.BoxLayout({ style_class: 'message-list-sections',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
@ -1129,6 +1147,7 @@ const CalendarMessageList = new Lang.Class({
|
|||||||
destroyId: 0,
|
destroyId: 0,
|
||||||
visibleId: 0,
|
visibleId: 0,
|
||||||
emptyChangedId: 0,
|
emptyChangedId: 0,
|
||||||
|
canClearChangedId: 0,
|
||||||
keyFocusId: 0
|
keyFocusId: 0
|
||||||
};
|
};
|
||||||
obj.destroyId = section.actor.connect('destroy', Lang.bind(this,
|
obj.destroyId = section.actor.connect('destroy', Lang.bind(this,
|
||||||
@ -1139,6 +1158,8 @@ const CalendarMessageList = new Lang.Class({
|
|||||||
Lang.bind(this, this._sync));
|
Lang.bind(this, this._sync));
|
||||||
obj.emptyChangedId = section.connect('empty-changed',
|
obj.emptyChangedId = section.connect('empty-changed',
|
||||||
Lang.bind(this, this._sync));
|
Lang.bind(this, this._sync));
|
||||||
|
obj.canClearChangedId = section.connect('can-clear-changed',
|
||||||
|
Lang.bind(this, this._sync));
|
||||||
obj.keyFocusId = section.connect('key-focus-in',
|
obj.keyFocusId = section.connect('key-focus-in',
|
||||||
Lang.bind(this, this._onKeyFocusIn));
|
Lang.bind(this, this._onKeyFocusIn));
|
||||||
|
|
||||||
@ -1152,6 +1173,7 @@ const CalendarMessageList = new Lang.Class({
|
|||||||
section.actor.disconnect(obj.destroyId);
|
section.actor.disconnect(obj.destroyId);
|
||||||
section.actor.disconnect(obj.visibleId);
|
section.actor.disconnect(obj.visibleId);
|
||||||
section.disconnect(obj.emptyChangedId);
|
section.disconnect(obj.emptyChangedId);
|
||||||
|
section.disconnect(obj.canClearChangedId);
|
||||||
section.disconnect(obj.keyFocusId);
|
section.disconnect(obj.keyFocusId);
|
||||||
|
|
||||||
this._sections.delete(section);
|
this._sections.delete(section);
|
||||||
@ -1172,10 +1194,16 @@ const CalendarMessageList = new Lang.Class({
|
|||||||
if (!visible)
|
if (!visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let showPlaceholder = sections.every(function(s) {
|
let empty = sections.every(function(s) {
|
||||||
return s.empty || !s.actor.visible;
|
return s.empty || !s.actor.visible;
|
||||||
});
|
});
|
||||||
this._placeholder.actor.visible = showPlaceholder;
|
this._placeholder.actor.visible = empty;
|
||||||
|
this._clearButton.visible = !empty;
|
||||||
|
|
||||||
|
let canClear = sections.some(function(s) {
|
||||||
|
return s.canClear && s.actor.visible;
|
||||||
|
});
|
||||||
|
this._clearButton.reactive = canClear;
|
||||||
},
|
},
|
||||||
|
|
||||||
setEventSource: function(eventSource) {
|
setEventSource: function(eventSource) {
|
||||||
|
@ -298,7 +298,7 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
* requested authentication was not gained; this can happen
|
* requested authentication was not gained; this can happen
|
||||||
* because of an authentication error (like invalid password),
|
* because of an authentication error (like invalid password),
|
||||||
* for instance. */
|
* for instance. */
|
||||||
this._errorMessageLabel.set_text(_("Sorry, that didn\'t work. Please try again."));
|
this._errorMessageLabel.set_text(_("Sorry, that didn’t work. Please try again."));
|
||||||
this._errorMessageLabel.show();
|
this._errorMessageLabel.show();
|
||||||
this._infoMessageLabel.hide();
|
this._infoMessageLabel.hide();
|
||||||
this._nullMessageLabel.hide();
|
this._nullMessageLabel.hide();
|
||||||
|
@ -6,11 +6,17 @@ const GLib = imports.gi.GLib;
|
|||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Tpl = imports.gi.TelepathyLogger;
|
|
||||||
const Tp = imports.gi.TelepathyGLib;
|
var Tpl = null;
|
||||||
|
var Tp = null;
|
||||||
|
try {
|
||||||
|
Tpl = imports.gi.TelepathyLogger;
|
||||||
|
Tp = imports.gi.TelepathyGLib;
|
||||||
|
} catch(e) {
|
||||||
|
log('Telepathy is not available, chat integration will be disabled.');
|
||||||
|
}
|
||||||
|
|
||||||
const History = imports.misc.history;
|
const History = imports.misc.history;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@ -20,6 +26,8 @@ const Params = imports.misc.params;
|
|||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
|
const HAVE_TP = (Tp != null && Tpl != null);
|
||||||
|
|
||||||
// See Notification.appendMessage
|
// See Notification.appendMessage
|
||||||
const SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes
|
const SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes
|
||||||
const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||||
@ -71,8 +79,43 @@ function makeMessageFromTplEvent(event) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const TelepathyClient = new Lang.Class({
|
const TelepathyComponent = new Lang.Class({
|
||||||
|
Name: 'TelepathyComponent',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._client = null;
|
||||||
|
|
||||||
|
if (!HAVE_TP)
|
||||||
|
return; // Telepathy isn't available
|
||||||
|
|
||||||
|
this._client = new TelepathyClient();
|
||||||
|
},
|
||||||
|
|
||||||
|
enable: function() {
|
||||||
|
if (!this._client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._client.register();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('Couldn\'t register Telepathy client. Error: \n' + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._client.account_manager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
|
||||||
|
this._client.account_manager.prepare_async(null, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
disable: function() {
|
||||||
|
if (!this._client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._client.unregister();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const TelepathyClient = HAVE_TP ? new Lang.Class({
|
||||||
Name: 'TelepathyClient',
|
Name: 'TelepathyClient',
|
||||||
|
Extends: Tp.BaseClient,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
// channel path -> ChatSource
|
// channel path -> ChatSource
|
||||||
@ -97,39 +140,28 @@ const TelepathyClient = new Lang.Class({
|
|||||||
// channel matching its filters is detected.
|
// channel matching its filters is detected.
|
||||||
// The second argument, recover, means _observeChannels will be run
|
// The second argument, recover, means _observeChannels will be run
|
||||||
// for any existing channel as well.
|
// for any existing channel as well.
|
||||||
this._tpClient = new Shell.TpClient({ name: 'GnomeShell',
|
this.parent({ name: 'GnomeShell',
|
||||||
account_manager: this._accountManager,
|
account_manager: this._accountManager,
|
||||||
uniquify_name: true });
|
uniquify_name: true });
|
||||||
this._tpClient.set_observe_channels_func(
|
|
||||||
Lang.bind(this, this._observeChannels));
|
// We only care about single-user text-based chats
|
||||||
this._tpClient.set_approve_channels_func(
|
let filter = {};
|
||||||
Lang.bind(this, this._approveChannels));
|
filter[Tp.PROP_CHANNEL_CHANNEL_TYPE] = Tp.IFACE_CHANNEL_TYPE_TEXT;
|
||||||
this._tpClient.set_handle_channels_func(
|
filter[Tp.PROP_CHANNEL_TARGET_HANDLE_TYPE] = Tp.HandleType.CONTACT;
|
||||||
Lang.bind(this, this._handleChannels));
|
|
||||||
|
this.set_observer_recover(true);
|
||||||
|
this.add_observer_filter(filter);
|
||||||
|
this.add_approver_filter(filter);
|
||||||
|
this.add_handler_filter(filter);
|
||||||
|
|
||||||
// Allow other clients (such as Empathy) to pre-empt our channels if
|
// Allow other clients (such as Empathy) to pre-empt our channels if
|
||||||
// needed
|
// needed
|
||||||
this._tpClient.set_delegated_channels_callback(
|
this.set_delegated_channels_callback(
|
||||||
Lang.bind(this, this._delegatedChannelsCb));
|
Lang.bind(this, this._delegatedChannelsCb));
|
||||||
},
|
},
|
||||||
|
|
||||||
enable: function() {
|
vfunc_observe_channels: function(account, conn, channels,
|
||||||
try {
|
dispatchOp, requests, context) {
|
||||||
this._tpClient.register();
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('Couldn\'t register Telepathy client. Error: \n' + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._accountManager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
|
|
||||||
this._accountManager.prepare_async(null, null);
|
|
||||||
},
|
|
||||||
|
|
||||||
disable: function() {
|
|
||||||
this._tpClient.unregister();
|
|
||||||
},
|
|
||||||
|
|
||||||
_observeChannels: function(observer, account, conn, channels,
|
|
||||||
dispatchOp, requests, context) {
|
|
||||||
let len = channels.length;
|
let len = channels.length;
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
let channel = channels[i];
|
let channel = channels[i];
|
||||||
@ -153,7 +185,7 @@ const TelepathyClient = new Lang.Class({
|
|||||||
if (this._chatSources[channel.get_object_path()])
|
if (this._chatSources[channel.get_object_path()])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let source = new ChatSource(account, conn, channel, contact, this._tpClient);
|
let source = new ChatSource(account, conn, channel, contact, this);
|
||||||
|
|
||||||
this._chatSources[channel.get_object_path()] = source;
|
this._chatSources[channel.get_object_path()] = source;
|
||||||
source.connect('destroy', Lang.bind(this,
|
source.connect('destroy', Lang.bind(this,
|
||||||
@ -162,8 +194,8 @@ const TelepathyClient = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleChannels: function(handler, account, conn, channels,
|
vfunc_handle_channels: function(account, conn, channels, requests,
|
||||||
requests, user_action_time, context) {
|
user_action_time, context) {
|
||||||
this._handlingChannels(account, conn, channels, true);
|
this._handlingChannels(account, conn, channels, true);
|
||||||
context.accept();
|
context.accept();
|
||||||
},
|
},
|
||||||
@ -193,7 +225,7 @@ const TelepathyClient = new Lang.Class({
|
|||||||
// Telepathy spec states that handlers must foreground channels
|
// Telepathy spec states that handlers must foreground channels
|
||||||
// in HandleChannels calls which are already being handled.
|
// in HandleChannels calls which are already being handled.
|
||||||
|
|
||||||
if (notify && this._tpClient.is_handling_channel(channel)) {
|
if (notify && this.is_handling_channel(channel)) {
|
||||||
// We are already handling the channel, display the source
|
// We are already handling the channel, display the source
|
||||||
let source = this._chatSources[channel.get_object_path()];
|
let source = this._chatSources[channel.get_object_path()];
|
||||||
if (source)
|
if (source)
|
||||||
@ -202,8 +234,8 @@ const TelepathyClient = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_approveChannels: function(approver, account, conn, channels,
|
vfunc_add_dispatch_operation: function(account, conn, channels,
|
||||||
dispatchOp, context) {
|
dispatchOp, context) {
|
||||||
let channel = channels[0];
|
let channel = channels[0];
|
||||||
let chanType = channel.get_channel_type();
|
let chanType = channel.get_channel_type();
|
||||||
|
|
||||||
@ -230,7 +262,7 @@ const TelepathyClient = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Approve private text channels right away as we are going to handle it
|
// Approve private text channels right away as we are going to handle it
|
||||||
dispatchOp.claim_with_async(this._tpClient, Lang.bind(this, function(dispatchOp, result) {
|
dispatchOp.claim_with_async(this, Lang.bind(this, function(dispatchOp, result) {
|
||||||
try {
|
try {
|
||||||
dispatchOp.claim_with_finish(result);
|
dispatchOp.claim_with_finish(result);
|
||||||
this._handlingChannels(account, conn, [channel], false);
|
this._handlingChannels(account, conn, [channel], false);
|
||||||
@ -246,7 +278,7 @@ const TelepathyClient = new Lang.Class({
|
|||||||
// Nothing to do as we don't make a distinction between observed and
|
// Nothing to do as we don't make a distinction between observed and
|
||||||
// handled channels.
|
// handled channels.
|
||||||
},
|
},
|
||||||
});
|
}) : null;
|
||||||
|
|
||||||
const ChatSource = new Lang.Class({
|
const ChatSource = new Lang.Class({
|
||||||
Name: 'ChatSource',
|
Name: 'ChatSource',
|
||||||
@ -660,7 +692,9 @@ const ChatNotification = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (message.direction == NotificationDirection.RECEIVED)
|
if (message.direction == NotificationDirection.RECEIVED)
|
||||||
this.update(this.source.title, messageBody, { bannerMarkup: true });
|
this.update(this.source.title, messageBody,
|
||||||
|
{ datetime: GLib.DateTime.new_from_unix_local (message.timestamp),
|
||||||
|
bannerMarkup: true });
|
||||||
|
|
||||||
let group = (message.direction == NotificationDirection.RECEIVED ?
|
let group = (message.direction == NotificationDirection.RECEIVED ?
|
||||||
'received' : 'sent');
|
'received' : 'sent');
|
||||||
@ -962,4 +996,4 @@ const ChatNotificationBanner = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Component = TelepathyClient;
|
const Component = TelepathyComponent;
|
||||||
|
@ -8,6 +8,7 @@ const Gtk = imports.gi.Gtk;
|
|||||||
const GWeather = imports.gi.GWeather;
|
const GWeather = imports.gi.GWeather;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const Pango = imports.gi.Pango;
|
||||||
const Cairo = imports.cairo;
|
const Cairo = imports.cairo;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@ -20,6 +21,7 @@ const Main = imports.ui.main;
|
|||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const Calendar = imports.ui.calendar;
|
const Calendar = imports.ui.calendar;
|
||||||
|
const Weather = imports.misc.weather;
|
||||||
|
|
||||||
function _isToday(date) {
|
function _isToday(date) {
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
@ -36,7 +38,7 @@ const TodayButton = new Lang.Class({
|
|||||||
// on the current date can be confusing. So don't make the button reactive
|
// on the current date can be confusing. So don't make the button reactive
|
||||||
// until the selected date changes.
|
// until the selected date changes.
|
||||||
this.actor = new St.Button({ style_class: 'datemenu-today-button',
|
this.actor = new St.Button({ style_class: 'datemenu-today-button',
|
||||||
x_align: St.Align.START,
|
x_expand: true, x_align: St.Align.START,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
reactive: false
|
reactive: false
|
||||||
});
|
});
|
||||||
@ -77,7 +79,7 @@ const TodayButton = new Lang.Class({
|
|||||||
* below the time in the shell; it should combine the weekday and the
|
* below the time in the shell; it should combine the weekday and the
|
||||||
* date, e.g. "Tuesday February 17 2015".
|
* date, e.g. "Tuesday February 17 2015".
|
||||||
*/
|
*/
|
||||||
let dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
|
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
|
||||||
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
|
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -87,9 +89,7 @@ const WorldClocksSection = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._clock = new GnomeDesktop.WallClock();
|
this._clock = new GnomeDesktop.WallClock();
|
||||||
this._settings = null;
|
|
||||||
this._clockNotifyId = 0;
|
this._clockNotifyId = 0;
|
||||||
this._changedId = 0;
|
|
||||||
|
|
||||||
this._locations = [];
|
this._locations = [];
|
||||||
|
|
||||||
@ -98,8 +98,7 @@ const WorldClocksSection = new Lang.Class({
|
|||||||
can_focus: true });
|
can_focus: true });
|
||||||
this.actor.connect('clicked', Lang.bind(this,
|
this.actor.connect('clicked', Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
let app = this._getClockApp();
|
this._clockAppMon.activateApp();
|
||||||
app.activate();
|
|
||||||
|
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
Main.panel.closeCalendar();
|
Main.panel.closeCalendar();
|
||||||
@ -112,40 +111,25 @@ const WorldClocksSection = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.child = this._grid;
|
this.actor.child = this._grid;
|
||||||
|
|
||||||
Shell.AppSystem.get_default().connect('installed-changed',
|
this._clockAppMon = new Util.AppSettingsMonitor('org.gnome.clocks.desktop',
|
||||||
Lang.bind(this, this._sync));
|
'org.gnome.clocks');
|
||||||
|
this._clockAppMon.connect('available-changed',
|
||||||
|
Lang.bind(this, this._sync));
|
||||||
|
this._clockAppMon.watchSetting('world-clocks',
|
||||||
|
Lang.bind(this, this._clocksChanged));
|
||||||
this._sync();
|
this._sync();
|
||||||
},
|
},
|
||||||
|
|
||||||
_getClockApp: function() {
|
|
||||||
return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop');
|
|
||||||
},
|
|
||||||
|
|
||||||
_sync: function() {
|
_sync: function() {
|
||||||
this.actor.visible = (this._getClockApp() != null);
|
this.actor.visible = this._clockAppMon.available;
|
||||||
|
|
||||||
if (this.actor.visible) {
|
|
||||||
if (!this._settings) {
|
|
||||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.clocks' });
|
|
||||||
this._changedId =
|
|
||||||
this._settings.connect('changed::world-clocks',
|
|
||||||
Lang.bind(this, this._clocksChanged));
|
|
||||||
this._clocksChanged();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this._settings)
|
|
||||||
this._settings.disconnect(this._changedId);
|
|
||||||
this._settings = null;
|
|
||||||
this._changedId = 0;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_clocksChanged: function() {
|
_clocksChanged: function(settings) {
|
||||||
this._grid.destroy_all_children();
|
this._grid.destroy_all_children();
|
||||||
this._locations = [];
|
this._locations = [];
|
||||||
|
|
||||||
let world = GWeather.Location.get_world();
|
let world = GWeather.Location.get_world();
|
||||||
let clocks = this._settings.get_value('world-clocks').deep_unpack();
|
let clocks = settings.get_value('world-clocks').deep_unpack();
|
||||||
for (let i = 0; i < clocks.length; i++) {
|
for (let i = 0; i < clocks.length; i++) {
|
||||||
let l = world.deserialize(clocks[i].location);
|
let l = world.deserialize(clocks[i].location);
|
||||||
this._locations.push({ location: l });
|
this._locations.push({ location: l });
|
||||||
@ -210,6 +194,136 @@ const WorldClocksSection = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const WeatherSection = new Lang.Class({
|
||||||
|
Name: 'WeatherSection',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._weatherClient = new Weather.WeatherClient();
|
||||||
|
|
||||||
|
this.actor = new St.Button({ style_class: 'weather-button',
|
||||||
|
x_fill: true,
|
||||||
|
can_focus: true });
|
||||||
|
this.actor.connect('clicked', () => {
|
||||||
|
this._weatherClient.activateApp();
|
||||||
|
|
||||||
|
Main.overview.hide();
|
||||||
|
Main.panel.closeCalendar();
|
||||||
|
});
|
||||||
|
this.actor.connect('notify::mapped', () => {
|
||||||
|
if (this.actor.mapped)
|
||||||
|
this._weatherClient.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
let box = new St.BoxLayout({ style_class: 'weather-box',
|
||||||
|
vertical: true });
|
||||||
|
|
||||||
|
this.actor.child = box;
|
||||||
|
|
||||||
|
box.add_child(new St.Label({ style_class: 'weather-header',
|
||||||
|
x_align: Clutter.ActorAlign.START,
|
||||||
|
text: _("Weather") }));
|
||||||
|
|
||||||
|
this._conditionsLabel = new St.Label({ style_class: 'weather-conditions',
|
||||||
|
x_align: Clutter.ActorAlign.START });
|
||||||
|
this._conditionsLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
|
this._conditionsLabel.clutter_text.line_wrap = true;
|
||||||
|
box.add_child(this._conditionsLabel);
|
||||||
|
|
||||||
|
this._weatherClient.connect('changed', Lang.bind(this, this._sync));
|
||||||
|
this._sync();
|
||||||
|
},
|
||||||
|
|
||||||
|
_getSummary: function(info) {
|
||||||
|
let summary = info.get_conditions();
|
||||||
|
if (summary == '-')
|
||||||
|
return info.get_sky();
|
||||||
|
return summary;
|
||||||
|
},
|
||||||
|
|
||||||
|
_sameSummary: function(info1, info2) {
|
||||||
|
let [ok1, phenom1, qualifier1] = info1.get_value_conditions();
|
||||||
|
let [ok2, phenom2, qualifier2] = info2.get_value_conditions();
|
||||||
|
if (ok1 || ok2)
|
||||||
|
return ok1 == ok2 && phenom1 == phenom2 && qualifier1 == qualifier2;
|
||||||
|
|
||||||
|
let [, sky1] = info1.get_value_sky();
|
||||||
|
let [, sky2] = info2.get_value_sky();
|
||||||
|
return sky1 == sky2;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getSummaryText: function() {
|
||||||
|
let info = this._weatherClient.info;
|
||||||
|
let forecasts = info.get_forecast_list();
|
||||||
|
if (forecasts.length == 0) // No forecasts, just current conditions
|
||||||
|
return '%s.'.format(this._getSummary(info));
|
||||||
|
|
||||||
|
let current = info;
|
||||||
|
let summaries = [this._getSummary(info)];
|
||||||
|
for (let i = 0; i < forecasts.length; i++) {
|
||||||
|
let [ok, timestamp] = forecasts[i].get_value_update();
|
||||||
|
if (!_isToday(new Date(timestamp * 1000)))
|
||||||
|
continue; // Ignore forecasts from other days
|
||||||
|
|
||||||
|
if (this._sameSummary(current, forecasts[i]))
|
||||||
|
continue; // Ignore consecutive runs of equal summaries
|
||||||
|
|
||||||
|
current = forecasts[i];
|
||||||
|
if (summaries.push(this._getSummary(current)) == 3)
|
||||||
|
break; // Use a maximum of three summaries
|
||||||
|
}
|
||||||
|
|
||||||
|
let fmt;
|
||||||
|
switch(summaries.length) {
|
||||||
|
/* Translators: %s is a weather condition like "Clear sky"; see
|
||||||
|
libgweather for the possible condition strings. If at all
|
||||||
|
possible, the sentence should match the grammatical case etc. of
|
||||||
|
the inserted conditions. */
|
||||||
|
case 1: fmt = _("%s all day."); break;
|
||||||
|
|
||||||
|
/* Translators: %s is a weather condition like "Clear sky"; see
|
||||||
|
libgweather for the possible condition strings. If at all
|
||||||
|
possible, the sentence should match the grammatical case etc. of
|
||||||
|
the inserted conditions. */
|
||||||
|
case 2: fmt = _("%s, then %s later."); break;
|
||||||
|
|
||||||
|
/* Translators: %s is a weather condition like "Clear sky"; see
|
||||||
|
libgweather for the possible condition strings. If at all
|
||||||
|
possible, the sentence should match the grammatical case etc. of
|
||||||
|
the inserted conditions. */
|
||||||
|
case 3: fmt = _("%s, then %s, followed by %s later."); break;
|
||||||
|
}
|
||||||
|
return String.prototype.format.apply(fmt, summaries);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getLabelText: function() {
|
||||||
|
if (!this._weatherClient.hasLocation)
|
||||||
|
return _("Select a location…");
|
||||||
|
|
||||||
|
if (this._weatherClient.loading)
|
||||||
|
return _("Loading…");
|
||||||
|
|
||||||
|
let info = this._weatherClient.info;
|
||||||
|
if (info.is_valid())
|
||||||
|
return this._getSummaryText() + ' ' +
|
||||||
|
/* Translators: %s is a temperature with unit, e.g. "23℃" */
|
||||||
|
_("Feels like %s.").format(info.get_apparent());
|
||||||
|
|
||||||
|
if (info.network_error())
|
||||||
|
return _("Go online for weather information");
|
||||||
|
|
||||||
|
return _("Weather information is currently unavailable");
|
||||||
|
},
|
||||||
|
|
||||||
|
_sync: function() {
|
||||||
|
this.actor.visible = this._weatherClient.available;
|
||||||
|
|
||||||
|
if (!this.actor.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._conditionsLabel.text = this._getLabelText();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const MessagesIndicator = new Lang.Class({
|
const MessagesIndicator = new Lang.Class({
|
||||||
Name: 'MessagesIndicator',
|
Name: 'MessagesIndicator',
|
||||||
|
|
||||||
@ -256,8 +370,7 @@ const IndicatorPad = new Lang.Class({
|
|||||||
|
|
||||||
_init: function(actor) {
|
_init: function(actor) {
|
||||||
this._source = actor;
|
this._source = actor;
|
||||||
this._source.connect('notify::visible',
|
this._source.connect('notify::visible', () => { this.queue_relayout(); });
|
||||||
Lang.bind(this, this.queue_relayout));
|
|
||||||
this.parent();
|
this.parent();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -297,14 +410,38 @@ const FreezableBinLayout = new Lang.Class({
|
|||||||
|
|
||||||
vfunc_get_preferred_width: function(container, forHeight) {
|
vfunc_get_preferred_width: function(container, forHeight) {
|
||||||
if (!this._frozen || this._savedWidth.some(isNaN))
|
if (!this._frozen || this._savedWidth.some(isNaN))
|
||||||
this._savedWidth = this.parent(container, forHeight);
|
return this.parent(container, forHeight);
|
||||||
return this._savedWidth;
|
return this._savedWidth;
|
||||||
},
|
},
|
||||||
|
|
||||||
vfunc_get_preferred_height: function(container, forWidth) {
|
vfunc_get_preferred_height: function(container, forWidth) {
|
||||||
if (!this._frozen || this._savedHeight.some(isNaN))
|
if (!this._frozen || this._savedHeight.some(isNaN))
|
||||||
this._savedHeight = this.parent(container, forWidth);
|
return this.parent(container, forWidth);
|
||||||
return this._savedHeight;
|
return this._savedHeight;
|
||||||
|
},
|
||||||
|
|
||||||
|
vfunc_allocate: function(container, allocation, flags) {
|
||||||
|
this.parent(container, allocation, flags);
|
||||||
|
|
||||||
|
let [width, height] = allocation.get_size();
|
||||||
|
this._savedWidth = [width, width];
|
||||||
|
this._savedHeight = [height, height];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const CalendarColumnLayout = new Lang.Class({
|
||||||
|
Name: 'CalendarColumnLayout',
|
||||||
|
Extends: Clutter.BoxLayout,
|
||||||
|
|
||||||
|
_init: function(actor) {
|
||||||
|
this.parent({ orientation: Clutter.Orientation.VERTICAL });
|
||||||
|
this._calActor = actor;
|
||||||
|
},
|
||||||
|
|
||||||
|
vfunc_get_preferred_width: function(container, forHeight) {
|
||||||
|
if (!this._calActor || this._calActor.get_parent() != container)
|
||||||
|
return this.parent(container, forHeight);
|
||||||
|
return this._calActor.get_preferred_width(forHeight);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -364,14 +501,16 @@ const DateMenuButton = new Lang.Class({
|
|||||||
hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
|
hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
|
||||||
|
|
||||||
// Fill up the second column
|
// Fill up the second column
|
||||||
vbox = new St.BoxLayout({ style_class: 'datemenu-calendar-column',
|
let boxLayout = new CalendarColumnLayout(this._calendar.actor);
|
||||||
vertical: true });
|
vbox = new St.Widget({ style_class: 'datemenu-calendar-column',
|
||||||
|
layout_manager: boxLayout });
|
||||||
|
boxLayout.hookup_style(vbox);
|
||||||
hbox.add(vbox);
|
hbox.add(vbox);
|
||||||
|
|
||||||
this._date = new TodayButton(this._calendar);
|
this._date = new TodayButton(this._calendar);
|
||||||
vbox.add_actor(this._date.actor);
|
vbox.add_actor(this._date.actor);
|
||||||
|
|
||||||
vbox.add(this._calendar.actor);
|
vbox.add_actor(this._calendar.actor);
|
||||||
|
|
||||||
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
|
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
|
||||||
x_expand: true, x_fill: true,
|
x_expand: true, x_fill: true,
|
||||||
@ -386,6 +525,8 @@ const DateMenuButton = new Lang.Class({
|
|||||||
this._clocksItem = new WorldClocksSection();
|
this._clocksItem = new WorldClocksSection();
|
||||||
displaysBox.add(this._clocksItem.actor, { x_fill: true });
|
displaysBox.add(this._clocksItem.actor, { x_fill: true });
|
||||||
|
|
||||||
|
this._weatherItem = new WeatherSection();
|
||||||
|
displaysBox.add(this._weatherItem.actor, { x_fill: true });
|
||||||
|
|
||||||
// Done with hbox for calendar and event list
|
// Done with hbox for calendar and event list
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ const DRAG_DISTANCE = 80;
|
|||||||
const EdgeDragAction = new Lang.Class({
|
const EdgeDragAction = new Lang.Class({
|
||||||
Name: 'EdgeDragAction',
|
Name: 'EdgeDragAction',
|
||||||
Extends: Clutter.GestureAction,
|
Extends: Clutter.GestureAction,
|
||||||
|
Signals: { 'activated': {} },
|
||||||
|
|
||||||
_init : function(side, allowedModes) {
|
_init : function(side, allowedModes) {
|
||||||
this.parent();
|
this.parent();
|
||||||
@ -81,4 +82,3 @@ const EdgeDragAction = new Lang.Class({
|
|||||||
this.emit('activated');
|
this.emit('activated');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(EdgeDragAction.prototype);
|
|
||||||
|
@ -457,7 +457,6 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
_setLabelText(this._descriptionLabel, description);
|
_setLabelText(this._descriptionLabel, description);
|
||||||
_setLabelText(this._subjectLabel, subject);
|
_setLabelText(this._subjectLabel, subject);
|
||||||
|
|
||||||
let dialogContent = DialogContent[this._type];
|
|
||||||
if (dialogContent.iconName) {
|
if (dialogContent.iconName) {
|
||||||
this._iconBin.child = new St.Icon({ icon_name: dialogContent.iconName,
|
this._iconBin.child = new St.Icon({ icon_name: dialogContent.iconName,
|
||||||
icon_size: _DIALOG_ICON_SIZE,
|
icon_size: _DIALOG_ICON_SIZE,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
imports.gi.versions.Clutter = '1.0';
|
const Config = imports.misc.config;
|
||||||
|
|
||||||
|
imports.gi.versions.Clutter = Config.LIBMUTTER_API_VERSION;
|
||||||
imports.gi.versions.Gio = '2.0';
|
imports.gi.versions.Gio = '2.0';
|
||||||
imports.gi.versions.Gdk = '3.0';
|
imports.gi.versions.Gdk = '3.0';
|
||||||
imports.gi.versions.GdkPixbuf = '2.0';
|
imports.gi.versions.GdkPixbuf = '2.0';
|
||||||
|
@ -252,7 +252,7 @@ const InstallExtensionDialog = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
invocation.return_value(GLib.Variant.new('(s)', 'successful'));
|
invocation.return_value(GLib.Variant.new('(s)', ['successful']));
|
||||||
}
|
}
|
||||||
|
|
||||||
_httpSession.queue_message(message, Lang.bind(this, function(session, message) {
|
_httpSession.queue_message(message, Lang.bind(this, function(session, message) {
|
||||||
|
@ -38,6 +38,7 @@ const connect = Lang.bind(_signals, _signals.connect);
|
|||||||
const disconnect = Lang.bind(_signals, _signals.disconnect);
|
const disconnect = Lang.bind(_signals, _signals.disconnect);
|
||||||
|
|
||||||
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
|
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
|
||||||
|
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
|
||||||
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
|
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
|
||||||
|
|
||||||
var initted = false;
|
var initted = false;
|
||||||
@ -238,11 +239,16 @@ function initExtension(uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getEnabledExtensions() {
|
function getEnabledExtensions() {
|
||||||
let extensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
let extensions;
|
||||||
if (!Array.isArray(Main.sessionMode.enabledExtensions))
|
if (Array.isArray(Main.sessionMode.enabledExtensions))
|
||||||
|
extensions = Main.sessionMode.enabledExtensions;
|
||||||
|
else
|
||||||
|
extensions = [];
|
||||||
|
|
||||||
|
if (global.settings.get_boolean(DISABLE_USER_EXTENSIONS_KEY))
|
||||||
return extensions;
|
return extensions;
|
||||||
|
|
||||||
return Main.sessionMode.enabledExtensions.concat(extensions);
|
return extensions.concat(global.settings.get_strv(ENABLED_EXTENSIONS_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEnabledExtensionsChanged() {
|
function onEnabledExtensionsChanged() {
|
||||||
@ -276,18 +282,27 @@ function _onVersionValidationChanged() {
|
|||||||
// temporarily disable them all
|
// temporarily disable them all
|
||||||
enabledExtensions = [];
|
enabledExtensions = [];
|
||||||
for (let uuid in ExtensionUtils.extensions)
|
for (let uuid in ExtensionUtils.extensions)
|
||||||
reloadExtension(ExtensionUtils.extensions[uuid]);
|
try {
|
||||||
|
reloadExtension(ExtensionUtils.extensions[uuid]);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(uuid, e);
|
||||||
|
}
|
||||||
enabledExtensions = getEnabledExtensions();
|
enabledExtensions = getEnabledExtensions();
|
||||||
|
|
||||||
if (Main.sessionMode.allowExtensions) {
|
if (Main.sessionMode.allowExtensions) {
|
||||||
enabledExtensions.forEach(function(uuid) {
|
enabledExtensions.forEach(function(uuid) {
|
||||||
enableExtension(uuid);
|
try {
|
||||||
|
enableExtension(uuid);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(uuid, e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _loadExtensions() {
|
function _loadExtensions() {
|
||||||
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||||
|
global.settings.connect('changed::' + DISABLE_USER_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||||
global.settings.connect('changed::' + EXTENSION_DISABLE_VERSION_CHECK_KEY, _onVersionValidationChanged);
|
global.settings.connect('changed::' + EXTENSION_DISABLE_VERSION_CHECK_KEY, _onVersionValidationChanged);
|
||||||
|
|
||||||
enabledExtensions = getEnabledExtensions();
|
enabledExtensions = getEnabledExtensions();
|
||||||
|
@ -19,6 +19,7 @@ const CandidateArea = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new St.BoxLayout({ vertical: true,
|
this.actor = new St.BoxLayout({ vertical: true,
|
||||||
|
reactive: true,
|
||||||
visible: false });
|
visible: false });
|
||||||
this._candidateBoxes = [];
|
this._candidateBoxes = [];
|
||||||
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
||||||
@ -39,6 +40,19 @@ const CandidateArea = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.actor.connect('scroll-event', Lang.bind(this, function(actor, event) {
|
||||||
|
let direction = event.get_scroll_direction();
|
||||||
|
switch(direction) {
|
||||||
|
case Clutter.ScrollDirection.UP:
|
||||||
|
this.emit('cursor-up');
|
||||||
|
break;
|
||||||
|
case Clutter.ScrollDirection.DOWN:
|
||||||
|
this.emit('cursor-down');
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
return Clutter.EVENT_PROPAGATE;
|
||||||
|
}));
|
||||||
|
|
||||||
this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
|
this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
|
||||||
|
|
||||||
this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' });
|
this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' });
|
||||||
@ -144,6 +158,14 @@ const CandidatePopup = new Lang.Class({
|
|||||||
this._candidateArea.connect('next-page', Lang.bind(this, function() {
|
this._candidateArea.connect('next-page', Lang.bind(this, function() {
|
||||||
this._panelService.page_down();
|
this._panelService.page_down();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._candidateArea.connect('cursor-up', Lang.bind(this, function() {
|
||||||
|
this._panelService.cursor_up();
|
||||||
|
}));
|
||||||
|
this._candidateArea.connect('cursor-down', Lang.bind(this, function() {
|
||||||
|
this._panelService.cursor_down();
|
||||||
|
}));
|
||||||
|
|
||||||
this._candidateArea.connect('candidate-clicked', Lang.bind(this, function(ca, index, button, state) {
|
this._candidateArea.connect('candidate-clicked', Lang.bind(this, function(ca, index, button, state) {
|
||||||
this._panelService.candidate_clicked(index, button, state);
|
this._panelService.candidate_clicked(index, button, state);
|
||||||
}));
|
}));
|
||||||
|
@ -33,7 +33,6 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
|||||||
'const Mainloop = imports.mainloop; ' +
|
'const Mainloop = imports.mainloop; ' +
|
||||||
'const Meta = imports.gi.Meta; ' +
|
'const Meta = imports.gi.Meta; ' +
|
||||||
'const Shell = imports.gi.Shell; ' +
|
'const Shell = imports.gi.Shell; ' +
|
||||||
'const Tp = imports.gi.TelepathyGLib; ' +
|
|
||||||
'const Main = imports.ui.main; ' +
|
'const Main = imports.ui.main; ' +
|
||||||
'const Lang = imports.lang; ' +
|
'const Lang = imports.lang; ' +
|
||||||
'const Tweener = imports.ui.tweener; ' +
|
'const Tweener = imports.ui.tweener; ' +
|
||||||
|
@ -318,6 +318,7 @@ const Message = new Lang.Class({
|
|||||||
|
|
||||||
this._iconBin = new St.Bin({ style_class: 'message-icon-bin',
|
this._iconBin = new St.Bin({ style_class: 'message-icon-bin',
|
||||||
y_expand: true,
|
y_expand: true,
|
||||||
|
y_align: St.Align.START,
|
||||||
visible: false });
|
visible: false });
|
||||||
hbox.add_actor(this._iconBin);
|
hbox.add_actor(this._iconBin);
|
||||||
|
|
||||||
@ -331,18 +332,18 @@ const Message = new Lang.Class({
|
|||||||
let titleBox = new St.BoxLayout();
|
let titleBox = new St.BoxLayout();
|
||||||
contentBox.add_actor(titleBox);
|
contentBox.add_actor(titleBox);
|
||||||
|
|
||||||
this.titleLabel = new St.Label({ style_class: 'message-title',
|
this.titleLabel = new St.Label({ style_class: 'message-title' });
|
||||||
x_expand: true,
|
|
||||||
x_align: Clutter.ActorAlign.START });
|
|
||||||
this.setTitle(title);
|
this.setTitle(title);
|
||||||
titleBox.add_actor(this.titleLabel);
|
titleBox.add_actor(this.titleLabel);
|
||||||
|
|
||||||
this._secondaryBin = new St.Bin({ style_class: 'message-secondary-bin' });
|
this._secondaryBin = new St.Bin({ style_class: 'message-secondary-bin',
|
||||||
|
x_expand: true, y_expand: true,
|
||||||
|
x_fill: true, y_fill: true });
|
||||||
titleBox.add_actor(this._secondaryBin);
|
titleBox.add_actor(this._secondaryBin);
|
||||||
|
|
||||||
let closeIcon = new St.Icon({ icon_name: 'window-close-symbolic',
|
let closeIcon = new St.Icon({ icon_name: 'window-close-symbolic',
|
||||||
icon_size: 16 });
|
icon_size: 16 });
|
||||||
this._closeButton = new St.Button({ child: closeIcon, visible: false });
|
this._closeButton = new St.Button({ child: closeIcon, opacity: 0 });
|
||||||
titleBox.add_actor(this._closeButton);
|
titleBox.add_actor(this._closeButton);
|
||||||
|
|
||||||
this._bodyStack = new St.Widget({ x_expand: true });
|
this._bodyStack = new St.Widget({ x_expand: true });
|
||||||
@ -493,9 +494,8 @@ const Message = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_sync: function() {
|
_sync: function() {
|
||||||
let hovered = this.actor.hover;
|
let visible = this.actor.hover && this.canClose();
|
||||||
this._closeButton.visible = hovered && this.canClose();
|
this._closeButton.opacity = visible ? 255 : 0;
|
||||||
this._secondaryBin.visible = !hovered;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClicked: function() {
|
_onClicked: function() {
|
||||||
@ -520,32 +520,10 @@ Signals.addSignalMethods(Message.prototype);
|
|||||||
const MessageListSection = new Lang.Class({
|
const MessageListSection = new Lang.Class({
|
||||||
Name: 'MessageListSection',
|
Name: 'MessageListSection',
|
||||||
|
|
||||||
_init: function(title) {
|
_init: function() {
|
||||||
this.actor = new St.BoxLayout({ style_class: 'message-list-section',
|
this.actor = new St.BoxLayout({ style_class: 'message-list-section',
|
||||||
clip_to_allocation: true,
|
clip_to_allocation: true,
|
||||||
x_expand: true, vertical: true });
|
x_expand: true, vertical: true });
|
||||||
let titleBox = new St.BoxLayout({ style_class: 'message-list-section-title-box' });
|
|
||||||
this.actor.add_actor(titleBox);
|
|
||||||
|
|
||||||
this._title = new St.Button({ style_class: 'message-list-section-title',
|
|
||||||
label: title,
|
|
||||||
can_focus: true,
|
|
||||||
x_expand: true,
|
|
||||||
x_align: St.Align.START });
|
|
||||||
titleBox.add_actor(this._title);
|
|
||||||
|
|
||||||
this._title.connect('clicked', Lang.bind(this, this._onTitleClicked));
|
|
||||||
this._title.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
|
|
||||||
|
|
||||||
let closeIcon = new St.Icon({ icon_name: 'window-close-symbolic' });
|
|
||||||
this._closeButton = new St.Button({ style_class: 'message-list-section-close',
|
|
||||||
child: closeIcon,
|
|
||||||
accessible_name: _("Clear section"),
|
|
||||||
can_focus: true });
|
|
||||||
this._closeButton.set_x_align(Clutter.ActorAlign.END);
|
|
||||||
titleBox.add_actor(this._closeButton);
|
|
||||||
|
|
||||||
this._closeButton.connect('clicked', Lang.bind(this, this.clear));
|
|
||||||
|
|
||||||
this._list = new St.BoxLayout({ style_class: 'message-list-section-list',
|
this._list = new St.BoxLayout({ style_class: 'message-list-section-list',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
@ -563,14 +541,10 @@ const MessageListSection = new Lang.Class({
|
|||||||
this._messages = new Map();
|
this._messages = new Map();
|
||||||
this._date = new Date();
|
this._date = new Date();
|
||||||
this.empty = true;
|
this.empty = true;
|
||||||
|
this.canClear = false;
|
||||||
this._sync();
|
this._sync();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTitleClicked: function() {
|
|
||||||
Main.overview.hide();
|
|
||||||
Main.panel.closeCalendar();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onKeyFocusIn: function(actor) {
|
_onKeyFocusIn: function(actor) {
|
||||||
this.emit('key-focus-in', actor);
|
this.emit('key-focus-in', actor);
|
||||||
},
|
},
|
||||||
@ -719,7 +693,13 @@ const MessageListSection = new Lang.Class({
|
|||||||
if (changed)
|
if (changed)
|
||||||
this.emit('empty-changed');
|
this.emit('empty-changed');
|
||||||
|
|
||||||
this._closeButton.visible = this._canClear();
|
let canClear = this._canClear();
|
||||||
|
changed = this.canClear !== canClear;
|
||||||
|
this.canClear = canClear;
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
this.emit('can-clear-changed');
|
||||||
|
|
||||||
this.actor.visible = this.allowed && this._shouldShow();
|
this.actor.visible = this.allowed && this._shouldShow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -368,6 +368,7 @@ const Notification = new Lang.Class({
|
|||||||
secondaryGIcon: null,
|
secondaryGIcon: null,
|
||||||
bannerMarkup: false,
|
bannerMarkup: false,
|
||||||
clear: false,
|
clear: false,
|
||||||
|
datetime: null,
|
||||||
soundName: null,
|
soundName: null,
|
||||||
soundFile: null });
|
soundFile: null });
|
||||||
|
|
||||||
@ -375,6 +376,11 @@ const Notification = new Lang.Class({
|
|||||||
this.bannerBodyText = banner;
|
this.bannerBodyText = banner;
|
||||||
this.bannerBodyMarkup = params.bannerMarkup;
|
this.bannerBodyMarkup = params.bannerMarkup;
|
||||||
|
|
||||||
|
if (params.datetime)
|
||||||
|
this.datetime = params.datetime;
|
||||||
|
else
|
||||||
|
this.datetime = GLib.DateTime.new_now_local();
|
||||||
|
|
||||||
if (params.gicon || params.clear)
|
if (params.gicon || params.clear)
|
||||||
this.gicon = params.gicon;
|
this.gicon = params.gicon;
|
||||||
|
|
||||||
@ -535,7 +541,8 @@ const NotificationBanner = new Lang.Class({
|
|||||||
|
|
||||||
_addSecondaryIcon: function() {
|
_addSecondaryIcon: function() {
|
||||||
if (this.notification.secondaryGIcon) {
|
if (this.notification.secondaryGIcon) {
|
||||||
let icon = new St.Icon({ gicon: this.notification.secondaryGIcon });
|
let icon = new St.Icon({ gicon: this.notification.secondaryGIcon,
|
||||||
|
x_align: Clutter.ActorAlign.END });
|
||||||
this.setSecondaryActor(icon);
|
this.setSecondaryActor(icon);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -796,7 +803,7 @@ const Source = new Lang.Class({
|
|||||||
notification.acknowledged = false;
|
notification.acknowledged = false;
|
||||||
this.pushNotification(notification);
|
this.pushNotification(notification);
|
||||||
|
|
||||||
if (this.policy.showBanners) {
|
if (this.policy.showBanners || notification.urgency == Urgency.CRITICAL) {
|
||||||
this.emit('notify', notification);
|
this.emit('notify', notification);
|
||||||
} else {
|
} else {
|
||||||
notification.playSound();
|
notification.playSound();
|
||||||
@ -1224,7 +1231,7 @@ const MessageTray = new Lang.Class({
|
|||||||
if (this._notificationState == State.HIDDEN) {
|
if (this._notificationState == State.HIDDEN) {
|
||||||
let nextNotification = this._notificationQueue[0] || null;
|
let nextNotification = this._notificationQueue[0] || null;
|
||||||
if (hasNotifications && nextNotification) {
|
if (hasNotifications && nextNotification) {
|
||||||
let limited = this._busy || Main.layoutManager.bottomMonitor.inFullscreen;
|
let limited = this._busy || Main.layoutManager.primaryMonitor.inFullscreen;
|
||||||
let showNextNotification = (!limited || nextNotification.forFeedback || nextNotification.urgency == Urgency.CRITICAL);
|
let showNextNotification = (!limited || nextNotification.forFeedback || nextNotification.urgency == Urgency.CRITICAL);
|
||||||
if (showNextNotification)
|
if (showNextNotification)
|
||||||
this._showNotification();
|
this._showNotification();
|
||||||
|
@ -36,6 +36,8 @@ const MprisPlayerIface = '<node> \
|
|||||||
<method name="PlayPause" /> \
|
<method name="PlayPause" /> \
|
||||||
<method name="Next" /> \
|
<method name="Next" /> \
|
||||||
<method name="Previous" /> \
|
<method name="Previous" /> \
|
||||||
|
<property name="CanGoNext" type="b" access="read" /> \
|
||||||
|
<property name="CanGoPrevious" type="b" access="read" /> \
|
||||||
<property name="CanPlay" type="b" access="read" /> \
|
<property name="CanPlay" type="b" access="read" /> \
|
||||||
<property name="Metadata" type="a{sv}" access="read" /> \
|
<property name="Metadata" type="a{sv}" access="read" /> \
|
||||||
<property name="PlaybackStatus" type="s" access="read" /> \
|
<property name="PlaybackStatus" type="s" access="read" /> \
|
||||||
@ -57,7 +59,7 @@ const MediaMessage = new Lang.Class({
|
|||||||
this._icon = new St.Icon({ style_class: 'media-message-cover-icon' });
|
this._icon = new St.Icon({ style_class: 'media-message-cover-icon' });
|
||||||
this.setIcon(this._icon);
|
this.setIcon(this._icon);
|
||||||
|
|
||||||
this.addMediaControl('media-skip-backward-symbolic',
|
this._prevButton = this.addMediaControl('media-skip-backward-symbolic',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._player.previous();
|
this._player.previous();
|
||||||
}));
|
}));
|
||||||
@ -67,7 +69,7 @@ const MediaMessage = new Lang.Class({
|
|||||||
this._player.playPause();
|
this._player.playPause();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.addMediaControl('media-skip-forward-symbolic',
|
this._nextButton = this.addMediaControl('media-skip-forward-symbolic',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._player.next();
|
this._player.next();
|
||||||
}));
|
}));
|
||||||
@ -82,6 +84,10 @@ const MediaMessage = new Lang.Class({
|
|||||||
Main.panel.closeCalendar();
|
Main.panel.closeCalendar();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateNavButton: function(button, sensitive) {
|
||||||
|
button.reactive = sensitive;
|
||||||
|
},
|
||||||
|
|
||||||
_update: function() {
|
_update: function() {
|
||||||
this.setTitle(this._player.trackArtists.join(', '));
|
this.setTitle(this._player.trackArtists.join(', '));
|
||||||
this.setBody(this._player.trackTitle);
|
this.setBody(this._player.trackTitle);
|
||||||
@ -99,6 +105,9 @@ const MediaMessage = new Lang.Class({
|
|||||||
let iconName = isPlaying ? 'media-playback-pause-symbolic'
|
let iconName = isPlaying ? 'media-playback-pause-symbolic'
|
||||||
: 'media-playback-start-symbolic';
|
: 'media-playback-start-symbolic';
|
||||||
this._playPauseButton.child.icon_name = iconName;
|
this._playPauseButton.child.icon_name = iconName;
|
||||||
|
|
||||||
|
this._updateNavButton(this._prevButton, this._player.canGoPrevious);
|
||||||
|
this._updateNavButton(this._nextButton, this._player.canGoNext);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -139,10 +148,18 @@ const MprisPlayer = new Lang.Class({
|
|||||||
this._playerProxy.PlayPauseRemote();
|
this._playerProxy.PlayPauseRemote();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get canGoNext() {
|
||||||
|
return this._playerProxy.CanGoNext;
|
||||||
|
},
|
||||||
|
|
||||||
next: function() {
|
next: function() {
|
||||||
this._playerProxy.NextRemote();
|
this._playerProxy.NextRemote();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get canGoPrevious() {
|
||||||
|
return this._playerProxy.CanGoPrevious;
|
||||||
|
},
|
||||||
|
|
||||||
previous: function() {
|
previous: function() {
|
||||||
this._playerProxy.PreviousRemote();
|
this._playerProxy.PreviousRemote();
|
||||||
},
|
},
|
||||||
@ -214,7 +231,7 @@ const MediaSection = new Lang.Class({
|
|||||||
Extends: MessageList.MessageListSection,
|
Extends: MessageList.MessageListSection,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("Media"));
|
this.parent();
|
||||||
|
|
||||||
this._players = new Map();
|
this._players = new Map();
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ const FdoNotificationDaemon = new Lang.Class({
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
let source = new FdoNotificationDaemonSource(title, pid, sender, ndata ? ndata.hints['desktop-entry'] : null);
|
source = new FdoNotificationDaemonSource(title, pid, sender, ndata ? ndata.hints['desktop-entry'] : null);
|
||||||
|
|
||||||
this._sources.push(source);
|
this._sources.push(source);
|
||||||
source.connect('destroy', Lang.bind(this, function() {
|
source.connect('destroy', Lang.bind(this, function() {
|
||||||
@ -600,7 +600,8 @@ const GtkNotificationDaemonNotification = new Lang.Class({
|
|||||||
"priority": priority,
|
"priority": priority,
|
||||||
"buttons": buttons,
|
"buttons": buttons,
|
||||||
"default-action": defaultAction,
|
"default-action": defaultAction,
|
||||||
"default-action-target": defaultActionTarget } = notification;
|
"default-action-target": defaultActionTarget,
|
||||||
|
"timestamp": time } = notification;
|
||||||
|
|
||||||
if (priority) {
|
if (priority) {
|
||||||
let urgency = PRIORITY_URGENCY_MAP[priority.unpack()];
|
let urgency = PRIORITY_URGENCY_MAP[priority.unpack()];
|
||||||
@ -623,7 +624,8 @@ const GtkNotificationDaemonNotification = new Lang.Class({
|
|||||||
this._defaultActionTarget = defaultActionTarget;
|
this._defaultActionTarget = defaultActionTarget;
|
||||||
|
|
||||||
this.update(title.unpack(), body ? body.unpack() : null,
|
this.update(title.unpack(), body ? body.unpack() : null,
|
||||||
{ gicon: gicon ? Gio.icon_deserialize(gicon) : null });
|
{ gicon: gicon ? Gio.icon_deserialize(gicon) : null,
|
||||||
|
datetime : time ? GLib.DateTime.new_from_unix_local(time.unpack()) : null });
|
||||||
},
|
},
|
||||||
|
|
||||||
_activateAction: function(namespacedActionId, target) {
|
_activateAction: function(namespacedActionId, target) {
|
||||||
@ -690,6 +692,7 @@ const GtkNotificationDaemonAppSource = new Lang.Class({
|
|||||||
throw new InvalidAppError();
|
throw new InvalidAppError();
|
||||||
|
|
||||||
this._notifications = {};
|
this._notifications = {};
|
||||||
|
this._notificationPending = false;
|
||||||
|
|
||||||
this.parent(this._app.get_name());
|
this.parent(this._app.get_name());
|
||||||
},
|
},
|
||||||
@ -702,27 +705,35 @@ const GtkNotificationDaemonAppSource = new Lang.Class({
|
|||||||
return new MessageTray.NotificationApplicationPolicy(this._appId);
|
return new MessageTray.NotificationApplicationPolicy(this._appId);
|
||||||
},
|
},
|
||||||
|
|
||||||
_createApp: function() {
|
_createApp: function(callback) {
|
||||||
return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath);
|
return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateAction: function(actionId, target) {
|
activateAction: function(actionId, target) {
|
||||||
let app = this._createApp();
|
this._createApp(function (app, error) {
|
||||||
app.ActivateActionRemote(actionId, target ? [target] : [], getPlatformData());
|
if (error == null)
|
||||||
|
app.ActivateActionRemote(actionId, target ? [target] : [], getPlatformData());
|
||||||
|
else
|
||||||
|
logError(error, 'Failed to activate application proxy');
|
||||||
|
});
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
Main.panel.closeCalendar();
|
Main.panel.closeCalendar();
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function() {
|
open: function() {
|
||||||
let app = this._createApp();
|
this._createApp(function (app, error) {
|
||||||
app.ActivateRemote(getPlatformData());
|
if (error == null)
|
||||||
|
app.ActivateRemote(getPlatformData());
|
||||||
|
else
|
||||||
|
logError(error, 'Failed to open application proxy');
|
||||||
|
});
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
Main.panel.closeCalendar();
|
Main.panel.closeCalendar();
|
||||||
},
|
},
|
||||||
|
|
||||||
addNotification: function(notificationId, notificationParams, showBanner) {
|
addNotification: function(notificationId, notificationParams, showBanner) {
|
||||||
|
this._notificationPending = true;
|
||||||
|
|
||||||
if (this._notifications[notificationId])
|
if (this._notifications[notificationId])
|
||||||
this._notifications[notificationId].destroy();
|
this._notifications[notificationId].destroy();
|
||||||
|
|
||||||
@ -736,6 +747,14 @@ const GtkNotificationDaemonAppSource = new Lang.Class({
|
|||||||
this.notify(notification);
|
this.notify(notification);
|
||||||
else
|
else
|
||||||
this.pushNotification(notification);
|
this.pushNotification(notification);
|
||||||
|
|
||||||
|
this._notificationPending = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function(reason) {
|
||||||
|
if (this._notificationPending)
|
||||||
|
return;
|
||||||
|
this.parent(reason);
|
||||||
},
|
},
|
||||||
|
|
||||||
removeNotification: function(notificationId) {
|
removeNotification: function(notificationId) {
|
||||||
@ -847,6 +866,9 @@ const GtkNotificationDaemon = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let timestamp = GLib.DateTime.new_now_local().to_unix();
|
||||||
|
notification['timestamp'] = new GLib.Variant('x', timestamp);
|
||||||
|
|
||||||
source.addNotification(notificationId, notification, true);
|
source.addNotification(notificationId, notification, true);
|
||||||
|
|
||||||
invocation.return_value(null);
|
invocation.return_value(null);
|
||||||
|
@ -107,9 +107,9 @@ const Overview = new Lang.Class({
|
|||||||
|
|
||||||
this._overviewCreated = true;
|
this._overviewCreated = true;
|
||||||
|
|
||||||
/* Translators: This is the main view to select
|
|
||||||
activities. See also note for "Activities" string. */
|
|
||||||
this._overview = new St.BoxLayout({ name: 'overview',
|
this._overview = new St.BoxLayout({ name: 'overview',
|
||||||
|
/* Translators: This is the main view to select
|
||||||
|
activities. See also note for "Activities" string. */
|
||||||
accessible_name: _("Overview"),
|
accessible_name: _("Overview"),
|
||||||
vertical: true });
|
vertical: true });
|
||||||
this._overview.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
|
this._overview.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
|
||||||
@ -378,7 +378,7 @@ const Overview = new Lang.Class({
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
let window = windows[0];
|
let window = windows[0];
|
||||||
let clone = new Clutter.Clone({ source: window.get_texture(),
|
let clone = new Clutter.Clone({ source: window,
|
||||||
x: window.x, y: window.y });
|
x: window.x, y: window.y });
|
||||||
clone.source.connect('destroy', Lang.bind(this, function() {
|
clone.source.connect('destroy', Lang.bind(this, function() {
|
||||||
clone.destroy();
|
clone.destroy();
|
||||||
|
147
js/ui/padOsd.js
147
js/ui/padOsd.js
@ -30,6 +30,72 @@ const CCW = 1;
|
|||||||
const UP = 0;
|
const UP = 0;
|
||||||
const DOWN = 1;
|
const DOWN = 1;
|
||||||
|
|
||||||
|
const PadChooser = new Lang.Class({
|
||||||
|
Name: 'PadChooser',
|
||||||
|
|
||||||
|
_init: function (device, groupDevices) {
|
||||||
|
this.actor = new St.Button({ style_class: 'pad-chooser-button',
|
||||||
|
toggle_mode: true,
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.MIDDLE,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
this.currentDevice = device;
|
||||||
|
this._padChooserMenu = null;
|
||||||
|
|
||||||
|
let arrow = new St.Icon({ style_class: 'popup-menu-arrow',
|
||||||
|
icon_name: 'pan-down-symbolic',
|
||||||
|
accessible_role: Atk.Role.ARROW });
|
||||||
|
this.actor.set_child(arrow);
|
||||||
|
this._ensureMenu(groupDevices);
|
||||||
|
|
||||||
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, function (actor) {
|
||||||
|
if (actor.get_checked()) {
|
||||||
|
if (this._padChooserMenu != null)
|
||||||
|
this._padChooserMenu.open(true);
|
||||||
|
else
|
||||||
|
this.set_checked(false);
|
||||||
|
} else {
|
||||||
|
this._padChooserMenu.close(true);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_ensureMenu: function (devices) {
|
||||||
|
this._padChooserMenu = new PopupMenu.PopupMenu(this.actor, 0.5, St.Side.TOP);
|
||||||
|
this._padChooserMenu.connect('menu-closed', Lang.bind(this, function() { this.actor.set_checked(false); }));
|
||||||
|
this._padChooserMenu.actor.hide();
|
||||||
|
Main.uiGroup.add_actor(this._padChooserMenu.actor);
|
||||||
|
|
||||||
|
for (let i = 0; i < devices.length; i++) {
|
||||||
|
let device = devices[i];
|
||||||
|
if (device == this.currentDevice)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
this._padChooserMenu.addAction(device.get_device_name(), () => {
|
||||||
|
this.emit('pad-selected', device);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDestroy: function () {
|
||||||
|
this._padChooserMenu.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function (devices) {
|
||||||
|
if (this._padChooserMenu)
|
||||||
|
this._padChooserMenu.actor.destroy();
|
||||||
|
this.actor.set_checked(false);
|
||||||
|
this._ensureMenu(devices);
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function () {
|
||||||
|
this.actor.destroy();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(PadChooser.prototype);
|
||||||
|
|
||||||
const KeybindingEntry = new Lang.Class({
|
const KeybindingEntry = new Lang.Class({
|
||||||
Name: 'KeybindingEntry',
|
Name: 'KeybindingEntry',
|
||||||
|
|
||||||
@ -528,16 +594,39 @@ const PadOsd = new Lang.Class({
|
|||||||
|
|
||||||
_init: function (padDevice, settings, imagePath, editionMode, monitorIndex) {
|
_init: function (padDevice, settings, imagePath, editionMode, monitorIndex) {
|
||||||
this.padDevice = padDevice;
|
this.padDevice = padDevice;
|
||||||
|
this._groupPads = [ padDevice ];
|
||||||
this._settings = settings;
|
this._settings = settings;
|
||||||
this._imagePath = imagePath;
|
this._imagePath = imagePath;
|
||||||
this._editionMode = editionMode;
|
this._editionMode = editionMode;
|
||||||
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
||||||
|
this._padChooser = null;
|
||||||
|
|
||||||
let deviceManager = Clutter.DeviceManager.get_default();
|
let deviceManager = Clutter.DeviceManager.get_default();
|
||||||
|
this._deviceAddedId = deviceManager.connect('device-added', Lang.bind(this, function (manager, 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', Lang.bind(this, function (manager, device) {
|
this._deviceRemovedId = deviceManager.connect('device-removed', Lang.bind(this, function (manager, device) {
|
||||||
// If the device is being removed, destroy the padOsd.
|
// If the device is being removed, destroy the padOsd.
|
||||||
if (device == this.padDevice)
|
if (device == this.padDevice) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
} else if (this._groupPads.indexOf(device) != -1) {
|
||||||
|
// Or update the pad chooser if the device belongs to
|
||||||
|
// the same group.
|
||||||
|
this._groupPads.splice(this._groupPads.indexOf(device), 1);
|
||||||
|
this._updatePadChooser();
|
||||||
|
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
deviceManager.list_devices().forEach(Lang.bind(this, function(device) {
|
||||||
|
if (device != this.padDevice &&
|
||||||
|
device.get_device_type() == Clutter.InputDeviceType.PAD_DEVICE &&
|
||||||
|
this.padDevice.is_grouped(device))
|
||||||
|
this._groupPads.push(device);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ style_class: 'pad-osd-window',
|
this.actor = new St.BoxLayout({ style_class: 'pad-osd-window',
|
||||||
@ -552,13 +641,25 @@ const PadOsd = new Lang.Class({
|
|||||||
let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
|
let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
|
||||||
this.actor.add_constraint(constraint);
|
this.actor.add_constraint(constraint);
|
||||||
|
|
||||||
|
this._titleBox = new St.BoxLayout({ style_class: 'pad-osd-title-box',
|
||||||
|
vertical: false,
|
||||||
|
x_expand: false,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER });
|
||||||
|
this.actor.add_actor(this._titleBox);
|
||||||
|
|
||||||
|
let labelBox = new St.BoxLayout({ style_class: 'pad-osd-title-menu-box',
|
||||||
|
vertical: true });
|
||||||
|
this._titleBox.add_actor(labelBox);
|
||||||
|
|
||||||
this._titleLabel = new St.Label({ style: 'font-side: larger; font-weight: bold;',
|
this._titleLabel = new St.Label({ style: 'font-side: larger; font-weight: bold;',
|
||||||
x_align: Clutter.ActorAlign.CENTER });
|
x_align: Clutter.ActorAlign.CENTER });
|
||||||
this._titleLabel.clutter_text.set_text(padDevice.get_device_name());
|
this._titleLabel.clutter_text.set_text(padDevice.get_device_name());
|
||||||
this.actor.add_actor(this._titleLabel);
|
labelBox.add_actor(this._titleLabel);
|
||||||
|
|
||||||
this._tipLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER });
|
this._tipLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER });
|
||||||
this.actor.add_actor(this._tipLabel);
|
labelBox.add_actor(this._tipLabel);
|
||||||
|
|
||||||
|
this._updatePadChooser();
|
||||||
|
|
||||||
this._actionEditor = new ActionEditor();
|
this._actionEditor = new ActionEditor();
|
||||||
this._actionEditor.connect('done', Lang.bind(this, this._endButtonActionEdition));
|
this._actionEditor.connect('done', Lang.bind(this, this._endButtonActionEdition));
|
||||||
@ -605,6 +706,33 @@ const PadOsd = new Lang.Class({
|
|||||||
Main.pushModal(this.actor);
|
Main.pushModal(this.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updatePadChooser: function () {
|
||||||
|
if (this._groupPads.length > 1) {
|
||||||
|
if (this._padChooser == null) {
|
||||||
|
this._padChooser = new PadChooser(this.padDevice, this._groupPads)
|
||||||
|
this._padChooser.connect('pad-selected', Lang.bind(this, function (chooser, pad) {
|
||||||
|
this._requestForOtherPad(pad);
|
||||||
|
}));
|
||||||
|
this._titleBox.add_child(this._padChooser.actor);
|
||||||
|
} else {
|
||||||
|
this._padChooser.update(this._groupPads);
|
||||||
|
}
|
||||||
|
} else if (this._padChooser != null) {
|
||||||
|
this._padChooser.destroy();
|
||||||
|
this._padChooser = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_requestForOtherPad: function (pad) {
|
||||||
|
if (pad == this.padDevice ||
|
||||||
|
this._groupPads.indexOf(pad) == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let editionMode = this._editionMode;
|
||||||
|
this.destroy();
|
||||||
|
global.display.request_pad_osd(pad, editionMode);
|
||||||
|
},
|
||||||
|
|
||||||
_createLabel: function (type, number, dir) {
|
_createLabel: function (type, number, dir) {
|
||||||
let str = global.display.get_pad_action_label(this.padDevice, type, number);
|
let str = global.display.get_pad_action_label(this.padDevice, type, number);
|
||||||
let label = new St.Label({ text: str ? str : _("None") });
|
let label = new St.Label({ text: str ? str : _("None") });
|
||||||
@ -632,6 +760,13 @@ const PadOsd = new Lang.Class({
|
|||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the event comes from another pad in the same group,
|
||||||
|
// show the OSD for it.
|
||||||
|
if (this._groupPads.indexOf(event.get_source_device()) != -1) {
|
||||||
|
this._requestForOtherPad(event.get_source_device());
|
||||||
|
return Clutter.EVENT_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
return Clutter.EVENT_PROPAGATE;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -700,11 +835,15 @@ const PadOsd = new Lang.Class({
|
|||||||
Main.popModal(this.actor);
|
Main.popModal(this.actor);
|
||||||
this._actionEditor.close();
|
this._actionEditor.close();
|
||||||
|
|
||||||
|
let deviceManager = Clutter.DeviceManager.get_default();
|
||||||
if (this._deviceRemovedId != 0) {
|
if (this._deviceRemovedId != 0) {
|
||||||
let deviceManager = Clutter.DeviceManager.get_default();
|
|
||||||
deviceManager.disconnect(this._deviceRemovedId);
|
deviceManager.disconnect(this._deviceRemovedId);
|
||||||
this._deviceRemovedId = 0;
|
this._deviceRemovedId = 0;
|
||||||
}
|
}
|
||||||
|
if (this._deviceAddedId != 0) {
|
||||||
|
deviceManager.disconnect(this._deviceAddedId);
|
||||||
|
this._deviceAddedId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (this._capturedEventId != 0) {
|
if (this._capturedEventId != 0) {
|
||||||
global.stage.disconnect(this._capturedEventId);
|
global.stage.disconnect(this._capturedEventId);
|
||||||
|
@ -719,9 +719,11 @@ const AggregateMenu = new Lang.Class({
|
|||||||
this._system = new imports.ui.status.system.Indicator();
|
this._system = new imports.ui.status.system.Indicator();
|
||||||
this._screencast = new imports.ui.status.screencast.Indicator();
|
this._screencast = new imports.ui.status.screencast.Indicator();
|
||||||
this._location = new imports.ui.status.location.Indicator();
|
this._location = new imports.ui.status.location.Indicator();
|
||||||
|
this._nightLight = new imports.ui.status.nightLight.Indicator();
|
||||||
|
|
||||||
this._indicators.add_child(this._screencast.indicators);
|
this._indicators.add_child(this._screencast.indicators);
|
||||||
this._indicators.add_child(this._location.indicators);
|
this._indicators.add_child(this._location.indicators);
|
||||||
|
this._indicators.add_child(this._nightLight.indicators);
|
||||||
if (this._network) {
|
if (this._network) {
|
||||||
this._indicators.add_child(this._network.indicators);
|
this._indicators.add_child(this._network.indicators);
|
||||||
}
|
}
|
||||||
@ -745,6 +747,7 @@ const AggregateMenu = new Lang.Class({
|
|||||||
this.menu.addMenuItem(this._location.menu);
|
this.menu.addMenuItem(this._location.menu);
|
||||||
this.menu.addMenuItem(this._rfkill.menu);
|
this.menu.addMenuItem(this._rfkill.menu);
|
||||||
this.menu.addMenuItem(this._power.menu);
|
this.menu.addMenuItem(this._power.menu);
|
||||||
|
this.menu.addMenuItem(this._nightLight.menu);
|
||||||
this.menu.addMenuItem(this._system.menu);
|
this.menu.addMenuItem(this._system.menu);
|
||||||
|
|
||||||
menuLayout.addSizeChild(this._location.menu.actor);
|
menuLayout.addSizeChild(this._location.menu.actor);
|
||||||
|
@ -174,8 +174,14 @@ const Button = new Lang.Class({
|
|||||||
// menu is higher then the screen; it's useful if part of the menu is
|
// menu is higher then the screen; it's useful if part of the menu is
|
||||||
// scrollable so the minimum height is smaller than the natural height
|
// scrollable so the minimum height is smaller than the natural height
|
||||||
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
|
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
|
||||||
|
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||||
let verticalMargins = this.menu.actor.margin_top + this.menu.actor.margin_bottom;
|
let verticalMargins = this.menu.actor.margin_top + this.menu.actor.margin_bottom;
|
||||||
this.menu.actor.style = ('max-height: ' + Math.round(workArea.height - verticalMargins) + 'px;');
|
|
||||||
|
// The workarea and margin dimensions are in physical pixels, but CSS
|
||||||
|
// measures are in logical pixels, so make sure to consider the scale
|
||||||
|
// factor when computing max-height
|
||||||
|
let maxHeight = Math.round((workArea.height - verticalMargins) / scaleFactor);
|
||||||
|
this.menu.actor.style = ('max-height: %spx;').format(maxHeight);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
|
@ -605,6 +605,24 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
menuItem.actor.show();
|
menuItem.actor.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
moveMenuItem: function(menuItem, position) {
|
||||||
|
let items = this._getMenuItems();
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
while (i < items.length && position > 0) {
|
||||||
|
if (items[i] != menuItem)
|
||||||
|
position--;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < items.length) {
|
||||||
|
if (items[i] != menuItem)
|
||||||
|
this.box.set_child_below_sibling(menuItem.actor, items[i].actor);
|
||||||
|
} else {
|
||||||
|
this.box.set_child_above_sibling(menuItem.actor, null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addMenuItem: function(menuItem, position) {
|
addMenuItem: function(menuItem, position) {
|
||||||
let before_item = null;
|
let before_item = null;
|
||||||
if (position == undefined) {
|
if (position == undefined) {
|
||||||
@ -767,6 +785,11 @@ const PopupMenu = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onKeyPress: function(actor, event) {
|
_onKeyPress: function(actor, event) {
|
||||||
|
// Disable toggling the menu by keyboard
|
||||||
|
// when it cannot be toggled by pointer
|
||||||
|
if (!actor.reactive)
|
||||||
|
return Clutter.EVENT_PROPAGATE;
|
||||||
|
|
||||||
let navKey;
|
let navKey;
|
||||||
switch (this._boxPointer.arrowSide) {
|
switch (this._boxPointer.arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
|
@ -278,7 +278,8 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
name: metas[i]['name'],
|
name: metas[i]['name'],
|
||||||
description: metas[i]['description'],
|
description: metas[i]['description'],
|
||||||
createIcon: Lang.bind(this,
|
createIcon: Lang.bind(this,
|
||||||
this.createIcon, metas[i]) });
|
this.createIcon, metas[i]),
|
||||||
|
clipboardText: metas[i]['clipboardText'] });
|
||||||
}
|
}
|
||||||
callback(resultMetas);
|
callback(resultMetas);
|
||||||
},
|
},
|
||||||
|
@ -33,6 +33,9 @@ const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
|||||||
const LOCK_ENABLED_KEY = 'lock-enabled';
|
const LOCK_ENABLED_KEY = 'lock-enabled';
|
||||||
const LOCK_DELAY_KEY = 'lock-delay';
|
const LOCK_DELAY_KEY = 'lock-delay';
|
||||||
|
|
||||||
|
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
|
||||||
|
const DISABLE_LOCK_KEY = 'disable-lock-screen';
|
||||||
|
|
||||||
const LOCKED_STATE_STR = 'screenShield.locked';
|
const LOCKED_STATE_STR = 'screenShield.locked';
|
||||||
// fraction of screen height the arrow must reach before completing
|
// fraction of screen height the arrow must reach before completing
|
||||||
// the slide up automatically
|
// the slide up automatically
|
||||||
@ -541,6 +544,9 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._settings = new Gio.Settings({ schema_id: SCREENSAVER_SCHEMA });
|
this._settings = new Gio.Settings({ schema_id: SCREENSAVER_SCHEMA });
|
||||||
this._settings.connect('changed::' + LOCK_ENABLED_KEY, Lang.bind(this, this._syncInhibitor));
|
this._settings.connect('changed::' + LOCK_ENABLED_KEY, Lang.bind(this, this._syncInhibitor));
|
||||||
|
|
||||||
|
this._lockSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
|
||||||
|
this._lockSettings.connect('changed::' + DISABLE_LOCK_KEY, Lang.bind(this, this._syncInhibitor));
|
||||||
|
|
||||||
this._isModal = false;
|
this._isModal = false;
|
||||||
this._hasLockScreen = false;
|
this._hasLockScreen = false;
|
||||||
this._isGreeter = false;
|
this._isGreeter = false;
|
||||||
@ -701,8 +707,10 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_syncInhibitor: function() {
|
_syncInhibitor: function() {
|
||||||
|
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
|
||||||
|
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
|
||||||
let inhibit = (this._loginSession && this._loginSession.Active &&
|
let inhibit = (this._loginSession && this._loginSession.Active &&
|
||||||
!this._isActive && this._settings.get_boolean(LOCK_ENABLED_KEY));
|
!this._isActive && lockEnabled && !lockLocked);
|
||||||
if (inhibit) {
|
if (inhibit) {
|
||||||
this._loginManager.inhibit(_("GNOME needs to lock the screen"),
|
this._loginManager.inhibit(_("GNOME needs to lock the screen"),
|
||||||
Lang.bind(this, function(inhibitor) {
|
Lang.bind(this, function(inhibitor) {
|
||||||
@ -1290,6 +1298,11 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
lock: function(animate) {
|
lock: function(animate) {
|
||||||
|
if (this._lockSettings.get_boolean(DISABLE_LOCK_KEY)) {
|
||||||
|
log('Screen lock is locked down, not locking') // lock, lock - who's there?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Warn the user if we can't become modal
|
// Warn the user if we can't become modal
|
||||||
if (!this._becomeModal()) {
|
if (!this._becomeModal()) {
|
||||||
Main.notifyError(_("Unable to lock"),
|
Main.notifyError(_("Unable to lock"),
|
||||||
|
@ -152,6 +152,8 @@ const SearchResultsBase = new Lang.Class({
|
|||||||
|
|
||||||
this._resultDisplays = {};
|
this._resultDisplays = {};
|
||||||
|
|
||||||
|
this._clipboard = St.Clipboard.get_default();
|
||||||
|
|
||||||
this._cancellable = new Gio.Cancellable();
|
this._cancellable = new Gio.Cancellable();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -181,6 +183,8 @@ const SearchResultsBase = new Lang.Class({
|
|||||||
|
|
||||||
_activateResult: function(result, id) {
|
_activateResult: function(result, id) {
|
||||||
this.provider.activateResult(id, this._terms);
|
this.provider.activateResult(id, this._terms);
|
||||||
|
if (result.metaInfo.clipboardText)
|
||||||
|
this._clipboard.set_text(St.ClipboardType.CLIPBOARD, result.metaInfo.clipboardText);
|
||||||
Main.overview.toggle();
|
Main.overview.toggle();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ const ShellMountPasswordDialog = new Lang.Class({
|
|||||||
this.setInitialKeyFocus(this._passwordEntry);
|
this.setInitialKeyFocus(this._passwordEntry);
|
||||||
|
|
||||||
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label',
|
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label',
|
||||||
text: _("Sorry, that didn\'t work. Please try again.") });
|
text: _("Sorry, that didn’t work. Please try again.") });
|
||||||
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
this._errorMessageLabel.clutter_text.line_wrap = true;
|
this._errorMessageLabel.clutter_text.line_wrap = true;
|
||||||
this._errorMessageLabel.hide();
|
this._errorMessageLabel.hide();
|
||||||
|
@ -102,8 +102,8 @@ const ATIndicator = new Lang.Class({
|
|||||||
if (this._syncMenuVisibilityIdle)
|
if (this._syncMenuVisibilityIdle)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._syncMenuVisbilityIdle = Mainloop.idle_add(Lang.bind(this, this._syncMenuVisibility));
|
this._syncMenuVisibilityIdle = Mainloop.idle_add(Lang.bind(this, this._syncMenuVisibility));
|
||||||
GLib.Source.set_name_by_id(this._syncMenuVisbilityIdle, '[gnome-shell] this._syncMenuVisibility');
|
GLib.Source.set_name_by_id(this._syncMenuVisibilityIdle, '[gnome-shell] this._syncMenuVisibility');
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildItemExtended: function(string, initial_value, writable, on_set) {
|
_buildItemExtended: function(string, initial_value, writable, on_set) {
|
||||||
|
@ -9,6 +9,7 @@ const Main = imports.ui.main;
|
|||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
|
const PermissionStore = imports.misc.permissionStore;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -62,26 +63,6 @@ var AgentIface = '<node> \
|
|||||||
</interface> \
|
</interface> \
|
||||||
</node>';
|
</node>';
|
||||||
|
|
||||||
var PermissionStoreIface = '<node> \
|
|
||||||
<interface name="org.freedesktop.impl.portal.PermissionStore"> \
|
|
||||||
<method name="Lookup"> \
|
|
||||||
<arg name="table" type="s" direction="in"/> \
|
|
||||||
<arg name="id" type="s" direction="in"/> \
|
|
||||||
<arg name="permissions" type="a{sas}" direction="out"/> \
|
|
||||||
<arg name="data" type="v" direction="out"/> \
|
|
||||||
</method> \
|
|
||||||
<method name="Set"> \
|
|
||||||
<arg name="table" type="s" direction="in"/> \
|
|
||||||
<arg name="create" type="b" direction="in"/> \
|
|
||||||
<arg name="id" type="s" direction="in"/> \
|
|
||||||
<arg name="app_permissions" type="a{sas}" direction="in"/> \
|
|
||||||
<arg name="data" type="v" direction="in"/> \
|
|
||||||
</method> \
|
|
||||||
</interface> \
|
|
||||||
</node>';
|
|
||||||
|
|
||||||
const PermissionStore = Gio.DBusProxy.makeProxyWrapper(PermissionStoreIface);
|
|
||||||
|
|
||||||
const Indicator = new Lang.Class({
|
const Indicator = new Lang.Class({
|
||||||
Name: 'LocationIndicator',
|
Name: 'LocationIndicator',
|
||||||
Extends: PanelMenu.SystemIndicator,
|
Extends: PanelMenu.SystemIndicator,
|
||||||
@ -253,10 +234,7 @@ const Indicator = new Lang.Class({
|
|||||||
|
|
||||||
_connectToPermissionStore: function() {
|
_connectToPermissionStore: function() {
|
||||||
this._permStoreProxy = null;
|
this._permStoreProxy = null;
|
||||||
new PermissionStore(Gio.DBus.session,
|
new PermissionStore.PermissionStore(Lang.bind(this, this._onPermStoreProxyReady), null);
|
||||||
'org.freedesktop.impl.portal.PermissionStore',
|
|
||||||
'/org/freedesktop/impl/portal/PermissionStore',
|
|
||||||
Lang.bind(this, this._onPermStoreProxyReady));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPermStoreProxyReady: function(proxy, error) {
|
_onPermStoreProxyReady: function(proxy, error) {
|
||||||
@ -284,6 +262,7 @@ const AppAuthorizer = new Lang.Class({
|
|||||||
this.reqAccuracyLevel = reqAccuracyLevel;
|
this.reqAccuracyLevel = reqAccuracyLevel;
|
||||||
this._permStoreProxy = permStoreProxy;
|
this._permStoreProxy = permStoreProxy;
|
||||||
this._maxAccuracyLevel = maxAccuracyLevel;
|
this._maxAccuracyLevel = maxAccuracyLevel;
|
||||||
|
this._permissions = {};
|
||||||
|
|
||||||
this._accuracyLevel = GeoclueAccuracyLevel.NONE;
|
this._accuracyLevel = GeoclueAccuracyLevel.NONE;
|
||||||
},
|
},
|
||||||
|
@ -299,11 +299,22 @@ const NMConnectionSection = new Lang.Class({
|
|||||||
|
|
||||||
let item = this._connectionItems.get(connection.get_uuid());
|
let item = this._connectionItems.get(connection.get_uuid());
|
||||||
if (item)
|
if (item)
|
||||||
item.updateForConnection(connection);
|
this._updateForConnection(item, connection);
|
||||||
else
|
else
|
||||||
this._addConnection(connection);
|
this._addConnection(connection);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateForConnection: function(item, connection) {
|
||||||
|
let pos = this._connections.indexOf(connection);
|
||||||
|
|
||||||
|
this._connections.splice(pos, 1);
|
||||||
|
pos = Util.insertSorted(this._connections, connection, Lang.bind(this, this._connectionSortFunction));
|
||||||
|
this._labelSection.moveMenuItem(item.labelItem, pos);
|
||||||
|
this._radioSection.moveMenuItem(item.radioItem, pos);
|
||||||
|
|
||||||
|
item.updateForConnection(connection);
|
||||||
|
},
|
||||||
|
|
||||||
_addConnection: function(connection) {
|
_addConnection: function(connection) {
|
||||||
let item = this._makeConnectionItem(connection);
|
let item = this._makeConnectionItem(connection);
|
||||||
if (!item)
|
if (!item)
|
||||||
@ -758,6 +769,14 @@ const NMWirelessDialog = new Lang.Class({
|
|||||||
this._scanTimeoutId = Mainloop.timeout_add_seconds(15, Lang.bind(this, this._onScanTimeout));
|
this._scanTimeoutId = Mainloop.timeout_add_seconds(15, Lang.bind(this, this._onScanTimeout));
|
||||||
GLib.Source.set_name_by_id(this._scanTimeoutId, '[gnome-shell] this._onScanTimeout');
|
GLib.Source.set_name_by_id(this._scanTimeoutId, '[gnome-shell] this._onScanTimeout');
|
||||||
this._onScanTimeout();
|
this._onScanTimeout();
|
||||||
|
|
||||||
|
let id = Main.sessionMode.connect('updated', () => {
|
||||||
|
if (Main.sessionMode.allowSettings)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Main.sessionMode.disconnect(id);
|
||||||
|
this.close();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
@ -1343,7 +1362,11 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
if (!this._device.active_connection)
|
if (!this._device.active_connection)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
let connection = this._settings.get_connection_by_path(this._device.active_connection.connection);
|
let connectionPath = this._device.active_connection.connection;
|
||||||
|
if (!connectionPath)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let connection = this._settings.get_connection_by_path(connectionPath);
|
||||||
if (!connection)
|
if (!connection)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1420,7 +1443,7 @@ const NMVPNConnectionItem = new Lang.Class({
|
|||||||
case NetworkManager.VPNConnectionState.PREPARE:
|
case NetworkManager.VPNConnectionState.PREPARE:
|
||||||
case NetworkManager.VPNConnectionState.CONNECT:
|
case NetworkManager.VPNConnectionState.CONNECT:
|
||||||
case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
|
case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
|
||||||
return _("connecting...");
|
return _("connecting…");
|
||||||
case NetworkManager.VPNConnectionState.NEED_AUTH:
|
case NetworkManager.VPNConnectionState.NEED_AUTH:
|
||||||
/* Translators: this is for network connections that require some kind of key or password */
|
/* Translators: this is for network connections that require some kind of key or password */
|
||||||
return _("authentication required");
|
return _("authentication required");
|
||||||
@ -1543,8 +1566,10 @@ const NMVPNSection = new Lang.Class({
|
|||||||
item.setActiveConnection(null);
|
item.setActiveConnection(null);
|
||||||
}
|
}
|
||||||
vpnConnections.forEach(Lang.bind(this, function(a) {
|
vpnConnections.forEach(Lang.bind(this, function(a) {
|
||||||
let item = this._connectionItems.get(a._connection.get_uuid());
|
if (a._connection) {
|
||||||
item.setActiveConnection(a);
|
let item = this._connectionItems.get(a._connection.get_uuid());
|
||||||
|
item.setActiveConnection(a);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2053,7 +2078,7 @@ const NMApplet = new Lang.Class({
|
|||||||
// (but in general we should only prompt a portal if we know there is a portal)
|
// (but in general we should only prompt a portal if we know there is a portal)
|
||||||
if (GLib.getenv('GNOME_SHELL_CONNECTIVITY_TEST') != null)
|
if (GLib.getenv('GNOME_SHELL_CONNECTIVITY_TEST') != null)
|
||||||
isPortal = isPortal || this._client.connectivity < NetworkManager.ConnectivityState.FULL;
|
isPortal = isPortal || this._client.connectivity < NetworkManager.ConnectivityState.FULL;
|
||||||
if (!isPortal)
|
if (!isPortal || Main.sessionMode.isGreeter)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let path = this._mainConnection.get_path();
|
let path = this._mainConnection.get_path();
|
||||||
|
74
js/ui/status/nightLight.js
Normal file
74
js/ui/status/nightLight.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
|
const BUS_NAME = 'org.gnome.SettingsDaemon.Color';
|
||||||
|
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Color';
|
||||||
|
|
||||||
|
const ColorInterface = '<node> \
|
||||||
|
<interface name="org.gnome.SettingsDaemon.Color"> \
|
||||||
|
<property name="DisabledUntilTomorrow" type="b" access="readwrite"/> \
|
||||||
|
<property name="NightLightActive" type="b" access="read"/> \
|
||||||
|
</interface> \
|
||||||
|
</node>';
|
||||||
|
|
||||||
|
const ColorProxy = Gio.DBusProxy.makeProxyWrapper(ColorInterface);
|
||||||
|
|
||||||
|
const Indicator = new Lang.Class({
|
||||||
|
Name: 'NightLightIndicator',
|
||||||
|
Extends: PanelMenu.SystemIndicator,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
|
this._indicator = this._addIndicator();
|
||||||
|
this._indicator.icon_name = 'night-light-symbolic';
|
||||||
|
this._proxy = new ColorProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
|
||||||
|
(proxy, error) => {
|
||||||
|
if (error) {
|
||||||
|
log(error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._proxy.connect('g-properties-changed',
|
||||||
|
Lang.bind(this, this._sync));
|
||||||
|
this._sync();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._item = new PopupMenu.PopupSubMenuMenuItem("", true);
|
||||||
|
this._item.icon.icon_name = 'night-light-symbolic';
|
||||||
|
this._disableItem = this._item.menu.addAction('', () => {
|
||||||
|
this._proxy.DisabledUntilTomorrow = !this._proxy.DisabledUntilTomorrow;
|
||||||
|
});
|
||||||
|
this._item.menu.addAction(_("Turn Off"), () => {
|
||||||
|
let settings = new Gio.Settings({ schema_id: 'org.gnome.settings-daemon.plugins.color' });
|
||||||
|
settings.set_boolean('night-light-enabled', false);
|
||||||
|
});
|
||||||
|
this._item.menu.addSettingsAction(_("Display Settings"), 'gnome-display-panel.desktop');
|
||||||
|
this.menu.addMenuItem(this._item);
|
||||||
|
|
||||||
|
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||||
|
this._sessionUpdated();
|
||||||
|
this._sync();
|
||||||
|
},
|
||||||
|
|
||||||
|
_sessionUpdated: function() {
|
||||||
|
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
||||||
|
this.menu.setSensitive(sensitive);
|
||||||
|
},
|
||||||
|
|
||||||
|
_sync: function() {
|
||||||
|
let visible = this._proxy.NightLightActive;
|
||||||
|
let disabled = this._proxy.DisabledUntilTomorrow;
|
||||||
|
|
||||||
|
this._item.label.text = disabled ? _("Night Light Disabled")
|
||||||
|
: _("Night Light On");
|
||||||
|
this._disableItem.label.text = disabled ? _("Resume")
|
||||||
|
: _("Disable Until Tomorrow");
|
||||||
|
this._item.actor.visible = this._indicator.visible = visible;
|
||||||
|
}
|
||||||
|
});
|
@ -48,8 +48,14 @@ const AltSwitcher = new Lang.Class({
|
|||||||
|
|
||||||
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
||||||
|
|
||||||
|
this._flipped = false;
|
||||||
|
|
||||||
|
this._clickAction = new Clutter.ClickAction();
|
||||||
|
this._clickAction.connect('long-press', Lang.bind(this, this._onLongPress));
|
||||||
|
|
||||||
this.actor = new St.Bin();
|
this.actor = new St.Bin();
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
this.actor.connect('notify::mapped', () => { this._flipped = false; });
|
||||||
},
|
},
|
||||||
|
|
||||||
_sync: function() {
|
_sync: function() {
|
||||||
@ -58,14 +64,25 @@ const AltSwitcher = new Lang.Class({
|
|||||||
if (this._standard.visible && this._alternate.visible) {
|
if (this._standard.visible && this._alternate.visible) {
|
||||||
let [x, y, mods] = global.get_pointer();
|
let [x, y, mods] = global.get_pointer();
|
||||||
let altPressed = (mods & Clutter.ModifierType.MOD1_MASK) != 0;
|
let altPressed = (mods & Clutter.ModifierType.MOD1_MASK) != 0;
|
||||||
childToShow = altPressed ? this._alternate : this._standard;
|
if (this._flipped)
|
||||||
|
childToShow = altPressed ? this._standard : this._alternate;
|
||||||
|
else
|
||||||
|
childToShow = altPressed ? this._alternate : this._standard;
|
||||||
} else if (this._standard.visible) {
|
} else if (this._standard.visible) {
|
||||||
childToShow = this._standard;
|
childToShow = this._standard;
|
||||||
} else if (this._alternate.visible) {
|
} else if (this._alternate.visible) {
|
||||||
childToShow = this._alternate;
|
childToShow = this._alternate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.actor.get_child() != childToShow) {
|
let childShown = this.actor.get_child();
|
||||||
|
if (childShown != childToShow) {
|
||||||
|
if (childShown) {
|
||||||
|
if (childShown.fake_release)
|
||||||
|
childShown.fake_release();
|
||||||
|
childShown.remove_action(this._clickAction);
|
||||||
|
}
|
||||||
|
childToShow.add_action(this._clickAction);
|
||||||
|
|
||||||
let hasFocus = this.actor.contains(global.stage.get_key_focus());
|
let hasFocus = this.actor.contains(global.stage.get_key_focus());
|
||||||
this.actor.set_child(childToShow);
|
this.actor.set_child(childToShow);
|
||||||
if (hasFocus)
|
if (hasFocus)
|
||||||
@ -96,6 +113,16 @@ const AltSwitcher = new Lang.Class({
|
|||||||
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
return Clutter.EVENT_PROPAGATE;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onLongPress: function(action, actor, state) {
|
||||||
|
if (state == Clutter.LongPressState.QUERY ||
|
||||||
|
state == Clutter.LongPressState.CANCEL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
this._flipped = !this._flipped;
|
||||||
|
this._sync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Indicator = new Lang.Class({
|
const Indicator = new Lang.Class({
|
||||||
|
@ -10,6 +10,7 @@ const Signals = imports.signals;
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const GObject = imports.gi.GObject;
|
||||||
|
|
||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@ -77,6 +78,7 @@ Signals.addSignalMethods(TouchpadShowOverviewAction.prototype);
|
|||||||
const ShowOverviewAction = new Lang.Class({
|
const ShowOverviewAction = new Lang.Class({
|
||||||
Name: 'ShowOverviewAction',
|
Name: 'ShowOverviewAction',
|
||||||
Extends: Clutter.GestureAction,
|
Extends: Clutter.GestureAction,
|
||||||
|
Signals: { 'activated': { param_types: [GObject.TYPE_DOUBLE] } },
|
||||||
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this.parent();
|
this.parent();
|
||||||
@ -135,7 +137,6 @@ const ShowOverviewAction = new Lang.Class({
|
|||||||
this.emit('activated', areaDiff);
|
this.emit('activated', areaDiff);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ShowOverviewAction.prototype);
|
|
||||||
|
|
||||||
const ViewSelector = new Lang.Class({
|
const ViewSelector = new Lang.Class({
|
||||||
Name: 'ViewSelector',
|
Name: 'ViewSelector',
|
||||||
|
@ -18,6 +18,7 @@ const ModalDialog = imports.ui.modalDialog;
|
|||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const WindowMenu = imports.ui.windowMenu;
|
const WindowMenu = imports.ui.windowMenu;
|
||||||
const PadOsd = imports.ui.padOsd;
|
const PadOsd = imports.ui.padOsd;
|
||||||
|
const EdgeDragAction = imports.ui.edgeDragAction;
|
||||||
|
|
||||||
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
|
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
|
||||||
const MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
|
const MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
|
||||||
@ -33,6 +34,25 @@ const UNDIM_TIME = 0.250;
|
|||||||
const DISPLAY_REVERT_TIMEOUT = 20; // in seconds - keep in sync with mutter
|
const DISPLAY_REVERT_TIMEOUT = 20; // in seconds - keep in sync with mutter
|
||||||
const ONE_SECOND = 1000; // in ms
|
const ONE_SECOND = 1000; // in ms
|
||||||
|
|
||||||
|
const GSD_WACOM_BUS_NAME = 'org.gnome.SettingsDaemon.Wacom';
|
||||||
|
const GSD_WACOM_OBJECT_PATH = '/org/gnome/SettingsDaemon/Wacom';
|
||||||
|
|
||||||
|
const GsdWacomIface = '<node name="/org/gnome/SettingsDaemon/Wacom"> \
|
||||||
|
<interface name="org.gnome.SettingsDaemon.Wacom"> \
|
||||||
|
<method name="SetGroupModeLED"> \
|
||||||
|
<arg name="device_path" direction="in" type="s"/> \
|
||||||
|
<arg name="group" direction="in" type="u"/> \
|
||||||
|
<arg name="mode" direction="in" type="u"/> \
|
||||||
|
</method> \
|
||||||
|
<method name="SetOLEDLabels"> \
|
||||||
|
<arg name="device_path" direction="in" type="s"/> \
|
||||||
|
<arg name="labels" direction="in" type="as"/> \
|
||||||
|
</method> \
|
||||||
|
</interface> \
|
||||||
|
</node>';
|
||||||
|
|
||||||
|
const GsdWacomProxy = Gio.DBusProxy.makeProxyWrapper(GsdWacomIface);
|
||||||
|
|
||||||
const DisplayChangeDialog = new Lang.Class({
|
const DisplayChangeDialog = new Lang.Class({
|
||||||
Name: 'DisplayChangeDialog',
|
Name: 'DisplayChangeDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
@ -535,6 +555,7 @@ Signals.addSignalMethods(TouchpadWorkspaceSwitchAction.prototype);
|
|||||||
const WorkspaceSwitchAction = new Lang.Class({
|
const WorkspaceSwitchAction = new Lang.Class({
|
||||||
Name: 'WorkspaceSwitchAction',
|
Name: 'WorkspaceSwitchAction',
|
||||||
Extends: Clutter.SwipeAction,
|
Extends: Clutter.SwipeAction,
|
||||||
|
Signals: { 'activated': { param_types: [Meta.MotionDirection.$gtype] } },
|
||||||
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
const MOTION_THRESHOLD = 50;
|
const MOTION_THRESHOLD = 50;
|
||||||
@ -572,11 +593,11 @@ const WorkspaceSwitchAction = new Lang.Class({
|
|||||||
this.emit('activated', dir);
|
this.emit('activated', dir);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(WorkspaceSwitchAction.prototype);
|
|
||||||
|
|
||||||
const AppSwitchAction = new Lang.Class({
|
const AppSwitchAction = new Lang.Class({
|
||||||
Name: 'AppSwitchAction',
|
Name: 'AppSwitchAction',
|
||||||
Extends: Clutter.GestureAction,
|
Extends: Clutter.GestureAction,
|
||||||
|
Signals: { 'activated': {} },
|
||||||
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this.parent();
|
this.parent();
|
||||||
@ -638,7 +659,6 @@ const AppSwitchAction = new Lang.Class({
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(AppSwitchAction.prototype);
|
|
||||||
|
|
||||||
const ResizePopup = new Lang.Class({
|
const ResizePopup = new Lang.Class({
|
||||||
Name: 'ResizePopup',
|
Name: 'ResizePopup',
|
||||||
@ -656,7 +676,7 @@ const ResizePopup = new Lang.Class({
|
|||||||
set: function(rect, displayW, displayH) {
|
set: function(rect, displayW, displayH) {
|
||||||
/* Translators: This represents the size of a window. The first number is
|
/* Translators: This represents the size of a window. The first number is
|
||||||
* the width of the window and the second is the height. */
|
* the width of the window and the second is the height. */
|
||||||
let text = _("%d x %d").format(displayW, displayH);
|
let text = _("%d × %d").format(displayW, displayH);
|
||||||
this._label.set_text(text);
|
this._label.set_text(text);
|
||||||
|
|
||||||
this._widget.set_position(rect.x, rect.y);
|
this._widget.set_position(rect.x, rect.y);
|
||||||
@ -920,6 +940,34 @@ const WindowManager = new Lang.Class({
|
|||||||
|
|
||||||
global.display.connect('show-resize-popup', Lang.bind(this, this._showResizePopup));
|
global.display.connect('show-resize-popup', Lang.bind(this, this._showResizePopup));
|
||||||
global.display.connect('show-pad-osd', Lang.bind(this, this._showPadOsd));
|
global.display.connect('show-pad-osd', Lang.bind(this, this._showPadOsd));
|
||||||
|
global.display.connect('show-osd', Lang.bind(this, function (display, monitorIndex, iconName, label) {
|
||||||
|
let icon = Gio.Icon.new_for_string(iconName);
|
||||||
|
Main.osdWindowManager.show(monitorIndex, icon, label, null);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._gsdWacomProxy = new GsdWacomProxy(Gio.DBus.session, GSD_WACOM_BUS_NAME,
|
||||||
|
GSD_WACOM_OBJECT_PATH,
|
||||||
|
Lang.bind(this, function(proxy, error) {
|
||||||
|
if (error) {
|
||||||
|
log(error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
global.display.connect('pad-mode-switch', Lang.bind(this, function (display, pad, group, mode) {
|
||||||
|
let labels = [];
|
||||||
|
|
||||||
|
//FIXME: Fix num buttons
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
let str = display.get_pad_action_label(pad, Meta.PadActionType.BUTTON, i);
|
||||||
|
labels.push(str ? str: '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._gsdWacomProxy) {
|
||||||
|
this._gsdWacomProxy.SetOLEDLabelsRemote(pad.get_device_node(), labels);
|
||||||
|
this._gsdWacomProxy.SetGroupModeLEDRemote(pad.get_device_node(), group, mode);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
Main.overview.connect('showing', Lang.bind(this, function() {
|
||||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||||
@ -949,6 +997,12 @@ const WindowManager = new Lang.Class({
|
|||||||
gesture = new AppSwitchAction();
|
gesture = new AppSwitchAction();
|
||||||
gesture.connect('activated', Lang.bind(this, this._switchApp));
|
gesture.connect('activated', Lang.bind(this, this._switchApp));
|
||||||
global.stage.add_action(gesture);
|
global.stage.add_action(gesture);
|
||||||
|
|
||||||
|
gesture = new EdgeDragAction.EdgeDragAction(St.Side.BOTTOM, Shell.ActionMode.ALL);
|
||||||
|
gesture.connect('activated', Lang.bind(this, function() {
|
||||||
|
Main.keyboard.show(Main.layoutManager.bottomIndex);
|
||||||
|
}));
|
||||||
|
global.stage.add_action(gesture);
|
||||||
},
|
},
|
||||||
|
|
||||||
_showPadOsd: function (display, device, settings, imagePath, editionMode, monitorIndex) {
|
_showPadOsd: function (display, device, settings, imagePath, editionMode, monitorIndex) {
|
||||||
@ -1082,6 +1136,9 @@ const WindowManager = new Lang.Class({
|
|||||||
if (!this._shouldAnimate())
|
if (!this._shouldAnimate())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!actor.get_texture())
|
||||||
|
return false;
|
||||||
|
|
||||||
let type = actor.meta_window.get_window_type();
|
let type = actor.meta_window.get_window_type();
|
||||||
return types.indexOf(type) >= 0;
|
return types.indexOf(type) >= 0;
|
||||||
},
|
},
|
||||||
@ -1286,6 +1343,8 @@ const WindowManager = new Lang.Class({
|
|||||||
_sizeChangedWindow: function(shellwm, actor) {
|
_sizeChangedWindow: function(shellwm, actor) {
|
||||||
if (!actor.__fullscreenInfo)
|
if (!actor.__fullscreenInfo)
|
||||||
return;
|
return;
|
||||||
|
if (this._resizing.indexOf(actor) != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
let actorClone = actor.__fullscreenInfo.clone;
|
let actorClone = actor.__fullscreenInfo.clone;
|
||||||
let targetRect = actor.meta_window.get_frame_rect();
|
let targetRect = actor.meta_window.get_frame_rect();
|
||||||
|
@ -97,8 +97,6 @@ const WindowMenu = new Lang.Class({
|
|||||||
if (window.is_always_on_all_workspaces())
|
if (window.is_always_on_all_workspaces())
|
||||||
item.setSensitive(false);
|
item.setSensitive(false);
|
||||||
|
|
||||||
let nWorkspaces = global.screen.n_workspaces;
|
|
||||||
|
|
||||||
if (!isSticky) {
|
if (!isSticky) {
|
||||||
let workspace = window.get_workspace();
|
let workspace = window.get_workspace();
|
||||||
if (workspace != workspace.get_neighbor(Meta.MotionDirection.LEFT)) {
|
if (workspace != workspace.get_neighbor(Meta.MotionDirection.LEFT)) {
|
||||||
|
@ -111,7 +111,7 @@ const WindowClone = new Lang.Class({
|
|||||||
this.metaWindow._delegate = this;
|
this.metaWindow._delegate = this;
|
||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
|
|
||||||
this._windowClone = new Clutter.Clone({ source: realWindow.get_texture() });
|
this._windowClone = new Clutter.Clone({ source: realWindow });
|
||||||
// We expect this.actor to be used for all interaction rather than
|
// We expect this.actor to be used for all interaction rather than
|
||||||
// this._windowClone; as the former is reactive and the latter
|
// this._windowClone; as the former is reactive and the latter
|
||||||
// is not, this just works for most cases. However, for DND all
|
// is not, this just works for most cases. However, for DND all
|
||||||
@ -471,6 +471,10 @@ const WindowOverlay = new Lang.Class({
|
|||||||
this.title = title;
|
this.title = title;
|
||||||
this.closeButton = button;
|
this.closeButton = button;
|
||||||
|
|
||||||
|
// Don't block drop targets
|
||||||
|
Shell.util_set_hidden_from_pick(this.title, true);
|
||||||
|
Shell.util_set_hidden_from_pick(this.border, true);
|
||||||
|
|
||||||
parentActor.add_actor(this.title);
|
parentActor.add_actor(this.title);
|
||||||
parentActor.add_actor(this.border);
|
parentActor.add_actor(this.border);
|
||||||
parentActor.add_actor(this.closeButton);
|
parentActor.add_actor(this.closeButton);
|
||||||
|
@ -24,9 +24,10 @@ const XdndHandler = new Lang.Class({
|
|||||||
if (!Meta.is_wayland_compositor())
|
if (!Meta.is_wayland_compositor())
|
||||||
global.init_xdnd();
|
global.init_xdnd();
|
||||||
|
|
||||||
global.connect('xdnd-enter', Lang.bind(this, this._onEnter));
|
var dnd = Meta.get_backend().get_dnd();
|
||||||
global.connect('xdnd-position-changed', Lang.bind(this, this._onPositionChanged));
|
dnd.connect('dnd-enter', Lang.bind(this, this._onEnter));
|
||||||
global.connect('xdnd-leave', Lang.bind(this, this._onLeave));
|
dnd.connect('dnd-position-change', Lang.bind(this, this._onPositionChanged));
|
||||||
|
dnd.connect('dnd-leave', Lang.bind(this, this._onLeave));
|
||||||
|
|
||||||
this._windowGroupVisibilityHandlerId = 0;
|
this._windowGroupVisibilityHandlerId = 0;
|
||||||
},
|
},
|
||||||
|
@ -53,6 +53,7 @@ js/ui/status/brightness.js
|
|||||||
js/ui/status/keyboard.js
|
js/ui/status/keyboard.js
|
||||||
js/ui/status/location.js
|
js/ui/status/location.js
|
||||||
js/ui/status/network.js
|
js/ui/status/network.js
|
||||||
|
js/ui/status/nightLight.js
|
||||||
js/ui/status/power.js
|
js/ui/status/power.js
|
||||||
js/ui/status/rfkill.js
|
js/ui/status/rfkill.js
|
||||||
js/ui/status/system.js
|
js/ui/status/system.js
|
||||||
|
2
po/fa.po
2
po/fa.po
@ -1674,7 +1674,7 @@ msgstr "تقویم اوولوشن"
|
|||||||
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||||
#: src/calendar-server/evolution-calendar.desktop.in:6
|
#: src/calendar-server/evolution-calendar.desktop.in:6
|
||||||
msgid "evolution"
|
msgid "evolution"
|
||||||
msgstr "اوولوشن"
|
msgstr "evolution"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound outputs on a particular device
|
#. * The number of sound outputs on a particular device
|
||||||
|
357
po/gd.po
357
po/gd.po
@ -1,14 +1,14 @@
|
|||||||
# Scottish Gaelic translation for gnome-shell.
|
# Scottish Gaelic translation for gnome-shell.
|
||||||
# Copyright (C) 2015 gnome-shell's COPYRIGHT HOLDER
|
# Copyright (C) 2015 gnome-shell's COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
# GunChleoc <fios@foramnagaidhlig.net>, 2015, 2016.
|
# GunChleoc <fios@foramnagaidhlig.net>, 2015, 2016, 2017.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"=gnome-shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2016-09-12 23:57+0000\n"
|
"POT-Creation-Date: 2017-03-02 17:53+0000\n"
|
||||||
"PO-Revision-Date: 2016-09-13 10:47+0100\n"
|
"PO-Revision-Date: 2017-03-07 12:03+0100\n"
|
||||||
"Last-Translator: GunChleoc <fios@foramnagaidhlig.net>\n"
|
"Last-Translator: GunChleoc <fios@foramnagaidhlig.net>\n"
|
||||||
"Language-Team: Fòram na Gàidhlig\n"
|
"Language-Team: Fòram na Gàidhlig\n"
|
||||||
"Language: gd\n"
|
"Language: gd\n"
|
||||||
@ -61,10 +61,136 @@ msgstr "Slige GNOME"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Stiùireadh uinneagan is tòiseachadh aplacaidean"
|
msgstr "Stiùireadh uinneagan is tòiseachadh aplacaidean"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:6
|
||||||
|
msgid "Enable internal tools useful for developers and testers from Alt-F2"
|
||||||
|
msgstr "Cuir an comas innealan an luchd-leasachaidh 's deuchainne o Alt-F2"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:9
|
||||||
|
msgid ""
|
||||||
|
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
|
||||||
|
"dialog."
|
||||||
|
msgstr ""
|
||||||
|
"Ceadaich inntrigeadh dha na h-innealan a chum dì-bhugachaidh 's sgrùdaidh le "
|
||||||
|
"còmhradh Alt-F2."
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:16
|
#: data/org.gnome.shell.gschema.xml.in:16
|
||||||
msgid "UUIDs of extensions to enable"
|
msgid "UUIDs of extensions to enable"
|
||||||
msgstr "UUIDs nan leudachan ri an cur an comas"
|
msgstr "UUIDs nan leudachan ri an cur an comas"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:17
|
||||||
|
msgid ""
|
||||||
|
"GNOME Shell extensions have a UUID property; this key lists extensions which "
|
||||||
|
"should be loaded. Any extension that wants to be loaded needs to be in this "
|
||||||
|
"list. You can also manipulate this list with the EnableExtension and "
|
||||||
|
"DisableExtension D-Bus methods on org.gnome.Shell."
|
||||||
|
msgstr ""
|
||||||
|
"Tha buadh UUID aig leudachain na Slige GNOME; seallaidh an iuchair sin na "
|
||||||
|
"leudachain a bu chòir luchdadh. Feumaidh gach leudachan a tha ag iarraidh "
|
||||||
|
"luchdadh a bhith air an liosta seo. 'S urrainn dhut an liosta seo "
|
||||||
|
"atharrachadh cuideachd leis na modhan D-Bus EnableExtension agus "
|
||||||
|
"DisableExtension air org.gnome.Shell."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:26
|
||||||
|
msgid "Disables the validation of extension version compatibility"
|
||||||
|
msgstr ""
|
||||||
|
"Cuiridh seo à comas dearbhadh na co-chòrdalachd airson tionndadh nan "
|
||||||
|
"leudachan"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:27
|
||||||
|
msgid ""
|
||||||
|
"GNOME Shell will only load extensions that claim to support the current "
|
||||||
|
"running version. Enabling this option will disable this check and try to "
|
||||||
|
"load all extensions regardless of the versions they claim to support."
|
||||||
|
msgstr ""
|
||||||
|
"Cha luchdaich an t-Slige GNOME ach leudachain a dh'innseas gu bheil iar co-"
|
||||||
|
"chòrdail leis an tionndadh a tha 'ga ruith. Ma chuireas tu an roghainn seo "
|
||||||
|
"an comas, thèid an dearbhadh a chur à comas agus feuchaidh sinn ris a h-uile "
|
||||||
|
"leudachan a luchdadh ge b' e dè na tionndaidhean ris an cuir iad taic dhan "
|
||||||
|
"rèir-san."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:35
|
||||||
|
msgid "List of desktop file IDs for favorite applications"
|
||||||
|
msgstr ""
|
||||||
|
"Liosta dhe IDan nam faidhlichean desktop airson nan aplacaidean as annsa "
|
||||||
|
"leat"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:36
|
||||||
|
msgid ""
|
||||||
|
"The applications corresponding to these identifiers will be displayed in the "
|
||||||
|
"favorites area."
|
||||||
|
msgstr ""
|
||||||
|
"Thèid na h-aplacaidean a fhreagras ris na h-aithnichearan seo a shealltainn "
|
||||||
|
"air raon nan annsachdan."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:43
|
||||||
|
msgid "App Picker View"
|
||||||
|
msgstr "Sealladh roghnaichear nan aplacaid"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:44
|
||||||
|
msgid "Index of the currently selected view in the application picker."
|
||||||
|
msgstr "Inneacs an t-seallaidh làithrich ann an roghnaichear nan aplacaid."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:50
|
||||||
|
msgid "History for command (Alt-F2) dialog"
|
||||||
|
msgstr "Eachdraidh a' chòmhraidh-àithne (Alt-F2)"
|
||||||
|
|
||||||
|
#. Translators: looking glass is a debugger and inspector tool, see https://wiki.gnome.org/Projects/GnomeShell/LookingGlass
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:55
|
||||||
|
msgid "History for the looking glass dialog"
|
||||||
|
msgstr "Eachdraidh a' chomhraidh aig looking glass"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:59
|
||||||
|
msgid "Always show the 'Log out' menu item in the user menu."
|
||||||
|
msgstr ""
|
||||||
|
"Seall nì \"Clàraich a-mach\" air clàr-taice a' chleachdaiche an-còmhnaidh."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:60
|
||||||
|
msgid ""
|
||||||
|
"This key overrides the automatic hiding of the 'Log out' menu item in single-"
|
||||||
|
"user, single-session situations."
|
||||||
|
msgstr ""
|
||||||
|
"Tar-àithnidh an iuchair seo am falach fèin-obrachail aig \"Clàraich a-mach\" "
|
||||||
|
"air a' chlar-taice ann an suidheachaidhean le aon chleachdaiche 's aon "
|
||||||
|
"seisean a-mhàin."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:67
|
||||||
|
msgid ""
|
||||||
|
"Whether to remember password for mounting encrypted or remote filesystems"
|
||||||
|
msgstr ""
|
||||||
|
"Co-dhiù an dèid am facal-faire a chuimhneachadh airson munntachadh "
|
||||||
|
"shiostaman-fhaidhlichean crioptaichte no cèine"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:68
|
||||||
|
msgid ""
|
||||||
|
"The shell will request a password when an encrypted device or a remote "
|
||||||
|
"filesystem is mounted. If the password can be saved for future use a "
|
||||||
|
"'Remember Password' checkbox will be present. This key sets the default "
|
||||||
|
"state of the checkbox."
|
||||||
|
msgstr ""
|
||||||
|
"Iarraidh an t-slige facal-fàire ort nuair a thèid siostam-fhaidhlichean "
|
||||||
|
"crioptaichte no cèin a mhunntachadh. Ma ghabhas am facal-faire sàbhaladh "
|
||||||
|
"airson na h-ama ri teachd, bidh bogsa-còmhraige \"Cuimhnich am facal-fàire\" "
|
||||||
|
"ann. Suidhichidh an iuchair seo staid tùsail na bogsa-còmhraige ud."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:77
|
||||||
|
msgid ""
|
||||||
|
"Whether the default Bluetooth adapter had set up devices associated to it"
|
||||||
|
msgstr ""
|
||||||
|
"Co-dhiù an robh uidheaman co-cheangailte ris an adaptar Bluetooth gus nach "
|
||||||
|
"robh"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:78
|
||||||
|
msgid ""
|
||||||
|
"The shell will only show a Bluetooth menu item if a Bluetooth adapter is "
|
||||||
|
"powered, or if there were devices set up associated with the default "
|
||||||
|
"adapter. This will be reset if the default adapter is ever seen not to have "
|
||||||
|
"devices associated to it."
|
||||||
|
msgstr ""
|
||||||
|
"Cha seall an t-slige nì clàir-taice \"Bluetooth\" ach ma tha cumhachd aig "
|
||||||
|
"adaptar Bluetooth na ma chaidh uidheaman co-cheangailte ris an adaptar "
|
||||||
|
"tùsail roimhe. Thèid seo ath-shuidheachadh ma chithear an t-adaptar tùsail "
|
||||||
|
"gun uidheam co-cheangailte ris."
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:93
|
#: data/org.gnome.shell.gschema.xml.in:93
|
||||||
msgid "Keybinding to open the application menu"
|
msgid "Keybinding to open the application menu"
|
||||||
msgstr "Nasgadh iuchrach gus clàr-taice na h-aplacaid fhosgladh"
|
msgstr "Nasgadh iuchrach gus clàr-taice na h-aplacaid fhosgladh"
|
||||||
@ -74,12 +200,10 @@ msgid "Keybinding to open the application menu."
|
|||||||
msgstr "Nasgadh iuchrach gus clàr-taice na h-aplacaid fhosgladh."
|
msgstr "Nasgadh iuchrach gus clàr-taice na h-aplacaid fhosgladh."
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:100
|
#: data/org.gnome.shell.gschema.xml.in:100
|
||||||
#| msgid "Keybinding to open the application menu"
|
|
||||||
msgid "Keybinding to open the \"Show Applications\" view"
|
msgid "Keybinding to open the \"Show Applications\" view"
|
||||||
msgstr "Nasgadh iuchrach gus an sealladh \"Seall aplacaidean\" fhosgladh"
|
msgstr "Nasgadh iuchrach gus an sealladh \"Seall aplacaidean\" fhosgladh"
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:101
|
#: data/org.gnome.shell.gschema.xml.in:101
|
||||||
#| msgid "Keybinding to open the application menu."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
|
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -87,23 +211,19 @@ msgstr ""
|
|||||||
"gnìomhachd fhosgladh."
|
"gnìomhachd fhosgladh."
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:108
|
#: data/org.gnome.shell.gschema.xml.in:108
|
||||||
#| msgid "Keybinding to open the application menu"
|
|
||||||
msgid "Keybinding to open the overview"
|
msgid "Keybinding to open the overview"
|
||||||
msgstr "Nasgadh iuchrach gus am foir-shealladh fhosgladh"
|
msgstr "Nasgadh iuchrach gus am foir-shealladh fhosgladh"
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:109
|
#: data/org.gnome.shell.gschema.xml.in:109
|
||||||
#| msgid "Keybinding to open the application menu."
|
|
||||||
msgid "Keybinding to open the Activities Overview."
|
msgid "Keybinding to open the Activities Overview."
|
||||||
msgstr "Nasgadh iuchrach gus foir-shealladh na gnìomhachd fhosgladh."
|
msgstr "Nasgadh iuchrach gus foir-shealladh na gnìomhachd fhosgladh."
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:115
|
#: data/org.gnome.shell.gschema.xml.in:115
|
||||||
#| msgid "Keybinding to focus the active notification"
|
|
||||||
msgid "Keybinding to toggle the visibility of the notification list"
|
msgid "Keybinding to toggle the visibility of the notification list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nasgadh iuchrach gus an fhaicsinneachd air liosta nam brathan a thoglachadh"
|
"Nasgadh iuchrach gus an fhaicsinneachd air liosta nam brathan a thoglachadh"
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:116
|
#: data/org.gnome.shell.gschema.xml.in:116
|
||||||
#| msgid "Keybinding to focus the active notification."
|
|
||||||
msgid "Keybinding to toggle the visibility of the notification list."
|
msgid "Keybinding to toggle the visibility of the notification list."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nasgadh iuchrach gus an fhaicsinneachd air liosta nam brathan a thoglachadh."
|
"Nasgadh iuchrach gus an fhaicsinneachd air liosta nam brathan a thoglachadh."
|
||||||
@ -116,10 +236,94 @@ msgstr "Nasgadh iuchrach gus am fòcas a chur air a' bhrath ghnìomhach"
|
|||||||
msgid "Keybinding to focus the active notification."
|
msgid "Keybinding to focus the active notification."
|
||||||
msgstr "Nasgadh iuchrach gus am fòcas a chur air a' bhrath ghnìomhach."
|
msgstr "Nasgadh iuchrach gus am fòcas a chur air a' bhrath ghnìomhach."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:129
|
||||||
|
msgid ""
|
||||||
|
"Keybinding that pauses and resumes all running tweens, for debugging purposes"
|
||||||
|
msgstr ""
|
||||||
|
"Nasgadh iuchrach a chuir gach tween a tha 'ga ruith 'na stad 's a "
|
||||||
|
"thòisicheas orra a-rithist a chum dì-bhugachaidh"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:138
|
||||||
|
msgid "Which keyboard to use"
|
||||||
|
msgstr "Am meur-chlàr ri chleachdadh"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:139
|
||||||
|
msgid "The type of keyboard to use."
|
||||||
|
msgstr "An seòrsa de mheur-chlàr a thèid a chleachdadh."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:150
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:177
|
||||||
|
msgid "Limit switcher to current workspace."
|
||||||
|
msgstr "Cuingich an t-suidsear air an rum-obrach làithreach."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:151
|
||||||
|
msgid ""
|
||||||
|
"If true, only applications that have windows on the current workspace are "
|
||||||
|
"shown in the switcher. Otherwise, all applications are included."
|
||||||
|
msgstr ""
|
||||||
|
"Mas e true a th' ann, cha dèid a shealltainn san t-suidsear ach na "
|
||||||
|
"h-aplacaidean aig a bheil uinneag san rum-obrach làithreach. Mur e, thèid a "
|
||||||
|
"h-uile aplacaid a ghabhail a-steach."
|
||||||
|
|
||||||
#: data/org.gnome.shell.gschema.xml.in:168
|
#: data/org.gnome.shell.gschema.xml.in:168
|
||||||
msgid "The application icon mode."
|
msgid "The application icon mode."
|
||||||
msgstr "Modh ìomhaigheag na h-aplacaid."
|
msgstr "Modh ìomhaigheag na h-aplacaid."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:169
|
||||||
|
msgid ""
|
||||||
|
"Configures how the windows are shown in the switcher. Valid possibilities "
|
||||||
|
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
|
||||||
|
"only' (shows only the application icon) or 'both'."
|
||||||
|
msgstr ""
|
||||||
|
"Rèitichidh seo an dòigh sa thèid na h-uinneagan a shealltainn san "
|
||||||
|
"t-suidsear. 'S e \"thumbnail-only\" (seallaidh seo dealbhag na h-uinneige), "
|
||||||
|
"\"app-icon-only\" (seallaidh seo ìomhaigheag na h-aplacaid) no \"both\" "
|
||||||
|
"(seallaidh seo an dà chuid dhiubh) a tha sna luachan dligheach."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:178
|
||||||
|
msgid ""
|
||||||
|
"If true, only windows from the current workspace are shown in the switcher. "
|
||||||
|
"Otherwise, all windows are included."
|
||||||
|
msgstr ""
|
||||||
|
"Mas e true a th' ann, cha dèid a shealltainn san t-suidsear ach na "
|
||||||
|
"h-uinneagan a tha san rum-obrach làithreach. Mur e, thèid a h-uile uinneag a "
|
||||||
|
"ghabhail a-steach."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:189
|
||||||
|
msgid "Attach modal dialog to the parent window"
|
||||||
|
msgstr "Ceangail còmhradh mòdach ris an uinneag-pàraint"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:190
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:199
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:207
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:215
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:223
|
||||||
|
msgid ""
|
||||||
|
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
|
||||||
|
msgstr ""
|
||||||
|
"Tar-àithnidh an iuchair seo an iuchair ann an org.gnome.mutter nuair a thèid "
|
||||||
|
"Slige GNOME a ruith."
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:198
|
||||||
|
msgid "Enable edge tiling when dropping windows on screen edges"
|
||||||
|
msgstr ""
|
||||||
|
"Cuir leacadh nan oirean an comas nuair a thèid uinneagan a leigeil às aig "
|
||||||
|
"oir na sgrìn"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:206
|
||||||
|
msgid "Workspaces are managed dynamically"
|
||||||
|
msgstr "Thèid na rumannan-obrach a stiùireadh a làimh"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:214
|
||||||
|
msgid "Workspaces only on primary monitor"
|
||||||
|
msgstr "Rumannan-obrach air a' phrìomh-sgrìn a-mhàin"
|
||||||
|
|
||||||
|
#: data/org.gnome.shell.gschema.xml.in:222
|
||||||
|
msgid "Delay focus changes in mouse mode until the pointer stops moving"
|
||||||
|
msgstr ""
|
||||||
|
"Cuir dàil air atharraichean an fòcais ann am modh luchaige gus an sguir an "
|
||||||
|
"tomhaire air gluasad"
|
||||||
|
|
||||||
#: data/org.gnome.Shell.PortalHelper.desktop.in.in:3
|
#: data/org.gnome.Shell.PortalHelper.desktop.in.in:3
|
||||||
msgid "Network Login"
|
msgid "Network Login"
|
||||||
msgstr "Clàradh a-steach lìonraidh"
|
msgstr "Clàradh a-steach lìonraidh"
|
||||||
@ -141,7 +345,7 @@ msgstr "Leudachain na Slige GNOME"
|
|||||||
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
|
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
|
||||||
#: js/ui/components/networkAgent.js:145 js/ui/components/polkitAgent.js:179
|
#: js/ui/components/networkAgent.js:145 js/ui/components/polkitAgent.js:179
|
||||||
#: js/ui/endSessionDialog.js:483 js/ui/extensionDownloader.js:195
|
#: js/ui/endSessionDialog.js:483 js/ui/extensionDownloader.js:195
|
||||||
#: js/ui/shellMountOperation.js:399 js/ui/status/network.js:916
|
#: js/ui/shellMountOperation.js:399 js/ui/status/network.js:926
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Sguir dheth"
|
msgstr "Sguir dheth"
|
||||||
|
|
||||||
@ -331,12 +535,12 @@ msgstr "Cuir ris na h-annsachdan"
|
|||||||
msgid "Show Details"
|
msgid "Show Details"
|
||||||
msgstr "Seall am mion-fhiosrachadh"
|
msgstr "Seall am mion-fhiosrachadh"
|
||||||
|
|
||||||
#: js/ui/appFavorites.js:134
|
#: js/ui/appFavorites.js:136
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s has been added to your favorites."
|
msgid "%s has been added to your favorites."
|
||||||
msgstr "Chaidh %s a chur ris na h-annsachdan agad."
|
msgstr "Chaidh %s a chur ris na h-annsachdan agad."
|
||||||
|
|
||||||
#: js/ui/appFavorites.js:168
|
#: js/ui/appFavorites.js:170
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s has been removed from your favorites."
|
msgid "%s has been removed from your favorites."
|
||||||
msgstr "Chaidh %s a toirt air falbh o na h-annsachdan agad."
|
msgstr "Chaidh %s a toirt air falbh o na h-annsachdan agad."
|
||||||
@ -346,7 +550,6 @@ msgid "Select Audio Device"
|
|||||||
msgstr "Tagh uidheam fuaime"
|
msgstr "Tagh uidheam fuaime"
|
||||||
|
|
||||||
#: js/ui/audioDeviceSelection.js:69
|
#: js/ui/audioDeviceSelection.js:69
|
||||||
#| msgid "Account Settings"
|
|
||||||
msgid "Sound Settings"
|
msgid "Sound Settings"
|
||||||
msgstr "Roghainnean fuaime"
|
msgstr "Roghainnean fuaime"
|
||||||
|
|
||||||
@ -499,8 +702,8 @@ msgstr "Facal-faire:"
|
|||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Am facal-faire a-rithist:"
|
msgstr "Am facal-faire a-rithist:"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:140 js/ui/status/network.js:269
|
#: js/ui/components/networkAgent.js:140 js/ui/status/network.js:270
|
||||||
#: js/ui/status/network.js:352 js/ui/status/network.js:919
|
#: js/ui/status/network.js:353 js/ui/status/network.js:929
|
||||||
msgid "Connect"
|
msgid "Connect"
|
||||||
msgstr "Ceangail"
|
msgstr "Ceangail"
|
||||||
|
|
||||||
@ -528,11 +731,11 @@ msgstr "Facal-faire na h-iuchrach prìobhaidich: "
|
|||||||
msgid "Service: "
|
msgid "Service: "
|
||||||
msgstr "Seirbheis: "
|
msgstr "Seirbheis: "
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:658
|
#: js/ui/components/networkAgent.js:320 js/ui/components/networkAgent.js:666
|
||||||
msgid "Authentication required by wireless network"
|
msgid "Authentication required by wireless network"
|
||||||
msgstr "Tha an lìonra uèirleas ag iarraidh dearbhadh"
|
msgstr "Tha an lìonra uèirleas ag iarraidh dearbhadh"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:659
|
#: js/ui/components/networkAgent.js:321 js/ui/components/networkAgent.js:667
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Passwords or encryption keys are required to access the wireless network "
|
"Passwords or encryption keys are required to access the wireless network "
|
||||||
@ -541,7 +744,7 @@ msgstr ""
|
|||||||
"Tha feum air faclan-faire no iuchraichean crioptachaidh gus an lìonra "
|
"Tha feum air faclan-faire no iuchraichean crioptachaidh gus an lìonra "
|
||||||
"uèirleas “%s” inntrigeadh."
|
"uèirleas “%s” inntrigeadh."
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:325 js/ui/components/networkAgent.js:662
|
#: js/ui/components/networkAgent.js:325 js/ui/components/networkAgent.js:670
|
||||||
msgid "Wired 802.1X authentication"
|
msgid "Wired 802.1X authentication"
|
||||||
msgstr "Dearbhadh Wired 802.1X"
|
msgstr "Dearbhadh Wired 802.1X"
|
||||||
|
|
||||||
@ -549,15 +752,15 @@ msgstr "Dearbhadh Wired 802.1X"
|
|||||||
msgid "Network name: "
|
msgid "Network name: "
|
||||||
msgstr "Ainm an lìonraidh: "
|
msgstr "Ainm an lìonraidh: "
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:332 js/ui/components/networkAgent.js:666
|
#: js/ui/components/networkAgent.js:332 js/ui/components/networkAgent.js:674
|
||||||
msgid "DSL authentication"
|
msgid "DSL authentication"
|
||||||
msgstr "Dearbhadh DSL"
|
msgstr "Dearbhadh DSL"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:339 js/ui/components/networkAgent.js:672
|
#: js/ui/components/networkAgent.js:339 js/ui/components/networkAgent.js:680
|
||||||
msgid "PIN code required"
|
msgid "PIN code required"
|
||||||
msgstr "Tha feum air còd PIN"
|
msgstr "Tha feum air còd PIN"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:340 js/ui/components/networkAgent.js:673
|
#: js/ui/components/networkAgent.js:340 js/ui/components/networkAgent.js:681
|
||||||
msgid "PIN code is needed for the mobile broadband device"
|
msgid "PIN code is needed for the mobile broadband device"
|
||||||
msgstr "Tha feum air còd PIN airson an inneil-làimhe banna-leathainn"
|
msgstr "Tha feum air còd PIN airson an inneil-làimhe banna-leathainn"
|
||||||
|
|
||||||
@ -565,17 +768,17 @@ msgstr "Tha feum air còd PIN airson an inneil-làimhe banna-leathainn"
|
|||||||
msgid "PIN: "
|
msgid "PIN: "
|
||||||
msgstr "PIN: "
|
msgstr "PIN: "
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:348 js/ui/components/networkAgent.js:679
|
#: js/ui/components/networkAgent.js:348 js/ui/components/networkAgent.js:687
|
||||||
msgid "Mobile broadband network password"
|
msgid "Mobile broadband network password"
|
||||||
msgstr "Facal-faire a' bhanna-leathainn inneil-làimhe"
|
msgstr "Facal-faire a' bhanna-leathainn inneil-làimhe"
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:349 js/ui/components/networkAgent.js:663
|
#: js/ui/components/networkAgent.js:349 js/ui/components/networkAgent.js:671
|
||||||
#: js/ui/components/networkAgent.js:667 js/ui/components/networkAgent.js:680
|
#: js/ui/components/networkAgent.js:675 js/ui/components/networkAgent.js:688
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "A password is required to connect to “%s”."
|
msgid "A password is required to connect to “%s”."
|
||||||
msgstr "tha feum air facal-faire airson ceangal ri “%s”."
|
msgstr "tha feum air facal-faire airson ceangal ri “%s”."
|
||||||
|
|
||||||
#: js/ui/components/networkAgent.js:647 js/ui/status/network.js:1658
|
#: js/ui/components/networkAgent.js:655 js/ui/status/network.js:1672
|
||||||
msgid "Network Manager"
|
msgid "Network Manager"
|
||||||
msgstr "Manaidsear nan lìonra"
|
msgstr "Manaidsear nan lìonra"
|
||||||
|
|
||||||
@ -769,8 +972,6 @@ msgid "Power off after updates are installed"
|
|||||||
msgstr "Cuir a' chumhachd dheth nuair a bhios na h-ùrachaidhean air an stàladh"
|
msgstr "Cuir a' chumhachd dheth nuair a bhios na h-ùrachaidhean air an stàladh"
|
||||||
|
|
||||||
#: js/ui/endSessionDialog.js:137
|
#: js/ui/endSessionDialog.js:137
|
||||||
#| msgctxt "title"
|
|
||||||
#| msgid "Restart & Install Updates"
|
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart & Install Upgrade"
|
msgid "Restart & Install Upgrade"
|
||||||
msgstr "Ath-thòisich ⁊ stàlaich an t-àrdachadh"
|
msgstr "Ath-thòisich ⁊ stàlaich an t-àrdachadh"
|
||||||
@ -896,14 +1097,10 @@ msgid "System Information"
|
|||||||
msgstr "Fiosrachadh an t-siostaim"
|
msgstr "Fiosrachadh an t-siostaim"
|
||||||
|
|
||||||
#: js/ui/mpris.js:194
|
#: js/ui/mpris.js:194
|
||||||
#| msgctxt "program"
|
|
||||||
#| msgid "Unknown"
|
|
||||||
msgid "Unknown artist"
|
msgid "Unknown artist"
|
||||||
msgstr "Neach-ciùil nach aithne dhuinn"
|
msgstr "Neach-ciùil nach aithne dhuinn"
|
||||||
|
|
||||||
#: js/ui/mpris.js:195
|
#: js/ui/mpris.js:195
|
||||||
#| msgctxt "program"
|
|
||||||
#| msgid "Unknown"
|
|
||||||
msgid "Unknown title"
|
msgid "Unknown title"
|
||||||
msgstr "Tiotal nach aithne dhuinn"
|
msgstr "Tiotal nach aithne dhuinn"
|
||||||
|
|
||||||
@ -963,6 +1160,10 @@ msgstr "Cuir a-steach àithne"
|
|||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr "Dùin"
|
msgstr "Dùin"
|
||||||
|
|
||||||
|
#: js/ui/runDialog.js:277
|
||||||
|
msgid "Restart is not available on Wayland"
|
||||||
|
msgstr "Chan eil ath-thòiseachadh ri làimh air Wayland"
|
||||||
|
|
||||||
#: js/ui/runDialog.js:282
|
#: js/ui/runDialog.js:282
|
||||||
msgid "Restarting…"
|
msgid "Restarting…"
|
||||||
msgstr "'Ga thòiseachadh às ùr…"
|
msgstr "'Ga thòiseachadh às ùr…"
|
||||||
@ -1006,11 +1207,11 @@ msgstr "Feumaidh GNOME an sgrìn a glasadh"
|
|||||||
#.
|
#.
|
||||||
#. XXX: another option is to kick the user into the gdm login
|
#. XXX: another option is to kick the user into the gdm login
|
||||||
#. screen, where we're not affected by grabs
|
#. screen, where we're not affected by grabs
|
||||||
#: js/ui/screenShield.js:825 js/ui/screenShield.js:1291
|
#: js/ui/screenShield.js:825 js/ui/screenShield.js:1292
|
||||||
msgid "Unable to lock"
|
msgid "Unable to lock"
|
||||||
msgstr "Cha ghabh a ghlasadh"
|
msgstr "Cha ghabh a ghlasadh"
|
||||||
|
|
||||||
#: js/ui/screenShield.js:826 js/ui/screenShield.js:1292
|
#: js/ui/screenShield.js:826 js/ui/screenShield.js:1293
|
||||||
msgid "Lock was blocked by an application"
|
msgid "Lock was blocked by an application"
|
||||||
msgstr "Chaidh a' ghlas a bhacadh le aplacaid"
|
msgstr "Chaidh a' ghlas a bhacadh le aplacaid"
|
||||||
|
|
||||||
@ -1094,7 +1295,7 @@ msgstr "Teacsa mòr"
|
|||||||
msgid "Bluetooth"
|
msgid "Bluetooth"
|
||||||
msgstr "Bluetooth"
|
msgstr "Bluetooth"
|
||||||
|
|
||||||
#: js/ui/status/bluetooth.js:56 js/ui/status/network.js:624
|
#: js/ui/status/bluetooth.js:56 js/ui/status/network.js:625
|
||||||
msgid "Bluetooth Settings"
|
msgid "Bluetooth Settings"
|
||||||
msgstr "Roghainnean Bluetooth"
|
msgstr "Roghainnean Bluetooth"
|
||||||
|
|
||||||
@ -1116,13 +1317,13 @@ msgstr "Dheth"
|
|||||||
msgid "Not In Use"
|
msgid "Not In Use"
|
||||||
msgstr "Chan eil e 'ga chleachdadh"
|
msgstr "Chan eil e 'ga chleachdadh"
|
||||||
|
|
||||||
#: js/ui/status/bluetooth.js:142 js/ui/status/network.js:1279
|
#: js/ui/status/bluetooth.js:142 js/ui/status/network.js:1289
|
||||||
msgid "Turn On"
|
msgid "Turn On"
|
||||||
msgstr "Cuir air"
|
msgstr "Cuir air"
|
||||||
|
|
||||||
#: js/ui/status/bluetooth.js:142 js/ui/status/network.js:178
|
#: js/ui/status/bluetooth.js:142 js/ui/status/network.js:179
|
||||||
#: js/ui/status/network.js:353 js/ui/status/network.js:1279
|
#: js/ui/status/network.js:354 js/ui/status/network.js:1289
|
||||||
#: js/ui/status/network.js:1394 js/ui/status/rfkill.js:90
|
#: js/ui/status/network.js:1404 js/ui/status/rfkill.js:90
|
||||||
#: js/ui/status/rfkill.js:117
|
#: js/ui/status/rfkill.js:117
|
||||||
msgid "Turn Off"
|
msgid "Turn Off"
|
||||||
msgstr "Cuir dheth"
|
msgstr "Cuir dheth"
|
||||||
@ -1171,18 +1372,18 @@ msgstr ""
|
|||||||
"'S urrainn dhut inntrigeadh an ionaid atharrachadh uair sam bith ann an "
|
"'S urrainn dhut inntrigeadh an ionaid atharrachadh uair sam bith ann an "
|
||||||
"roghainnean na prìobhaideachd."
|
"roghainnean na prìobhaideachd."
|
||||||
|
|
||||||
#: js/ui/status/network.js:101
|
#: js/ui/status/network.js:102
|
||||||
msgid "<unknown>"
|
msgid "<unknown>"
|
||||||
msgstr "<neo-aithnichte>"
|
msgstr "<neo-aithnichte>"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:451 js/ui/status/network.js:1308
|
#: js/ui/status/network.js:452 js/ui/status/network.js:1318
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Off"
|
msgid "%s Off"
|
||||||
msgstr "%s dheth"
|
msgstr "%s dheth"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:454
|
#: js/ui/status/network.js:455
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Connected"
|
msgid "%s Connected"
|
||||||
msgstr "%s ceangailte"
|
msgstr "%s ceangailte"
|
||||||
@ -1190,168 +1391,168 @@ msgstr "%s ceangailte"
|
|||||||
#. Translators: this is for network devices that are physically present but are not
|
#. Translators: this is for network devices that are physically present but are not
|
||||||
#. under NetworkManager's control (and thus cannot be used in the menu);
|
#. under NetworkManager's control (and thus cannot be used in the menu);
|
||||||
#. %s is a network identifier
|
#. %s is a network identifier
|
||||||
#: js/ui/status/network.js:459
|
#: js/ui/status/network.js:460
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Unmanaged"
|
msgid "%s Unmanaged"
|
||||||
msgstr "%s gun stiùireadh"
|
msgstr "%s gun stiùireadh"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:462
|
#: js/ui/status/network.js:463
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Disconnecting"
|
msgid "%s Disconnecting"
|
||||||
msgstr "A' dì-cheangal %s"
|
msgstr "A' dì-cheangal %s"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:469 js/ui/status/network.js:1300
|
#: js/ui/status/network.js:470 js/ui/status/network.js:1310
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Connecting"
|
msgid "%s Connecting"
|
||||||
msgstr "A' ceangal %s"
|
msgstr "A' ceangal %s"
|
||||||
|
|
||||||
#. Translators: this is for network connections that require some kind of key or password; %s is a network identifier
|
#. Translators: this is for network connections that require some kind of key or password; %s is a network identifier
|
||||||
#: js/ui/status/network.js:472
|
#: js/ui/status/network.js:473
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Requires Authentication"
|
msgid "%s Requires Authentication"
|
||||||
msgstr "Tha %s ag iarraidh dearbhadh"
|
msgstr "Tha %s ag iarraidh dearbhadh"
|
||||||
|
|
||||||
#. Translators: this is for devices that require some kind of firmware or kernel
|
#. Translators: this is for devices that require some kind of firmware or kernel
|
||||||
#. module, which is missing; %s is a network identifier
|
#. module, which is missing; %s is a network identifier
|
||||||
#: js/ui/status/network.js:480
|
#: js/ui/status/network.js:481
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "Firmware Missing For %s"
|
msgid "Firmware Missing For %s"
|
||||||
msgstr "Tha bathar-an-sàs a dhìth air %s"
|
msgstr "Tha bathar-an-sàs a dhìth air %s"
|
||||||
|
|
||||||
#. Translators: this is for a network device that cannot be activated (for example it
|
#. Translators: this is for a network device that cannot be activated (for example it
|
||||||
#. is disabled by rfkill, or it has no coverage; %s is a network identifier
|
#. is disabled by rfkill, or it has no coverage; %s is a network identifier
|
||||||
#: js/ui/status/network.js:484
|
#: js/ui/status/network.js:485
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Unavailable"
|
msgid "%s Unavailable"
|
||||||
msgstr "Chan eil %s ri fhaighinn"
|
msgstr "Chan eil %s ri fhaighinn"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:487
|
#: js/ui/status/network.js:488
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Connection Failed"
|
msgid "%s Connection Failed"
|
||||||
msgstr "Dh'fhàillig le %s a cheangal"
|
msgstr "Dh'fhàillig le %s a cheangal"
|
||||||
|
|
||||||
#: js/ui/status/network.js:503
|
#: js/ui/status/network.js:504
|
||||||
msgid "Wired Settings"
|
msgid "Wired Settings"
|
||||||
msgstr "Roghainnean le uèir"
|
msgstr "Roghainnean le uèir"
|
||||||
|
|
||||||
#: js/ui/status/network.js:545
|
#: js/ui/status/network.js:546
|
||||||
msgid "Mobile Broadband Settings"
|
msgid "Mobile Broadband Settings"
|
||||||
msgstr "Roghainnean banna-leathainn inneal-làimhe"
|
msgstr "Roghainnean banna-leathainn inneal-làimhe"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:588 js/ui/status/network.js:1305
|
#: js/ui/status/network.js:589 js/ui/status/network.js:1315
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Hardware Disabled"
|
msgid "%s Hardware Disabled"
|
||||||
msgstr "Tha bathar-cruaidh %s à comas"
|
msgstr "Tha bathar-cruaidh %s à comas"
|
||||||
|
|
||||||
#. Translators: this is for a network device that cannot be activated
|
#. Translators: this is for a network device that cannot be activated
|
||||||
#. because it's disabled by rfkill (airplane mode); %s is a network identifier
|
#. because it's disabled by rfkill (airplane mode); %s is a network identifier
|
||||||
#: js/ui/status/network.js:592
|
#: js/ui/status/network.js:593
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Disabled"
|
msgid "%s Disabled"
|
||||||
msgstr "%s à comas"
|
msgstr "%s à comas"
|
||||||
|
|
||||||
#: js/ui/status/network.js:632
|
#: js/ui/status/network.js:633
|
||||||
msgid "Connect to Internet"
|
msgid "Connect to Internet"
|
||||||
msgstr "Ceangail ris an eadar-lìon"
|
msgstr "Ceangail ris an eadar-lìon"
|
||||||
|
|
||||||
#: js/ui/status/network.js:813
|
#: js/ui/status/network.js:823
|
||||||
msgid "Airplane Mode is On"
|
msgid "Airplane Mode is On"
|
||||||
msgstr "Tha am modh itealain air"
|
msgstr "Tha am modh itealain air"
|
||||||
|
|
||||||
#: js/ui/status/network.js:814
|
#: js/ui/status/network.js:824
|
||||||
msgid "Wi-Fi is disabled when airplane mode is on."
|
msgid "Wi-Fi is disabled when airplane mode is on."
|
||||||
msgstr "Tha WiFi à comas fhad 's a tha am modh itealain air."
|
msgstr "Tha WiFi à comas fhad 's a tha am modh itealain air."
|
||||||
|
|
||||||
#: js/ui/status/network.js:815
|
#: js/ui/status/network.js:825
|
||||||
msgid "Turn Off Airplane Mode"
|
msgid "Turn Off Airplane Mode"
|
||||||
msgstr "Cuir am modh itealain dheth"
|
msgstr "Cuir am modh itealain dheth"
|
||||||
|
|
||||||
#: js/ui/status/network.js:824
|
#: js/ui/status/network.js:834
|
||||||
msgid "Wi-Fi is Off"
|
msgid "Wi-Fi is Off"
|
||||||
msgstr "Tha WiFi dheth"
|
msgstr "Tha WiFi dheth"
|
||||||
|
|
||||||
#: js/ui/status/network.js:825
|
#: js/ui/status/network.js:835
|
||||||
msgid "Wi-Fi needs to be turned on in order to connect to a network."
|
msgid "Wi-Fi needs to be turned on in order to connect to a network."
|
||||||
msgstr "Feumaidh tu WiFi a chur air gus ceangal ri lìonra."
|
msgstr "Feumaidh tu WiFi a chur air gus ceangal ri lìonra."
|
||||||
|
|
||||||
#: js/ui/status/network.js:826
|
#: js/ui/status/network.js:836
|
||||||
msgid "Turn On Wi-Fi"
|
msgid "Turn On Wi-Fi"
|
||||||
msgstr "Cuir WiFi air"
|
msgstr "Cuir WiFi air"
|
||||||
|
|
||||||
#: js/ui/status/network.js:851
|
#: js/ui/status/network.js:861
|
||||||
msgid "Wi-Fi Networks"
|
msgid "Wi-Fi Networks"
|
||||||
msgstr "Lìonraidhean WiFi"
|
msgstr "Lìonraidhean WiFi"
|
||||||
|
|
||||||
#: js/ui/status/network.js:853
|
#: js/ui/status/network.js:863
|
||||||
msgid "Select a network"
|
msgid "Select a network"
|
||||||
msgstr "Tagh lìonra"
|
msgstr "Tagh lìonra"
|
||||||
|
|
||||||
#: js/ui/status/network.js:883
|
#: js/ui/status/network.js:893
|
||||||
msgid "No Networks"
|
msgid "No Networks"
|
||||||
msgstr "Chan eil lìonra ann"
|
msgstr "Chan eil lìonra ann"
|
||||||
|
|
||||||
#: js/ui/status/network.js:904 js/ui/status/rfkill.js:115
|
#: js/ui/status/network.js:914 js/ui/status/rfkill.js:115
|
||||||
msgid "Use hardware switch to turn off"
|
msgid "Use hardware switch to turn off"
|
||||||
msgstr "Cleachd suidse bathair-chruaidh gus a chur dheth"
|
msgstr "Cleachd suidse bathair-chruaidh gus a chur dheth"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1171
|
#: js/ui/status/network.js:1181
|
||||||
msgid "Select Network"
|
msgid "Select Network"
|
||||||
msgstr "Tagh lìonra"
|
msgstr "Tagh lìonra"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1177
|
#: js/ui/status/network.js:1187
|
||||||
msgid "Wi-Fi Settings"
|
msgid "Wi-Fi Settings"
|
||||||
msgstr "Roghainnean WiFi"
|
msgstr "Roghainnean WiFi"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:1296
|
#: js/ui/status/network.js:1306
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Hotspot Active"
|
msgid "%s Hotspot Active"
|
||||||
msgstr "Tha %s hotspot gnìomhach"
|
msgstr "Tha %s hotspot gnìomhach"
|
||||||
|
|
||||||
#. Translators: %s is a network identifier
|
#. Translators: %s is a network identifier
|
||||||
#: js/ui/status/network.js:1311
|
#: js/ui/status/network.js:1321
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid "%s Not Connected"
|
msgid "%s Not Connected"
|
||||||
msgstr "Chan eil %s ceangailte"
|
msgstr "Chan eil %s ceangailte"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1411
|
#: js/ui/status/network.js:1421
|
||||||
msgid "connecting..."
|
msgid "connecting..."
|
||||||
msgstr "'ga cheangal..."
|
msgstr "'ga cheangal..."
|
||||||
|
|
||||||
#. Translators: this is for network connections that require some kind of key or password
|
#. Translators: this is for network connections that require some kind of key or password
|
||||||
#: js/ui/status/network.js:1414
|
#: js/ui/status/network.js:1424
|
||||||
msgid "authentication required"
|
msgid "authentication required"
|
||||||
msgstr "tha feum air dearbhadh"
|
msgstr "tha feum air dearbhadh"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1416
|
#: js/ui/status/network.js:1426
|
||||||
msgid "connection failed"
|
msgid "connection failed"
|
||||||
msgstr "dh'fhàillig leis a' cheangal"
|
msgstr "dh'fhàillig leis a' cheangal"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1482 js/ui/status/rfkill.js:93
|
#: js/ui/status/network.js:1492 js/ui/status/rfkill.js:93
|
||||||
msgid "Network Settings"
|
msgid "Network Settings"
|
||||||
msgstr "Roghainnean an lìonraidh"
|
msgstr "Roghainnean an lìonraidh"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1484
|
#: js/ui/status/network.js:1494
|
||||||
msgid "VPN Settings"
|
msgid "VPN Settings"
|
||||||
msgstr "Roghainnean VPN"
|
msgstr "Roghainnean VPN"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1503
|
#: js/ui/status/network.js:1513
|
||||||
msgid "VPN"
|
msgid "VPN"
|
||||||
msgstr "VPN"
|
msgstr "VPN"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1513
|
#: js/ui/status/network.js:1523
|
||||||
msgid "VPN Off"
|
msgid "VPN Off"
|
||||||
msgstr "Tha VPN dheth"
|
msgstr "Tha VPN dheth"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1697
|
#: js/ui/status/network.js:1711
|
||||||
msgid "Connection failed"
|
msgid "Connection failed"
|
||||||
msgstr "Dh'fhàillig leis a' cheangal"
|
msgstr "Dh'fhàillig leis a' cheangal"
|
||||||
|
|
||||||
#: js/ui/status/network.js:1698
|
#: js/ui/status/network.js:1712
|
||||||
msgid "Activation of network connection failed"
|
msgid "Activation of network connection failed"
|
||||||
msgstr "Dh'fhàillig gnìomhachadh a' cheangail ris an lìonra"
|
msgstr "Dh'fhàillig gnìomhachadh a' cheangail ris an lìonra"
|
||||||
|
|
||||||
|
48
po/he.po
48
po/he.po
@ -2319,33 +2319,9 @@ msgstr "המשתמש בחר להתעלם מתיבת דו־שיח האימות"
|
|||||||
|
|
||||||
#~ msgid "Networking is disabled"
|
#~ msgid "Networking is disabled"
|
||||||
#~ msgstr "תכונת הרשת מנוטרלת"
|
#~ msgstr "תכונת הרשת מנוטרלת"
|
||||||
|
|
||||||
#~ msgid "%d hour remaining"
|
|
||||||
#~ msgid_plural "%d hours remaining"
|
|
||||||
#~ msgstr[0] "נותרה שעה"
|
|
||||||
#~ msgstr[1] "נותרו %d שעות"
|
|
||||||
#~ msgstr[2] "נותרו שעתיים"
|
|
||||||
|
|
||||||
#~ msgid "%d %s %d %s remaining"
|
#~ msgid "%d %s %d %s remaining"
|
||||||
#~ msgstr "%d %s %d %s נותרו"
|
#~ msgstr "%d %s %d %s נותרו"
|
||||||
|
|
||||||
#~ msgid "hour"
|
|
||||||
#~ msgid_plural "hours"
|
|
||||||
#~ msgstr[0] "שעה"
|
|
||||||
#~ msgstr[1] "שעות"
|
|
||||||
#~ msgstr[2] "שעתיים"
|
|
||||||
|
|
||||||
#~ msgid "minute"
|
|
||||||
#~ msgid_plural "minutes"
|
|
||||||
#~ msgstr[0] "דקה"
|
|
||||||
#~ msgstr[1] "דקות"
|
|
||||||
#~ msgstr[2] "דקות"
|
|
||||||
|
|
||||||
#~ msgid "%d minute remaining"
|
|
||||||
#~ msgid_plural "%d minutes remaining"
|
|
||||||
#~ msgstr[0] "דקה אחת נותרה"
|
|
||||||
#~ msgstr[1] "%d דקות נותרו"
|
|
||||||
#~ msgstr[2] "שתי דקות נותרו"
|
|
||||||
|
|
||||||
#~ msgid "AC Adapter"
|
#~ msgid "AC Adapter"
|
||||||
#~ msgstr "מתאם חשמל"
|
#~ msgstr "מתאם חשמל"
|
||||||
@ -2611,30 +2587,6 @@ msgstr "המשתמש בחר להתעלם מתיבת דו־שיח האימות"
|
|||||||
|
|
||||||
#~ msgid "Less than a minute ago"
|
#~ msgid "Less than a minute ago"
|
||||||
#~ msgstr "לפני פחות מדקה"
|
#~ msgstr "לפני פחות מדקה"
|
||||||
|
|
||||||
#~ msgid "%d minute ago"
|
|
||||||
#~ msgid_plural "%d minutes ago"
|
|
||||||
#~ msgstr[0] "לפני דקה"
|
|
||||||
#~ msgstr[1] "לפני %d דקות"
|
|
||||||
#~ msgstr[2] "לפני 2 דקות"
|
|
||||||
|
|
||||||
#~ msgid "%d hour ago"
|
|
||||||
#~ msgid_plural "%d hours ago"
|
|
||||||
#~ msgstr[0] "לפני שעה"
|
|
||||||
#~ msgstr[1] "לפני %d שעות"
|
|
||||||
#~ msgstr[2] "לפני שעתיים"
|
|
||||||
|
|
||||||
#~ msgid "%d day ago"
|
|
||||||
#~ msgid_plural "%d days ago"
|
|
||||||
#~ msgstr[0] "לפני יום"
|
|
||||||
#~ msgstr[1] "לפני %d ימים"
|
|
||||||
#~ msgstr[2] "לפני יומיים"
|
|
||||||
|
|
||||||
#~ msgid "%d week ago"
|
|
||||||
#~ msgid_plural "%d weeks ago"
|
|
||||||
#~ msgstr[0] "לפני שבוע"
|
|
||||||
#~ msgstr[1] "לפני %d שבועות"
|
|
||||||
#~ msgstr[2] "לפני שבועיים"
|
|
||||||
|
|
||||||
#~ msgid "Shut Down"
|
#~ msgid "Shut Down"
|
||||||
#~ msgstr "כיבוי"
|
#~ msgstr "כיבוי"
|
||||||
|
4
po/pt.po
4
po/pt.po
@ -301,7 +301,7 @@ msgstr "Sessão na rede"
|
|||||||
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||||
#: data/org.gnome.Shell.PortalHelper.desktop.in.in:9
|
#: data/org.gnome.Shell.PortalHelper.desktop.in.in:9
|
||||||
msgid "network-workgroup"
|
msgid "network-workgroup"
|
||||||
msgstr "Grupo de Trabalho na Rede"
|
msgstr "network-workgroup"
|
||||||
|
|
||||||
#: js/extensionPrefs/main.js:117
|
#: js/extensionPrefs/main.js:117
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
@ -1685,7 +1685,7 @@ msgstr "Calendário do Evolution"
|
|||||||
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
#. Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||||
#: src/calendar-server/evolution-calendar.desktop.in:6
|
#: src/calendar-server/evolution-calendar.desktop.in:6
|
||||||
msgid "evolution"
|
msgid "evolution"
|
||||||
msgstr "Evolution"
|
msgstr "evolution"
|
||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound outputs on a particular device
|
#. * The number of sound outputs on a particular device
|
||||||
|
712
po/pt_BR.po
712
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
717
po/sr@latin.po
717
po/sr@latin.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