Compare commits

..

1 Commits

Author SHA1 Message Date
389539d1a0 mutter/clutter/cogl merge build fixes 2016-04-11 23:12:23 +02:00
219 changed files with 25631 additions and 40197 deletions

4
.gitignore vendored
View File

@ -16,6 +16,7 @@ config.log
config.status config.status
config config
configure configure
data/50-gnome-shell-*.xml
data/org.gnome.Shell.desktop data/org.gnome.Shell.desktop
data/org.gnome.Shell.desktop.in data/org.gnome.Shell.desktop.in
data/gnome-shell-extension-prefs.desktop data/gnome-shell-extension-prefs.desktop
@ -25,6 +26,8 @@ data/gschemas.compiled
data/perf-background.xml data/perf-background.xml
data/org.gnome.shell.gschema.xml data/org.gnome.shell.gschema.xml
data/org.gnome.shell.gschema.valid data/org.gnome.shell.gschema.valid
data/org.gnome.shell.evolution.calendar.gschema.xml
data/org.gnome.shell.evolution.calendar.gschema.valid
data/org.gnome.Shell.PortalHelper.desktop data/org.gnome.Shell.PortalHelper.desktop
data/org.gnome.Shell.PortalHelper.service data/org.gnome.Shell.PortalHelper.service
data/theme/.sass-cache data/theme/.sass-cache
@ -71,6 +74,7 @@ src/*-marshal.[ch]
src/Makefile src/Makefile
src/Makefile.in src/Makefile.in
src/calendar-server/evolution-calendar.desktop src/calendar-server/evolution-calendar.desktop
src/calendar-server/evolution-calendar.desktop.in
src/calendar-server/org.gnome.Shell.CalendarServer.service src/calendar-server/org.gnome.Shell.CalendarServer.service
src/gnome-shell src/gnome-shell
src/gnome-shell-calendar-server src/gnome-shell-calendar-server

354
NEWS
View File

@ -1,357 +1,3 @@
3.24.3
======
* Bypass proxies for captive portal [Bastien; #769692]
* Fix missing icons in freedesktop notifications [Florian; #784245]
* Fix blocked clicks in shutdown dialog [Florian; #781738]
* Implement tablet rings/strips configuration [Carlos; #782033]
* Misc. bug fixes [Matthias, Jeremy, Bastien, Florian; #780215, #782802,
#783286, #784130, #784353, #781471]
Contributors:
Jeremy Bicha, Carlos Garnacho, Matthias Liertzer, Florian Müllner,
Bastien Nocera
Translations:
Christian Stadelmann [de], Марко Костић [sr], Милош Поповић [sr@latin],
Furkan Ahmet Kara [tr], Jeremy Bicha [es, he]
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
======
* Implement Pad configuration OSD [Carlos; #771067]
* Show overview on three-finger touchpad pinch [Carlos; #765937]
* Summarize network sections with too many devices [Florian; #773892]
* Always show primary network icon when connected [Florian; #773890]
* Fix fullscreen transitions on wayland [Rui; #770345]
* Work around portal failures by using a URL without HTPPS redirect [Debarshi; #769940]
* Fix app view hiding when no usage data is available [Florian, Xiaoguang; #774381]
* Misc. bug fixes [Florian, Ray; #773875, #740043, #773893, #774643, #774805]
Contributors:
Carlos Garnacho, Rui Matos, Florian Müllner, Debarshi Ray, Ray Strode,
Xiaoguang Wang
Translations:
Balázs Meskó [hu], Fabio Tomat [fur], Marek Cernocky [cs], Stas Solovey [ru],
Daniel Mustieles [es], Marek Černocký [cs], Piotr Drąg [pl],
Rafael Fontenelle [pt_BR], Baurzhan Muftakhidinov [kk], Jiri Grönroos [fi],
Kjartan Maraas [nb]
3.23.1
======
* Request periodic scans while WiFi list is open [Dan; #767918]
* Include extension UUID in structured log metadata [Jonh; #770717]
* Line-wrap PAM messages on login screen [Tao; #764445]
* Add a way to launch an app on the discrete GPU [Bastien; #773117]
* Only allow graphs to lift screen shield when locked [Florian; #773328]
* Add reload option to gnome-shell-extension-tool [Jonh; #772593]
* Update background animations when resuming from suspend [Florian; #773265]
* Misc. bug fixes [Cosimo, Bastien, Florian, Philip, Carlos; #772723, #772287,
#756432, #772386, #772386, #773085, #773634]
Contributors:
Cosimo Cecchi, Philip Chimento, Carlos Garcia Campos, Florian Müllner,
Bastien Nocera, Jonh Wendell, Dan Williams, Tao Yang
Translations:
Fabio Tomat [fur], Philip Chimento [zh_CN], YunQiang Su [zh_CN],
Jordi Mas [ca], Piotr Drąg [pl], Muhammet Kara [tr], Marek Černocký [cs],
Daniel Korostil [uk], Dušan Kazik [sk]
3.22.1
======
* Fix hidden network indicator on startup [Florian; #772249]
* Fix order of windows with modal dialogs in window switcher [Florian; #747153]
* Fix feedback loop between StClipboard and X11 bridge [Carlos; #760745]
* Reliably match windows from Flatpak apps [Florian; #772615]
* Misc. bug fixes [Philip; #742249]
Contributors:
Philip Chimento, Carlos Garnacho, Florian Müllner
Translations:
Inaki Larranaga Murgoitio [eu], Khaled Hosny [ar], BM [uz@cyrillic],
Milo Casagrande [it], Cheng-Chia Tseng [zh_TW], gogo [hr]
3.22.0
======
* Misc. bug fixes [Florian, Rui; #771391, #771536] #771656]
Contributors:
Rui Matos, Florian Müllner
Translations:
Ask Hjorth Larsen [da], GNOME Translation Robot [gd], Alexandre Franke [fr],
Daniel Korostil [uk], Jordi Mas [ca], Khaled Hosny [ar], David King [en_GB]
3.21.92
=======
* Adjust screen capture to work with multiple stage views [Jonas; #770128]
* Improve handling of cycle shortcuts [Florian; #771063]
* Fix windows not getting undimmed in some cases [Rui; #770163, #752524]
* Disable extension version check by default [Florian; #770887]
* Misc. bug fixes [Rui, Florian, Michael; #770382, #770888, #770328]
Contributors:
Jonas Ådahl, Michael Catanzaro, Fran Dieguez, Olivier Fourdan, Rui Matos,
Florian Müllner
Translations:
Changwoo Ryu [ko], Baurzhan Muftakhidinov [kk], Aurimas Černius [lt],
Muhammet Kara [tr], Trần Ngọc Quân [vi], A S Alam [pa], Yosef Or Boczko [he],
Anders Jonsson [sv], Tiago Santos [pt], Hannie Dumoleyn [nl],
Rūdolfs Mazurs [lv], Claude Paroz [fr], Arash Mousavi [fa],
Fran Dieguez [gl], Stas Solovey [ru], Tom Tryfonidis [el]
3.21.91
=======
Translations:
Mario Blättermann [de], Jiri Grönroos [fi], Dušan Kazik [sk],
Andika Triwidada [id], Daniel Mustieles [es], Fabio Tomat [fur],
Enrico Nicoletto [pt_BR], Matej Urbančič [sl], Мирослав Николић [sr, sr@latin]
3.21.90.1
=========
Contributors:
Piotr Drąg
Translations:
Marek Černocký [cs], Balázs Úr [hu]
3.21.90
=======
* Improve on-screen keyboard on wayland [Carlos; #765009]
* Misc. bug fixes [Florian; #769156, #769216, #769074]
Contributors:
Carlos Garnacho, Florian Müllner
Translations:
Fabio Tomat [fur], Tiago Santos [pt], Daniel Mustieles [es],
Bernd Homuth [de], Aurimas Černius [lt], Balázs Úr [hu],
Yosef Or Boczko [he], Jiri Grönroos [fi], Marek Cernocky [cs],
Muhammet Kara [tr], Enrico Nicoletto [pt_BR], Andika Triwidada [id]
3.21.4
======
* overview: Fix switching workspaces when scrolling on non-primary monitors
[Florian; #766883, #768316]
* Fix crash when using screen recorder under wayland [Rui; #767001]
* Update theme on video memory purge errors [Rui; #739178]
* Free old backgrounds immediately [Hyungwon; #766353]
* Add support for system upgrades to end session dialog [Kalev; #763611]
* Fix maximized windows flickering to the wrong size on restart [Owen; #761566]
* Hide ignored events in calendar as well [Florian; #768538]
* calendar: Only hide dismissed occurrence of recurring event [Florian; #748226]
* Provide org.freedesktop.impl.portal.access implementation [Florian; #768669]
* Misc. bug fixes and cleanups [Rui, Florian, Marinus, Jonas; #767954, #768317,
#746867, #762206, #768956, #768979]
Contributors:
Jonas Ådahl, Piotr Drąg, Hyungwon Hwang, Kalev Lember, Rui Matos,
Florian Müllner, Marinus Schraal, Owen W. Taylor
Translations:
Andika Triwidada [id], Daniel Mustieles [es], Bruce Cowan [en_GB],
Dušan Kazik [sk], Piotr Drąg [pl], Chao-Hsiung Liao [zh_HK]
3.21.3
======
* Do not disable suspend action when locked [Florian; #725960]
* Remember input sources MRU list [Cosimo; #766826]
* networkAgent: Handle VPN service aliases [David; #658484]
* Plug a memory leak [Hans; #710230]
Contributors:
Cosimo Cecchi, Florian Müllner, Hans Petter Jansson, David Woodhouse
Translations:
Tiago Santos [pt], Cédric Valmary [oc], Muhammet Kara [tr],
Daniel Mustieles [es], Rafael Fontenelle [pt_BR]
3.21.2
======
* Fix sorting of hidden apps in app switcher [Florian; #766238]
* Set logind's LockedHint property when locked [Victor; #764773]
* Allocate framebuffers early to fix a crash on NVIDIA [Martin; #764898]
* Fix cycle-windows/cycle-group keybindings [Florian; #730739]
* Switch to shared desktop schema for calendar settings [Iain; #766318]
* Misc. bug fixes [Florian, Cosimo, Michele; #766325, #758471, #757556,
#757019, #766598]
Contributors:
Cosimo Cecchi, Michele Gaio, Iain Lane, Florian Müllner, Martin Szulecki,
Victor Toso
Translations:
Tiago Santos [pt], Kjartan Maraas [nb], Jiro Matsuzawa [ja],
Cédric Valmary [oc], Sveinn í Felli [is]
3.21.1
======
* Save screencasts in HOME if XDG_VIDEO_DIR doesn't exist [Florian; #765015]
* Don't show orientation lock when g-s-d won't rotate [Florian; #765267]
* Misc. bug fixes [Heiher, Florian, Marek, Rui; #722752, #765061, #763068,
#765607, #757676, #760439]
Contributors:
Heiher, Marek Chalupa, Rui Matos, Florian Müllner
Translations:
Arash Mousavi [fa], Kristjan SCHMIDT [eo], GNOME Translation Robot [gd]
3.20.1
======
* Plug a memory leak [Aaron; #735705]
Contributors:
Aaron Plattner
Translations:
Daniel Korostil [uk], Matej Urbančič [sl], Inaki Larranaga Murgoitio [eu],
Cheng-Chia Tseng [zh_TW], Fabio Tomat [fur], Trần Ngọc Quân [vi],
YunQiang Su [zh_CN], Marek Černocký [cs], Arash Mousavi [fa],
Alexander Shopov [bg], Khaled Hosny [ar]
3.20.0 3.20.0
====== ======

View File

@ -4,12 +4,8 @@
srcdir=`dirname $0` srcdir=`dirname $0`
test -z "$srcdir" && srcdir=. test -z "$srcdir" && srcdir=.
olddir="$(pwd)" (test -f $srcdir/configure.ac \
&& test -d $srcdir/src) || {
cd "${srcdir}"
(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
@ -23,13 +19,9 @@ then
fi fi
git submodule update git submodule update
aclocal --install || exit 1 which gnome-autogen.sh || {
gtkdocize --copy || exit 1 echo "You need to install gnome-common from GNOME Git (or from"
intltoolize --force --copy --automake || exit 1 echo "your OS vendor's package manager)."
autoreconf --verbose --force --install || exit 1 exit 1
}
cd "${olddir}" . gnome-autogen.sh
if [ "$NOCONFIGURE" = "" ]; then
"${srcdir}/configure" "$@" || exit 1
fi

View File

@ -1029,7 +1029,6 @@ NPP_GetValue(NPP instance,
if (!instance->pdata) if (!instance->pdata)
return NPERR_INVALID_INSTANCE_ERROR; return NPERR_INVALID_INSTANCE_ERROR;
funcs.retainobject (instance->pdata);
*(NPObject**)value = instance->pdata; *(NPObject**)value = instance->pdata;
break; break;

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63) AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.24.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) AC_INIT([gnome-shell],[3.20.0],[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,20 +17,20 @@ 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])
LT_INIT([disable-static]) LT_INIT([disable-static])
# i18n # i18n
IT_PROG_INTLTOOL([0.40])
GETTEXT_PACKAGE=gnome-shell GETTEXT_PACKAGE=gnome-shell
AC_SUBST(GETTEXT_PACKAGE) AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
[The prefix for our gettext translation domains.]) [The prefix for our gettext translation domains.])
AM_GNU_GETTEXT_VERSION([0.19.6])
AM_GNU_GETTEXT([external])
PKG_PROG_PKG_CONFIG([0.22]) PKG_PROG_PKG_CONFIG([0.22])
AC_PATH_PROG([XSLTPROC], [xsltproc]) AC_PATH_PROG([XSLTPROC], [xsltproc])
@ -41,15 +41,6 @@ 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
@ -61,7 +52,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 $LIBMUTTER_CLUTTER) PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules mutter-clutter-1.0)
else else
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
fi fi
@ -83,13 +74,15 @@ AS_IF([test x$enable_systemd != xno], [
AC_MSG_RESULT($enable_systemd) AC_MSG_RESULT($enable_systemd)
GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1 CLUTTER_MIN_VERSION=1.21.5
GJS_MIN_VERSION=1.47.0 GOBJECT_INTROSPECTION_MIN_VERSION=1.45.4
MUTTER_MIN_VERSION=3.24.0 GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.20.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
@ -102,14 +95,14 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
libxml-2.0 libxml-2.0
gtk+-3.0 >= $GTK_MIN_VERSION gtk+-3.0 >= $GTK_MIN_VERSION
atk-bridge-2.0 atk-bridge-2.0
gjs-1.0 >= $GJS_MIN_VERSION gjs-internals-1.0 >= $GJS_MIN_VERSION
$recorder_modules $recorder_modules
gdk-x11-3.0 libsoup-2.4 gdk-x11-3.0 libsoup-2.4
$LIBMUTTER_CLUTTER >= $MUTTER_MIN_VERSION mutter-clutter-1.0 >= $CLUTTER_MIN_VERSION
$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
@ -117,17 +110,15 @@ 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-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, $LIBMUTTER_CLUTTER gtk+-3.0 libcroco-0.6 >= 0.6.8 x11) PKG_CHECK_MODULES(ST, mutter-clutter-1.0 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, $LIBMUTTER_CLUTTER gtk+-3.0) PKG_CHECK_MODULES(TRAY, mutter-clutter-1.0 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.19.2)
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],
@ -153,10 +144,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`
@ -262,6 +253,7 @@ AC_CONFIG_FILES([
docs/reference/st/Makefile docs/reference/st/Makefile
docs/reference/st/st-docs.sgml docs/reference/st/st-docs.sgml
js/Makefile js/Makefile
src/calendar-server/evolution-calendar.desktop.in
src/Makefile src/Makefile
src/gvc/Makefile src/gvc/Makefile
browser-plugin/Makefile browser-plugin/Makefile

View File

@ -1,24 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.shell.keybindings" <KeyListEntries schema="org.gnome.shell.keybindings"
group="system" group="system"
name="System" _name="System"
wm_name="GNOME Shell" wm_name="GNOME Shell"
package="gnome-shell"> package="gnome-shell">
<KeyListEntry name="toggle-message-tray" <KeyListEntry name="toggle-message-tray"
description="Show the notification list"/> _description="Show the notification list"/>
<KeyListEntry name="focus-active-notification" <KeyListEntry name="focus-active-notification"
description="Focus the active notification"/> _description="Focus the active notification"/>
<KeyListEntry name="toggle-overview" <KeyListEntry name="toggle-overview"
description="Show the overview"/> _description="Show the overview"/>
<KeyListEntry name="toggle-application-view" <KeyListEntry name="toggle-application-view"
description="Show all applications"/> _description="Show all applications"/>
<KeyListEntry name="open-application-menu" <KeyListEntry name="open-application-menu"
description="Open the application menu"/> _description="Open the application menu"/>
</KeyListEntries> </KeyListEntries>

View File

@ -7,16 +7,12 @@ desktop_DATA = org.gnome.Shell.desktop gnome-shell-extension-prefs.desktop
if HAVE_NETWORKMANAGER if HAVE_NETWORKMANAGER
desktop_DATA += org.gnome.Shell.PortalHelper.desktop desktop_DATA += org.gnome.Shell.PortalHelper.desktop
portaldir = $(datadir)/xdg-desktop-portal/portals
portal_DATA = gnome-shell.portal
servicedir = $(datadir)/dbus-1/services servicedir = $(datadir)/dbus-1/services
service_DATA = org.gnome.Shell.PortalHelper.service service_DATA = org.gnome.Shell.PortalHelper.service
CLEANFILES += \ CLEANFILES += \
org.gnome.Shell.PortalHelper.service \ org.gnome.Shell.PortalHelper.service \
org.gnome.Shell.PortalHelper.desktop \ org.gnome.Shell.PortalHelper.desktop \
org.gnome.Shell.PortalHelper.desktop.in \
$(NULL) $(NULL)
endif endif
@ -32,13 +28,10 @@ endif
-e "s|@VERSION[@]|$(VERSION)|" \ -e "s|@VERSION[@]|$(VERSION)|" \
$< > $@ || rm $@ $< > $@ || rm $@
%.desktop:%.desktop.in @INTLTOOL_DESKTOP_RULE@
$(AM_V_GEN) $(MSGFMT) --desktop --template $(builddir)/$< \
-d $(top_srcdir)/po -o $@
introspectiondir = $(datadir)/dbus-1/interfaces introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = \ introspection_DATA = \
org.gnome.Shell.PadOsd.xml \
org.gnome.Shell.Screencast.xml \ org.gnome.Shell.Screencast.xml \
org.gnome.Shell.Screenshot.xml \ org.gnome.Shell.Screenshot.xml \
org.gnome.ShellSearchProvider.xml \ org.gnome.ShellSearchProvider.xml \
@ -64,7 +57,6 @@ dist_theme_files = \
theme/gnome-shell-sass/NEWS \ theme/gnome-shell-sass/NEWS \
theme/gnome-shell-sass/README \ theme/gnome-shell-sass/README \
theme/gnome-shell-sass/gnome-shell-sass.doap \ theme/gnome-shell-sass/gnome-shell-sass.doap \
theme/pad-osd.css \
theme/parse-sass.sh \ theme/parse-sass.sh \
$(NULL) $(NULL)
@ -88,11 +80,14 @@ perf-background.xml: perf-background.xml.in
$< > $@ || rm $@ $< > $@ || rm $@
keysdir = @GNOME_KEYBINDINGS_KEYSDIR@ keysdir = @GNOME_KEYBINDINGS_KEYSDIR@
keys_DATA = 50-gnome-shell-system.xml keys_in_files = 50-gnome-shell-system.xml.in
keys_DATA = $(keys_in_files:.xml.in=.xml)
gsettings_SCHEMAS = org.gnome.shell.gschema.xml gsettings_SCHEMAS = org.gnome.shell.gschema.xml
%.gschema.xml: %.gschema.xml.in Makefile @INTLTOOL_XML_NOMERGE_RULE@
%.gschema.xml.in: %.gschema.xml.in.in Makefile
$(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \ $(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \
$< > $@ || rm $@ $< > $@ || rm $@
@ -111,16 +106,15 @@ convert_DATA = gnome-shell-overrides.convert
EXTRA_DIST = \ EXTRA_DIST = \
org.gnome.Shell.desktop.in.in \ org.gnome.Shell.desktop.in.in \
gnome-shell-extension-prefs.desktop.in.in \ gnome-shell-extension-prefs.desktop.in.in \
$(portal_DATA) \
$(introspection_DATA) \ $(introspection_DATA) \
$(menu_DATA) \ $(menu_DATA) \
$(convert_DATA) \ $(convert_DATA) \
$(keys_DATA) \ $(keys_in_files) \
$(dist_theme_files) \ $(dist_theme_files) \
perf-background.xml.in \ perf-background.xml.in \
org.gnome.Shell.PortalHelper.desktop.in.in \ org.gnome.Shell.PortalHelper.desktop.in \
org.gnome.Shell.PortalHelper.service.in \ org.gnome.Shell.PortalHelper.service.in \
org.gnome.shell.gschema.xml.in \ org.gnome.shell.gschema.xml.in.in \
gnome-shell-theme.gresource.xml \ gnome-shell-theme.gresource.xml \
$(resource_files) \ $(resource_files) \
$(NULL) $(NULL)
@ -129,9 +123,11 @@ CLEANFILES += \
org.gnome.Shell.desktop.in \ org.gnome.Shell.desktop.in \
gnome-shell-extension-prefs.in \ gnome-shell-extension-prefs.in \
$(desktop_DATA) \ $(desktop_DATA) \
$(keys_DATA) \
$(gsettings_SCHEMAS) \ $(gsettings_SCHEMAS) \
perf-background.xml \ perf-background.xml \
gschemas.compiled \ gschemas.compiled \
org.gnome.shell.gschema.valid \ org.gnome.shell.gschema.valid \
org.gnome.shell.gschema.xml.in \
gnome-shell-theme.gresource \ gnome-shell-theme.gresource \
$(NULL) $(NULL)

View File

@ -1,7 +1,7 @@
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=Shell Extensions _Name=GNOME Shell Extension Preferences
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
X-GNOME-Bugzilla-Product=gnome-shell X-GNOME-Bugzilla-Product=gnome-shell

View File

@ -22,7 +22,6 @@
<file>no-events.svg</file> <file>no-events.svg</file>
<file>no-notifications.svg</file> <file>no-notifications.svg</file>
<file>noise-texture.png</file> <file>noise-texture.png</file>
<file>pad-osd.css</file>
<file>page-indicator-active.svg</file> <file>page-indicator-active.svg</file>
<file>page-indicator-inactive.svg</file> <file>page-indicator-inactive.svg</file>
<file>page-indicator-checked.svg</file> <file>page-indicator-checked.svg</file>

View File

@ -1,4 +0,0 @@
[portal]
DBusName=org.freedesktop.impl.portal.desktop.gnome
Interfaces=org.freedesktop.impl.portal.Access
UseIn=gnome

View File

@ -1,28 +0,0 @@
<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>
<!--
org.gnome.Shell.PadOSD:
@short_description: Pad OSD interface
The interface used to show button map OSD on pad devices.
-->
<interface name='org.gnome.Shell.Wacom.PadOsd'>
<!--
Show:
@device_node: device node file, usually in /dev/input/...
@edition_mode: whether toggling edition mode on when showing
Shows the pad button map OSD for the requested device, the OSD
will be shown according the current device settings (output
mapping, left handed mode, ...)
-->
<method name='Show'>
<arg name='device_node' direction='in' type='o'/>
<arg name='edition_mode' direction='in' type='b'/>
</method>
</interface>
</node>

View File

@ -1,10 +1,9 @@
[Desktop Entry] [Desktop Entry]
Name=Network Login _Name=Network Login
Type=Application Type=Application
Exec=gapplication launch org.gnome.Shell.PortalHelper Exec=gapplication launch org.gnome.Shell.PortalHelper
DBusActivatable=true DBusActivatable=true
NoDisplay=true NoDisplay=true
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=network-workgroup Icon=network-workgroup
StartupNotify=true StartupNotify=true
OnlyShowIn=GNOME; OnlyShowIn=GNOME;

View File

@ -1,7 +1,7 @@
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=GNOME Shell _Name=GNOME Shell
Comment=Window management and application launching _Comment=Window management and application launching
Exec=@bindir@/gnome-shell Exec=@bindir@/gnome-shell
X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell X-GNOME-Bugzilla-Product=gnome-shell

View File

@ -3,139 +3,143 @@
gettext-domain="@GETTEXT_PACKAGE@"> gettext-domain="@GETTEXT_PACKAGE@">
<key name="development-tools" type="b"> <key name="development-tools" type="b">
<default>true</default> <default>true</default>
<summary> <_summary>
Enable internal tools useful for developers and testers from Alt-F2 Enable internal tools useful for developers and testers from Alt-F2
</summary> </_summary>
<description> <_description>
Allows access to internal debugging and monitoring tools Allows access to internal debugging and monitoring tools
using the Alt-F2 dialog. using the Alt-F2 dialog.
</description> </_description>
</key> </key>
<key name="enabled-extensions" type="as"> <key name="enabled-extensions" type="as">
<default>[]</default> <default>[]</default>
<summary>UUIDs of extensions to enable</summary> <_summary>UUIDs of extensions to enable</_summary>
<description> <_description>
GNOME Shell extensions have a UUID property; this key lists extensions GNOME Shell extensions have a UUID property; this key lists extensions
which should be loaded. Any extension that wants to be loaded needs 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 to be in this list. You can also manipulate this list with the
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell. EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
</description> </_description>
</key>
<key name="disable-user-extensions" type="b">
<default>false</default>
<summary>Disable user extensions</summary>
<description>
Disable all extensions the user has enabled without affecting
the “enabled-extension” setting.
</description>
</key> </key>
<key name="disable-extension-version-validation" type="b"> <key name="disable-extension-version-validation" type="b">
<default>true</default> <default>false</default>
<summary>Disables the validation of extension version compatibility</summary> <_summary>Disables the validation of extension version compatibility</_summary>
<description> <_description>
GNOME Shell will only load extensions that claim to support the current GNOME Shell will only load extensions that claim to support the current
running version. Enabling this option will disable this check and try to running version. Enabling this option will disable this check and try to
load all extensions regardless of the versions they claim to support. load all extensions regardless of the versions they claim to support.
</description> </_description>
</key> </key>
<key name="favorite-apps" type="as"> <key name="favorite-apps" type="as">
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default> <default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<summary>List of desktop file IDs for favorite applications</summary> <_summary>List of desktop file IDs for favorite applications</_summary>
<description> <_description>
The applications corresponding to these identifiers The applications corresponding to these identifiers
will be displayed in the favorites area. will be displayed in the favorites area.
</description> </_description>
</key> </key>
<key name="app-picker-view" type="u"> <key name="app-picker-view" type="u">
<default>0</default> <default>0</default>
<summary>App Picker View</summary> <_summary>App Picker View</_summary>
<description> <_description>
Index of the currently selected view in the application picker. Index of the currently selected view in the application picker.
</description> </_description>
</key> </key>
<key name="command-history" type="as"> <key name="command-history" type="as">
<default>[]</default> <default>[]</default>
<summary>History for command (Alt-F2) dialog</summary> <_summary>History for command (Alt-F2) dialog</_summary>
</key> </key>
<key name="looking-glass-history" type="as"> <key name="looking-glass-history" type="as">
<default>[]</default> <default>[]</default>
<!-- Translators: looking glass is a debugger and inspector tool, see https://wiki.gnome.org/Projects/GnomeShell/LookingGlass --> <!-- Translators: looking glass is a debugger and inspector tool, see https://live.gnome.org/GnomeShell/LookingGlass -->
<summary>History for the looking glass dialog</summary> <_summary>History for the looking glass dialog</_summary>
</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>
<key name="remember-mount-password" type="b"> <key name="remember-mount-password" type="b">
<default>false</default> <default>false</default>
<summary>Whether to remember password for mounting encrypted or remote filesystems</summary> <_summary>Whether to remember password for mounting encrypted or remote filesystems</_summary>
<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>
<key name="had-bluetooth-devices-setup" type="b"> <key name="had-bluetooth-devices-setup" type="b">
<default>false</default> <default>false</default>
<summary>Whether the default Bluetooth adapter had set up devices associated to it</summary> <_summary>Whether the default Bluetooth adapter had set up devices associated to it</_summary>
<description> <_description>
The shell will only show a Bluetooth menu item if a Bluetooth The shell will only show a Bluetooth menu item if a Bluetooth
adapter is powered, or if there were devices set up associated adapter is powered, or if there were devices set up associated
with the default adapter. This will be reset if the default with the default adapter. This will be reset if the default
adapter is ever seen not to have devices associated to it. adapter is ever seen not to have devices associated to it.
</description> </_description>
</key> </key>
<child name="calendar" schema="org.gnome.shell.calendar"/>
<child name="keybindings" schema="org.gnome.shell.keybindings"/> <child name="keybindings" schema="org.gnome.shell.keybindings"/>
<child name="keyboard" schema="org.gnome.shell.keyboard"/> <child name="keyboard" schema="org.gnome.shell.keyboard"/>
</schema> </schema>
<schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="show-weekdate" type="b">
<default>false</default>
<_summary>Show the week date in the calendar</_summary>
<_description>
If true, display the ISO week date in the calendar.
</_description>
</key>
</schema>
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/" <schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
gettext-domain="@GETTEXT_PACKAGE@"> gettext-domain="@GETTEXT_PACKAGE@">
<key name="open-application-menu" type="as"> <key name="open-application-menu" type="as">
<default>["&lt;Super&gt;F10"]</default> <default>["&lt;Super&gt;F10"]</default>
<summary>Keybinding to open the application menu</summary> <_summary>Keybinding to open the application menu</_summary>
<description> <_description>
Keybinding to open the application menu. Keybinding to open the application menu.
</description> </_description>
</key> </key>
<key name="toggle-application-view" type="as"> <key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default> <default>["&lt;Super&gt;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>
<key name="toggle-overview" type="as"> <key name="toggle-overview" type="as">
<default>["&lt;Super&gt;s"]</default> <default>["&lt;Super&gt;s"]</default>
<summary>Keybinding to open the overview</summary> <_summary>Keybinding to open the overview</_summary>
<description> <_description>
Keybinding to open the Activities Overview. Keybinding to open the Activities Overview.
</description> </_description>
</key> </key>
<key name="toggle-message-tray" type="as"> <key name="toggle-message-tray" type="as">
<default>["&lt;Super&gt;v","&lt;Super&gt;m"]</default> <default>["&lt;Super&gt;v","&lt;Super&gt;m"]</default>
<summary>Keybinding to toggle the visibility of the notification list</summary> <_summary>Keybinding to toggle the visibility of the notification list</_summary>
<description> <_description>
Keybinding to toggle the visibility of the notification list. Keybinding to toggle the visibility of the notification list.
</description> </_description>
</key> </key>
<key name="focus-active-notification" type="as"> <key name="focus-active-notification" type="as">
<default>["&lt;Super&gt;n"]</default> <default>["&lt;Super&gt;n"]</default>
<summary>Keybinding to focus the active notification</summary> <_summary>Keybinding to focus the active notification</_summary>
<description> <_description>
Keybinding to focus the active notification. Keybinding to focus the active notification.
</description> </_description>
</key> </key>
<key name="pause-resume-tweens" type="as"> <key name="pause-resume-tweens" type="as">
<default>[]</default> <default>[]</default>
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary> <_summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</_summary>
<description></description> <_description></_description>
</key> </key>
</schema> </schema>
@ -143,10 +147,10 @@
gettext-domain="@GETTEXT_PACKAGE@"> gettext-domain="@GETTEXT_PACKAGE@">
<key name="keyboard-type" type="s"> <key name="keyboard-type" type="s">
<default>'touch'</default> <default>'touch'</default>
<summary>Which keyboard to use</summary> <_summary>Which keyboard to use</_summary>
<description> <_description>
The type of keyboard to use. The type of keyboard to use.
</description> </_description>
</key> </key>
</schema> </schema>
@ -155,11 +159,11 @@
gettext-domain="@GETTEXT_PACKAGE@"> gettext-domain="@GETTEXT_PACKAGE@">
<key type="b" name="current-workspace-only"> <key type="b" name="current-workspace-only">
<default>false</default> <default>false</default>
<summary>Limit switcher to current workspace.</summary> <_summary>Limit switcher to current workspace.</_summary>
<description> <_description>
If true, only applications that have windows on the current workspace are shown in the switcher. If true, only applications that have windows on the current workspace are shown in the switcher.
Otherwise, all applications are included. Otherwise, all applications are included.
</description> </_description>
</key> </key>
</schema> </schema>
@ -173,20 +177,20 @@
gettext-domain="@GETTEXT_PACKAGE@"> gettext-domain="@GETTEXT_PACKAGE@">
<key name="app-icon-mode" enum="org.gnome.shell.window-switcher.AppIconMode"> <key name="app-icon-mode" enum="org.gnome.shell.window-switcher.AppIconMode">
<default>'both'</default> <default>'both'</default>
<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">
<default>true</default> <default>true</default>
<summary>Limit switcher to current workspace.</summary> <_summary>Limit switcher to current workspace.</_summary>
<description> <_description>
If true, only windows from the current workspace are shown in the switcher. If true, only windows from the current workspace are shown in the switcher.
Otherwise, all windows are included. Otherwise, all windows are included.
</description> </_description>
</key> </key>
</schema> </schema>
@ -194,43 +198,43 @@
gettext-domain="@GETTEXT_PACKAGE@"> gettext-domain="@GETTEXT_PACKAGE@">
<key name="attach-modal-dialogs" type="b"> <key name="attach-modal-dialogs" type="b">
<default>true</default> <default>true</default>
<summary>Attach modal dialog to the parent window</summary> <_summary>Attach modal dialog to the parent window</_summary>
<description> <_description>
This key overrides the key in org.gnome.mutter when running This key overrides the key in org.gnome.mutter when running
GNOME Shell. GNOME Shell.
</description> </_description>
</key> </key>
<key name="edge-tiling" type="b"> <key name="edge-tiling" type="b">
<default>true</default> <default>true</default>
<summary>Enable edge tiling when dropping windows on screen edges</summary> <_summary>Enable edge tiling when dropping windows on screen edges</_summary>
<description> <_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell. This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description> </_description>
</key> </key>
<key name="dynamic-workspaces" type="b"> <key name="dynamic-workspaces" type="b">
<default>true</default> <default>true</default>
<summary>Workspaces are managed dynamically</summary> <_summary>Workspaces are managed dynamically</_summary>
<description> <_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell. This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description> </_description>
</key> </key>
<key name="workspaces-only-on-primary" type="b"> <key name="workspaces-only-on-primary" type="b">
<default>true</default> <default>true</default>
<summary>Workspaces only on primary monitor</summary> <_summary>Workspaces only on primary monitor</_summary>
<description> <_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell. This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description> </_description>
</key> </key>
<key name="focus-change-on-pointer-rest" type="b"> <key name="focus-change-on-pointer-rest" type="b">
<default>true</default> <default>true</default>
<summary>Delay focus changes in mouse mode until the pointer stops moving</summary> <_summary>Delay focus changes in mouse mode until the pointer stops moving</_summary>
<description> <_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell. This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description> </_description>
</key> </key>
</schema> </schema>
</schemalist> </schemalist>

View File

@ -427,29 +427,6 @@ StScrollBar {
.audio-selection-device-icon { .audio-selection-device-icon {
icon-size: 64px; } icon-size: 64px; }
/* Access Dialog */
.access-dialog {
spacing: 30px; }
.access-dialog-main-layout {
padding: 12px 20px 0;
spacing: 12px; }
.access-dialog-content {
max-width: 28em;
spacing: 20px; }
.access-dialog-icon {
min-width: 48px;
icon-size: 48px; }
.access-dialog-title {
font-weight: bold; }
.access-dialog-subtitle {
color: #999999;
font-weight: bold; }
/* Geolocation Dialog */ /* Geolocation Dialog */
.geolocation-dialog { .geolocation-dialog {
spacing: 30px; } spacing: 30px; }
@ -558,21 +535,6 @@ StScrollBar {
border-radius: 0.3em; border-radius: 0.3em;
background-color: rgba(11, 12, 13, 0.5); background-color: rgba(11, 12, 13, 0.5);
color: #eeeeec; } color: #eeeeec; }
.osd-window .level-bar {
background-color: #eeeeec;
border-radius: 0.3em; }
/* Pad OSD */
.pad-osd-window {
padding: 32px;
background-color: rgba(0, 0, 0, 0.8); }
.pad-osd-window .pad-osd-title-box {
spacing: 12px; }
.pad-osd-window .pad-osd-title-menu-box {
spacing: 6px; }
.combo-box-label {
width: 15em; }
/* App Switcher */ /* App Switcher */
.switcher-popup { .switcher-popup {
@ -616,10 +578,6 @@ StScrollBar {
width: 96px; width: 96px;
height: 96px; } height: 96px; }
/* Window Cycler */
.cycler-highlight {
border: 5px solid #215d9c; }
/* Workspace Switcher */ /* Workspace Switcher */
.workspace-switcher-group { .workspace-switcher-group {
padding: 12px; } padding: 12px; }
@ -738,20 +696,9 @@ 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,
.weather-button, .message-list-section-title {
.events-section-title {
border-radius: 4px; border-radius: 4px;
padding: .4em; } padding: .4em; }
@ -764,15 +711,12 @@ 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,
.weather-button:hover, .message-list-section-title:hover,
.weather-button:focus, .message-list-section-title: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,
.weather-button:active, .message-list-section-title:active {
.events-section-title:active {
color: white; color: white;
background-color: #215d9c; } background-color: #215d9c; }
@ -780,17 +724,13 @@ StScrollBar {
font-size: 1.5em; } font-size: 1.5em; }
.world-clocks-header, .world-clocks-header,
.weather-header, .message-list-section-title {
.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;
@ -826,7 +766,7 @@ StScrollBar {
border-radius: 1.4em; } border-radius: 1.4em; }
.calendar-day-base:hover, .calendar-day-base:focus { .calendar-day-base:hover, .calendar-day-base:focus {
background-color: #0d0d0d; } background-color: #0d0d0d; }
.calendar-day-base:active, .calendar-day-base:selected { .calendar-day-base:active {
color: white; color: white;
background-color: #215d9c; background-color: #215d9c;
border-color: transparent; } border-color: transparent; }
@ -875,68 +815,69 @@ 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: 1em; } spacing: 1.5em; }
.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: #0d0d0d; } background-color: #262626; }
.message-icon-bin { .message-icon-bin {
padding: 10px 3px 10px 10px; } padding: 8px 0px 8px 8px; }
.message-icon-bin:rtl { .message-icon-bin:rtl {
padding: 10px 10px 10px 3px; } padding: 8px 8px 8px 0px; }
.message-icon-bin > StIcon { .message-icon-bin > StIcon {
color: #cccccc; icon-size: 32px; }
icon-size: 16px;
-st-icon-style: symbolic; } .message-secondary-bin:ltr {
padding-left: 8px; }
.message-secondary-bin:rtl {
padding-right: 8px; }
.message-secondary-bin { .message-secondary-bin {
padding: 0 12px; } color: #999999; }
.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 {
color: #f2f2f2; } font-weight: bold;
font-size: 1.1em; }
.message-content { .message-content {
color: #cccccc; padding: 8px;
padding: 10px; } font-size: .9em; }
.message-media-control { .message-media-control {
padding: 12px; padding: 6px; }
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: 48px !important; } icon-size: 32px; }
.media-message-cover-icon.fallback { .media-message-cover-icon.fallback {
color: #1a1a1a; color: #1a1a1a;
background-color: #000; background-color: #000;

View File

@ -427,29 +427,6 @@ StScrollBar {
.audio-selection-device-icon { .audio-selection-device-icon {
icon-size: 64px; } icon-size: 64px; }
/* Access Dialog */
.access-dialog {
spacing: 30px; }
.access-dialog-main-layout {
padding: 12px 20px 0;
spacing: 12px; }
.access-dialog-content {
max-width: 28em;
spacing: 20px; }
.access-dialog-icon {
min-width: 48px;
icon-size: 48px; }
.access-dialog-title {
font-weight: bold; }
.access-dialog-subtitle {
color: #8e8e80;
font-weight: bold; }
/* Geolocation Dialog */ /* Geolocation Dialog */
.geolocation-dialog { .geolocation-dialog {
spacing: 30px; } spacing: 30px; }
@ -558,21 +535,6 @@ StScrollBar {
border-radius: 0.3em; border-radius: 0.3em;
background-color: rgba(11, 12, 13, 0.5); background-color: rgba(11, 12, 13, 0.5);
color: #eeeeec; } color: #eeeeec; }
.osd-window .level-bar {
background-color: #eeeeec;
border-radius: 0.3em; }
/* Pad OSD */
.pad-osd-window {
padding: 32px;
background-color: rgba(0, 0, 0, 0.8); }
.pad-osd-window .pad-osd-title-box {
spacing: 12px; }
.pad-osd-window .pad-osd-title-menu-box {
spacing: 6px; }
.combo-box-label {
width: 15em; }
/* App Switcher */ /* App Switcher */
.switcher-popup { .switcher-popup {
@ -616,10 +578,6 @@ StScrollBar {
width: 96px; width: 96px;
height: 96px; } height: 96px; }
/* Window Cycler */
.cycler-highlight {
border: 5px solid #215d9c; }
/* Workspace Switcher */ /* Workspace Switcher */
.workspace-switcher-group { .workspace-switcher-group {
padding: 12px; } padding: 12px; }
@ -738,20 +696,9 @@ 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,
.weather-button, .message-list-section-title {
.events-section-title {
border-radius: 4px; border-radius: 4px;
padding: .4em; } padding: .4em; }
@ -764,15 +711,12 @@ 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,
.weather-button:hover, .message-list-section-title:hover,
.weather-button:focus, .message-list-section-title: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,
.weather-button:active, .message-list-section-title:active {
.events-section-title:active {
color: white; color: white;
background-color: #215d9c; } background-color: #215d9c; }
@ -780,17 +724,13 @@ StScrollBar {
font-size: 1.5em; } font-size: 1.5em; }
.world-clocks-header, .world-clocks-header,
.weather-header, .message-list-section-title {
.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;
@ -826,7 +766,7 @@ StScrollBar {
border-radius: 1.4em; } border-radius: 1.4em; }
.calendar-day-base:hover, .calendar-day-base:focus { .calendar-day-base:hover, .calendar-day-base:focus {
background-color: #454c4c; } background-color: #454c4c; }
.calendar-day-base:active, .calendar-day-base:selected { .calendar-day-base:active {
color: white; color: white;
background-color: #215d9c; background-color: #215d9c;
border-color: transparent; } border-color: transparent; }
@ -875,68 +815,69 @@ 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: 1em; } spacing: 1.5em; }
.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: #454c4c; } background-color: #5d6767; }
.message-icon-bin { .message-icon-bin {
padding: 10px 3px 10px 10px; } padding: 8px 0px 8px 8px; }
.message-icon-bin:rtl { .message-icon-bin:rtl {
padding: 10px 10px 10px 3px; } padding: 8px 8px 8px 0px; }
.message-icon-bin > StIcon { .message-icon-bin > StIcon {
color: #bebeb6; icon-size: 32px; }
icon-size: 16px;
-st-icon-style: symbolic; } .message-secondary-bin:ltr {
padding-left: 8px; }
.message-secondary-bin:rtl {
padding-right: 8px; }
.message-secondary-bin { .message-secondary-bin {
padding: 0 12px; } color: #8e8e80; }
.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 {
color: #e2e2df; } font-weight: bold;
font-size: 1.1em; }
.message-content { .message-content {
color: #bebeb6; padding: 8px;
padding: 10px; } font-size: .9em; }
.message-media-control { .message-media-control {
padding: 12px; padding: 6px; }
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: 48px !important; } icon-size: 32px; }
.media-message-cover-icon.fallback { .media-message-cover-icon.fallback {
color: #515a5a; color: #515a5a;
background-color: #393f3f; background-color: #393f3f;

View File

@ -1,30 +0,0 @@
.Leader {
stroke-width: .5 !important;
stroke: #535353;
fill: none !important;
}
.Button {
stroke-width: .25;
stroke: #ededed;
fill: #ededed;
}
.Ring {
stroke-width: .5 !important;
stroke: #535353 !important;
fill: none !important;
}
.Label {
stroke: none !important;
stroke-width: .1 !important;
font-size: .1 !important;
fill: transparent !important;
}
.TouchStrip, .TouchRing {
stroke-width: .1 !important;
stroke: #ededed !important;
fill: #535353 !important;
}

View File

@ -113,7 +113,7 @@ expand_content_files=
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS) GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS)
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la -rpath $(MUTTER_TYPELIB_DIR) GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la
# This includes the standard gtk-doc make rules, copied by gtkdocize. # This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make include $(top_srcdir)/gtk-doc.make
@ -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_MODULE).types DISTCLEANFILES = $(DOC_MODULES).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

View File

@ -50,6 +50,7 @@
<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>

View File

@ -78,7 +78,7 @@ expand_content_files=
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS= GTKDOC_CFLAGS=
GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la -rpath $(MUTTER_TYPELIB_DIR) GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la
# This includes the standard gtk-doc make rules, copied by gtkdocize. # This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make include $(top_srcdir)/gtk-doc.make

View File

@ -11,7 +11,6 @@ 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)

View File

@ -5,7 +5,6 @@ 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;
@ -93,11 +92,9 @@ const Application = new Lang.Class({
widget = this._buildErrorUI(extension, e); widget = this._buildErrorUI(extension, e);
} }
let dialog = new Gtk.Window({ modal: !this._skipMainWindow, let dialog = new Gtk.Dialog({ use_header_bar: true,
type_hint: Gdk.WindowTypeHint.DIALOG }); modal: true,
dialog.set_titlebar(new Gtk.HeaderBar({ show_close_button: true, title: extension.metadata.name });
title: extension.metadata.name,
visible: true }));
if (this._skipMainWindow) { if (this._skipMainWindow) {
this.application.add_window(dialog); this.application.add_window(dialog);
@ -110,7 +107,7 @@ const Application = new Lang.Class({
} }
dialog.set_default_size(600, 400); dialog.set_default_size(600, 400);
dialog.add(widget); dialog.get_content_area().add(widget);
dialog.show(); dialog.show();
}, },
@ -146,21 +143,16 @@ 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_default_size(800, 500); this._window.set_size_request(800, 500);
this._titlebar = new Gtk.HeaderBar({ show_close_button: true, this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
title: _("Shell Extensions") }); title: _("GNOME Shell Extensions") });
this._window.set_titlebar(this._titlebar); this._window.set_titlebar(this._titlebar);
let killSwitch = new Gtk.Switch({ valign: Gtk.Align.CENTER }); let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER,
this._titlebar.pack_end(killSwitch); shadow_type: Gtk.ShadowType.IN,
halign: Gtk.Align.CENTER,
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 });
@ -253,18 +245,6 @@ 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,
@ -283,10 +263,6 @@ 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();
}, },
@ -295,8 +271,7 @@ 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_end: 24, spacing: 24, hexpand: true, margin: 12, spacing: 6 });
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,
@ -310,9 +285,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 DescriptionLabel({ label: desc, wrap: true, lines: 2, label = new Gtk.Label({ label: desc,
ellipsize: Pango.EllipsizeMode.END, ellipsize: Pango.EllipsizeMode.END,
xalign: 0, yalign: 0 }); halign: Gtk.Align.START });
vbox.add(label); vbox.add(label);
let button = new Gtk.Button({ valign: Gtk.Align.CENTER, let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
@ -343,8 +318,7 @@ 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 !this._settings.get_boolean('disable-user-extensions') && return !(checkVersion && ExtensionUtils.isOutOfDate(extension));
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
}, },
_isEnabled: function() { _isEnabled: function() {

View File

@ -13,7 +13,6 @@ const Params = imports.misc.params;
const ShellEntry = imports.ui.shellEntry; const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget; const UserWidget = imports.ui.userWidget;
const Pango = imports.gi.Pango;
const DEFAULT_BUTTON_WELL_ICON_SIZE = 16; const DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
@ -114,7 +113,6 @@ const AuthPrompt = new Lang.Class({
this._message = new St.Label({ opacity: 0, this._message = new St.Label({ opacity: 0,
styleClass: 'login-dialog-message' }); styleClass: 'login-dialog-message' });
this._message.clutter_text.line_wrap = true; this._message.clutter_text.line_wrap = true;
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START }); this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',

View File

@ -23,12 +23,6 @@ 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) });
try {
self.init(null); self.init(null);
} catch(e) {
log('Failed to connect to Fprint service: ' + e.message);
return null;
}
return self; return self;
} }

View File

@ -804,11 +804,6 @@ const LoginDialog = new Lang.Class({
this._user = null; this._user = null;
if (this._nextSignalId) {
this._authPrompt.disconnect(this._nextSignalId);
this._nextSignalId = 0;
}
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
if (!this._disableUserList) if (!this._disableUserList)
this._showUserList(); this._showUserList();
@ -1225,7 +1220,7 @@ const LoginDialog = new Lang.Class({
}, },
addCharacter: function(unichar) { addCharacter: function(unichar) {
// Don't allow type ahead at the login screen this._authPrompt.addCharacter(unichar);
}, },
finish: function(onComplete) { finish: function(onComplete) {

View File

@ -128,22 +128,18 @@ const ShellUserVerifier = new Lang.Class({
this._client = client; this._client = client;
this._defaultService = null;
this._preemptingService = null;
this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed', this._settings.connect('changed',
Lang.bind(this, this._updateDefaultService)); Lang.bind(this, this._updateDefaultService));
this._updateDefaultService(); this._updateDefaultService();
this._fprintManager = Fprint.FprintManager(); this._fprintManager = new 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
// at startup should result in immediately initiating authentication. // at startup should result in immediately initiating authentication.
// This is different than fingeprint readers, where we only check them // This is different than fingeprint readers, where we only check them
// after a user has been picked. // after a user has been picked.
this.smartcardDetected = false;
this._checkForSmartcard(); this._checkForSmartcard();
this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted', this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
@ -297,8 +293,7 @@ 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;
} }

View File

@ -23,17 +23,14 @@
<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>
<file>portalHelper/main.js</file> <file>portalHelper/main.js</file>
<file>ui/accessDialog.js</file>
<file>ui/altTab.js</file> <file>ui/altTab.js</file>
<file>ui/animation.js</file> <file>ui/animation.js</file>
<file>ui/appDisplay.js</file> <file>ui/appDisplay.js</file>
@ -74,7 +71,6 @@
<file>ui/osdMonitorLabeler.js</file> <file>ui/osdMonitorLabeler.js</file>
<file>ui/overview.js</file> <file>ui/overview.js</file>
<file>ui/overviewControls.js</file> <file>ui/overviewControls.js</file>
<file>ui/padOsd.js</file>
<file>ui/panel.js</file> <file>ui/panel.js</file>
<file>ui/panelMenu.js</file> <file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file> <file>ui/pointerWatcher.js</file>
@ -119,7 +115,6 @@
<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>

View File

@ -15,5 +15,3 @@ 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@'

View File

@ -6,7 +6,9 @@
const Lang = imports.lang; const Lang = imports.lang;
const Signals = imports.signals; const Signals = imports.signals;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const ShellJS = imports.gi.ShellJS;
const Config = imports.misc.config; const Config = imports.misc.config;
const FileUtils = imports.misc.fileUtils; const FileUtils = imports.misc.fileUtils;
@ -19,25 +21,14 @@ const ExtensionType = {
// Maps uuid -> metadata object // Maps uuid -> metadata object
const extensions = {}; const extensions = {};
/**
* getCurrentExtension:
*
* Returns the current extension, or null if not called from an extension.
*/
function getCurrentExtension() { function getCurrentExtension() {
let stack = (new Error()).stack.split('\n'); let stack = (new Error()).stack;
let extensionStackLine;
// Search for an occurrence of an extension stack frame // Assuming we're importing this directly from an extension (and we shouldn't
// Start at 1 because 0 is the stack frame of this function // ever not be), its UUID should be directly in the path here.
for (let i = 1; i < stack.length; i++) { let extensionStackLine = stack.split('\n')[1];
if (stack[i].indexOf('/gnome-shell/extensions/') > -1) {
extensionStackLine = stack[i];
break;
}
}
if (!extensionStackLine) if (!extensionStackLine)
return null; throw new Error('Could not find current extension');
// The stack line is like: // The stack line is like:
// init([object Object])@/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8 // init([object Object])@/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
@ -47,7 +38,7 @@ function getCurrentExtension() {
// @/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8 // @/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
let match = new RegExp('@(.+):\\d+').exec(extensionStackLine); let match = new RegExp('@(.+):\\d+').exec(extensionStackLine);
if (!match) if (!match)
return null; throw new Error('Could not find current extension');
let path = match[1]; let path = match[1];
let file = Gio.File.new_for_path(path); let file = Gio.File.new_for_path(path);
@ -61,7 +52,7 @@ function getCurrentExtension() {
file = file.get_parent(); file = file.get_parent();
} }
return null; throw new Error('Could not find current extension');
} }
/** /**
@ -149,13 +140,12 @@ function createExtensionObject(uuid, dir, type) {
return extension; return extension;
} }
var _extension = null;
function installImporter(extension) { function installImporter(extension) {
let oldSearchPath = imports.searchPath.slice(); // make a copy _extension = extension;
imports.searchPath = [extension.dir.get_parent().get_path()]; ShellJS.add_extension_importer('imports.misc.extensionUtils._extension', 'imports', extension.path);
// importing a "subdir" creates a new importer object that doesn't affect _extension = null;
// the global one
extension.imports = imports[extension.uuid];
imports.searchPath = oldSearchPath;
} }
const ExtensionFinder = new Lang.Class({ const ExtensionFinder = new Lang.Class({

View File

@ -69,7 +69,7 @@ const HistoryManager = new Lang.Class({
this._indexChanged(); this._indexChanged();
} }
return this._historyIndex ? this._history[this._historyIndex -1] : null; return this._historyIndex[this._history.length];
}, },
addItem: function(input) { addItem: function(input) {

View File

@ -6,11 +6,10 @@ 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);
IBusCandidatePopup = imports.ui.ibusCandidatePopup; const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
} catch (e) { } catch (e) {
var IBus = null; var IBus = null;
log(e); log(e);
@ -190,7 +189,7 @@ const IBusManager = new Lang.Class({
}, },
getEngineDesc: function(id) { getEngineDesc: function(id) {
if (!IBus || !this._ready || !this._engines.hasOwnProperty(id)) if (!IBus || !this._ready)
return null; return null;
return this._engines[id]; return this._engines[id];

View File

@ -128,8 +128,7 @@ 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 _layout, _variant; let [found, , , _layout, _variant] = this._xkbInfo.get_layout_info(id);
[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

View File

@ -40,9 +40,6 @@ const SystemdLoginSessionIface = '<node> \
<signal name="Lock" /> \ <signal name="Lock" /> \
<signal name="Unlock" /> \ <signal name="Unlock" /> \
<property name="Active" type="b" access="read" /> \ <property name="Active" type="b" access="read" /> \
<method name="SetLockedHint"> \
<arg type="b" direction="in"/> \
</method> \
</interface> \ </interface> \
</node>'; </node>';
@ -134,13 +131,10 @@ const LoginManagerSystemd = new Lang.Class({
canSuspend: function(asyncCallback) { canSuspend: function(asyncCallback) {
this._proxy.CanSuspendRemote(function(result, error) { this._proxy.CanSuspendRemote(function(result, error) {
if (error) { if (error)
asyncCallback(false, false); asyncCallback(false);
} else { else
let needsAuth = result[0] == 'challenge'; asyncCallback(result[0] != 'no' && result[0] != 'na');
let canSuspend = needsAuth || result[0] == 'yes';
asyncCallback(canSuspend, needsAuth);
}
}); });
}, },
@ -193,7 +187,7 @@ const LoginManagerDummy = new Lang.Class({
}, },
canSuspend: function(asyncCallback) { canSuspend: function(asyncCallback) {
asyncCallback(false, false); asyncCallback(false);
}, },
listSessions: function(asyncCallback) { listSessions: function(asyncCallback) {

View File

@ -1,37 +0,0 @@
// -*- 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);
};

View File

@ -1,12 +1,9 @@
// -*- 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;
@ -97,7 +94,7 @@ function spawnApp(argv) {
Gio.AppInfoCreateFlags.SUPPORTS_STARTUP_NOTIFICATION); Gio.AppInfoCreateFlags.SUPPORTS_STARTUP_NOTIFICATION);
let context = global.create_app_launch_context(0, -1); let context = global.create_app_launch_context(0, -1);
app.launch([], context, false); app.launch([], context);
} catch(err) { } catch(err) {
_handleSpawnError(argv[0], err); _handleSpawnError(argv[0], err);
} }
@ -164,41 +161,6 @@ 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
@ -281,10 +243,7 @@ function formatTime(time, params) {
// xgettext:no-c-format // xgettext:no-c-format
format = N_("%B %d %Y, %l\u2236%M %p"); format = N_("%B %d %Y, %l\u2236%M %p");
} }
return date.format(Shell.util_translate_time_string(format));
let formattedTime = date.format(Shell.util_translate_time_string(format));
// prepend LTR-mark to colon/ratio to force a text direction on times
return formattedTime.replace(/([:\u2236])/g, '\u200e$1');
} }
function createTimeLabel(date, params) { function createTimeLabel(date, params) {
@ -439,94 +398,3 @@ 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);

View File

@ -1,247 +0,0 @@
// -*- 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);

View File

@ -19,15 +19,7 @@ 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_URI = 'http://' + CONNECTIVITY_CHECK_HOST;
const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC; const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
const HelperDBusInterface = '<node> \ const HelperDBusInterface = '<node> \
@ -50,71 +42,6 @@ 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,
@ -122,14 +49,8 @@ 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 = 'http://www.gnome.org';
this._originalUrlWasGnome = true; this._originalUrlWasGnome = true;
} else { } else {
this._originalUrlWasGnome = false; this._originalUrlWasGnome = false;
@ -141,38 +62,28 @@ const PortalWindow = new Lang.Class({
this._lastRecheck = 0; this._lastRecheck = 0;
this._recheckAtExit = false; this._recheckAtExit = false;
this._webContext = WebKit.WebContext.new_ephemeral(); this._webView = new WebKit.WebView();
this._webContext.set_cache_model(WebKit.CacheModel.DOCUMENT_VIEWER);
this._webContext.set_network_proxy_settings(WebKit.NetworkProxyMode.NO_PROXY, null);
this._webView = WebKit.WebView.new_with_context(this._webContext);
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy)); this._webView.connect('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::uri', Lang.bind(this, this._syncUri)); this._webView.connect('notify::title', Lang.bind(this, this._syncTitle));
this._syncUri(); this._syncTitle();
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']);
}, },
destroyWindow: function() { _syncTitle: function() {
this.destroy(); let title = this._webView.title;
},
_syncUri: function() { if (title) {
let uri = this._webView.uri; this.title = title;
if (uri) } else {
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null)); /* TRANSLATORS: this is the title of the wifi captive portal login
else * window, until we know the title of the actual login page */
this._headerBar.setSubtitle(''); this.title = _("Web Authentication Redirect");
}
}, },
refresh: function() { refresh: function() {
@ -188,46 +99,8 @@ 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;
} }
@ -239,12 +112,12 @@ const PortalWindow = new Lang.Class({
let uri = new Soup.URI(request.get_uri()); let uri = new Soup.URI(request.get_uri());
if (!uri.host_equal(this._uri) && this._originalUrlWasGnome) { if (!uri.host_equal(this._uri) && this._originalUrlWasGnome) {
if (uri.get_host() == CONNECTIVITY_CHECK_HOST && this._everSeenRedirect) { if (uri.get_host() == 'www.gnome.org' && this._everSeenRedirect) {
// Yay, we got to gnome! // Yay, we got to gnome!
decision.ignore(); decision.ignore();
this._doneCallback(PortalHelperResult.COMPLETED); this._doneCallback(PortalHelperResult.COMPLETED);
return true; return true;
} else if (uri.get_host() != CONNECTIVITY_CHECK_HOST) { } else if (uri.get_host() != 'www.gnome.org') {
this._everSeenRedirect = true; this._everSeenRedirect = true;
} }
} }
@ -293,10 +166,6 @@ 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) {
@ -328,7 +197,7 @@ const WebPortalHelper = new Lang.Class({
if (obj.connection == connection) { if (obj.connection == connection) {
if (obj.window) if (obj.window)
obj.window.destroyWindow(); obj.window.destroy();
this._queue.splice(i, 1); this._queue.splice(i, 1);
break; break;
} }
@ -357,7 +226,7 @@ const WebPortalHelper = new Lang.Class({
if (top.window != null) if (top.window != null)
return; return;
top.window = new PortalWindow(this, top.url, top.timestamp, Lang.bind(this, function(result) { top.window = new PortalWindow(this, top.uri, top.timestamp, Lang.bind(this, function(result) {
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result])); this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
})); }));
}, },
@ -370,11 +239,6 @@ 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);

View File

@ -1,202 +0,0 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const CheckBox = imports.ui.checkBox;
const ModalDialog = imports.ui.modalDialog;
const RequestIface = '<node> \
<interface name="org.freedesktop.impl.portal.Request"> \
<method name="Close"/> \
</interface> \
</node>';
const AccessIface = '<node> \
<interface name="org.freedesktop.impl.portal.Access"> \
<method name="AccessDialog"> \
<arg type="o" name="handle" direction="in"/> \
<arg type="s" name="app_id" direction="in"/> \
<arg type="s" name="parent_window" direction="in"/> \
<arg type="s" name="title" direction="in"/> \
<arg type="s" name="subtitle" direction="in"/> \
<arg type="s" name="body" direction="in"/> \
<arg type="a{sv}" name="options" direction="in"/> \
<arg type="u" name="response" direction="out"/> \
<arg type="a{sv}" name="results" direction="out"/> \
</method> \
</interface> \
</node>';
const DialogResponse = {
OK: 0,
CANCEL: 1,
CLOSED: 2
};
const AccessDialog = new Lang.Class({
Name: 'AccessDialog',
Extends: ModalDialog.ModalDialog,
_init: function(invocation, handle, title, subtitle, body, options) {
this.parent({ styleClass: 'access-dialog' });
this._invocation = invocation;
this._handle = handle;
this._requestExported = false;
this._request = Gio.DBusExportedObject.wrapJSObject(RequestIface, this);
for (let option in options)
options[option] = options[option].deep_unpack();
this._buildLayout(title, subtitle, body, options);
},
_buildLayout: function(title, subtitle, body, options) {
// No support for non-modal system dialogs, so ignore the option
//let modal = options['modal'] || true;
let denyLabel = options['deny_label'] || _("Deny Access");
let grantLabel = options['grant_label'] || _("Grant Access");
let iconName = options['icon'] || null;
let choices = options['choices'] || [];
let mainContentBox = new St.BoxLayout();
mainContentBox.style_class = 'access-dialog-main-layout';
this.contentLayout.add_actor(mainContentBox);
let icon = new St.Icon({ style_class: 'access-dialog-icon',
icon_name: iconName,
y_align: Clutter.ActorAlign.START });
mainContentBox.add_actor(icon);
let messageBox = new St.BoxLayout({ vertical: true });
messageBox.style_class = 'access-dialog-content',
mainContentBox.add_actor(messageBox);
let label;
label = new St.Label({ style_class: 'access-dialog-title headline',
text: title });
messageBox.add_actor(label);
label = new St.Label({ style_class: 'access-dialog-subtitle',
text: subtitle });
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
label.clutter_text.line_wrap = true;
messageBox.add_actor(label);
this._choices = new Map();
for (let i = 0; i < choices.length; i++) {
let [id, name, opts, selected] = choices[i];
if (opts.length > 0)
continue; // radio buttons, not implemented
let check = new CheckBox.CheckBox();
check.getLabelActor().text = name;
check.actor.checked = selected == "true";
messageBox.add_actor(check.actor);
this._choices.set(id, check);
}
label = new St.Label({ text: body });
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
label.clutter_text.line_wrap = true;
messageBox.add_actor(label);
this.addButton({ label: denyLabel,
action: () => {
this._sendResponse(DialogResponse.CANCEL);
},
key: Clutter.KEY_Escape });
this.addButton({ label: grantLabel,
action: () => {
this._sendResponse(DialogResponse.OK);
}});
},
open: function() {
this.parent();
let connection = this._invocation.get_connection();
this._requestExported = this._request.export(connection, this._handle);
},
CloseAsync: function(invocation, params) {
if (this._invocation.get_sender() != invocation.get_sender()) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'');
return;
}
this._sendResponse(DialogResponse.CLOSED);
},
_sendResponse: function(response) {
if (this._requestExported)
this._request.unexport();
this._requestExported = false;
let results = {};
if (response == DialogResponse.OK) {
for (let [id, check] of this._choices) {
let checked = check.actor.checked ? 'true' : 'false';
results[id] = new GLib.Variant('s', checked);
}
}
// Delay actual response until the end of the close animation (if any)
this.connect('closed', () => {
this._invocation.return_value(new GLib.Variant('(ua{sv})',
[response, results]));
});
this.close();
}
});
const AccessDialogDBus = new Lang.Class({
Name: 'AccessDialogDBus',
_init: function() {
this._accessDialog = null;
this._windowTracker = Shell.WindowTracker.get_default();
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AccessIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/portal/desktop');
Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
AccessDialogAsync: function(params, invocation) {
if (this._accessDialog) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.LIMITS_EXCEEDED,
'Already showing a system access dialog');
return;
}
let [handle, appId, parentWindow, title, subtitle, body, options] = params;
// We probably want to use parentWindow and global.display.focus_window
// for this check in the future
if (appId && appId + '.desktop' != this._windowTracker.focus_app.id) {
invocation.return_error_literal(Gio.DBusError,
Gio.DBusError.ACCESS_DENIED,
'Only the focused app is allowed to show a system access dialog');
return;
}
let dialog = new AccessDialog(invocation, handle, title,
subtitle, body, options);
dialog.open();
dialog.connect('closed', () => { this._accessDialog = null; });
this._accessDialog = dialog;
}
});

View File

@ -33,9 +33,10 @@ const AppIconMode = {
}; };
function _createWindowClone(window, size) { function _createWindowClone(window, size) {
let [width, height] = window.get_size(); let windowTexture = window.get_texture();
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: window, return new Clutter.Clone({ source: windowTexture,
width: width * scale, width: width * scale,
height: height * scale, height: height * scale,
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
@ -45,19 +46,6 @@ function _createWindowClone(window, size) {
y_expand: true }); y_expand: true });
}; };
function getWindows(workspace) {
// We ignore skip-taskbar windows in switchers, but if they are attached
// to their parent, their position in the MRU list may be more appropriate
// than the parent; so start with the complete list ...
let windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL,
workspace);
// ... map windows to their parent where appropriate ...
return windows.map(w => {
return w.is_attached_dialog() ? w.get_transient_for() : w;
// ... and filter out skip-taskbar windows and duplicates
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
}
const AppSwitcherPopup = new Lang.Class({ const AppSwitcherPopup = new Lang.Class({
Name: 'AppSwitcherPopup', Name: 'AppSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup, Extends: SwitcherPopup.SwitcherPopup,
@ -366,149 +354,6 @@ const AppSwitcherPopup = new Lang.Class({
} }
}); });
const CyclerHighlight = new Lang.Class({
Name: 'CyclerHighlight',
_init: function() {
this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._clone = new Clutter.Clone();
this.actor.add_actor(this._clone);
this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
this.actor.add_actor(this._highlight);
let coordinate = Clutter.BindCoordinate.ALL;
let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
this._clone.bind_property('source', constraint, 'source', 0);
this.actor.add_constraint(constraint);
this.actor.connect('notify::allocation',
Lang.bind(this, this._onAllocationChanged));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
},
set window(w) {
if (this._window == w)
return;
this._window = w;
if (this._clone.source)
this._clone.source.sync_visibility();
let windowActor = this._window ? this._window.get_compositor_private()
: null;
if (windowActor)
windowActor.hide();
this._clone.source = windowActor;
},
_onAllocationChanged: function() {
if (!this._window) {
this._highlight.set_size(0, 0);
this._highlight.hide();
} else {
let [x, y] = this.actor.allocation.get_origin();
let rect = this._window.get_frame_rect();
this._highlight.set_size(rect.width, rect.height);
this._highlight.set_position(rect.x - x, rect.y - y);
this._highlight.show();
}
},
_onDestroy: function() {
this.window = null;
}
});
const CyclerPopup = new Lang.Class({
Name: 'CyclerPopup',
Extends: SwitcherPopup.SwitcherPopup,
Abstract: true,
_init : function() {
this.parent();
this._items = this._getWindows();
if (this._items.length == 0)
return;
this._highlight = new CyclerHighlight();
global.window_group.add_actor(this._highlight.actor);
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
this._switcherList = { actor: new St.Widget(),
highlight: Lang.bind(this, this._highlightItem),
connect: function() {} };
},
_highlightItem: function(index, justOutline) {
this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight.actor, null);
},
_finish: function() {
let window = this._items[this._selectedIndex];
let ws = window.get_workspace();
let activeWs = global.screen.get_active_workspace();
if (window.minimized) {
Main.wm.skipNextEffect(window.get_compositor_private());
window.unminimize();
}
if (activeWs == ws) {
Main.activateWindow(window);
} else {
// If the selected window is on a different workspace, we don't
// want it to disappear, then slide in with the workspace; instead,
// always activate it on the active workspace ...
activeWs.activate_with_focus(window, global.get_current_time());
// ... then slide it over to the original workspace if necessary
Main.wm.actionMoveWindow(window, ws);
}
this.parent();
},
_onDestroy: function() {
this._highlight.actor.destroy();
this.parent();
}
});
const GroupCyclerPopup = new Lang.Class({
Name: 'GroupCyclerPopup',
Extends: CyclerPopup,
_getWindows: function() {
let app = Shell.WindowTracker.get_default().focus_app;
return app ? app.get_windows() : [];
},
_keyPressHandler: function(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
this._select(this._next());
else if (action == Meta.KeyBindingAction.CYCLE_GROUP_BACKWARD)
this._select(this._previous());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
});
const WindowSwitcherPopup = new Lang.Class({ const WindowSwitcherPopup = new Lang.Class({
Name: 'WindowSwitcherPopup', Name: 'WindowSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup, Extends: SwitcherPopup.SwitcherPopup,
@ -529,7 +374,7 @@ const WindowSwitcherPopup = new Lang.Class({
_getWindowList: function() { _getWindowList: function() {
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null; let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
return getWindows(workspace); return global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
}, },
_keyPressHandler: function(keysym, action) { _keyPressHandler: function(keysym, action) {
@ -556,32 +401,6 @@ const WindowSwitcherPopup = new Lang.Class({
} }
}); });
const WindowCyclerPopup = new Lang.Class({
Name: 'WindowCyclerPopup',
Extends: CyclerPopup,
_init: function() {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
this.parent();
},
_getWindows: function() {
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
return getWindows(workspace);
},
_keyPressHandler: function(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
this._select(this._next());
else if (action == Meta.KeyBindingAction.CYCLE_WINDOWS_BACKWARD)
this._select(this._previous());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
});
const AppIcon = new Lang.Class({ const AppIcon = new Lang.Class({
Name: 'AppIcon', Name: 'AppIcon',

View File

@ -67,7 +67,7 @@ const Animation = new Lang.Class({
}, },
_animationsLoaded: function() { _animationsLoaded: function() {
this._isLoaded = this._animations.get_n_children() > 0; this._isLoaded = true;
if (this._isPlaying) if (this._isPlaying)
this.play(); this.play();

View File

@ -60,18 +60,6 @@ const PAGE_SWITCH_TIME = 0.3;
const VIEWS_SWITCH_TIME = 0.4; const VIEWS_SWITCH_TIME = 0.4;
const VIEWS_SWITCH_ANIMATION_DELAY = 0.1; const VIEWS_SWITCH_ANIMATION_DELAY = 0.1;
const SWITCHEROO_BUS_NAME = 'net.hadess.SwitcherooControl';
const SWITCHEROO_OBJECT_PATH = '/net/hadess/SwitcherooControl';
const SwitcherooProxyInterface = '<node> \
<interface name="net.hadess.SwitcherooControl"> \
<property name="HasDualGpu" type="b" access="read"/> \
</interface> \
</node>';
const SwitcherooProxy = Gio.DBusProxy.makeProxyWrapper(SwitcherooProxyInterface);
let discreteGpuAvailable = false;
function _getCategories(info) { function _getCategories(info) {
let categoriesStr = info.get_categories(); let categoriesStr = info.get_categories();
if (!categoriesStr) if (!categoriesStr)
@ -210,14 +198,6 @@ const BaseAppView = new Lang.Class({
}, },
animate: function(animationDirection, onComplete) { animate: function(animationDirection, onComplete) {
if (onComplete) {
let animationDoneId = this._grid.connect('animation-done', Lang.bind(this,
function () {
this._grid.disconnect(animationDoneId);
onComplete();
}));
}
if (animationDirection == IconGrid.AnimationDirection.IN) { if (animationDirection == IconGrid.AnimationDirection.IN) {
let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this, let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
function() { function() {
@ -233,6 +213,14 @@ const BaseAppView = new Lang.Class({
} else { } else {
this._doSpringAnimation(animationDirection); this._doSpringAnimation(animationDirection);
} }
if (onComplete) {
let animationDoneId = this._grid.connect('animation-done', Lang.bind(this,
function () {
this._grid.disconnect(animationDoneId);
onComplete();
}));
}
}, },
animateSwitch: function(animationDirection) { animateSwitch: function(animationDirection) {
@ -899,8 +887,6 @@ 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;
@ -911,6 +897,7 @@ 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',
@ -982,36 +969,10 @@ const AppDisplay = new Lang.Class({
initialView = Views.ALL; initialView = Views.ALL;
this._showView(initialView); this._showView(initialView);
this._updateFrequentVisibility(); this._updateFrequentVisibility();
Gio.DBus.system.watch_name(SWITCHEROO_BUS_NAME,
Gio.BusNameWatcherFlags.NONE,
Lang.bind(this, this._switcherooProxyAppeared),
Lang.bind(this, function() {
this._switcherooProxy = null;
this._updateDiscreteGpuAvailable();
}));
},
_updateDiscreteGpuAvailable: function() {
if (!this._switcherooProxy)
discreteGpuAvailable = false;
else
discreteGpuAvailable = this._switcherooProxy.HasDualGpu;
},
_switcherooProxyAppeared: function() {
this._switcherooProxy = new SwitcherooProxy(Gio.DBus.system, SWITCHEROO_BUS_NAME, SWITCHEROO_OBJECT_PATH,
Lang.bind(this, function(proxy, error) {
if (error) {
log(error.message);
return;
}
this._updateDiscreteGpuAvailable();
}));
}, },
animate: function(animationDirection, onComplete) { animate: function(animationDirection, onComplete) {
let currentView = this._views.filter(v => v.control.has_style_pseudo_class('checked')).pop().view; let currentView = this._views[global.settings.get_uint('app-picker-view')].view;
// Animate controls opacity using iconGrid animation time, since // Animate controls opacity using iconGrid animation time, since
// it will be the time the AllView or FrequentView takes to show // it will be the time the AllView or FrequentView takes to show
@ -1083,8 +1044,6 @@ const AppSearchProvider = new Lang.Class({
_init: function() { _init: function() {
this._appSys = Shell.AppSystem.get_default(); this._appSys = Shell.AppSystem.get_default();
this.id = 'applications'; this.id = 'applications';
this.isRemoteProvider = false;
this.canLaunchSearch = false;
}, },
getResultMetas: function(apps, callback) { getResultMetas: function(apps, callback) {
@ -1253,7 +1212,6 @@ const FolderIcon = new Lang.Class({
_init: function(id, path, parentView) { _init: function(id, path, parentView) {
this.id = id; this.id = id;
this.name = '';
this._parentView = parentView; this._parentView = parentView;
this._folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder', this._folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder',
@ -1856,7 +1814,7 @@ const AppIconMenu = new Lang.Class({
if (!source.actor.mapped) if (!source.actor.mapped)
this.close(); this.close();
})); }));
source.actor.connect('destroy', Lang.bind(this, this.destroy)); source.actor.connect('destroy', Lang.bind(this, function () { this.actor.destroy(); }));
Main.uiGroup.add_actor(this.actor); Main.uiGroup.add_actor(this.actor);
}, },
@ -1903,19 +1861,6 @@ const AppIconMenu = new Lang.Class({
this._appendSeparator(); this._appendSeparator();
} }
if (discreteGpuAvailable &&
this._source.app.state == Shell.AppState.STOPPED &&
actions.indexOf('activate-discrete-gpu') == -1) {
this._onDiscreteGpuMenuItem = this._appendMenuItem(_("Launch using Dedicated Graphics Card"));
this._onDiscreteGpuMenuItem.connect('activate', Lang.bind(this, function() {
if (this._source.app.state == Shell.AppState.STOPPED)
this._source.animateLaunch();
this._source.app.launch(0, -1, true);
this.emit('activate-window', null);
}));
}
for (let i = 0; i < actions.length; i++) { for (let i = 0; i < actions.length; i++) {
let action = actions[i]; let action = actions[i];
let item = this._appendMenuItem(appInfo.get_action_name(action)); let item = this._appendMenuItem(appInfo.get_action_name(action));

View File

@ -10,10 +10,8 @@ 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': 'org.gnome.Calculator.desktop', 'gcalctool.desktop': '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',
@ -21,7 +19,6 @@ 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',
@ -59,14 +56,12 @@ 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;
} }
@ -76,6 +71,7 @@ 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) {

View File

@ -102,7 +102,6 @@ const Lang = imports.lang;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const Signals = imports.signals; const Signals = imports.signals;
const LoginManager = imports.misc.loginManager;
const Main = imports.ui.main; const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
@ -142,6 +141,7 @@ 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 = {};
@ -166,8 +166,7 @@ const BackgroundCache = new Lang.Class({
settingsSchema: null, settingsSchema: null,
onLoaded: null }); onLoaded: null });
let animation = this._animations[params.settingsSchema]; if (this._animations[params.settingsSchema] && _fileEqual0(this._animationFile, params.file)) {
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 +177,7 @@ const BackgroundCache = new Lang.Class({
return; return;
} }
animation = new Animation({ file: params.file }); let 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,14 +254,6 @@ const Background = new Lang.Class({
this._loadAnimation(this._animation.file); this._loadAnimation(this._animation.file);
})); }));
let loginManager = LoginManager.getLoginManager();
this._prepareForSleepId = loginManager.connect('prepare-for-sleep',
(lm, aboutToSuspend) => {
if (aboutToSuspend)
return;
this._refreshAnimation();
});
this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() { this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() {
this.emit('changed'); this.emit('changed');
})); }));
@ -285,26 +276,16 @@ 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;
}, },
updateResolution: function() { updateResolution: function() {
if (this._animation) if (this._animation) {
this._refreshAnimation();
},
_refreshAnimation: function() {
if (!this._animation)
return;
this._removeAnimationTimeout(); this._removeAnimationTimeout();
this._updateAnimation(); this._updateAnimation();
}
}, },
_setLoaded: function() { _setLoaded: function() {
@ -382,9 +363,11 @@ 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)
@ -713,7 +696,6 @@ const BackgroundManager = new Lang.Class({
time: FADE_ANIMATION_TIME, time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad', transition: 'easeOutQuad',
onComplete: function() { onComplete: function() {
oldBackgroundActor.background.run_dispose();
oldBackgroundActor.destroy(); oldBackgroundActor.destroy();
} }
}); });

View File

@ -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 = 16; const MESSAGE_ICON_SIZE = 32;
// 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;
@ -120,9 +120,6 @@ const EmptyEventSource = new Lang.Class({
destroy: function() { destroy: function() {
}, },
ignoreEvent: function(event) {
},
requestRange: function(begin, end) { requestRange: function(begin, end) {
}, },
@ -187,15 +184,6 @@ const DBusEventSource = new Lang.Class({
this.isLoading = false; this.isLoading = false;
this.isDummy = false; this.isDummy = false;
this._ignoredEvents = new Map();
let savedState = global.get_persistent_state('as', 'ignored_events');
if (savedState)
savedState.deep_unpack().forEach(Lang.bind(this,
function(eventId) {
this._ignoredEvents.set(eventId, true);
}));
this._initialized = false; this._initialized = false;
this._dbusProxy = new CalendarServer(); this._dbusProxy = new CalendarServer();
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(object, result) { this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(object, result) {
@ -310,16 +298,6 @@ const DBusEventSource = new Lang.Class({
} }
}, },
ignoreEvent: function(event) {
if (this._ignoredEvents.get(event.id))
return;
this._ignoredEvents.set(event.id, true);
let savedState = new GLib.Variant('as', [...this._ignoredEvents.keys()]);
global.set_persistent_state('ignored_events', savedState);
this.emit('changed');
},
requestRange: function(begin, end) { requestRange: function(begin, end) {
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) { if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
this.isLoading = true; this.isLoading = true;
@ -335,10 +313,6 @@ const DBusEventSource = new Lang.Class({
let result = []; let result = [];
for(let n = 0; n < this._events.length; n++) { for(let n = 0; n < this._events.length; n++) {
let event = this._events[n]; let event = this._events[n];
if (this._ignoredEvents.has(event.id))
continue;
if (_dateIntervalsOverlap (event.date, event.end, begin, end)) { if (_dateIntervalsOverlap (event.date, event.end, begin, end)) {
result.push(event); result.push(event);
} }
@ -371,7 +345,7 @@ const Calendar = new Lang.Class({
_init: function() { _init: function() {
this._weekStart = Shell.util_get_week_start(); this._weekStart = Shell.util_get_week_start();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' }); this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.calendar' });
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange)); this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY); this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
@ -686,12 +660,12 @@ const Calendar = new Lang.Class({
this._buttons.forEach(Lang.bind(this, function(button) { this._buttons.forEach(Lang.bind(this, function(button) {
if (sameDay(button._date, this._selectedDate)) { if (sameDay(button._date, this._selectedDate)) {
button.add_style_pseudo_class('selected'); button.add_style_pseudo_class('active');
if (this._shouldDateGrabFocus) if (this._shouldDateGrabFocus)
button.grab_key_focus(); button.grab_key_focus();
} }
else else
button.remove_style_pseudo_class('selected'); button.remove_style_pseudo_class('active');
})); }));
} }
}); });
@ -706,14 +680,6 @@ 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() {
@ -761,8 +727,8 @@ const NotificationMessage = new Lang.Class({
_init: function(notification) { _init: function(notification) {
this.notification = notification; this.notification = notification;
this.parent(notification.title, notification.bannerBodyText);
this.setUseBodyMarkup(notification.bannerBodyMarkup); this.setUseBodyMarkup(notification.bannerBodyMarkup);
this.parent(notification.title, notification.bannerBodyText);
this.setIcon(this._getIcon()); this.setIcon(this._getIcon());
@ -819,16 +785,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._ignoredEvents = new Map();
this._title = new St.Button({ style_class: 'events-section-title', let savedState = global.get_persistent_state('as', 'ignored_events');
label: '', if (savedState)
x_align: St.Align.START, savedState.deep_unpack().forEach(Lang.bind(this,
can_focus: true }); function(eventId) {
this.actor.insert_child_below(this._title, null); this._ignoredEvents.set(eventId, true);
}));
this._title.connect('clicked', Lang.bind(this, this._onTitleClicked)); this.parent('');
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));
@ -836,7 +802,9 @@ const EventsSection = new Lang.Class({
}, },
_ignoreEvent: function(event) { _ignoreEvent: function(event) {
this._eventSource.ignoreEvent(event); this._ignoredEvents.set(event.id, true);
let savedState = new GLib.Variant('as', [...this._ignoredEvents.keys()]);
global.set_persistent_state('ignored_events', savedState);
}, },
setEventSource: function(eventSource) { setEventSource: function(eventSource) {
@ -849,10 +817,10 @@ const EventsSection = new Lang.Class({
}, },
_updateTitle: function() { _updateTitle: function() {
this._title.visible = !isToday(this._date); if (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();
@ -882,6 +850,9 @@ const EventsSection = new Lang.Class({
for (let i = 0; i < events.length; i++) { for (let i = 0; i < events.length; i++) {
let event = events[i]; let event = events[i];
if (this._ignoredEvents.has(event.id))
continue;
let message = new EventMessage(event, this._date); let message = new EventMessage(event, this._date);
message.connect('close', Lang.bind(this, function() { message.connect('close', Lang.bind(this, function() {
this._ignoreEvent(event); this._ignoreEvent(event);
@ -914,13 +885,12 @@ const EventsSection = new Lang.Class({
}, },
_onTitleClicked: function() { _onTitleClicked: function() {
Main.overview.hide(); this.parent();
Main.panel.closeCalendar();
let app = this._getCalendarApp(); let app = this._getCalendarApp();
if (app.get_id() == 'evolution.desktop') if (app.get_id() == 'evolution.desktop')
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop'); app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
app.launch([], global.create_app_launch_context(0, -1), false); app.launch([], global.create_app_launch_context(0, -1));
}, },
setDate: function(date) { setDate: function(date) {
@ -946,7 +916,7 @@ const NotificationSection = new Lang.Class({
Extends: MessageList.MessageListSection, Extends: MessageList.MessageListSection,
_init: function() { _init: function() {
this.parent(); this.parent(_("Notifications"));
this._sources = new Map(); this._sources = new Map();
this._nUrgent = 0; this._nUrgent = 0;
@ -964,14 +934,10 @@ const NotificationSection = new Lang.Class({
!Main.sessionMode.isGreeter; !Main.sessionMode.isGreeter;
}, },
_createTimeLabel: function(datetime) { _createTimeLabel: function() {
let label = new St.Label({ style_class: 'event-time', let label = Util.createTimeLabel(new Date());
x_align: Clutter.ActorAlign.START, label.style_class = 'event-time',
y_align: Clutter.ActorAlign.END }); label.x_align = Clutter.ActorAlign.END;
label.connect('notify::mapped', () => {
if (label.mapped)
label.text = Util.formatTimeSpan(datetime);
});
return label; return label;
}, },
@ -992,13 +958,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(notification.datetime)); message.setSecondaryActor(this._createTimeLabel());
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(notification.datetime)); message.setSecondaryActor(this._createTimeLabel());
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,
@ -1039,8 +1005,26 @@ 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;
} }
}); });
@ -1102,26 +1086,12 @@ 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);
box.add_actor(this._scrollView); this.actor.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,
@ -1147,7 +1117,6 @@ 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,
@ -1158,8 +1127,6 @@ 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));
@ -1173,7 +1140,6 @@ 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);
@ -1194,16 +1160,10 @@ const CalendarMessageList = new Lang.Class({
if (!visible) if (!visible)
return; return;
let empty = sections.every(function(s) { let showPlaceholder = sections.every(function(s) {
return s.empty || !s.actor.visible; return s.empty || !s.actor.visible;
}); });
this._placeholder.actor.visible = empty; this._placeholder.actor.visible = showPlaceholder;
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) {

View File

@ -64,8 +64,7 @@ function startAppForMount(app, mount) {
try { try {
retval = app.launch(files, retval = app.launch(files,
global.create_app_launch_context(0, -1), global.create_app_launch_context(0, -1))
false)
} catch (e) { } catch (e) {
log('Unable to launch the application ' + app.get_name() log('Unable to launch the application ' + app.get_name()
+ ': ' + e.toString()); + ': ' + e.toString());

View File

@ -615,14 +615,6 @@ const NetworkAgent = new Lang.Class({
this._vpnRequests = { }; this._vpnRequests = { };
this._notifications = { }; this._notifications = { };
this._pluginDir = Gio.file_new_for_path(GLib.build_filenamev([Config.SYSCONFDIR, 'NetworkManager/VPN']));
try {
let monitor = this._pluginDir.monitor(Gio.FileMonitorFlags.NONE, null);
monitor.connect('changed', () => { this._vpnCacheBuilt = false; });
} catch(e) {
log('Failed to create monitor for VPN plugin dir: ' + e.message);
}
this._native.connect('new-request', Lang.bind(this, this._newRequest)); this._native.connect('new-request', Lang.bind(this, this._newRequest));
this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest)); this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest));
@ -773,8 +765,9 @@ const NetworkAgent = new Lang.Class({
this._vpnCacheBuilt = true; this._vpnCacheBuilt = true;
this._vpnBinaries = { }; this._vpnBinaries = { };
let dir = Gio.file_new_for_path(GLib.build_filenamev([Config.SYSCONFDIR, 'NetworkManager/VPN']));
try { try {
let fileEnum = this._pluginDir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null); let fileEnum = dir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
let info; let info;
while ((info = fileEnum.next_file(null))) { while ((info = fileEnum.next_file(null))) {
@ -784,7 +777,7 @@ const NetworkAgent = new Lang.Class({
try { try {
let keyfile = new GLib.KeyFile(); let keyfile = new GLib.KeyFile();
keyfile.load_from_file(this._pluginDir.get_child(name).get_path(), GLib.KeyFileFlags.NONE); keyfile.load_from_file(dir.get_child(name).get_path(), GLib.KeyFileFlags.NONE);
let service = keyfile.get_string('VPN Connection', 'service'); let service = keyfile.get_string('VPN Connection', 'service');
let binary = keyfile.get_string('GNOME', 'auth-dialog'); let binary = keyfile.get_string('GNOME', 'auth-dialog');
let externalUIMode = false; let externalUIMode = false;
@ -803,21 +796,13 @@ const NetworkAgent = new Lang.Class({
path = GLib.build_filenamev([Config.LIBEXECDIR, path]); path = GLib.build_filenamev([Config.LIBEXECDIR, path]);
} }
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) { if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE))
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints }; this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
try { else
let aliases = keyfile.get_string_list('VPN Connection', 'aliases');
for (let alias of aliases) {
this._vpnBinaries[alias] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
}
} catch(e) { } // ignore errors if key does not exist
} else {
throw new Error('VPN plugin at %s is not executable'.format(path)); throw new Error('VPN plugin at %s is not executable'.format(path));
}
} catch(e) { } catch(e) {
log('Error \'%s\' while processing VPN keyfile \'%s\''. log('Error \'%s\' while processing VPN keyfile \'%s\''.
format(e.message, this._pluginDir.get_child(name).get_path())); format(e.message, dir.get_child(name).get_path()));
continue; continue;
} }
} }

View File

@ -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 didnt 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();

View File

@ -6,17 +6,11 @@ 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;
var Tpl = null; const Tp = imports.gi.TelepathyGLib;
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;
@ -26,8 +20,6 @@ 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
@ -79,43 +71,8 @@ function makeMessageFromTplEvent(event) {
}; };
} }
const TelepathyComponent = new Lang.Class({ const TelepathyClient = 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
@ -140,27 +97,38 @@ const TelepathyClient = HAVE_TP ? 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.parent({ name: 'GnomeShell', this._tpClient = new Shell.TpClient({ name: 'GnomeShell',
account_manager: this._accountManager, account_manager: this._accountManager,
uniquify_name: true }); uniquify_name: true });
this._tpClient.set_observe_channels_func(
// We only care about single-user text-based chats Lang.bind(this, this._observeChannels));
let filter = {}; this._tpClient.set_approve_channels_func(
filter[Tp.PROP_CHANNEL_CHANNEL_TYPE] = Tp.IFACE_CHANNEL_TYPE_TEXT; Lang.bind(this, this._approveChannels));
filter[Tp.PROP_CHANNEL_TARGET_HANDLE_TYPE] = Tp.HandleType.CONTACT; this._tpClient.set_handle_channels_func(
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.set_delegated_channels_callback( this._tpClient.set_delegated_channels_callback(
Lang.bind(this, this._delegatedChannelsCb)); Lang.bind(this, this._delegatedChannelsCb));
}, },
vfunc_observe_channels: function(account, conn, channels, enable: function() {
try {
this._tpClient.register();
} catch (e) {
throw new Error('Couldn\'t register Telepathy client. Error: \n' + e);
}
if (!this._accountManager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
this._accountManager.prepare_async(null, null);
},
disable: function() {
this._tpClient.unregister();
},
_observeChannels: function(observer, account, conn, channels,
dispatchOp, requests, context) { 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++) {
@ -185,7 +153,7 @@ const TelepathyClient = HAVE_TP ? 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); let source = new ChatSource(account, conn, channel, contact, this._tpClient);
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,
@ -194,8 +162,8 @@ const TelepathyClient = HAVE_TP ? new Lang.Class({
})); }));
}, },
vfunc_handle_channels: function(account, conn, channels, requests, _handleChannels: function(handler, account, conn, channels,
user_action_time, context) { requests, user_action_time, context) {
this._handlingChannels(account, conn, channels, true); this._handlingChannels(account, conn, channels, true);
context.accept(); context.accept();
}, },
@ -225,7 +193,7 @@ const TelepathyClient = HAVE_TP ? 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.is_handling_channel(channel)) { if (notify && this._tpClient.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)
@ -234,7 +202,7 @@ const TelepathyClient = HAVE_TP ? new Lang.Class({
} }
}, },
vfunc_add_dispatch_operation: function(account, conn, channels, _approveChannels: function(approver, 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();
@ -262,7 +230,7 @@ const TelepathyClient = HAVE_TP ? 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, Lang.bind(this, function(dispatchOp, result) { dispatchOp.claim_with_async(this._tpClient, 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);
@ -278,7 +246,7 @@ const TelepathyClient = HAVE_TP ? 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',
@ -507,11 +475,6 @@ const ChatSource = new Lang.Class({
this._channel.close_async(function(channel, result) { this._channel.close_async(function(channel, result) {
channel.close_finish(result); channel.close_finish(result);
}); });
} else {
// Don't indicate any unread messages when the notification
// that represents them has been destroyed.
this._pendingMessages = [];
this.countUpdated();
} }
// Keep source alive while the channel is open // Keep source alive while the channel is open
@ -692,9 +655,7 @@ const ChatNotification = new Lang.Class({
} }
if (message.direction == NotificationDirection.RECEIVED) if (message.direction == NotificationDirection.RECEIVED)
this.update(this.source.title, messageBody, this.update(this.source.title, messageBody, { bannerMarkup: true });
{ 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');
@ -996,4 +957,4 @@ const ChatNotificationBanner = new Lang.Class({
} }
}); });
const Component = TelepathyComponent; const Component = TelepathyClient;

View File

@ -756,44 +756,42 @@ const Dash = new Lang.Class({
let newIndex = 0; let newIndex = 0;
let oldIndex = 0; let oldIndex = 0;
while (newIndex < newApps.length || oldIndex < oldApps.length) { while (newIndex < newApps.length || oldIndex < oldApps.length) {
let oldApp = oldApps.length > oldIndex ? oldApps[oldIndex] : null;
let newApp = newApps.length > newIndex ? newApps[newIndex] : null;
// No change at oldIndex/newIndex // No change at oldIndex/newIndex
if (oldApp == newApp) { if (oldApps[oldIndex] == newApps[newIndex]) {
oldIndex++; oldIndex++;
newIndex++; newIndex++;
continue; continue;
} }
// App removed at oldIndex // App removed at oldIndex
if (oldApp && newApps.indexOf(oldApp) == -1) { if (oldApps[oldIndex] &&
newApps.indexOf(oldApps[oldIndex]) == -1) {
removedActors.push(children[oldIndex]); removedActors.push(children[oldIndex]);
oldIndex++; oldIndex++;
continue; continue;
} }
// App added at newIndex // App added at newIndex
if (newApp && oldApps.indexOf(newApp) == -1) { if (newApps[newIndex] &&
addedItems.push({ app: newApp, oldApps.indexOf(newApps[newIndex]) == -1) {
item: this._createAppItem(newApp), addedItems.push({ app: newApps[newIndex],
item: this._createAppItem(newApps[newIndex]),
pos: newIndex }); pos: newIndex });
newIndex++; newIndex++;
continue; continue;
} }
// App moved // App moved
let nextApp = newApps.length > newIndex + 1 ? newApps[newIndex + 1] let insertHere = newApps[newIndex + 1] &&
: null; newApps[newIndex + 1] == oldApps[oldIndex];
let insertHere = nextApp && nextApp == oldApp;
let alreadyRemoved = removedActors.reduce(function(result, actor) { let alreadyRemoved = removedActors.reduce(function(result, actor) {
let removedApp = actor.child._delegate.app; let removedApp = actor.child._delegate.app;
return result || removedApp == newApp; return result || removedApp == newApps[newIndex];
}, false); }, false);
if (insertHere || alreadyRemoved) { if (insertHere || alreadyRemoved) {
let newItem = this._createAppItem(newApp); let newItem = this._createAppItem(newApps[newIndex]);
addedItems.push({ app: newApp, addedItems.push({ app: newApps[newIndex],
item: newItem, item: newItem,
pos: newIndex + removedActors.length }); pos: newIndex + removedActors.length });
newIndex++; newIndex++;

View File

@ -8,7 +8,6 @@ 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;
@ -21,7 +20,6 @@ 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();
@ -38,7 +36,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_expand: true, x_align: St.Align.START, x_align: St.Align.START,
can_focus: true, can_focus: true,
reactive: false reactive: false
}); });
@ -79,7 +77,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".
*/ */
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y")); let 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);
} }
}); });
@ -89,7 +87,9 @@ 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,7 +98,8 @@ 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() {
this._clockAppMon.activateApp(); let app = this._getClockApp();
app.activate();
Main.overview.hide(); Main.overview.hide();
Main.panel.closeCalendar(); Main.panel.closeCalendar();
@ -111,25 +112,40 @@ const WorldClocksSection = new Lang.Class({
this.actor.child = this._grid; this.actor.child = this._grid;
this._clockAppMon = new Util.AppSettingsMonitor('org.gnome.clocks.desktop', Shell.AppSystem.get_default().connect('installed-changed',
'org.gnome.clocks');
this._clockAppMon.connect('available-changed',
Lang.bind(this, this._sync)); Lang.bind(this, this._sync));
this._clockAppMon.watchSetting('world-clocks',
Lang.bind(this, this._clocksChanged));
this._sync(); this._sync();
}, },
_sync: function() { _getClockApp: function() {
this.actor.visible = this._clockAppMon.available; return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop');
}, },
_clocksChanged: function(settings) { _sync: function() {
this.actor.visible = (this._getClockApp() != null);
if (this.actor.visible) {
if (!this._settings) {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.clocks' });
this._changedId =
this._settings.connect('changed::world-clocks',
Lang.bind(this, this._clocksChanged));
this._clocksChanged();
}
} else {
if (this._settings)
this._settings.disconnect(this._changedId);
this._settings = null;
this._changedId = 0;
}
},
_clocksChanged: function() {
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 = settings.get_value('world-clocks').deep_unpack(); let clocks = this._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 });
@ -194,136 +210,6 @@ 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',
@ -370,7 +256,8 @@ const IndicatorPad = new Lang.Class({
_init: function(actor) { _init: function(actor) {
this._source = actor; this._source = actor;
this._source.connect('notify::visible', () => { this.queue_relayout(); }); this._source.connect('notify::visible',
Lang.bind(this, this.queue_relayout));
this.parent(); this.parent();
}, },
@ -410,38 +297,14 @@ 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))
return this.parent(container, forHeight); this._savedWidth = 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))
return this.parent(container, forWidth); this._savedHeight = 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);
} }
}); });
@ -474,8 +337,6 @@ const DateMenuButton = new Lang.Class({
let layout = new FreezableBinLayout(); let layout = new FreezableBinLayout();
let bin = new St.Widget({ layout_manager: layout }); let bin = new St.Widget({ layout_manager: layout });
// For some minimal compatibility with PopupMenuItem
bin._delegate = this;
this.menu.box.add_child(bin); this.menu.box.add_child(bin);
hbox = new St.BoxLayout({ name: 'calendarArea' }); hbox = new St.BoxLayout({ name: 'calendarArea' });
@ -503,16 +364,14 @@ 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
let boxLayout = new CalendarColumnLayout(this._calendar.actor); vbox = new St.BoxLayout({ style_class: 'datemenu-calendar-column',
vbox = new St.Widget({ style_class: 'datemenu-calendar-column', vertical: true });
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_actor(this._calendar.actor); vbox.add(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,
@ -527,8 +386,6 @@ 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

View File

@ -571,12 +571,19 @@ const _Draggable = new Lang.Class({
return; return;
} }
this._animateDragEnd(eventTime, this._animationInProgress = true;
// No target, so snap back
Tweener.addTween(this._dragActor,
{ x: snapBackX, { x: snapBackX,
y: snapBackY, y: snapBackY,
scale_x: snapBackScale, scale_x: snapBackScale,
scale_y: snapBackScale, scale_y: snapBackScale,
opacity: this._dragOrigOpacity,
time: SNAP_BACK_ANIMATION_TIME, time: SNAP_BACK_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._onAnimationComplete,
onCompleteScope: this,
onCompleteParams: [this._dragActor, eventTime]
}); });
}, },
@ -589,44 +596,18 @@ const _Draggable = new Lang.Class({
this._dragActor.set_scale(restoreScale, restoreScale); this._dragActor.set_scale(restoreScale, restoreScale);
this._dragActor.opacity = 0; this._dragActor.opacity = 0;
this._animateDragEnd(eventTime,
{ time: REVERT_ANIMATION_TIME });
},
_animateDragEnd: function (eventTime, params) {
this._animationInProgress = true; this._animationInProgress = true;
Tweener.addTween(this._dragActor,
// finish animation if the actor gets destroyed { opacity: this._dragOrigOpacity,
// during it time: REVERT_ANIMATION_TIME,
this._dragActorDestroyId = transition: 'easeOutQuad',
this._dragActor.connect('destroy', onComplete: this._onAnimationComplete,
Lang.bind(this, this._finishAnimation)); onCompleteScope: this,
onCompleteParams: [this._dragActor, eventTime]
params['opacity'] = this._dragOrigOpacity; });
params['transition'] = 'easeOutQuad';
params['onComplete'] = this._onAnimationComplete;
params['onCompleteScope'] = this;
params['onCompleteParams'] = [this._dragActor, eventTime];
// start the animation
Tweener.addTween(this._dragActor, params)
},
_finishAnimation : function () {
if (!this._animationInProgress)
return
this._animationInProgress = false;
if (!this._buttonDown)
this._dragComplete();
global.screen.set_cursor(Meta.Cursor.DEFAULT);
}, },
_onAnimationComplete : function (dragActor, eventTime) { _onAnimationComplete : function (dragActor, eventTime) {
dragActor.disconnect(this._dragActorDestroyId);
this._dragActorDestroyId = 0;
if (this._dragOrigParent) { if (this._dragOrigParent) {
Main.uiGroup.remove_child(this._dragActor); Main.uiGroup.remove_child(this._dragActor);
this._dragOrigParent.add_actor(this._dragActor); this._dragOrigParent.add_actor(this._dragActor);
@ -635,9 +616,12 @@ const _Draggable = new Lang.Class({
} else { } else {
dragActor.destroy(); dragActor.destroy();
} }
global.screen.set_cursor(Meta.Cursor.DEFAULT);
this.emit('drag-end', eventTime, false); this.emit('drag-end', eventTime, false);
this._finishAnimation();
this._animationInProgress = false;
if (!this._buttonDown)
this._dragComplete();
}, },
_dragComplete: function() { _dragComplete: function() {

View File

@ -14,7 +14,6 @@ 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();
@ -82,3 +81,4 @@ const EdgeDragAction = new Lang.Class({
this.emit('activated'); this.emit('activated');
} }
}); });
Signals.addSignalMethods(EdgeDragAction.prototype);

View File

@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* /*
* Copyright 2010-2016 Red Hat, Inc * Copyright 2010 Red Hat, Inc
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -114,7 +114,7 @@ const restartDialogContent = {
showOtherSessions: true, showOtherSessions: true,
}; };
const restartUpdateDialogContent = { const restartInstallDialogContent = {
subject: C_("title", "Restart & Install Updates"), subject: C_("title", "Restart & Install Updates"),
description: function(seconds) { description: function(seconds) {
@ -132,38 +132,18 @@ const restartUpdateDialogContent = {
showOtherSessions: true, showOtherSessions: true,
}; };
const restartUpgradeDialogContent = {
subject: C_("title", "Restart & Install Upgrade"),
upgradeDescription: function(distroName, distroVersion) {
/* Translators: This is the text displayed for system upgrades in the
shut down dialog. First %s gets replaced with the distro name and
second %s with the distro version to upgrade to */
return _("%s %s will be installed after restart. Upgrade installation can take a long time: ensure that you have backed up and that the computer is plugged in.").format(distroName, distroVersion);
},
disableTimer: true,
showBatteryWarning: false,
confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart &amp; Install") }],
iconName: 'view-refresh-symbolic',
iconStyleClass: 'end-session-dialog-shutdown-icon',
showOtherSessions: true,
};
const DialogType = { const DialogType = {
LOGOUT: 0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */, LOGOUT: 0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */,
SHUTDOWN: 1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */, SHUTDOWN: 1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */,
RESTART: 2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */, RESTART: 2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */,
UPDATE_RESTART: 3, UPDATE_RESTART: 3
UPGRADE_RESTART: 4
}; };
const DialogContent = { const DialogContent = {
0 /* DialogType.LOGOUT */: logoutDialogContent, 0 /* DialogType.LOGOUT */: logoutDialogContent,
1 /* DialogType.SHUTDOWN */: shutdownDialogContent, 1 /* DialogType.SHUTDOWN */: shutdownDialogContent,
2 /* DialogType.RESTART */: restartDialogContent, 2 /* DialogType.RESTART */: restartDialogContent,
3 /* DialogType.UPDATE_RESTART */: restartUpdateDialogContent, 3 /* DialogType.UPDATE_RESTART */: restartInstallDialogContent
4 /* DialogType.UPGRADE_RESTART */: restartUpgradeDialogContent
}; };
const MAX_USERS_IN_SESSION_DIALOG = 5; const MAX_USERS_IN_SESSION_DIALOG = 5;
@ -183,10 +163,7 @@ const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
const PkOfflineIface = '<node> \ const PkOfflineIface = '<node> \
<interface name="org.freedesktop.PackageKit.Offline"> \ <interface name="org.freedesktop.PackageKit.Offline"> \
<property name="UpdatePrepared" type="b" access="read"/> \ <property name="UpdatePrepared" type="b" access="read"/> \
<property name="UpdateTriggered" type="b" access="read"/> \ <property name="TriggerAction" type="s" access="read"/> \
<property name="UpgradePrepared" type="b" access="read"/> \
<property name="UpgradeTriggered" type="b" access="read"/> \
<property name="PreparedUpgrade" type="a{sv}" access="read"/> \
<method name="Trigger"> \ <method name="Trigger"> \
<arg type="s" name="action" direction="in"/> \ <arg type="s" name="action" direction="in"/> \
</method> \ </method> \
@ -438,25 +415,18 @@ const EndSessionDialog = new Lang.Class({
if (dialogContent.descriptionWithUser) if (dialogContent.descriptionWithUser)
description = dialogContent.descriptionWithUser(realName, displayTime); description = dialogContent.descriptionWithUser(realName, displayTime);
else
description = dialogContent.description(displayTime);
} }
} }
// Use a different description when we are installing a system upgrade
if (dialogContent.upgradeDescription) {
let name = this._pkOfflineProxy.PreparedUpgrade['name'].deep_unpack();
let version = this._pkOfflineProxy.PreparedUpgrade['version'].deep_unpack();
if (name != null && version != null)
description = dialogContent.upgradeDescription(name, version);
}
// Fall back to regular description
if (!description) if (!description)
description = dialogContent.description(displayTime); description = dialogContent.description(displayTime);
_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,
@ -728,12 +698,9 @@ const EndSessionDialog = new Lang.Class({
this._totalSecondsToStayOpen = totalSecondsToStayOpen; this._totalSecondsToStayOpen = totalSecondsToStayOpen;
this._type = type; this._type = type;
if (this._type == DialogType.RESTART) { if (this._type == DialogType.RESTART &&
if (this._pkOfflineProxy.UpdateTriggered) this._pkOfflineProxy.TriggerAction == 'reboot')
this._type = DialogType.UPDATE_RESTART; this._type = DialogType.UPDATE_RESTART;
else if (this._pkOfflineProxy.UpgradeTriggered)
this._type = DialogType.UPGRADE_RESTART;
}
this._applications = []; this._applications = [];
this._applicationList.destroy_all_children(); this._applicationList.destroy_all_children();
@ -760,19 +727,19 @@ const EndSessionDialog = new Lang.Class({
if (dialogContent.showOtherSessions) if (dialogContent.showOtherSessions)
this._loadSessions(); this._loadSessions();
let updateTriggered = this._pkOfflineProxy.UpdateTriggered; let updateAlreadyTriggered = this._pkOfflineProxy.TriggerAction == 'power-off' || this._pkOfflineProxy.TriggerAction == 'reboot';
let updatePrepared = this._pkOfflineProxy.UpdatePrepared; let updatePrepared = this._pkOfflineProxy.UpdatePrepared;
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed; let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText); _setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText);
this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed); this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
this._checkBox.actor.checked = (updatePrepared && updateTriggered); this._checkBox.actor.checked = (updatePrepared && updateAlreadyTriggered);
// We show the warning either together with the checkbox, or when // We show the warning either together with the checkbox, or when
// updates have already been triggered, but the user doesn't have // updates have already been triggered, but the user doesn't have
// enough permissions to cancel them. // enough permissions to cancel them.
this._batteryWarning.visible = (dialogContent.showBatteryWarning && this._batteryWarning.visible = (dialogContent.showBatteryWarning &&
(this._checkBox.actor.visible || updatePrepared && updateTriggered && !updatesAllowed)); (this._checkBox.actor.visible || updatePrepared && updateAlreadyTriggered && !updatesAllowed));
this._updateButtons(); this._updateButtons();
@ -782,9 +749,7 @@ const EndSessionDialog = new Lang.Class({
return; return;
} }
if (!dialogContent.disableTimer)
this._startTimer(); this._startTimer();
this._sync(); this._sync();
let signalId = this.connect('opened', let signalId = this.connect('opened',

View File

@ -1,8 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Config = imports.misc.config; imports.gi.versions.Clutter = '1.0';
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';
@ -63,19 +61,10 @@ function _patchLayoutClass(layoutClass, styleProps) {
}; };
} }
function _loggingFunc() { function _makeLoggingFunc(func) {
let fields = {'MESSAGE': [].join.call(arguments, ', ')}; return function() {
let domain = "GNOME Shell"; return func([].join.call(arguments, ', '));
};
// If the caller is an extension, add it as metadata
let extension = imports.misc.extensionUtils.getCurrentExtension();
if (extension != null) {
domain = extension.metadata.name;
fields['GNOME_SHELL_EXTENSION_UUID'] = extension.uuid;
fields['GNOME_SHELL_EXTENSION_NAME'] = extension.metadata.name;
}
GLib.log_structured(domain, GLib.LogLevelFlags.LEVEL_MESSAGE, fields);
} }
function init() { function init() {
@ -83,7 +72,7 @@ function init() {
// browser convention of having that namespace be called 'window'.) // browser convention of having that namespace be called 'window'.)
window.global = Shell.Global.get(); window.global = Shell.Global.get();
window.log = _loggingFunc; window.log = _makeLoggingFunc(window.log);
window._ = Gettext.gettext; window._ = Gettext.gettext;
window.C_ = Gettext.pgettext; window.C_ = Gettext.pgettext;

View File

@ -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) {

View File

@ -38,7 +38,6 @@ 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;
@ -239,16 +238,11 @@ function initExtension(uuid) {
} }
function getEnabledExtensions() { function getEnabledExtensions() {
let extensions; let extensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
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 extensions.concat(global.settings.get_strv(ENABLED_EXTENSIONS_KEY)); return Main.sessionMode.enabledExtensions.concat(extensions);
} }
function onEnabledExtensionsChanged() { function onEnabledExtensionsChanged() {
@ -282,27 +276,18 @@ function _onVersionValidationChanged() {
// temporarily disable them all // temporarily disable them all
enabledExtensions = []; enabledExtensions = [];
for (let uuid in ExtensionUtils.extensions) for (let uuid in ExtensionUtils.extensions)
try {
reloadExtension(ExtensionUtils.extensions[uuid]); 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) {
try {
enableExtension(uuid); 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();

View File

@ -19,7 +19,6 @@ 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) {
@ -40,19 +39,6 @@ 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' });
@ -158,14 +144,6 @@ 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);
})); }));

View File

@ -10,7 +10,6 @@ const Meta = imports.gi.Meta;
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;
const InputSourceManager = imports.ui.status.keyboard;
const BoxPointer = imports.ui.boxpointer; const BoxPointer = imports.ui.boxpointer;
const Layout = imports.ui.layout; const Layout = imports.ui.layout;
@ -570,7 +569,7 @@ const Keyboard = new Lang.Class({
shouldTakeEvent: function(event) { shouldTakeEvent: function(event) {
let actor = event.get_source(); let actor = event.get_source();
return Main.layoutManager.keyboardBox.contains(actor) || return Main.layoutManager.keyboardBox.contains(actor) ||
!!actor._extended_keys || !!actor.extended_key; actor._extended_keys || actor.extended_key;
}, },
_clearKeyboardRestTimer: function() { _clearKeyboardRestTimer: function() {
@ -758,48 +757,19 @@ const ShellWaylandAdapter = new Lang.Class({
Name: 'ShellWaylandAdapter', Name: 'ShellWaylandAdapter',
Extends: Caribou.XAdapter, Extends: Caribou.XAdapter,
_init: function () {
this.parent();
let deviceManager = Clutter.DeviceManager.get_default();
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
this._inputSourceManager = InputSourceManager.getInputSourceManager();
this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
Lang.bind(this, this._onSourceChanged));
this._sourcesModifiedId = this._inputSourceManager.connect ('sources-changed',
Lang.bind(this, this._onSourcesModified));
},
_onSourcesModified: function () {
this.emit('config-changed');
},
_onSourceChanged: function (inputSourceManager, oldSource) {
let source = inputSourceManager.currentSource;
this.emit('group-changed', source.index, source.id, '');
},
vfunc_get_groups: function () {
let inputSources = this._inputSourceManager.inputSources;
let groups = []
let variants = [];
for (let i in inputSources) {
let is = inputSources[i];
groups[is.index] = is.id;
variants[is.index] = '';
}
return [groups, groups.length, variants, variants.length];
},
vfunc_keyval_press: function(keyval) { vfunc_keyval_press: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(), let focus = global.stage.get_key_focus();
keyval, Clutter.KeyState.PRESSED); if (focus instanceof Clutter.Text)
Shell.util_text_insert_keyval(focus, keyval);
else
this.parent(keyval);
}, },
vfunc_keyval_release: function(keyval) { vfunc_keyval_release: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(), let focus = global.stage.get_key_focus();
keyval, Clutter.KeyState.RELEASED); if (focus instanceof Clutter.Text)
return; // do nothing
else
this.parent(keyval);
}, },
}); });

View File

@ -220,8 +220,7 @@ const LayoutManager = new Lang.Class({
global.stage.add_child(this.uiGroup); global.stage.add_child(this.uiGroup);
this.overviewGroup = new St.Widget({ name: 'overviewGroup', this.overviewGroup = new St.Widget({ name: 'overviewGroup',
visible: false, visible: false });
reactive: true });
this.addChrome(this.overviewGroup); this.addChrome(this.overviewGroup);
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup', this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
@ -592,10 +591,7 @@ const LayoutManager = new Lang.Class({
this.addChrome(this._coverPane); this.addChrome(this._coverPane);
if (Meta.is_restart()) { if (Meta.is_restart()) {
// On restart, we don't do an animation. Force an update of the // On restart, we don't do an animation
// regions immediately so that maximized windows restore to the
// right size taking struts into account.
this._updateRegions();
} else if (Main.sessionMode.isGreeter) { } else if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height; this.panelBox.translation_y = -this.panelBox.height;
} else { } else {
@ -896,10 +892,7 @@ const LayoutManager = new Lang.Class({
}, },
findMonitorForActor: function(actor) { findMonitorForActor: function(actor) {
let index = this.findIndexForActor(actor); return this.monitors[this.findIndexForActor(actor)];
if (index >= 0 && index < this.monitors.length)
return this.monitors[index];
return null;
}, },
_queueUpdateRegions: function() { _queueUpdateRegions: function() {
@ -945,11 +938,6 @@ const LayoutManager = new Lang.Class({
if (Main.modalCount > 0) if (Main.modalCount > 0)
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
// Bug workaround - get_transformed_position()/get_transformed_size() don't work after
// a change in stage size until the first pick or paint.
// https://bugzilla.gnome.org/show_bug.cgi?id=761565
global.stage.get_actor_at_pos(Clutter.PickMode.ALL, 0, 0);
let rects = [], struts = [], i; let rects = [], struts = [], i;
let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow); let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow);
let wantsInputRegion = !isPopupMenuVisible; let wantsInputRegion = !isPopupMenuVisible;
@ -969,11 +957,7 @@ const LayoutManager = new Lang.Class({
if (actorData.affectsInputRegion && wantsInputRegion && actorData.actor.get_paint_visibility()) if (actorData.affectsInputRegion && wantsInputRegion && actorData.actor.get_paint_visibility())
rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h })); rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h }));
let monitor = null; if (actorData.affectsStruts) {
if (actorData.affectsStruts)
monitor = this.findMonitorForActor(actorData.actor);
if (monitor) {
// Limit struts to the size of the screen // Limit struts to the size of the screen
let x1 = Math.max(x, 0); let x1 = Math.max(x, 0);
let x2 = Math.min(x + w, global.screen_width); let x2 = Math.min(x + w, global.screen_width);
@ -990,6 +974,7 @@ const LayoutManager = new Lang.Class({
// spans the width/height across the middle of the // spans the width/height across the middle of the
// screen, then we don't create a strut for it at all. // screen, then we don't create a strut for it at all.
let monitor = this.findMonitorForActor(actorData.actor);
let side; let side;
if (x1 <= monitor.x && x2 >= monitor.x + monitor.width) { if (x1 <= monitor.x && x2 >= monitor.x + monitor.width) {
if (y1 <= monitor.y) if (y1 <= monitor.y)

View File

@ -33,6 +33,7 @@ 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; ' +
@ -783,7 +784,6 @@ const LookingGlass = new Lang.Class({
this._open = false; this._open = false;
this._it = null;
this._offset = 0; this._offset = 0;
this._results = []; this._results = [];

View File

@ -11,7 +11,6 @@ const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const St = imports.gi.St; const St = imports.gi.St;
const AccessDialog = imports.ui.accessDialog;
const AudioDeviceSelection = imports.ui.audioDeviceSelection; const AudioDeviceSelection = imports.ui.audioDeviceSelection;
const Components = imports.ui.components; const Components = imports.ui.components;
const CtrlAltTab = imports.ui.ctrlAltTab; const CtrlAltTab = imports.ui.ctrlAltTab;
@ -26,7 +25,6 @@ const ModalDialog = imports.ui.modalDialog;
const OsdWindow = imports.ui.osdWindow; const OsdWindow = imports.ui.osdWindow;
const OsdMonitorLabeler = imports.ui.osdMonitorLabeler; const OsdMonitorLabeler = imports.ui.osdMonitorLabeler;
const Overview = imports.ui.overview; const Overview = imports.ui.overview;
const PadOsd = imports.ui.padOsd;
const Panel = imports.ui.panel; const Panel = imports.ui.panel;
const Params = imports.misc.params; const Params = imports.misc.params;
const RunDialog = imports.ui.runDialog; const RunDialog = imports.ui.runDialog;
@ -62,11 +60,9 @@ let screenShield = null;
let notificationDaemon = null; let notificationDaemon = null;
let windowAttentionHandler = null; let windowAttentionHandler = null;
let ctrlAltTabManager = null; let ctrlAltTabManager = null;
let padOsdService = null;
let osdWindowManager = null; let osdWindowManager = null;
let osdMonitorLabeler = null; let osdMonitorLabeler = null;
let sessionMode = null; let sessionMode = null;
let shellAccessDialogDBusService = null;
let shellAudioSelectionDBusService = null; let shellAudioSelectionDBusService = null;
let shellDBusService = null; let shellDBusService = null;
let shellMountOpDBusService = null; let shellMountOpDBusService = null;
@ -126,7 +122,6 @@ function start() {
_loadDefaultStylesheet); _loadDefaultStylesheet);
_initializeUI(); _initializeUI();
shellAccessDialogDBusService = new AccessDialog.AccessDialogDBus();
shellAudioSelectionDBusService = new AudioDeviceSelection.AudioDeviceSelectionDBus(); shellAudioSelectionDBusService = new AudioDeviceSelection.AudioDeviceSelectionDBus();
shellDBusService = new ShellDBus.GnomeShell(); shellDBusService = new ShellDBus.GnomeShell();
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler(); shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
@ -157,7 +152,6 @@ function _initializeUI() {
// working until it's updated. // working until it's updated.
uiGroup = layoutManager.uiGroup; uiGroup = layoutManager.uiGroup;
padOsdService = new PadOsd.PadOsdService();
screencastService = new Screencast.ScreencastService(); screencastService = new Screencast.ScreencastService();
xdndHandler = new XdndHandler.XdndHandler(); xdndHandler = new XdndHandler.XdndHandler();
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
@ -197,8 +191,6 @@ function _initializeUI() {
return true; return true;
}); });
global.display.connect('gl-video-memory-purged', loadTheme);
// Provide the bus object for gnome-session to // Provide the bus object for gnome-session to
// initiate logouts. // initiate logouts.
EndSessionDialog.init(); EndSessionDialog.init();

View File

@ -165,11 +165,6 @@ const ScaleLayout = new Lang.Class({
Name: 'ScaleLayout', Name: 'ScaleLayout',
Extends: Clutter.BinLayout, Extends: Clutter.BinLayout,
_init: function(params) {
this._container = null;
this.parent(params);
},
_connectContainer: function(container) { _connectContainer: function(container) {
if (this._container == container) if (this._container == container)
return; return;
@ -304,8 +299,6 @@ const Message = new Lang.Class({
_init: function(title, body) { _init: function(title, body) {
this.expanded = false; this.expanded = false;
this._useBodyMarkup = false;
this.actor = new St.Button({ style_class: 'message', this.actor = new St.Button({ style_class: 'message',
accessible_role: Atk.Role.NOTIFICATION, accessible_role: Atk.Role.NOTIFICATION,
can_focus: true, can_focus: true,
@ -325,7 +318,6 @@ 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);
@ -339,18 +331,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, opacity: 0 }); this._closeButton = new St.Button({ child: closeIcon, visible: false });
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 });
@ -501,8 +493,9 @@ const Message = new Lang.Class({
}, },
_sync: function() { _sync: function() {
let visible = this.actor.hover && this.canClose(); let hovered = this.actor.hover;
this._closeButton.opacity = visible ? 255 : 0; this._closeButton.visible = hovered && this.canClose();
this._secondaryBin.visible = !hovered;
}, },
_onClicked: function() { _onClicked: function() {
@ -527,10 +520,32 @@ Signals.addSignalMethods(Message.prototype);
const MessageListSection = new Lang.Class({ const MessageListSection = new Lang.Class({
Name: 'MessageListSection', Name: 'MessageListSection',
_init: function() { _init: function(title) {
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 });
@ -548,10 +563,14 @@ 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);
}, },
@ -700,13 +719,7 @@ const MessageListSection = new Lang.Class({
if (changed) if (changed)
this.emit('empty-changed'); this.emit('empty-changed');
let canClear = this._canClear(); this._closeButton.visible = 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();
} }
}); });

View File

@ -368,7 +368,6 @@ 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 });
@ -376,11 +375,6 @@ 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;
@ -541,8 +535,7 @@ 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);
} }
}, },
@ -803,7 +796,7 @@ const Source = new Lang.Class({
notification.acknowledged = false; notification.acknowledged = false;
this.pushNotification(notification); this.pushNotification(notification);
if (this.policy.showBanners || notification.urgency == Urgency.CRITICAL) { if (this.policy.showBanners) {
this.emit('notify', notification); this.emit('notify', notification);
} else { } else {
notification.playSound(); notification.playSound();
@ -1231,7 +1224,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.primaryMonitor.inFullscreen; let limited = this._busy || Main.layoutManager.bottomMonitor.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();

View File

@ -259,7 +259,7 @@ const ModalDialog = new Lang.Class({
if (this.state == State.OPENED || this.state == State.OPENING) if (this.state == State.OPENED || this.state == State.OPENING)
return true; return true;
if (!this.pushModal(timestamp)) if (!this.pushModal({ timestamp: timestamp }))
return false; return false;
this._fadeOpen(onPrimary); this._fadeOpen(onPrimary);
@ -318,11 +318,8 @@ const ModalDialog = new Lang.Class({
pushModal: function (timestamp) { pushModal: function (timestamp) {
if (this._hasModal) if (this._hasModal)
return true; return true;
if (!Main.pushModal(this._group, { timestamp: timestamp,
let params = { actionMode: this._actionMode }; actionMode: this._actionMode }))
if (timestamp)
params['timestamp'] = timestamp;
if (!Main.pushModal(this._group, params))
return false; return false;
this._hasModal = true; this._hasModal = true;

View File

@ -36,8 +36,6 @@ 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" /> \
@ -59,7 +57,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._prevButton = this.addMediaControl('media-skip-backward-symbolic', this.addMediaControl('media-skip-backward-symbolic',
Lang.bind(this, function() { Lang.bind(this, function() {
this._player.previous(); this._player.previous();
})); }));
@ -69,7 +67,7 @@ const MediaMessage = new Lang.Class({
this._player.playPause(); this._player.playPause();
})); }));
this._nextButton = this.addMediaControl('media-skip-forward-symbolic', this.addMediaControl('media-skip-forward-symbolic',
Lang.bind(this, function() { Lang.bind(this, function() {
this._player.next(); this._player.next();
})); }));
@ -84,10 +82,6 @@ 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);
@ -105,9 +99,6 @@ 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);
} }
}); });
@ -148,18 +139,10 @@ 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();
}, },
@ -231,7 +214,7 @@ const MediaSection = new Lang.Class({
Extends: MessageList.MessageListSection, Extends: MessageList.MessageListSection,
_init: function() { _init: function() {
this.parent(); this.parent(_("Media"));
this._players = new Map(); this._players = new Map();

View File

@ -128,10 +128,10 @@ const FdoNotificationDaemon = new Lang.Class({
switch (hints.urgency) { switch (hints.urgency) {
case Urgency.LOW: case Urgency.LOW:
case Urgency.NORMAL: case Urgency.NORMAL:
stockIcon = 'dialog-information'; stockIcon = 'gtk-dialog-info';
break; break;
case Urgency.CRITICAL: case Urgency.CRITICAL:
stockIcon = 'dialog-error'; stockIcon = 'gtk-dialog-error';
break; break;
} }
return new Gio.ThemedIcon({ name: stockIcon }); return new Gio.ThemedIcon({ name: stockIcon });
@ -186,8 +186,7 @@ const FdoNotificationDaemon = new Lang.Class({
return source; return source;
} }
let appId = ndata ? ndata.hints['desktop-entry'] || null : null; let source = new FdoNotificationDaemonSource(title, pid, sender, ndata ? ndata.hints['desktop-entry'] : null);
source = new FdoNotificationDaemonSource(title, pid, sender, appId);
this._sources.push(source); this._sources.push(source);
source.connect('destroy', Lang.bind(this, function() { source.connect('destroy', Lang.bind(this, function() {
@ -392,10 +391,10 @@ const FdoNotificationDaemon = new Lang.Class({
notification.setUrgency(MessageTray.Urgency.CRITICAL); notification.setUrgency(MessageTray.Urgency.CRITICAL);
break; break;
} }
notification.setResident(!!hints.resident); notification.setResident(hints.resident == true);
// 'transient' is a reserved keyword in JS, so we have to retrieve the value // 'transient' is a reserved keyword in JS, so we have to retrieve the value
// of the 'transient' hint with hints['transient'] rather than hints.transient // of the 'transient' hint with hints['transient'] rather than hints.transient
notification.setTransient(!!hints['transient']); notification.setTransient(hints['transient'] == true);
let sourceGIcon = source.useNotificationIcon ? gicon : null; let sourceGIcon = source.useNotificationIcon ? gicon : null;
source.processNotification(notification, sourceGIcon); source.processNotification(notification, sourceGIcon);
@ -601,8 +600,7 @@ const GtkNotificationDaemonNotification = new Lang.Class({
"priority": priority, "priority": priority,
"buttons": buttons, "buttons": buttons,
"default-action": defaultAction, "default-action": defaultAction,
"default-action-target": defaultActionTarget, "default-action-target": defaultActionTarget } = notification;
"timestamp": time } = notification;
if (priority) { if (priority) {
let urgency = PRIORITY_URGENCY_MAP[priority.unpack()]; let urgency = PRIORITY_URGENCY_MAP[priority.unpack()];
@ -625,8 +623,7 @@ 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) {
@ -693,7 +690,6 @@ 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());
}, },
@ -706,35 +702,27 @@ const GtkNotificationDaemonAppSource = new Lang.Class({
return new MessageTray.NotificationApplicationPolicy(this._appId); return new MessageTray.NotificationApplicationPolicy(this._appId);
}, },
_createApp: function(callback) { _createApp: function() {
return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath, callback); return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath);
}, },
activateAction: function(actionId, target) { activateAction: function(actionId, target) {
this._createApp(function (app, error) { let app = this._createApp();
if (error == null)
app.ActivateActionRemote(actionId, target ? [target] : [], getPlatformData()); 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() {
this._createApp(function (app, error) { let app = this._createApp();
if (error == null)
app.ActivateRemote(getPlatformData()); 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();
@ -748,14 +736,6 @@ 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) {
@ -867,9 +847,6 @@ 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);

View File

@ -22,13 +22,11 @@ const LevelBar = new Lang.Class({
this._level = 0; this._level = 0;
this.actor = new St.Bin({ style_class: 'level', this.actor = new St.Bin({ style_class: 'level',
x_align: St.Align.START, x_fill: true, y_fill: true });
y_fill: true }); this._bar = new St.DrawingArea();
this._bar = new St.Widget({ style_class: 'level-bar' }); this._bar.connect('repaint', Lang.bind(this, this._repaint));
this.actor.set_child(this._bar); this.actor.set_child(this._bar);
this.actor.connect('notify::width', () => { this.level = this.level; });
}, },
get level() { get level() {
@ -36,44 +34,39 @@ const LevelBar = new Lang.Class({
}, },
set level(value) { set level(value) {
this._level = Math.max(0, Math.min(value, 100)); let newValue = Math.max(0, Math.min(value, 100));
if (newValue == this._level)
let alloc = this.actor.get_allocation_box(); return;
let newWidth = Math.round((alloc.x2 - alloc.x1) * this._level / 100); this._level = newValue;
if (newWidth != this._bar.width) this._bar.queue_repaint();
this._bar.width = newWidth;
}
});
const OsdWindowConstraint = new Lang.Class({
Name: 'OsdWindowConstraint',
Extends: Clutter.Constraint,
_init: function(props) {
this._minSize = 0;
this.parent(props);
}, },
set minSize(v) { _repaint: function() {
this._minSize = v; let cr = this._bar.get_context();
if (this.actor)
this.actor.queue_relayout();
},
vfunc_update_allocation: function(actor, actorBox) { let node = this.actor.get_theme_node();
// Clutter will adjust the allocation for margins, let radius = node.get_border_radius(0); // assume same radius for all corners
// so add it to our minimum size Clutter.cairo_set_source_color(cr, node.get_foreground_color());
let minSize = this._minSize + actor.margin_top + actor.margin_bottom;
let [width, height] = actorBox.get_size();
// Enforce a ratio of 1 let [w, h] = this._bar.get_surface_size();
let size = Math.ceil(Math.max(minSize, height)); w *= (this._level / 100.);
actorBox.set_size(size, size);
// Recenter if (w == 0)
let [x, y] = actorBox.get_origin(); return;
actorBox.set_origin(Math.ceil(x + width / 2 - size / 2),
Math.ceil(y + height / 2 - size / 2)); cr.moveTo(radius, 0);
if (w >= radius)
cr.arc(w - radius, radius, radius, 1.5 * Math.PI, 2. * Math.PI);
else
cr.lineTo(w, 0);
if (w >= radius)
cr.arc(w - radius, h - radius, radius, 0, 0.5 * Math.PI);
else
cr.lineTo(w, h);
cr.arc(radius, h - radius, radius, 0.5 * Math.PI, Math.PI);
cr.arc(radius, radius, radius, Math.PI, 1.5 * Math.PI);
cr.fill();
cr.$dispose();
} }
}); });
@ -81,6 +74,7 @@ const OsdWindow = new Lang.Class({
Name: 'OsdWindow', Name: 'OsdWindow',
_init: function(monitorIndex) { _init: function(monitorIndex) {
this._popupSize = 0;
this.actor = new St.Widget({ x_expand: true, this.actor = new St.Widget({ x_expand: true,
y_expand: true, y_expand: true,
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
@ -90,12 +84,19 @@ const OsdWindow = 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._boxConstraint = new OsdWindowConstraint();
this._box = new St.BoxLayout({ style_class: 'osd-window', this._box = new St.BoxLayout({ style_class: 'osd-window',
vertical: true }); vertical: true });
this._box.add_constraint(this._boxConstraint);
this.actor.add_actor(this._box); this.actor.add_actor(this._box);
this._box.connect('style-changed', Lang.bind(this, this._onStyleChanged));
this._box.connect('notify::height', Lang.bind(this,
function() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
function() {
this._box.width = this._box.height;
}));
}));
this._icon = new St.Icon(); this._icon = new St.Icon();
this._box.add(this._icon, { expand: true }); this._box.add(this._icon, { expand: true });
@ -109,11 +110,8 @@ const OsdWindow = new Lang.Class({
this._reset(); this._reset();
Main.layoutManager.connect('monitors-changed', Main.layoutManager.connect('monitors-changed',
Lang.bind(this, this._relayout)); Lang.bind(this, this._monitorsChanged));
let themeContext = St.ThemeContext.get_for_stage(global.stage); this._monitorsChanged();
themeContext.connect('notify::scale-factor',
Lang.bind(this, this._relayout));
this._relayout();
Main.uiGroup.add_child(this.actor); Main.uiGroup.add_child(this.actor);
}, },
@ -191,7 +189,7 @@ const OsdWindow = new Lang.Class({
this.setLevel(null); this.setLevel(null);
}, },
_relayout: function() { _monitorsChanged: function() {
/* assume 110x110 on a 640x480 display and scale from there */ /* assume 110x110 on a 640x480 display and scale from there */
let monitor = Main.layoutManager.monitors[this._monitorIndex]; let monitor = Main.layoutManager.monitors[this._monitorIndex];
if (!monitor) if (!monitor)
@ -200,12 +198,30 @@ const OsdWindow = new Lang.Class({
let scalew = monitor.width / 640.0; let scalew = monitor.width / 640.0;
let scaleh = monitor.height / 480.0; let scaleh = monitor.height / 480.0;
let scale = Math.min(scalew, scaleh); let scale = Math.min(scalew, scaleh);
let popupSize = 110 * Math.max(1, scale); this._popupSize = 110 * Math.max(1, scale);
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._icon.icon_size = popupSize / (2 * scaleFactor); this._icon.icon_size = this._popupSize / (2 * scaleFactor);
this._box.translation_y = monitor.height / 4; this._box.translation_y = monitor.height / 4;
this._boxConstraint.minSize = popupSize; this._box.style_changed();
},
_onStyleChanged: function() {
let themeNode = this._box.get_theme_node();
let horizontalPadding = themeNode.get_horizontal_padding();
let verticalPadding = themeNode.get_vertical_padding();
let topBorder = themeNode.get_border_width(St.Side.TOP);
let bottomBorder = themeNode.get_border_width(St.Side.BOTTOM);
let leftBorder = themeNode.get_border_width(St.Side.LEFT);
let rightBorder = themeNode.get_border_width(St.Side.RIGHT);
let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder;
let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder;
// minWidth/minHeight here are in real pixels,
// but the theme takes measures in unscaled dimensions
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight) / scaleFactor);
} }
}); });

View File

@ -107,12 +107,18 @@ const Overview = new Lang.Class({
this._overviewCreated = true; this._overviewCreated = true;
this._overview = new St.BoxLayout({ name: 'overview', let layout = new Clutter.BinLayout();
this._stack = new Clutter.Actor({ layout_manager: layout });
this._stack.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
/* Translators: This is the main view to select /* Translators: This is the main view to select
activities. See also note for "Activities" string. */ activities. See also note for "Activities" string. */
this._overview = new St.BoxLayout({ name: 'overview',
accessible_name: _("Overview"), accessible_name: _("Overview"),
vertical: true }); reactive: true,
this._overview.add_constraint(new LayoutManager.MonitorConstraint({ primary: true })); vertical: true,
x_expand: true,
y_expand: true });
this._overview._delegate = this; this._overview._delegate = this;
// The main Background actors are inside global.window_group which are // The main Background actors are inside global.window_group which are
@ -120,7 +126,7 @@ const Overview = new Lang.Class({
// one. Instances of this class share a single CoglTexture behind the // one. Instances of this class share a single CoglTexture behind the
// scenes which allows us to show the background with different // scenes which allows us to show the background with different
// rendering options without duplicating the texture data. // rendering options without duplicating the texture data.
this._backgroundGroup = new Meta.BackgroundGroup({ reactive: true }); this._backgroundGroup = new Meta.BackgroundGroup();
Main.layoutManager.overviewGroup.add_child(this._backgroundGroup); Main.layoutManager.overviewGroup.add_child(this._backgroundGroup);
this._bgManagers = []; this._bgManagers = [];
@ -143,7 +149,8 @@ const Overview = new Lang.Class({
Main.layoutManager.overviewGroup.add_child(this._coverPane); Main.layoutManager.overviewGroup.add_child(this._coverPane);
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return Clutter.EVENT_STOP; })); this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return Clutter.EVENT_STOP; }));
Main.layoutManager.overviewGroup.add_child(this._overview); this._stack.add_actor(this._overview);
Main.layoutManager.overviewGroup.add_child(this._stack);
this._coverPane.hide(); this._coverPane.hide();
@ -152,9 +159,6 @@ const Overview = new Lang.Class({
dragMotion: Lang.bind(this, this._onDragMotion) dragMotion: Lang.bind(this, this._onDragMotion)
}; };
Main.layoutManager.overviewGroup.connect('scroll-event',
Lang.bind(this, this._onScrollEvent));
Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin)); Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd)); Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
@ -251,6 +255,7 @@ const Overview = new Lang.Class({
// Add our same-line elements after the search entry // Add our same-line elements after the search entry
this._overview.add(this._controls.actor, { y_fill: true, expand: true }); this._overview.add(this._controls.actor, { y_fill: true, expand: true });
this._controls.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
// TODO - recalculate everything when desktop size changes // TODO - recalculate everything when desktop size changes
this.dashIconSize = this._dash.iconSize; this.dashIconSize = this._dash.iconSize;
@ -367,7 +372,7 @@ const Overview = new Lang.Class({
if (this.isDummy) if (this.isDummy)
return; return;
this._backgroundGroup.add_action(action); this._overview.add_action(action);
}, },
_getDesktopClone: function() { _getDesktopClone: function() {
@ -378,7 +383,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, let clone = new Clutter.Clone({ source: window.get_texture(),
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();
@ -547,8 +552,8 @@ const Overview = new Lang.Class({
Meta.disable_unredirect_for_screen(global.screen); Meta.disable_unredirect_for_screen(global.screen);
this.viewSelector.show(); this.viewSelector.show();
this._overview.opacity = 0; this._stack.opacity = 0;
Tweener.addTween(this._overview, Tweener.addTween(this._stack,
{ opacity: 255, { opacity: 255,
transition: 'easeOutQuad', transition: 'easeOutQuad',
time: ANIMATION_TIME, time: ANIMATION_TIME,
@ -613,7 +618,7 @@ const Overview = new Lang.Class({
this.viewSelector.animateFromOverview(); this.viewSelector.animateFromOverview();
// Make other elements fade out. // Make other elements fade out.
Tweener.addTween(this._overview, Tweener.addTween(this._stack,
{ opacity: 0, { opacity: 0,
transition: 'easeOutQuad', transition: 'easeOutQuad',
time: ANIMATION_TIME, time: ANIMATION_TIME,

View File

@ -421,6 +421,7 @@ const ControlsManager = new Lang.Class({
let layout = new ControlsLayout(); let layout = new ControlsLayout();
this.actor = new St.Widget({ layout_manager: layout, this.actor = new St.Widget({ layout_manager: layout,
reactive: true,
x_expand: true, y_expand: true, x_expand: true, y_expand: true,
clip_to_allocation: true }); clip_to_allocation: true });
this._group = new St.BoxLayout({ name: 'overview-group', this._group = new St.BoxLayout({ name: 'overview-group',

View File

@ -1,996 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Rsvg = imports.gi.Rsvg;
const GObject = imports.gi.GObject;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const GDesktopEnums = imports.gi.GDesktopEnums;
const Atk = imports.gi.Atk;
const Cairo = imports.cairo;
const Signals = imports.signals;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const Layout = imports.ui.layout;
const ACTIVE_COLOR = "#729fcf";
const LTR = 0;
const RTL = 1;
const CW = 0;
const CCW = 1;
const UP = 0;
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({
Name: 'KeybindingEntry',
_init: function () {
this.actor = new St.Entry({ hint_text: _("New shortcut…"),
style: 'width: 10em' });
this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
},
_onCapturedEvent: function (actor, event) {
if (event.type() != Clutter.EventType.KEY_PRESS)
return Clutter.EVENT_PROPAGATE;
let str = Gtk.accelerator_name_with_keycode(null,
event.get_key_symbol(),
event.get_key_code(),
event.get_state());
this.actor.set_text(str);
this.emit('keybinding-edited', str);
return Clutter.EVENT_STOP;
}
});
Signals.addSignalMethods(KeybindingEntry.prototype);
const ActionComboBox = new Lang.Class({
Name: 'ActionComboBox',
_init: function () {
this.actor = new St.Button({ style_class: 'button' });
this.actor.connect('clicked', Lang.bind(this, this._onButtonClicked));
this.actor.set_toggle_mode(true);
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
spacing: 6 });
let box = new St.Widget({ layout_manager: boxLayout });
this.actor.set_child(box);
this._label = new St.Label({ style_class: 'combo-box-label' });
box.add_child(this._label)
let arrow = new St.Icon({ style_class: 'popup-menu-arrow',
icon_name: 'pan-down-symbolic',
accessible_role: Atk.Role.ARROW,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
box.add_child(arrow);
this._editMenu = new PopupMenu.PopupMenu(this.actor, 0, St.Side.TOP);
this._editMenu.connect('menu-closed', Lang.bind(this, function() { this.actor.set_checked(false); }));
this._editMenu.actor.hide();
Main.uiGroup.add_actor(this._editMenu.actor);
this._actionLabels = new Map();
this._actionLabels.set(GDesktopEnums.PadButtonAction.NONE, _("Application defined"));
this._actionLabels.set(GDesktopEnums.PadButtonAction.HELP, _("Show on-screen help"));
this._actionLabels.set(GDesktopEnums.PadButtonAction.SWITCH_MONITOR, _("Switch monitor"));
this._actionLabels.set(GDesktopEnums.PadButtonAction.KEYBINDING, _("Assign keystroke"));
this._buttonItems = [];
for (let [action, label] of this._actionLabels.entries()) {
let selectedAction = action;
let item = this._editMenu.addAction(label, Lang.bind(this, function() { this._onActionSelected(selectedAction) }));
/* These actions only apply to pad buttons */
if (selectedAction == GDesktopEnums.PadButtonAction.HELP ||
selectedAction == GDesktopEnums.PadButtonAction.SWITCH_MONITOR)
this._buttonItems.push(item);
}
this.setAction(GDesktopEnums.PadButtonAction.NONE);
},
_onActionSelected: function (action) {
this.setAction(action);
this.popdown();
this.emit('action-selected', action);
},
setAction: function (action) {
this._label.set_text(this._actionLabels.get(action));
},
popup: function () {
this._editMenu.open(true);
},
popdown: function () {
this._editMenu.close(true);
},
_onButtonClicked: function () {
if (this.actor.get_checked())
this.popup();
else
this.popdown();
},
setButtonActionsActive: function (active) {
this._buttonItems.forEach(item => { item.setSensitive(active); });
}
});
Signals.addSignalMethods(ActionComboBox.prototype);
const ActionEditor = new Lang.Class({
Name: 'ActionEditor',
_init: function () {
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
spacing: 12 });
this.actor = new St.Widget({ layout_manager: boxLayout });
this._actionComboBox = new ActionComboBox();
this._actionComboBox.connect('action-selected', Lang.bind(this, this._onActionSelected));
this.actor.add_actor(this._actionComboBox.actor);
this._keybindingEdit = new KeybindingEntry();
this._keybindingEdit.connect('keybinding-edited', Lang.bind(this, this._onKeybindingEdited));
this.actor.add_actor(this._keybindingEdit.actor);
this._doneButton = new St.Button({ label: _("Done"),
style_class: 'button',
x_expand: false});
this._doneButton.connect('clicked', Lang.bind(this, this._onEditingDone));
this.actor.add_actor(this._doneButton);
},
_updateKeybindingEntryState: function () {
if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING) {
this._keybindingEdit.actor.set_text(this._currentKeybinding);
this._keybindingEdit.actor.show();
this._keybindingEdit.actor.grab_key_focus();
} else {
this._keybindingEdit.actor.hide();
}
},
setSettings: function (settings, action) {
this._buttonSettings = settings;
this._currentAction = this._buttonSettings.get_enum('action');
this._currentKeybinding = this._buttonSettings.get_string('keybinding');
this._actionComboBox.setAction(this._currentAction);
this._updateKeybindingEntryState();
let isButton = (action == Meta.PadActionType.BUTTON);
this._actionComboBox.setButtonActionsActive(isButton);
},
close: function() {
this._actionComboBox.popdown();
this.actor.hide();
},
_onKeybindingEdited: function (entry, keybinding) {
this._currentKeybinding = keybinding;
},
_onActionSelected: function (menu, action) {
this._currentAction = action;
this._updateKeybindingEntryState();
},
_storeSettings: function () {
if (!this._buttonSettings)
return;
let keybinding = null;
if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING)
keybinding = this._currentKeybinding;
this._buttonSettings.set_enum('action', this._currentAction);
if (keybinding)
this._buttonSettings.set_string('keybinding', keybinding);
else
this._buttonSettings.reset('keybinding');
},
_onEditingDone: function () {
this._storeSettings();
this.close();
this.emit('done');
}
});
Signals.addSignalMethods(ActionEditor.prototype);
const PadDiagram = new Lang.Class({
Name: 'PadDiagram',
Extends: St.DrawingArea,
Properties: { 'left-handed': GObject.ParamSpec.boolean('left-handed',
'left-handed', 'Left handed',
GObject.ParamFlags.READWRITE |
GObject.ParamFlags.CONSTRUCT_ONLY,
false),
'image': GObject.ParamSpec.string('image', 'image', 'Image',
GObject.ParamFlags.READWRITE |
GObject.ParamFlags.CONSTRUCT_ONLY,
null),
'editor-actor': GObject.ParamSpec.object('editor-actor',
'editor-actor',
'Editor actor',
GObject.ParamFlags.READWRITE |
GObject.ParamFlags.CONSTRUCT_ONLY,
Clutter.Actor.$gtype) },
_init: function (params) {
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/pad-osd.css');
let [success, css, etag] = file.load_contents(null);
this._curEdited = null;
this._prevEdited = null;
this._css = css;
this._labels = [];
this._activeButtons = [];
this.parent(params);
},
get left_handed() {
return this._leftHanded;
},
set left_handed(leftHanded) {
this._leftHanded = leftHanded;
},
get image() {
return this._imagePath;
},
set image(imagePath) {
let originalHandle = Rsvg.Handle.new_from_file(imagePath);
let dimensions = originalHandle.get_dimensions();
this._imageWidth = dimensions.width;
this._imageHeight = dimensions.height;
this._imagePath = imagePath;
this._handle = this._composeStyledDiagram();
},
get editor_actor() {
return this._editorActor;
},
set editor_actor(actor) {
actor.hide();
this._editorActor = actor;
this.add_actor(actor);
},
_wrappingSvgHeader: function () {
return ('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" ' +
'xmlns:xi="http://www.w3.org/2001/XInclude" ' +
'width="' + this._imageWidth + '" height="' + this._imageHeight + '"> ' +
'<style type="text/css">');
},
_wrappingSvgFooter: function () {
return ('</style>' +
'<xi:include href="' + this._imagePath + '" />' +
'</svg>');
},
_cssString: function () {
let css = this._css;
for (let i = 0; i < this._activeButtons.length; i++) {
let ch = String.fromCharCode('A'.charCodeAt() + this._activeButtons[i]);
css += ('.' + ch + ' { ' +
' stroke: ' + ACTIVE_COLOR + ' !important; ' +
' fill: ' + ACTIVE_COLOR + ' !important; ' +
'} ');
}
return css;
},
_composeStyledDiagram: function () {
let svgData = '';
if (!GLib.file_test(this._imagePath, GLib.FileTest.EXISTS))
return null;
svgData += this._wrappingSvgHeader();
svgData += this._cssString();
svgData += this._wrappingSvgFooter();
let handle = new Rsvg.Handle();
handle.set_base_uri(GLib.path_get_dirname(this._imagePath));
handle.write(svgData);
handle.close();
return handle;
},
_updateDiagramScale: function () {
if (this._handle == null)
return;
[this._actorWidth, this._actorHeight] = this.get_size();
let dimensions = this._handle.get_dimensions();
let scaleX = this._actorWidth / dimensions.width;
let scaleY = this._actorHeight / dimensions.height;
this._scale = Math.min(scaleX, scaleY);
},
_allocateChild: function (child, x, y, direction) {
let [prefHeight, natHeight] = child.get_preferred_height(-1);
let [prefWidth, natWidth] = child.get_preferred_width(natHeight);
let childBox = new Clutter.ActorBox();
if (direction == LTR) {
childBox.x1 = x;
childBox.x2 = x + natWidth;
} else {
childBox.x1 = x - natWidth;
childBox.x2 = x;
}
childBox.y1 = y - natHeight / 2;
childBox.y2 = y + natHeight / 2;
child.allocate(childBox, 0);
},
vfunc_allocate: function (box, flags) {
this.parent(box, flags);
this._updateDiagramScale();
for (let i = 0; i < this._labels.length; i++) {
let [label, action, idx, dir] = this._labels[i];
let [found, x, y, arrangement] = this.getLabelCoords(action, idx, dir);
this._allocateChild(label, x, y, arrangement);
}
if (this._editorActor && this._curEdited) {
let [label, action, idx, dir] = this._curEdited;
let [found, x, y, arrangement] = this.getLabelCoords(action, idx, dir);
this._allocateChild(this._editorActor, x, y, arrangement);
}
},
vfunc_repaint: function () {
if (this._handle == null)
return;
if (this._scale == null)
this._updateDiagramScale();
let [width, height] = this.get_surface_size();
let dimensions = this._handle.get_dimensions();
let cr = this.get_context();
cr.save();
cr.translate(width/2, height/2);
cr.scale(this._scale, this._scale);
if (this._leftHanded)
cr.rotate(Math.PI);
cr.translate(-dimensions.width/2, -dimensions.height/2);
this._handle.render_cairo(cr);
cr.restore();
cr.$dispose();
},
_transformPoint: function (x, y) {
if (this._handle == null || this._scale == null)
return [x, y];
// I miss Cairo.Matrix
let dimensions = this._handle.get_dimensions();
x = x * this._scale + this._actorWidth / 2 - dimensions.width / 2 * this._scale;
y = y * this._scale + this._actorHeight / 2 - dimensions.height / 2 * this._scale;;
return [Math.round(x), Math.round(y)];
},
_getItemLabelCoords: function (labelName, leaderName) {
if (this._handle == null)
return [false];
let leaderPos, leaderSize, pos;
let found, direction;
[found, pos] = this._handle.get_position_sub('#' + labelName);
if (!found)
return [false];
[found, leaderPos] = this._handle.get_position_sub('#' + leaderName);
[found, leaderSize] = this._handle.get_dimensions_sub('#' + leaderName);
if (!found)
return [false];
if (pos.x > leaderPos.x + leaderSize.width)
direction = LTR;
else
direction = RTL;
if (this._leftHanded) {
direction = 1 - direction;
pos.x = this._imageWidth - pos.x;
pos.y = this._imageHeight - pos.y;
}
let [x, y] = this._transformPoint(pos.x, pos.y)
return [true, x, y, direction];
},
getButtonLabelCoords: function (button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let labelName = 'Label' + ch;
let leaderName = 'Leader' + ch;
return this._getItemLabelCoords(labelName, leaderName);
},
getRingLabelCoords: function (number, dir) {
let numStr = number > 0 ? number.toString() : '';
let dirStr = dir == CW ? 'CW' : 'CCW';
let labelName = 'LabelRing' + numStr + dirStr;
let leaderName = 'LeaderRing' + numStr + dirStr;
return this._getItemLabelCoords(labelName, leaderName);
},
getStripLabelCoords: function (number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
let dirStr = dir == UP ? 'Up' : 'Down';
let labelName = 'LabelStrip' + numStr + dirStr;
let leaderName = 'LeaderStrip' + numStr + dirStr;
return this._getItemLabelCoords(labelName, leaderName);
},
getLabelCoords: function (action, idx, dir) {
if (action == Meta.PadActionType.BUTTON)
return this.getButtonLabelCoords(idx);
else if (action == Meta.PadActionType.RING)
return this.getRingLabelCoords(idx, dir);
else if (action == Meta.PadActionType.STRIP)
return this.getStripLabelCoords(idx, dir);
return [false];
},
_invalidateSvg: function () {
if (this._handle == null)
return;
this._handle = this._composeStyledDiagram();
this.queue_repaint();
},
activateButton: function (button) {
this._activeButtons.push(button);
this._invalidateSvg();
},
deactivateButton: function (button) {
for (let i = 0; i < this._activeButtons.length; i++) {
if (this._activeButtons[i] == button)
this._activeButtons.splice(i, 1);
}
this._invalidateSvg();
},
addLabel: function (label, type, idx, dir) {
this._labels.push([label, type, idx, dir]);
this.add_actor(label);
},
_applyLabel: function(label, action, idx, dir, str) {
if (str != null) {
label.set_text(str);
let [found, x, y, arrangement] = this.getLabelCoords(action, idx, dir);
this._allocateChild(label, x, y, arrangement);
}
label.show();
},
stopEdition: function (continues, str) {
this._editorActor.hide();
if (this._prevEdited) {
let [label, action, idx, dir] = this._prevEdited;
this._applyLabel(label, action, idx, dir, str);
this._prevEdited = null;
}
if (this._curEdited) {
let [label, action, idx, dir] = this._curEdited;
this._applyLabel(label, action, idx, dir, str);
if (continues)
this._prevEdited = this._curEdited;
this._curEdited = null;
}
},
startEdition: function(action, idx, dir) {
let editedLabel;
if (this._curEdited)
return;
for (let i = 0; i < this._labels.length; i++) {
let [label, itemAction, itemIdx, itemDir] = this._labels[i];
if (action == itemAction && idx == itemIdx && dir == itemDir) {
this._curEdited = this._labels[i];
editedLabel = label;
break;
}
}
if (this._curEdited == null)
return;
let [found] = this.getLabelCoords(action, idx, dir);
if (!found)
return;
this._editorActor.show();
editedLabel.hide();
}
});
const PadOsd = new Lang.Class({
Name: 'PadOsd',
_init: function (padDevice, settings, imagePath, editionMode, monitorIndex) {
this.padDevice = padDevice;
this._groupPads = [ padDevice ];
this._settings = settings;
this._imagePath = imagePath;
this._editionMode = editionMode;
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
this._padChooser = null;
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) {
// If the device is being removed, destroy the padOsd.
if (device == this.padDevice) {
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',
x_expand: true,
y_expand: true,
vertical: true,
reactive: true });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
Main.uiGroup.add_actor(this.actor);
this._monitorIndex = monitorIndex;
let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
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;',
x_align: Clutter.ActorAlign.CENTER });
this._titleLabel.clutter_text.set_text(padDevice.get_device_name());
labelBox.add_actor(this._titleLabel);
this._tipLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER });
labelBox.add_actor(this._tipLabel);
this._updatePadChooser();
this._actionEditor = new ActionEditor();
this._actionEditor.connect('done', Lang.bind(this, this._endActionEdition));
this._padDiagram = new PadDiagram({ image: this._imagePath,
left_handed: settings.get_boolean('left-handed'),
editor_actor: this._actionEditor.actor,
x_expand: true,
y_expand: true });
this.actor.add_actor(this._padDiagram);
// FIXME: Fix num buttons.
let i = 0;
for (i = 0; i < 50; i++) {
let [found] = this._padDiagram.getButtonLabelCoords(i);
if (!found)
break;
this._createLabel(Meta.PadActionType.BUTTON, i);
}
for (i = 0; i < padDevice.get_n_rings(); i++) {
let [found] = this._padDiagram.getRingLabelCoords(i, CW);
if (!found)
break;
this._createLabel(Meta.PadActionType.RING, i, CW);
this._createLabel(Meta.PadActionType.RING, i, CCW);
}
for (i = 0; i < padDevice.get_n_strips(); i++) {
let [found] = this._padDiagram.getStripLabelCoords(i, UP);
if (!found)
break;
this._createLabel(Meta.PadActionType.STRIP, i, UP);
this._createLabel(Meta.PadActionType.STRIP, i, DOWN);
}
let buttonBox = new St.Widget({ layout_manager: new Clutter.BinLayout(),
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
this.actor.add_actor(buttonBox);
this._editButton = new St.Button({ label: _("Edit…"),
style_class: 'button',
x_align: Clutter.ActorAlign.CENTER,
can_focus: true });
this._editButton.connect('clicked', Lang.bind(this, function () { this.setEditionMode(true) }));
buttonBox.add_actor(this._editButton);
this._syncEditionMode();
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) {
let str = global.display.get_pad_action_label(this.padDevice, type, number);
let label = new St.Label({ text: str ? str : _("None") });
this._padDiagram.addLabel(label, type, number, dir);
},
_onCapturedEvent : function (actor, event) {
if (event.type() == Clutter.EventType.PAD_BUTTON_PRESS &&
event.get_source_device() == this.padDevice) {
this._padDiagram.activateButton(event.get_button());
let isModeSwitch = this.padDevice.get_mode_switch_button_group(event.get_button()) >= 0;
/* Buttons that switch between modes cannot be edited */
if (this._editionMode && !isModeSwitch)
this._startButtonActionEdition(event.get_button());
return Clutter.EVENT_STOP;
} else if (event.type() == Clutter.EventType.PAD_BUTTON_RELEASE &&
event.get_source_device() == this.padDevice) {
this._padDiagram.deactivateButton(event.get_button());
return Clutter.EVENT_STOP;
} else if (event.type() == Clutter.EventType.KEY_PRESS &&
(!this._editionMode || event.get_key_symbol() == Clutter.Escape)) {
if (this._editedAction != null)
this._endActionEdition();
else
this.destroy();
return Clutter.EVENT_STOP;
} else if (event.get_source_device() == this.padDevice &&
event.type() == Clutter.EventType.PAD_STRIP) {
if (this._editionMode) {
let [retval, number, mode] = event.get_pad_event_details();
this._startStripActionEdition(number, UP, mode);
}
} else if (event.get_source_device() == this.padDevice &&
event.type() == Clutter.EventType.PAD_RING) {
if (this._editionMode) {
let [retval, number, mode] = event.get_pad_event_details();
this._startRingActionEdition(number, CCW, mode);
}
}
// 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;
},
_syncEditionMode: function () {
this._editButton.set_reactive(!this._editionMode);
this._editButton.save_easing_state();
this._editButton.set_easing_duration(200);
this._editButton.set_opacity(this._editionMode ? 128 : 255);
this._editButton.restore_easing_state();
let title;
if (this._editionMode) {
title = _("Press a button to configure");
this._tipLabel.set_text(_("Press Esc to exit"));
} else {
title = this.padDevice.get_device_name();
this._tipLabel.set_text(_("Press any key to exit"));
}
this._titleLabel.clutter_text.set_markup('<span size="larger"><b>' + title + '</b></span>');
},
_isEditedAction: function (type, number, dir) {
if (!this._editedAction)
return false;
return (this._editedAction.type == type &&
this._editedAction.number == number &&
this._editedAction.dir == dir);
},
_followUpActionEdition: function (str) {
let { type, dir, number, mode } = this._editedAction;
let hasNextAction = (type == Meta.PadActionType.RING && dir == CCW ||
type == Meta.PadActionType.STRIP && dir == UP);
if (!hasNextAction)
return false;
this._padDiagram.stopEdition(true, str);
this._editedAction = null;
if (type == Meta.PadActionType.RING)
this._startRingActionEdition(number, CW, mode);
else
this._startStripActionEdition(number, DOWN, mode);
return true;
},
_endActionEdition: function () {
this._actionEditor.close();
if (this._editedAction != null) {
let str = global.display.get_pad_action_label(this.padDevice,
this._editedAction.type,
this._editedAction.number);
if (this._followUpActionEdition(str))
return;
this._padDiagram.stopEdition(false, str ? str : _("None"))
this._editedAction = null;
}
this._editedActionSettings = null;
},
_startActionEdition: function (key, type, number, dir, mode) {
if (this._isEditedAction(type, number, dir))
return;
this._endActionEdition();
this._editedAction = { type, number, dir, mode };
let settingsPath = this._settings.path + key + '/';
this._editedActionSettings = Gio.Settings.new_with_path('org.gnome.desktop.peripherals.tablet.pad-button',
settingsPath);
this._actionEditor.setSettings(this._editedActionSettings, type);
this._padDiagram.startEdition(type, number, dir);
},
_startButtonActionEdition: function (button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let key = 'button' + ch;
this._startActionEdition(key, Meta.PadActionType.BUTTON, button);
},
_startRingActionEdition: function (ring, dir, mode) {
let ch = String.fromCharCode('A'.charCodeAt() + ring);
let key = 'ring%s-%s-mode-%d'.format(ch, dir == CCW ? 'ccw' : 'cw', mode);
this._startActionEdition(key, Meta.PadActionType.RING, ring, dir, mode);
},
_startStripActionEdition: function (strip, dir, mode) {
let ch = String.fromCharCode('A'.charCodeAt() + strip);
let key = 'strip%s-%s-mode-%d'.format(ch, dir == UP ? 'up' : 'down', mode);
this._startActionEdition(key, Meta.PadActionType.STRIP, strip, dir, mode);
},
setEditionMode: function (editionMode) {
if (this._editionMode == editionMode)
return;
this._editionMode = editionMode;
this._syncEditionMode();
},
destroy: function () {
this.actor.destroy();
},
_onDestroy: function () {
Main.popModal(this.actor);
this._actionEditor.close();
let deviceManager = Clutter.DeviceManager.get_default();
if (this._deviceRemovedId != 0) {
deviceManager.disconnect(this._deviceRemovedId);
this._deviceRemovedId = 0;
}
if (this._deviceAddedId != 0) {
deviceManager.disconnect(this._deviceAddedId);
this._deviceAddedId = 0;
}
if (this._capturedEventId != 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
this.actor = null;
this.emit('closed');
}
});
Signals.addSignalMethods(PadOsd.prototype);
const PadOsdIface = '<node> \
<interface name="org.gnome.Shell.Wacom.PadOsd"> \
<method name="Show"> \
<arg name="device_node" direction="in" type="o"/> \
<arg name="edition_mode" direction="in" type="b"/> \
</method> \
</interface> \
</node>';
const PadOsdService = new Lang.Class({
Name: 'PadOsdService',
_init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(PadOsdIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Wacom');
Gio.DBus.session.own_name('org.gnome.Shell.Wacom.PadOsd', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
ShowAsync: function(params, invocation) {
let [deviceNode, editionMode] = params;
let deviceManager = Clutter.DeviceManager.get_default();
let devices = deviceManager.list_devices();
let padDevice = null;
devices.forEach(Lang.bind(this, function(device) {
if (deviceNode == device.get_device_node())
padDevice = device;
}));
if (padDevice == null ||
padDevice.get_device_type() != Clutter.InputDeviceType.PAD_DEVICE) {
invocation.return_error_literal(Gio.IOErrorEnum,
Gio.IOErrorEnum.CANCELLED,
"Invalid params");
return;
}
global.display.request_pad_osd(padDevice, editionMode);
invocation.return_value(null);
}
});
Signals.addSignalMethods(PadOsdService.prototype);

View File

@ -719,11 +719,9 @@ 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);
} }
@ -747,7 +745,6 @@ 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);
@ -1104,7 +1101,7 @@ const Panel = new Lang.Class({
}, },
_onMenuSet: function(indicator) { _onMenuSet: function(indicator) {
if (!indicator.menu || indicator.menu.hasOwnProperty('_openChangedId')) if (!indicator.menu || indicator.menu._openChangedId > 0)
return; return;
indicator.menu._openChangedId = indicator.menu.connect('open-state-changed', indicator.menu._openChangedId = indicator.menu.connect('open-state-changed',

View File

@ -174,14 +174,8 @@ 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() {

View File

@ -605,24 +605,6 @@ 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) {
@ -785,11 +767,6 @@ 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:
@ -806,16 +783,6 @@ const PopupMenu = new Lang.Class({
break; break;
} }
let state = event.get_state();
// if user has a modifier down (except capslock)
// then don't handle the key press here
state &= ~Clutter.ModifierType.LOCK_MASK;
state &= Clutter.ModifierType.MODIFIER_MASK;
if (state)
return Clutter.EVENT_PROPAGATE;
let symbol = event.get_key_symbol(); let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) { if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.toggle(); this.toggle();

View File

@ -192,10 +192,6 @@ const RemoteMenu = new Lang.Class({
_removeItem.bind(null, this)); _removeItem.bind(null, this));
}, },
get actionGroup() {
return this._actionGroup;
},
destroy: function() { destroy: function() {
this._tracker.destroy(); this._tracker.destroy();
this.parent(); this.parent();

View File

@ -200,7 +200,6 @@ const RemoteSearchProvider = new Lang.Class({
this.appInfo = appInfo; this.appInfo = appInfo;
this.id = appInfo.get_id(); this.id = appInfo.get_id();
this.isRemoteProvider = true; this.isRemoteProvider = true;
this.canLaunchSearch = false;
}, },
createIcon: function(size, meta) { createIcon: function(size, meta) {
@ -279,8 +278,7 @@ 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);
}, },
@ -299,7 +297,7 @@ const RemoteSearchProvider = new Lang.Class({
// the provider is not compatible with the new version of the interface, launch // the provider is not compatible with the new version of the interface, launch
// the app itself but warn so we can catch the error in logs // the app itself but warn so we can catch the error in logs
log('Search provider ' + this.appInfo.get_id() + ' does not implement LaunchSearch'); log('Search provider ' + this.appInfo.get_id() + ' does not implement LaunchSearch');
this.appInfo.launch([], global.create_app_launch_context(0, -1), false); this.appInfo.launch([], global.create_app_launch_context(0, -1));
} }
}); });

View File

@ -274,7 +274,7 @@ const RunDialog = new Lang.Class({
_restart: function() { _restart: function() {
if (Meta.is_wayland_compositor()) { if (Meta.is_wayland_compositor()) {
this._showError(_("Restart is not available on Wayland")); this._showError('Restart is not available on Wayland');
return; return;
} }
this._shouldFadeOut = false; this._shouldFadeOut = false;

View File

@ -33,9 +33,6 @@ 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
@ -352,6 +349,7 @@ const Arrow = new Lang.Class({
_init: function(params) { _init: function(params) {
this.parent(params); this.parent(params);
this.x_fill = this.y_fill = true; this.x_fill = this.y_fill = true;
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
this._drawingArea = new St.DrawingArea(); this._drawingArea = new St.DrawingArea();
this._drawingArea.connect('repaint', Lang.bind(this, this._drawArrow)); this._drawingArea.connect('repaint', Lang.bind(this, this._drawArrow));
@ -379,22 +377,6 @@ const Arrow = new Lang.Class({
cr.$dispose(); cr.$dispose();
}, },
vfunc_get_paint_volume: function(volume) {
if (!this.parent(volume))
return false;
if (!this._shadow)
return true;
let shadow_box = new Clutter.ActorBox();
this._shadow.get_box(this._drawingArea.get_allocation_box(), shadow_box);
volume.set_width(Math.max(shadow_box.x2 - shadow_box.x1, volume.get_width()));
volume.set_height(Math.max(shadow_box.y2 - shadow_box.y1, volume.get_height()));
return true;
},
vfunc_style_changed: function() { vfunc_style_changed: function() {
let node = this.get_theme_node(); let node = this.get_theme_node();
this._shadow = node.get_shadow('-arrow-shadow'); this._shadow = node.get_shadow('-arrow-shadow');
@ -402,8 +384,6 @@ const Arrow = new Lang.Class({
this._shadowHelper = St.ShadowHelper.new(this._shadow); this._shadowHelper = St.ShadowHelper.new(this._shadow);
else else
this._shadowHelper = null; this._shadowHelper = null;
this.parent();
}, },
vfunc_paint: function() { vfunc_paint: function() {
@ -544,9 +524,6 @@ 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;
@ -582,9 +559,6 @@ const ScreenShield = new Lang.Class({
if (prevIsActive != this._isActive) if (prevIsActive != this._isActive)
this.emit('active-changed'); this.emit('active-changed');
if (this._loginSession)
this._loginSession.SetLockedHintRemote(active);
this._syncInhibitor(); this._syncInhibitor();
}, },
@ -671,10 +645,7 @@ const ScreenShield = new Lang.Class({
let isEnter = (symbol == Clutter.KEY_Return || let isEnter = (symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter || symbol == Clutter.KEY_KP_Enter ||
symbol == Clutter.KEY_ISO_Enter); symbol == Clutter.KEY_ISO_Enter);
let isEscape = (symbol == Clutter.KEY_Escape); if (!isEnter && !(GLib.unichar_isprint(unichar) || symbol == Clutter.KEY_Escape))
let isLiftChar = (GLib.unichar_isprint(unichar) &&
(this._isLocked || !GLib.unichar_isgraph(unichar)));
if (!isEnter && !isEscape && !isLiftChar)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
if (this._isLocked && if (this._isLocked &&
@ -707,10 +678,8 @@ 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 && lockEnabled && !lockLocked); !this._isActive && this._settings.get_boolean(LOCK_ENABLED_KEY));
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) {
@ -739,7 +708,7 @@ const ScreenShield = new Lang.Class({
let unitaryDelay = ARROW_ANIMATION_TIME / (arrows.length + 1); let unitaryDelay = ARROW_ANIMATION_TIME / (arrows.length + 1);
let maxOpacity = 255 * ARROW_ANIMATION_PEAK_OPACITY; let maxOpacity = 255 * ARROW_ANIMATION_PEAK_OPACITY;
for (let i = 0; i < arrows.length; i++) { for (let i = 0; i < arrows.length; i++) {
arrows[i].opacity = 0; arrows.opacity = 0;
Tweener.addTween(arrows[i], Tweener.addTween(arrows[i],
{ opacity: 0, { opacity: 0,
delay: unitaryDelay * (N_ARROWS - (i + 1)), delay: unitaryDelay * (N_ARROWS - (i + 1)),
@ -858,7 +827,6 @@ const ScreenShield = new Lang.Class({
}, },
_activateFade: function(lightbox, time) { _activateFade: function(lightbox, time) {
Main.uiGroup.set_child_above_sibling(lightbox.actor, null);
lightbox.show(time); lightbox.show(time);
if (this._becameActiveId == 0) if (this._becameActiveId == 0)
@ -1298,11 +1266,6 @@ 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"),

View File

@ -152,8 +152,6 @@ 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();
}, },
@ -183,8 +181,6 @@ 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();
}, },

View File

@ -142,15 +142,15 @@ const GnomeShell = new Lang.Class({
for (let param in params) for (let param in params)
params[param] = params[param].deep_unpack(); params[param] = params[param].deep_unpack();
let monitorIndex = params['monitor'] || -1; let monitorIndex = -1;
let label = params['label'] || undefined; if (params['monitor'] >= 0)
let level = params['level'] || undefined; monitorIndex = params['monitor'];
let icon = null; let icon = null;
if (params['icon']) if (params['icon'])
icon = Gio.Icon.new_for_string(params['icon']); icon = Gio.Icon.new_for_string(params['icon']);
Main.osdWindowManager.show(monitorIndex, icon, label, level); Main.osdWindowManager.show(monitorIndex, icon, params['label'], params['level']);
}, },
FocusApp: function(id) { FocusApp: function(id) {

View File

@ -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 didnt 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();

View File

@ -102,8 +102,8 @@ const ATIndicator = new Lang.Class({
if (this._syncMenuVisibilityIdle) if (this._syncMenuVisibilityIdle)
return; return;
this._syncMenuVisibilityIdle = Mainloop.idle_add(Lang.bind(this, this._syncMenuVisibility)); this._syncMenuVisbilityIdle = Mainloop.idle_add(Lang.bind(this, this._syncMenuVisibility));
GLib.Source.set_name_by_id(this._syncMenuVisibilityIdle, '[gnome-shell] this._syncMenuVisibility'); GLib.Source.set_name_by_id(this._syncMenuVisbilityIdle, '[gnome-shell] this._syncMenuVisibility');
}, },
_buildItemExtended: function(string, initial_value, writable, on_set) { _buildItemExtended: function(string, initial_value, writable, on_set) {

View File

@ -137,7 +137,7 @@ const Indicator = new Lang.Class({
else if (nConnectedDevices == -1) else if (nConnectedDevices == -1)
this._item.label.text = _("Off"); this._item.label.text = _("Off");
else else
this._item.label.text = _("On"); this._item.label.text = _("Not In Use");
this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off"); this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off");
}, },

View File

@ -61,8 +61,8 @@ const InputSource = new Lang.Class({
this.emit('changed'); this.emit('changed');
}, },
activate: function(interactive) { activate: function() {
this.emit('activate', !!interactive); this.emit('activate');
}, },
_getXkbId: function() { _getXkbId: function() {
@ -109,7 +109,7 @@ const InputSourcePopup = new Lang.Class({
_finish : function() { _finish : function() {
this.parent(); this.parent();
this._items[this._selectedIndex].activate(true); this._items[this._selectedIndex].activate();
}, },
}); });
@ -159,14 +159,6 @@ const InputSourceSettings = new Lang.Class({
return []; return [];
}, },
get mruSources() {
return [];
},
set mruSources(sourcesList) {
// do nothing
},
get keyboardOptions() { get keyboardOptions() {
return []; return [];
}, },
@ -259,7 +251,6 @@ const InputSourceSessionSettings = new Lang.Class({
_DESKTOP_INPUT_SOURCES_SCHEMA: 'org.gnome.desktop.input-sources', _DESKTOP_INPUT_SOURCES_SCHEMA: 'org.gnome.desktop.input-sources',
_KEY_INPUT_SOURCES: 'sources', _KEY_INPUT_SOURCES: 'sources',
_KEY_MRU_SOURCES: 'mru-sources',
_KEY_KEYBOARD_OPTIONS: 'xkb-options', _KEY_KEYBOARD_OPTIONS: 'xkb-options',
_KEY_PER_WINDOW: 'per-window', _KEY_PER_WINDOW: 'per-window',
@ -270,9 +261,9 @@ const InputSourceSessionSettings = new Lang.Class({
this._settings.connect('changed::' + this._KEY_PER_WINDOW, Lang.bind(this, this._emitPerWindowChanged)); this._settings.connect('changed::' + this._KEY_PER_WINDOW, Lang.bind(this, this._emitPerWindowChanged));
}, },
_getSourcesList: function(key) { get inputSources() {
let sourcesList = []; let sourcesList = [];
let sources = this._settings.get_value(key); let sources = this._settings.get_value(this._KEY_INPUT_SOURCES);
let nSources = sources.n_children(); let nSources = sources.n_children();
for (let i = 0; i < nSources; i++) { for (let i = 0; i < nSources; i++) {
@ -282,19 +273,6 @@ const InputSourceSessionSettings = new Lang.Class({
return sourcesList; return sourcesList;
}, },
get inputSources() {
return this._getSourcesList(this._KEY_INPUT_SOURCES);
},
get mruSources() {
return this._getSourcesList(this._KEY_MRU_SOURCES);
},
set mruSources(sourcesList) {
let sources = GLib.Variant.new('a(ss)', sourcesList);
this._settings.set_value(this._KEY_MRU_SOURCES, sources);
},
get keyboardOptions() { get keyboardOptions() {
return this._settings.get_strv(this._KEY_KEYBOARD_OPTIONS); return this._settings.get_strv(this._KEY_KEYBOARD_OPTIONS);
}, },
@ -394,7 +372,7 @@ const InputSourceManager = new Lang.Class({
while (!(is = this._inputSources[nextIndex])) while (!(is = this._inputSources[nextIndex]))
nextIndex += 1; nextIndex += 1;
is.activate(true); is.activate();
return true; return true;
}, },
@ -422,25 +400,6 @@ const InputSourceManager = new Lang.Class({
this._keyboardManager.reapply(); this._keyboardManager.reapply();
}, },
_updateMruSettings: function() {
// If IBus is not ready we don't have a full picture of all
// the available sources, so don't update the setting
if (!this._ibusReady)
return;
// If IBus is temporarily disabled, don't update the setting
if (this._disableIBus)
return;
let sourcesList = [];
for (let i = 0; i < this._mruSources.length; ++i) {
let source = this._mruSources[i];
sourcesList.push([source.type, source.id]);
}
this._settings.mruSources = sourcesList;
},
_currentInputSourceChanged: function(newSource) { _currentInputSourceChanged: function(newSource) {
let oldSource; let oldSource;
[oldSource, this._currentSource] = [this._currentSource, newSource]; [oldSource, this._currentSource] = [this._currentSource, newSource];
@ -457,7 +416,7 @@ const InputSourceManager = new Lang.Class({
this._changePerWindowSource(); this._changePerWindowSource();
}, },
_activateInputSource: function(is, interactive) { _activateInputSource: function(is) {
KeyboardManager.holdKeyboard(); KeyboardManager.holdKeyboard();
this._keyboardManager.apply(is.xkbId); this._keyboardManager.apply(is.xkbId);
@ -475,54 +434,6 @@ const InputSourceManager = new Lang.Class({
this._ibusManager.setEngine(engine, KeyboardManager.releaseKeyboard); this._ibusManager.setEngine(engine, KeyboardManager.releaseKeyboard);
this._currentInputSourceChanged(is); this._currentInputSourceChanged(is);
if (interactive)
this._updateMruSettings();
},
_updateMruSources: function() {
let sourcesList = [];
for (let i in this._inputSources)
sourcesList.push(this._inputSources[i]);
this._keyboardManager.setUserLayouts(sourcesList.map(function(x) { return x.xkbId; }));
if (!this._disableIBus && this._mruSourcesBackup) {
this._mruSources = this._mruSourcesBackup;
this._mruSourcesBackup = null;
}
// Initialize from settings when we have no MRU sources list
if (this._mruSources.length == 0) {
let mruSettings = this._settings.mruSources;
for (let i = 0; i < mruSettings.length; i++) {
let mruSettingSource = mruSettings[i];
let mruSource = null;
for (let j = 0; j < sourcesList.length; j++) {
let source = sourcesList[j];
if (source.type == mruSettingSource.type &&
source.id == mruSettingSource.id) {
mruSource = source;
break;
}
}
if (mruSource)
this._mruSources.push(mruSource);
}
}
let mruSources = [];
for (let i = 0; i < this._mruSources.length; i++) {
for (let j = 0; j < sourcesList.length; j++)
if (this._mruSources[i].type == sourcesList[j].type &&
this._mruSources[i].id == sourcesList[j].id) {
mruSources = mruSources.concat(sourcesList.splice(j, 1));
break;
}
}
this._mruSources = mruSources.concat(sourcesList);
}, },
_inputSourcesChanged: function() { _inputSourcesChanged: function() {
@ -599,10 +510,30 @@ const InputSourceManager = new Lang.Class({
this.emit('sources-changed'); this.emit('sources-changed');
this._updateMruSources(); let sourcesList = [];
for (let i in this._inputSources)
sourcesList.push(this._inputSources[i]);
this._keyboardManager.setUserLayouts(sourcesList.map(function(x) { return x.xkbId; }));
if (!this._disableIBus && this._mruSourcesBackup) {
this._mruSources = this._mruSourcesBackup;
this._mruSourcesBackup = null;
}
let mruSources = [];
for (let i = 0; i < this._mruSources.length; i++) {
for (let j = 0; j < sourcesList.length; j++)
if (this._mruSources[i].type == sourcesList[j].type &&
this._mruSources[i].id == sourcesList[j].id) {
mruSources = mruSources.concat(sourcesList.splice(j, 1));
break;
}
}
this._mruSources = mruSources.concat(sourcesList);
if (this._mruSources.length > 0) if (this._mruSources.length > 0)
this._mruSources[0].activate(false); this._mruSources[0].activate();
// All ibus engines are preloaded here to reduce the launching time // All ibus engines are preloaded here to reduce the launching time
// when users switch the input sources. // when users switch the input sources.
@ -711,7 +642,7 @@ const InputSourceManager = new Lang.Class({
} }
if (window._currentSource) if (window._currentSource)
window._currentSource.activate(false); window._currentSource.activate();
}, },
_sourcesPerWindowChanged: function() { _sourcesPerWindowChanged: function() {
@ -832,10 +763,7 @@ const InputSourceIndicator = new Lang.Class({
let is = this._inputSourceManager.inputSources[i]; let is = this._inputSourceManager.inputSources[i];
let menuItem = new LayoutMenuItem(is.displayName, is.shortName); let menuItem = new LayoutMenuItem(is.displayName, is.shortName);
menuItem.connect('activate', function() { menuItem.connect('activate', Lang.bind(is, is.activate));
is.activate(true);
});
let indicatorLabel = new St.Label({ text: is.shortName, let indicatorLabel = new St.Label({ text: is.shortName,
visible: false }); visible: false });

View File

@ -9,7 +9,6 @@ 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;
@ -63,6 +62,26 @@ var AgentIface = '<node> \
</interface> \ </interface> \
</node>'; </node>';
var XdgAppIface = '<node> \
<interface name="org.freedesktop.XdgApp.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(XdgAppIface);
const Indicator = new Lang.Class({ const Indicator = new Lang.Class({
Name: 'LocationIndicator', Name: 'LocationIndicator',
Extends: PanelMenu.SystemIndicator, Extends: PanelMenu.SystemIndicator,
@ -234,7 +253,10 @@ const Indicator = new Lang.Class({
_connectToPermissionStore: function() { _connectToPermissionStore: function() {
this._permStoreProxy = null; this._permStoreProxy = null;
new PermissionStore.PermissionStore(Lang.bind(this, this._onPermStoreProxyReady), null); new PermissionStore(Gio.DBus.session,
'org.freedesktop.XdgApp',
'/org/freedesktop/XdgApp/PermissionStore',
Lang.bind(this, this._onPermStoreProxyReady));
}, },
_onPermStoreProxyReady: function(proxy, error) { _onPermStoreProxyReady: function(proxy, error) {
@ -262,7 +284,6 @@ 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;
}, },

View File

@ -5,7 +5,6 @@ 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 Lang = imports.lang; const Lang = imports.lang;
const Mainloop = imports.mainloop;
const NetworkManager = imports.gi.NetworkManager; const NetworkManager = imports.gi.NetworkManager;
const NMClient = imports.gi.NMClient; const NMClient = imports.gi.NMClient;
const NMGtk = imports.gi.NMGtk; const NMGtk = imports.gi.NMGtk;
@ -40,8 +39,6 @@ const NMAccessPointSecurity = {
WPA2_ENT: 6 WPA2_ENT: 6
}; };
const MAX_DEVICE_ITEMS = 4;
// small optimization, to avoid using [] all the time // small optimization, to avoid using [] all the time
const NM80211Mode = NetworkManager['80211Mode']; const NM80211Mode = NetworkManager['80211Mode'];
const NM80211ApFlags = NetworkManager['80211ApFlags']; const NM80211ApFlags = NetworkManager['80211ApFlags'];
@ -299,22 +296,11 @@ 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)
this._updateForConnection(item, connection); item.updateForConnection(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)
@ -635,7 +621,7 @@ const NMDeviceBluetooth = new Lang.Class({
_init: function(client, device, settings) { _init: function(client, device, settings) {
this.parent(client, device, settings); this.parent(client, device, settings);
this.item.menu.addMenuItem(createSettingsAction(_("Bluetooth Settings"), device)); this.item.menu.addMenuItem(createSettingsAction(_("Mobile Broadband Settings"), device));
}, },
_getDescription: function() { _getDescription: function() {
@ -643,7 +629,7 @@ const NMDeviceBluetooth = new Lang.Class({
}, },
getConnectLabel: function() { getConnectLabel: function() {
return _("Connect to Internet"); return _("Use as Internet connection");
}, },
getIndicatorIcon: function() { getIndicatorIcon: function() {
@ -766,17 +752,10 @@ const NMWirelessDialog = new Lang.Class({
this._updateSensitivity(); this._updateSensitivity();
this._syncView(); this._syncView();
this._scanTimeoutId = Mainloop.timeout_add_seconds(15, Lang.bind(this, this._onScanTimeout)); if (accessPoints.length == 0) {
GLib.Source.set_name_by_id(this._scanTimeoutId, '[gnome-shell] this._onScanTimeout'); /* If there are no visible access points, request a scan */
this._onScanTimeout(); this._device.request_scan_simple(null);
}
let id = Main.sessionMode.connect('updated', () => {
if (Main.sessionMode.allowSettings)
return;
Main.sessionMode.disconnect(id);
this.close();
});
}, },
destroy: function() { destroy: function() {
@ -801,19 +780,9 @@ const NMWirelessDialog = new Lang.Class({
this._airplaneModeChangedId = 0; this._airplaneModeChangedId = 0;
} }
if (this._scanTimeoutId) {
Mainloop.source_remove(this._scanTimeoutId);
this._scanTimeoutId = 0;
}
this.parent(); this.parent();
}, },
_onScanTimeout: function() {
this._device.request_scan_simple(null);
return GLib.SOURCE_CONTINUE;
},
_activeApChanged: function() { _activeApChanged: function() {
if (this._activeNetwork) if (this._activeNetwork)
this._activeNetwork.item.setActive(false); this._activeNetwork.item.setActive(false);
@ -1362,11 +1331,7 @@ const NMDeviceWireless = new Lang.Class({
if (!this._device.active_connection) if (!this._device.active_connection)
return false; return false;
let connectionPath = this._device.active_connection.connection; let connection = this._settings.get_connection_by_path(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;
@ -1443,7 +1408,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");
@ -1526,7 +1491,7 @@ const NMVPNSection = new Lang.Class({
if (nItems > 1) { if (nItems > 1) {
let appSys = Shell.AppSystem.get_default(); let appSys = Shell.AppSystem.get_default();
let app = appSys.lookup_app('gnome-network-panel.desktop'); let app = appSys.lookup_app('gnome-network-panel.desktop');
app.launch(0, -1, false); app.launch(0, -1);
} else { } else {
let connection = this._connections[0]; let connection = this._connections[0];
Util.spawnApp(['gnome-control-center', 'network', 'show-device', Util.spawnApp(['gnome-control-center', 'network', 'show-device',
@ -1566,10 +1531,8 @@ 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) {
if (a._connection) {
let item = this._connectionItems.get(a._connection.get_uuid()); let item = this._connectionItems.get(a._connection.get_uuid());
item.setActiveConnection(a); item.setActiveConnection(a);
}
})); }));
}, },
@ -1589,73 +1552,6 @@ const NMVPNSection = new Lang.Class({
}); });
Signals.addSignalMethods(NMVPNSection.prototype); Signals.addSignalMethods(NMVPNSection.prototype);
const DeviceCategory = new Lang.Class({
Name: 'DeviceCategory',
Extends: PopupMenu.PopupMenuSection,
_init: function(category) {
this.parent();
this._category = category;
this.devices = [];
this.section = new PopupMenu.PopupMenuSection();
this.section.box.connect('actor-added', Lang.bind(this, this._sync));
this.section.box.connect('actor-removed', Lang.bind(this, this._sync));
this.addMenuItem(this.section);
this._summaryItem = new PopupMenu.PopupSubMenuMenuItem('', true);
this._summaryItem.icon.icon_name = this._getSummaryIcon();
this.addMenuItem(this._summaryItem);
this._summaryItem.menu.addSettingsAction(_('Network Settings'),
'gnome-network-panel.desktop');
this._summaryItem.actor.hide();
},
_sync: function() {
let nDevices = this.section.box.get_children().reduce(
function(prev, child) {
return prev + (child.visible ? 1 : 0);
}, 0);
this._summaryItem.label.text = this._getSummaryLabel(nDevices);
let shouldSummarize = nDevices > MAX_DEVICE_ITEMS;
this._summaryItem.actor.visible = shouldSummarize;
this.section.actor.visible = !shouldSummarize;
},
_getSummaryIcon: function() {
switch(this._category) {
case NMConnectionCategory.WIRED:
return 'network-wired-symbolic';
case NMConnectionCategory.WIRELESS:
case NMConnectionCategory.WWAN:
return 'network-wireless-symbolic';
}
return '';
},
_getSummaryLabel: function(nDevices) {
switch(this._category) {
case NMConnectionCategory.WIRED:
return ngettext("%s Wired Connection",
"%s Wired Connections",
nDevices).format(nDevices);
case NMConnectionCategory.WIRELESS:
return ngettext("%s Wi-Fi Connection",
"%s Wi-Fi Connections",
nDevices).format(nDevices);
case NMConnectionCategory.WWAN:
return ngettext("%s Modem Connection",
"%s Modem Connections",
nDevices).format(nDevices);
}
return '';
}
});
const NMApplet = new Lang.Class({ const NMApplet = new Lang.Class({
Name: 'NMApplet', Name: 'NMApplet',
Extends: PanelMenu.SystemIndicator, Extends: PanelMenu.SystemIndicator,
@ -1699,6 +1595,15 @@ const NMApplet = new Lang.Class({
this._tryLateInit(); this._tryLateInit();
}, },
_createDeviceCategory: function() {
let category = {
section: new PopupMenu.PopupMenuSection(),
devices: [ ],
};
this.menu.addMenuItem(category.section);
return category;
},
_tryLateInit: function() { _tryLateInit: function() {
if (!this._client || !this._settings) if (!this._client || !this._settings)
return; return;
@ -1709,20 +1614,15 @@ const NMApplet = new Lang.Class({
this._mainConnection = null; this._mainConnection = null;
this._mainConnectionIconChangedId = 0; this._mainConnectionIconChangedId = 0;
this._mainConnectionStateChangedId = 0;
this._notification = null; this._notification = null;
this._nmDevices = []; this._nmDevices = [];
this._devices = { }; this._devices = { };
let categories = [NMConnectionCategory.WIRED, this._devices.wired = this._createDeviceCategory();
NMConnectionCategory.WIRELESS, this._devices.wireless = this._createDeviceCategory();
NMConnectionCategory.WWAN]; this._devices.wwan = this._createDeviceCategory();
for (let category of categories) {
this._devices[category] = new DeviceCategory(category);
this.menu.addMenuItem(this._devices[category]);
}
this._vpnSection = new NMVPNSection(this._client); this._vpnSection = new NMVPNSection(this._client);
this._vpnSection.connect('activation-failed', Lang.bind(this, this._onActivationFailed)); this._vpnSection.connect('activation-failed', Lang.bind(this, this._onActivationFailed));
@ -1732,8 +1632,6 @@ const NMApplet = new Lang.Class({
this._readConnections(); this._readConnections();
this._readDevices(); this._readDevices();
this._syncNMState(); this._syncNMState();
this._syncMainConnection();
this._syncVPNConnections();
this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState)); this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState)); this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
@ -2079,7 +1977,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 || Main.sessionMode.isGreeter) if (!isPortal)
return; return;
let path = this._mainConnection.get_path(); let path = this._mainConnection.get_path();
@ -2110,24 +2008,13 @@ const NMApplet = new Lang.Class({
}, },
_updateIcon: function() { _updateIcon: function() {
if (!this._client.networking_enabled) { if (!this._client.networking_enabled || !this._mainConnection) {
this._primaryIndicator.visible = false; this._primaryIndicator.visible = false;
} else { } else {
let dev = null; let dev = this._mainConnection._primaryDevice;
if (this._mainConnection) this._primaryIndicator.visible = (dev != null);
dev = this._mainConnection._primaryDevice; if (dev)
let state = this._client.get_state();
let connected = state == NetworkManager.State.CONNECTED_GLOBAL;
this._primaryIndicator.visible = (dev != null) || connected;
if (dev) {
this._primaryIndicator.icon_name = dev.getIndicatorIcon(); this._primaryIndicator.icon_name = dev.getIndicatorIcon();
} else if (connected) {
if (this._client.connectivity == NetworkManager.ConnectivityState.FULL)
this._primaryIndicator.icon_name = 'network-wired-symbolic';
else
this._primaryIndicator.icon_name = 'network-wired-no-route-symbolic';
}
} }
this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon(); this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon();

View File

@ -1,74 +0,0 @@
// -*- 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;
}
});

View File

@ -6,7 +6,6 @@ const Gdm = imports.gi.Gdm;
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 Meta = imports.gi.Meta;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const St = imports.gi.St; const St = imports.gi.St;
@ -42,26 +41,14 @@ const AltSwitcher = new Lang.Class({
_init: function(standard, alternate) { _init: function(standard, alternate) {
this._standard = standard; this._standard = standard;
this._standard.connect('notify::visible', Lang.bind(this, this._sync)); this._standard.connect('notify::visible', Lang.bind(this, this._sync));
if (this._standard instanceof St.Button)
this._standard.connect('clicked',
() => { this._clickAction.release(); });
this._alternate = alternate; this._alternate = alternate;
this._alternate.connect('notify::visible', Lang.bind(this, this._sync)); this._alternate.connect('notify::visible', Lang.bind(this, this._sync));
if (this._alternate instanceof St.Button)
this._alternate.connect('clicked',
() => { this._clickAction.release(); });
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() {
@ -70,9 +57,6 @@ 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;
if (this._flipped)
childToShow = altPressed ? this._standard : this._alternate;
else
childToShow = altPressed ? this._alternate : this._standard; childToShow = altPressed ? this._alternate : this._standard;
} else if (this._standard.visible) { } else if (this._standard.visible) {
childToShow = this._standard; childToShow = this._standard;
@ -80,15 +64,7 @@ const AltSwitcher = new Lang.Class({
childToShow = this._alternate; childToShow = this._alternate;
} }
let childShown = this.actor.get_child(); if (this.actor.get_child() != childToShow) {
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)
@ -119,16 +95,6 @@ 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({
@ -144,7 +110,6 @@ const Indicator = new Lang.Class({
this._session = new GnomeSession.SessionManager(); this._session = new GnomeSession.SessionManager();
this._loginManager = LoginManager.getLoginManager(); this._loginManager = LoginManager.getLoginManager();
this._monitorManager = Meta.MonitorManager.get();
this._haveShutdown = true; this._haveShutdown = true;
this._haveSuspend = true; this._haveSuspend = true;
@ -190,8 +155,6 @@ const Indicator = new Lang.Class({
this._orientationSettings.connect('changed::orientation-lock', this._orientationSettings.connect('changed::orientation-lock',
Lang.bind(this, this._updateOrientationLock)); Lang.bind(this, this._updateOrientationLock));
Main.layoutManager.connect('monitors-changed',
Lang.bind(this, this._updateOrientationLock));
Gio.DBus.system.watch_name(SENSOR_BUS_NAME, Gio.DBus.system.watch_name(SENSOR_BUS_NAME,
Gio.BusNameWatcherFlags.NONE, Gio.BusNameWatcherFlags.NONE,
Lang.bind(this, this._sensorProxyAppeared), Lang.bind(this, this._sensorProxyAppeared),
@ -301,8 +264,7 @@ const Indicator = new Lang.Class({
_updateOrientationLock: function() { _updateOrientationLock: function() {
if (this._sensorProxy) if (this._sensorProxy)
this._orientationLockAction.visible = this._sensorProxy.HasAccelerometer && this._orientationLockAction.visible = this._sensorProxy.HasAccelerometer;
this._monitorManager.get_is_builtin_display_on();
else else
this._orientationLockAction.visible = false; this._orientationLockAction.visible = false;
@ -339,17 +301,14 @@ const Indicator = new Lang.Class({
}, },
_updateHaveSuspend: function() { _updateHaveSuspend: function() {
this._loginManager.canSuspend(Lang.bind(this, this._loginManager.canSuspend(Lang.bind(this, function(result) {
function(canSuspend, needsAuth) { this._haveSuspend = result;
this._haveSuspend = canSuspend;
this._suspendNeedsAuth = needsAuth;
this._updateSuspend(); this._updateSuspend();
})); }));
}, },
_updateSuspend: function() { _updateSuspend: function() {
let disabled = (Main.sessionMode.isLocked && let disabled = Main.sessionMode.isLocked ||
this._suspendNeedsAuth) ||
(Main.sessionMode.isGreeter && (Main.sessionMode.isGreeter &&
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY)); this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
this._suspendAction.visible = this._haveSuspend && !disabled; this._suspendAction.visible = this._haveSuspend && !disabled;

View File

@ -10,7 +10,6 @@ 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;
@ -24,7 +23,6 @@ const EdgeDragAction = imports.ui.edgeDragAction;
const IconGrid = imports.ui.iconGrid; const IconGrid = imports.ui.iconGrid;
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings'; const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
const PINCH_GESTURE_THRESHOLD = 0.7;
const ViewPage = { const ViewPage = {
WINDOWS: 1, WINDOWS: 1,
@ -53,32 +51,9 @@ function getTermsForSearchString(searchString) {
return terms; return terms;
} }
const TouchpadShowOverviewAction = new Lang.Class({
Name: 'TouchpadShowOverviewAction',
_init: function(actor) {
actor.connect('captured-event', Lang.bind(this, this._handleEvent));
},
_handleEvent: function(actor, event) {
if (event.type() != Clutter.EventType.TOUCHPAD_PINCH)
return Clutter.EVENT_PROPAGATE;
if (event.get_touchpad_gesture_finger_count() != 3)
return Clutter.EVENT_PROPAGATE;
if (event.get_gesture_phase() == Clutter.TouchpadGesturePhase.END)
this.emit('activated', event.get_gesture_pinch_scale ());
return Clutter.EVENT_STOP;
}
});
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();
@ -137,6 +112,7 @@ 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',
@ -254,16 +230,11 @@ const ViewSelector = new Lang.Class({
global.stage.add_action(gesture); global.stage.add_action(gesture);
gesture = new ShowOverviewAction(); gesture = new ShowOverviewAction();
gesture.connect('activated', Lang.bind(this, this._pinchGestureActivated)); gesture.connect('activated', Lang.bind(this, function(action, areaDiff) {
global.stage.add_action(gesture); if (areaDiff < 0.7)
gesture = new TouchpadShowOverviewAction(global.stage);
gesture.connect('activated', Lang.bind(this, this._pinchGestureActivated));
},
_pinchGestureActivated: function(action, scale) {
if (scale < PINCH_GESTURE_THRESHOLD)
Main.overview.show(); Main.overview.show();
}));
global.stage.add_action(gesture);
}, },
_toggleAppsPage: function() { _toggleAppsPage: function() {

View File

@ -17,8 +17,6 @@ const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog; 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 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;
@ -34,25 +32,6 @@ 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,
@ -531,7 +510,7 @@ const TouchpadWorkspaceSwitchAction = new Lang.Class({
if (event.type() != Clutter.EventType.TOUCHPAD_SWIPE) if (event.type() != Clutter.EventType.TOUCHPAD_SWIPE)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
if (event.get_touchpad_gesture_finger_count() != 4) if (event.get_gesture_swipe_finger_count() != 4)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
if (event.get_gesture_phase() == Clutter.TouchpadGesturePhase.UPDATE) { if (event.get_gesture_phase() == Clutter.TouchpadGesturePhase.UPDATE) {
@ -555,7 +534,6 @@ 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;
@ -593,11 +571,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();
@ -659,6 +637,7 @@ 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',
@ -676,7 +655,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 × %d").format(displayW, displayH); let text = _("%d x %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);
@ -704,8 +683,6 @@ const WindowManager = new Lang.Class({
this._dimmedWindows = []; this._dimmedWindows = [];
this._skippedActors = [];
this._allowedKeybindings = {}; this._allowedKeybindings = {};
this._isWorkspacePrepended = false; this._isWorkspacePrepended = false;
@ -726,7 +703,6 @@ const WindowManager = new Lang.Class({
this._shellwm.connect('minimize', Lang.bind(this, this._minimizeWindow)); this._shellwm.connect('minimize', Lang.bind(this, this._minimizeWindow));
this._shellwm.connect('unminimize', Lang.bind(this, this._unminimizeWindow)); this._shellwm.connect('unminimize', Lang.bind(this, this._unminimizeWindow));
this._shellwm.connect('size-change', Lang.bind(this, this._sizeChangeWindow)); this._shellwm.connect('size-change', Lang.bind(this, this._sizeChangeWindow));
this._shellwm.connect('size-changed', Lang.bind(this, this._sizeChangedWindow));
this._shellwm.connect('map', Lang.bind(this, this._mapWindow)); this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow)); this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding)); this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding));
@ -874,34 +850,22 @@ const WindowManager = new Lang.Class({
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-applications', this.setCustomKeybindingHandler('switch-applications',
Shell.ActionMode.NORMAL, Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher)); Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group', this.setCustomKeybindingHandler('switch-group',
Shell.ActionMode.NORMAL, Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher)); Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-applications-backward', this.setCustomKeybindingHandler('switch-applications-backward',
Shell.ActionMode.NORMAL, Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher)); Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group-backward', this.setCustomKeybindingHandler('switch-group-backward',
Shell.ActionMode.NORMAL, Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher)); Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-windows', this.setCustomKeybindingHandler('switch-windows',
Shell.ActionMode.NORMAL, Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher)); Lang.bind(this, this._startWindowSwitcher));
this.setCustomKeybindingHandler('switch-windows-backward', this.setCustomKeybindingHandler('switch-windows-backward',
Shell.ActionMode.NORMAL, Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher)); Lang.bind(this, this._startWindowSwitcher));
this.setCustomKeybindingHandler('cycle-windows',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('cycle-windows-backward',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('cycle-group',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('cycle-group-backward',
Shell.ActionMode.NORMAL,
Lang.bind(this, this._startSwitcher));
this.setCustomKeybindingHandler('switch-panels', this.setCustomKeybindingHandler('switch-panels',
Shell.ActionMode.NORMAL | Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW | Shell.ActionMode.OVERVIEW |
@ -939,35 +903,6 @@ const WindowManager = new Lang.Class({
Lang.bind(this, this._toggleCalendar)); Lang.bind(this, this._toggleCalendar));
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-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++)
@ -998,18 +933,6 @@ const WindowManager = new Lang.Class({
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) {
this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex);
this._currentPadOsd.connect('closed', Lang.bind(this, function() { this._currentPadOsd = null }));
return this._currentPadOsd.actor;
}, },
_actionSwitchWorkspace: function(action, direction) { _actionSwitchWorkspace: function(action, direction) {
@ -1100,10 +1023,6 @@ const WindowManager = new Lang.Class({
this._workspaceTracker.keepWorkspaceAlive(workspace, duration); this._workspaceTracker.keepWorkspaceAlive(workspace, duration);
}, },
skipNextEffect: function(actor) {
this._skippedActors.push(actor);
},
setCustomKeybindingHandler: function(name, modes, handler) { setCustomKeybindingHandler: function(name, modes, handler) {
if (Meta.keybindings_set_custom_handler(name, handler)) if (Meta.keybindings_set_custom_handler(name, handler))
this.allowKeybinding(name, modes); this.allowKeybinding(name, modes);
@ -1130,15 +1049,9 @@ const WindowManager = new Lang.Class({
}, },
_shouldAnimateActor: function(actor, types) { _shouldAnimateActor: function(actor, types) {
if (this._removeEffect(this._skippedActors, actor))
return false;
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;
}, },
@ -1313,17 +1226,37 @@ const WindowManager = new Lang.Class({
return; return;
} }
if ((whichChange == Meta.SizeChange.FULLSCREEN || if (whichChange == Meta.SizeChange.FULLSCREEN)
whichChange == Meta.SizeChange.UNFULLSCREEN) && this._fullscreenWindow(shellwm, actor, oldFrameRect, oldBufferRect);
oldFrameRect.width > 0 && oldFrameRect.height > 0) else if (whichChange == Meta.SizeChange.UNFULLSCREEN)
this._fullscreenAnimation(shellwm, actor, oldFrameRect, whichChange); this._unfullscreenWindow(shellwm, actor, oldFrameRect, oldBufferRect);
else else
shellwm.completed_size_change(actor); shellwm.completed_size_change(actor);
}, },
_fullscreenAnimation: function(shellwm, actor, oldFrameRect, change) { _fullscreenWindow: function(shellwm, actor, oldFrameRect, oldBufferRect) {
let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()];
actor.translation_x = oldFrameRect.x - monitor.x;
actor.translation_y = oldFrameRect.y - monitor.y;
this._fullscreenAnimation(shellwm, actor, oldFrameRect);
},
_unfullscreenWindow: function(shellwm, actor, oldFrameRect, oldBufferRect) {
let targetRect = actor.meta_window.get_frame_rect();
let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()];
actor.translation_x = -(targetRect.x - monitor.x);
actor.translation_y = -(targetRect.y - monitor.y);
this._fullscreenAnimation(shellwm, actor, oldFrameRect);
},
_fullscreenAnimation: function(shellwm, actor, oldFrameRect) {
this._resizing.push(actor);
// Position a clone of the window on top of the old position, // Position a clone of the window on top of the old position,
// while actor updates are frozen. // while actor updates are frozen.
// Note that the MetaWindow has up to date sizing information for
// the new geometry already.
let targetRect = actor.meta_window.get_frame_rect();
let actorContent = Shell.util_get_content_for_window_actor(actor, oldFrameRect); let actorContent = Shell.util_get_content_for_window_actor(actor, oldFrameRect);
let actorClone = new St.Widget({ content: actorContent }); let actorClone = new St.Widget({ content: actorContent });
actorClone.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS); actorClone.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
@ -1331,28 +1264,10 @@ const WindowManager = new Lang.Class({
actorClone.set_size(oldFrameRect.width, oldFrameRect.height); actorClone.set_size(oldFrameRect.width, oldFrameRect.height);
Main.uiGroup.add_actor(actorClone); Main.uiGroup.add_actor(actorClone);
let rect = change == Meta.SizeChange.FULLSCREEN ? oldFrameRect : null; actor.__fullscreenClone = actorClone;
if (this._clearFullscreenInfo(actor)) let scaleX = targetRect.width / oldFrameRect.width;
this._shellwm.completed_size_change(actor); let scaleY = targetRect.height / oldFrameRect.height;
actor.__fullscreenInfo = { clone: actorClone,
oldRect: rect };
},
_sizeChangedWindow: function(shellwm, actor) {
if (!actor.__fullscreenInfo)
return;
if (this._resizing.indexOf(actor) != -1)
return;
let actorClone = actor.__fullscreenInfo.clone;
let targetRect = actor.meta_window.get_frame_rect();
let scaleX = targetRect.width / actorClone.width;
let scaleY = targetRect.height / actorClone.height;
this._resizing.push(actor);
// Now scale and fade out the clone // Now scale and fade out the clone
Tweener.addTween(actorClone, Tweener.addTween(actorClone,
@ -1365,17 +1280,9 @@ const WindowManager = new Lang.Class({
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
let monitor = Main.layoutManager.monitors[actor.meta_window.get_monitor()];
let oldRect = actor.__fullscreenInfo.oldRect;
if (oldRect) {
actor.translation_x = oldRect.x - monitor.x;
actor.translation_y = oldRect.y - monitor.y;
} else {
actor.translation_x = -(targetRect.x - monitor.x);
actor.translation_y = -(targetRect.y - monitor.y);
}
// Now set scale the actor to size it as the clone. // Now set scale the actor to size it as the clone.
// Note that the caller of this function already set a translation
// on the actor.
actor.scale_x = 1 / scaleX; actor.scale_x = 1 / scaleX;
actor.scale_y = 1 / scaleY; actor.scale_y = 1 / scaleY;
@ -1401,15 +1308,6 @@ const WindowManager = new Lang.Class({
shellwm.completed_size_change(actor); shellwm.completed_size_change(actor);
}, },
_clearFullscreenInfo: function(actor) {
if (actor.__fullscreenInfo) {
actor.__fullscreenInfo.clone.destroy();
delete actor.__fullscreenInfo;
return true;
}
return false;
},
_sizeChangeWindowDone: function(shellwm, actor) { _sizeChangeWindowDone: function(shellwm, actor) {
if (this._removeEffect(this._resizing, actor)) { if (this._removeEffect(this._resizing, actor)) {
Tweener.removeTweens(actor); Tweener.removeTweens(actor);
@ -1417,25 +1315,31 @@ const WindowManager = new Lang.Class({
actor.scale_y = 1.0; actor.scale_y = 1.0;
actor.translation_x = 0; actor.translation_x = 0;
actor.translation_y = 0; actor.translation_y = 0;
this._clearFullscreenInfo(actor);
let actorClone = actor.__fullscreenClone;
if (actorClone) {
actorClone.destroy();
delete actor.__fullscreenClone;
}
} }
}, },
_sizeChangeWindowOverwritten: function(shellwm, actor) { _sizeChangeWindowOverwritten: function(shellwm, actor) {
if (this._removeEffect(this._resizing, actor)) if (this._removeEffect(this._resizing, actor)) {
this._clearFullscreenInfo(actor); let actorClone = actor.__fullscreenClone;
if (actorClone) {
actorClone.destroy();
delete actor.__fullscreenClone;
}
}
}, },
_hasAttachedDialogs: function(window, ignoreWindow) { _hasAttachedDialogs: function(window, ignoreWindow) {
var count = 0; var count = 0;
window.foreach_transient(function(win) { window.foreach_transient(function(win) {
if (win != ignoreWindow && if (win != ignoreWindow && win.is_attached_dialog())
win.is_attached_dialog() &&
win.get_transient_for() == window) {
count++; count++;
return false; return false;
}
return true;
}); });
return count != 0; return count != 0;
}, },
@ -1504,11 +1408,6 @@ const WindowManager = new Lang.Class({
actor._windowType = type; actor._windowType = type;
})); }));
actor.meta_window.connect('unmanaged', Lang.bind(this, function(window) {
let parent = window.get_transient_for();
if (parent)
this._checkDimming(parent);
}));
if (actor.meta_window.is_attached_dialog()) if (actor.meta_window.is_attached_dialog())
this._checkDimming(actor.get_meta_window().get_transient_for()); this._checkDimming(actor.get_meta_window().get_transient_for());
@ -1614,7 +1513,7 @@ const WindowManager = new Lang.Class({
return; return;
} }
switch (actor.meta_window.window_type) { switch (actor._windowType) {
case Meta.WindowType.NORMAL: case Meta.WindowType.NORMAL:
actor.set_pivot_point(0.5, 0.5); actor.set_pivot_point(0.5, 0.5);
this._destroying.push(actor); this._destroying.push(actor);
@ -1845,37 +1744,23 @@ const WindowManager = new Lang.Class({
this._windowMenuManager.showWindowMenuForWindow(window, menu, rect); this._windowMenuManager.showWindowMenuForWindow(window, menu, rect);
}, },
_startSwitcher: function(display, screen, window, binding) { _startAppSwitcher : function(display, screen, window, binding) {
let constructor = null;
switch (binding.get_name()) {
case 'switch-applications':
case 'switch-applications-backward':
case 'switch-group':
case 'switch-group-backward':
constructor = AltTab.AppSwitcherPopup;
break;
case 'switch-windows':
case 'switch-windows-backward':
constructor = AltTab.WindowSwitcherPopup;
break;
case 'cycle-windows':
case 'cycle-windows-backward':
constructor = AltTab.WindowCyclerPopup;
break;
case 'cycle-group':
case 'cycle-group-backward':
constructor = AltTab.GroupCyclerPopup;
break;
}
if (!constructor)
return;
/* prevent a corner case where both popups show up at once */ /* prevent a corner case where both popups show up at once */
if (this._workspaceSwitcherPopup != null) if (this._workspaceSwitcherPopup != null)
this._workspaceSwitcherPopup.destroy(); this._workspaceSwitcherPopup.destroy();
let tabPopup = new constructor(); let tabPopup = new AltTab.AppSwitcherPopup();
if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
tabPopup.destroy();
},
_startWindowSwitcher : function(display, screen, window, binding) {
/* prevent a corner case where both popups show up at once */
if (this._workspaceSwitcherPopup != null)
this._workspaceSwitcherPopup.destroy();
let tabPopup = new AltTab.WindowSwitcherPopup();
if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask())) if (!tabPopup.show(binding.is_reversed(), binding.get_name(), binding.get_mask()))
tabPopup.destroy(); tabPopup.destroy();

View File

@ -97,6 +97,8 @@ 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)) {

View File

@ -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 }); this._windowClone = new Clutter.Clone({ source: realWindow.get_texture() });
// 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,10 +471,6 @@ 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);
@ -1100,7 +1096,6 @@ const Workspace = new Lang.Class({
_init : function(metaWorkspace, monitorIndex) { _init : function(metaWorkspace, monitorIndex) {
// When dragging a window, we use this slot for reserve space. // When dragging a window, we use this slot for reserve space.
this._reservedSlot = null; this._reservedSlot = null;
this._reservedSlotWindow = null;
this.metaWorkspace = metaWorkspace; this.metaWorkspace = metaWorkspace;
// The full geometry is the geometry we should try and position // The full geometry is the geometry we should try and position

View File

@ -19,7 +19,8 @@ const WorkspaceSwitcherPopup = new Lang.Class({
Name: 'WorkspaceSwitcherPopup', Name: 'WorkspaceSwitcherPopup',
_init : function() { _init : function() {
this.actor = new St.Widget({ x: 0, this.actor = new St.Widget({ reactive: true,
x: 0,
y: 0, y: 0,
width: global.screen_width, width: global.screen_width,
height: global.screen_height, height: global.screen_height,

View File

@ -45,11 +45,11 @@ const PrimaryActorLayout = new Lang.Class({
this.primaryActor = primaryActor; this.primaryActor = primaryActor;
}, },
vfunc_get_preferred_width: function(container, forHeight) { vfunc_get_preferred_width: function(forHeight) {
return this.primaryActor.get_preferred_width(forHeight); return this.primaryActor.get_preferred_width(forHeight);
}, },
vfunc_get_preferred_height: function(container, forWidth) { vfunc_get_preferred_height: function(forWidth) {
return this.primaryActor.get_preferred_height(forWidth); return this.primaryActor.get_preferred_height(forWidth);
}, },
}); });

View File

@ -103,7 +103,7 @@ const WorkspacesView = new Lang.Class({
page_increment: 1, page_increment: 1,
page_size: 1, page_size: 1,
step_increment: 0, step_increment: 0,
upper: global.screen.n_workspaces }); upper: 0 });
this.scrollAdjustment.connect('notify::value', this.scrollAdjustment.connect('notify::value',
Lang.bind(this, this._onScroll)); Lang.bind(this, this._onScroll));
@ -374,10 +374,6 @@ const ExtraWorkspaceView = new Lang.Class({
this._workspace.setActualGeometry(this._actualGeometry); this._workspace.setActualGeometry(this._actualGeometry);
}, },
getActiveWorkspace: function() {
return this._workspace;
},
animateToOverview: function(animationType) { animateToOverview: function(animationType) {
if (animationType == AnimationType.ZOOM) if (animationType == AnimationType.ZOOM)
this._workspace.zoomToOverview(); this._workspace.zoomToOverview();
@ -425,10 +421,8 @@ const WorkspacesDisplay = new Lang.Class({
// Only switch to the workspace when there's no application // Only switch to the workspace when there's no application
// windows open. The problem is that it's too easy to miss // windows open. The problem is that it's too easy to miss
// an app window and get the wrong one focused. // an app window and get the wrong one focused.
let event = Clutter.get_current_event();
let index = this._getMonitorIndexForEvent(event);
if ((action.get_button() == 1 || action.get_button() == 0) && if ((action.get_button() == 1 || action.get_button() == 0) &&
this._workspacesViews[index].getActiveWorkspace().isEmpty()) this._getPrimaryView().getActiveWorkspace().isEmpty())
Main.overview.hide(); Main.overview.hide();
})); }));
Main.overview.addAction(clickAction); Main.overview.addAction(clickAction);
@ -437,18 +431,11 @@ const WorkspacesDisplay = new Lang.Class({
let panAction = new Clutter.PanAction({ threshold_trigger_edge: Clutter.GestureTriggerEdge.AFTER }); let panAction = new Clutter.PanAction({ threshold_trigger_edge: Clutter.GestureTriggerEdge.AFTER });
panAction.connect('pan', Lang.bind(this, this._onPan)); panAction.connect('pan', Lang.bind(this, this._onPan));
panAction.connect('gesture-begin', Lang.bind(this, function() { panAction.connect('gesture-begin', Lang.bind(this, function() {
if (this._workspacesOnlyOnPrimary) {
let event = Clutter.get_current_event();
if (this._getMonitorIndexForEvent(event) != this._primaryIndex)
return false;
}
for (let i = 0; i < this._workspacesViews.length; i++) for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startSwipeScroll(); this._workspacesViews[i].startSwipeScroll();
return true; return true;
})); }));
panAction.connect('gesture-cancel', Lang.bind(this, function() { panAction.connect('gesture-cancel', Lang.bind(this, function() {
clickAction.release();
for (let i = 0; i < this._workspacesViews.length; i++) for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].endSwipeScroll(); this._workspacesViews[i].endSwipeScroll();
})); }));
@ -594,12 +581,6 @@ const WorkspacesDisplay = new Lang.Class({
} }
}, },
_getMonitorIndexForEvent: function(event) {
let [x, y] = event.get_coords();
let rect = new Meta.Rectangle({ x: x, y: y, width: 1, height: 1 });
return global.screen.get_monitor_index_for_rect(rect);
},
_getPrimaryView: function() { _getPrimaryView: function() {
if (!this._workspacesViews.length) if (!this._workspacesViews.length)
return null; return null;
@ -680,11 +661,6 @@ const WorkspacesDisplay = new Lang.Class({
_onScrollEvent: function(actor, event) { _onScrollEvent: function(actor, event) {
if (!this.actor.mapped) if (!this.actor.mapped)
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
if (this._workspacesOnlyOnPrimary &&
this._getMonitorIndexForEvent(event) != this._primaryIndex)
return Clutter.EVENT_PROPAGATE;
let activeWs = global.screen.get_active_workspace(); let activeWs = global.screen.get_active_workspace();
let ws; let ws;
switch (event.get_scroll_direction()) { switch (event.get_scroll_direction()) {

View File

@ -24,10 +24,9 @@ const XdndHandler = new Lang.Class({
if (!Meta.is_wayland_compositor()) if (!Meta.is_wayland_compositor())
global.init_xdnd(); global.init_xdnd();
var dnd = Meta.get_backend().get_dnd(); global.connect('xdnd-enter', Lang.bind(this, this._onEnter));
dnd.connect('dnd-enter', Lang.bind(this, this._onEnter)); global.connect('xdnd-position-changed', Lang.bind(this, this._onPositionChanged));
dnd.connect('dnd-position-change', Lang.bind(this, this._onPositionChanged)); global.connect('xdnd-leave', Lang.bind(this, this._onLeave));
dnd.connect('dnd-leave', Lang.bind(this, this._onLeave));
this._windowGroupVisibilityHandlerId = 0; this._windowGroupVisibilityHandlerId = 0;
}, },

View File

@ -29,7 +29,6 @@ gl
gu gu
he he
hi hi
hr
hu hu
ia ia
id id

View File

@ -1,68 +0,0 @@
# Makefile variables for PO directory in any package using GNU gettext.
# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)
# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..
# These options get passed to xgettext.
XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ \
--keyword=C_:1c,2 --keyword=NC_:1c,2 \
--keyword=g_dngettext:2,3 --add-comments \
--flag=g_dngettext:2:pass-c-format \
--flag=g_strdup_printf:1:c-format \
--flag=g_string_printf:2:c-format \
--flag=g_string_append_printf:2:c-format \
--flag=g_error_new:3:c-format \
--flag=g_set_error:4:c-format \
--flag=g_markup_printf_escaped:1:c-format \
--flag=g_log:3:c-format \
--flag=g_print:1:c-format \
--flag=g_printerr:1:c-format \
--flag=g_printf:1:c-format \
--flag=g_fprintf:2:c-format \
--flag=g_sprintf:2:c-format \
--flag=g_snprintf:3:c-format
# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
# package. (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.) Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Translation copyright holder
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
# in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
# understood.
# - Strings which make invalid assumptions about notation of date, time or
# money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS = http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
EXTRA_LOCALE_CATEGORIES =
# Ignore the timestamp of the .pot file, as git clones do not have
# deterministic timestamps, and .po files are updated by translators
# (only) in GNOME projects.
PO_DEPENDS_ON_POT = no
# This tells whether or not to forcibly update $(DOMAIN).pot and
# regenerate PO files on "make dist". Possible values are "yes" and
# "no". Set this to no if the POT file and PO files are maintained
# externally.
DIST_DEPENDS_ON_UPDATE_PO = no

View File

@ -1,17 +1,17 @@
# List of source files containing translatable strings. # List of source files containing translatable strings.
# Please keep this file sorted alphabetically. # Please keep this file sorted alphabetically.
data/50-gnome-shell-system.xml [encoding: UTF-8]
data/50-gnome-shell-system.xml.in
data/gnome-shell-extension-prefs.desktop.in.in data/gnome-shell-extension-prefs.desktop.in.in
data/org.gnome.Shell.desktop.in.in data/org.gnome.Shell.desktop.in.in
data/org.gnome.shell.gschema.xml.in data/org.gnome.shell.gschema.xml.in.in
data/org.gnome.Shell.PortalHelper.desktop.in.in data/org.gnome.Shell.PortalHelper.desktop.in
js/extensionPrefs/main.js js/extensionPrefs/main.js
js/gdm/authPrompt.js js/gdm/authPrompt.js
js/gdm/loginDialog.js js/gdm/loginDialog.js
js/gdm/util.js js/gdm/util.js
js/misc/util.js js/misc/util.js
js/portalHelper/main.js js/portalHelper/main.js
js/ui/accessDialog.js
js/ui/appDisplay.js js/ui/appDisplay.js
js/ui/appFavorites.js js/ui/appFavorites.js
js/ui/audioDeviceSelection.js js/ui/audioDeviceSelection.js
@ -39,7 +39,6 @@ js/ui/mpris.js
js/ui/notificationDaemon.js js/ui/notificationDaemon.js
js/ui/overviewControls.js js/ui/overviewControls.js
js/ui/overview.js js/ui/overview.js
js/ui/padOsd.js
js/ui/panel.js js/ui/panel.js
js/ui/popupMenu.js js/ui/popupMenu.js
js/ui/runDialog.js js/ui/runDialog.js
@ -53,7 +52,6 @@ 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
@ -63,7 +61,7 @@ js/ui/viewSelector.js
js/ui/windowAttentionHandler.js js/ui/windowAttentionHandler.js
js/ui/windowManager.js js/ui/windowManager.js
js/ui/windowMenu.js js/ui/windowMenu.js
src/calendar-server/evolution-calendar.desktop.in src/calendar-server/evolution-calendar.desktop.in.in
# Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it. # Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it.
src/gvc/gvc-mixer-control.c src/gvc/gvc-mixer-control.c
src/main.c src/main.c

4
po/POTFILES.skip Normal file
View File

@ -0,0 +1,4 @@
data/org.gnome.shell.evolution.calendar.gschema.xml.in
src/calendar-server/evolution-calendar.desktop.in
# Meh, autofools :-(
sub/src/calendar-server/evolution-calendar.desktop.in

Some files were not shown because too many files have changed in this diff Show More