Compare commits

..

7 Commits

Author SHA1 Message Date
1afb04d1e4 overview: new transition 2014-01-31 17:57:57 -05:00
51e63233ce viewSelector: Move to a sync() model for deciding which page to show
https://bugzilla.gnome.org/show_bug.cgi?id=722196
2014-01-31 17:57:57 -05:00
a7d7f94892 screenShield: Don't hide windows until we've fully locked the shield
Revert the commit that ties hasWindows to the session mode, as we
need to do the "transition" manually. Instead, show/hide the
sessionGroup ourselves.

For optimization purposes, we also need to hide the window groups
when in the overview. Ideally, these would be culled out by Clutter,
but they are not from experimentation.
2014-01-31 17:57:57 -05:00
427f516d45 layout: Replace SystemBackground with CSS on the systemGroup
This merges the implementation of the noise texture on the lockScreenDialog
and the startup animation -- they now just use the systemGroup.
2014-01-31 17:57:57 -05:00
cbb88ffdbb layout: Add sessionGroup / systemGroup to better-define layers
In order to build a better transition animation from the lock screen, we
need to split the world into layers, as per this reference:

https://raw.github.com/gnome-design-team/gnome-mockups/master/system-lock-login-boot/system-layers2.png

Everything that pertains to the user's session is in the "session group",
which includes the window group, overview, message tray (for now),
keyboard, OSDs, menus, etc.

For implementation sake, we did not match this mockup exactly. The new layers
look like this, from top to bottom:

 * Stage
   * Magnifier (clones the uiGroup)
   * uiGroup
     * overlayGroup
       * menuGroup
     * panelGroup
     * screenShieldGroup
     * sessionGroup
       * top_window_group
       * other boxes (trayBox, keyboardBox, etc.)
       * other groups (osdGroup, switcherPopupGroup, etc.)
       * overviewGroup
       * window_group
     * systemGroup

The "session startup" animation now only zooms in the sessionGroup.

The panel is now outside the session, as it needs to sit above the screen
shield. This also means that it's not zoomed in as part of startup. I think
this is OK.

This also means that the lightboxes that the screen shield uses to fade out
the screen have to go in a new group, above the panel. This is known as the
overlayGroup, which has no relation to the old mutter group of the same name.

We also change the screen shield to put the lockDialogGroup in the system
group, and put the lockScreenGroup in the screenShieldGroup, which means
that the layer stacking is correct. Note that we don't hide the session
group in the lock screen yet, which is something I want to do.

Since not a lot of items need to be in the uiGroup anymore, we've removed
the Main.uiGroup fallback; others should use sessionGroup instead, when
appropriate.
2014-01-31 17:57:57 -05:00
71670bad3b layout: Add different groups in the LayoutManager for discrete UI components
This helps take cruft out of the uiGroup, and ensures that components remain
stacked properly on top of each other. In the future, we'll use this group
to ensure that grabs are ordered properly, as well.
2014-01-31 17:57:57 -05:00
a2e4153fa0 background: Fix cancellable issues
If we have the following sequence:

    cache.getImageContent({ filename: "foo", cancellable: cancellable1 });
    cache.getImageContent({ filename: "foo", cancellable: cancellable2 });
    cancellable1.cancel();

Then the second load will complete with "null" as its content, even though
it was never cancelled, and we'll see a blank image. Meanwhile, since the
second load simply appends to the list of callers for the second load,
cancellable2 does absolutely nothing: cancelling it won't stop the load,
and it will still receive onFinished handling.

To prevent this from happening, give the actual load operation its own
Gio.Cancellable, which is "ref-counted" -- only cancel it when all the other
possible callers cancel.

Additionally, clean up the large nested loops by splitting out duplicated
code and other stuff.

https://bugzilla.gnome.org/show_bug.cgi?id=722149
2014-01-31 17:57:57 -05:00
150 changed files with 19915 additions and 33190 deletions

177
NEWS
View File

@ -1,180 +1,3 @@
3.12.2
======
* Fix turning off airplane mode [Giovanni; #728512]
* Handle empty VPN keyfiles [Adel; #728681]
* Fix setting zero-level in osdWindow [Bastien; #727384]
* Fix removal of multiple workspace thumbnails at once [Florian; #728820]
* Make airplane mode menu insensitive in lock screen [Giovanni; #729224]
* Fix keynav for alternatives in AltSwitcher [Florian; #727259]
* Fix zombie search providers showing up [Jasper; #728597]
Contributors:
Giovanni Campagna, Adel Gadllah, Florian Müllner, Bastien Nocera,
Jasper St. Pierre
Translations:
Wouter Bolsterlee [nl], Daniel Korostil [uk], Ihar Hrachyshka [be],
Giovanni Campagna [it], Carles Ferrando [ca@valencia]
3.12.1
======
* Ensure the currently focused app icon is viewable [Rui; #726759]
* Improve language in location menu [Zeeshan; #726498]
* Improve HiDpi support [Cosimo; #726907]
* Set accessible role for window previews [Alejandro; #726670]
* Fix bad antialiasing on panel menu buttons [Carlos; #727336]
* Don't hide location menu [Zeeshan; #727398]
* Fix IM candidate window obscuring current text [Rui; #727579]
* Fix extension-prefs tool when linked with --as-needed [Florian; #727948]
* Don't always extend struts to the screen edge [Florian; #663690]
Contributors:
Zeeshan Ali (Khattak), Cosimo Cecchi, Piotr Drąg, Rui Matos, Simon McVittie,
Florian Müllner, Alejandro Piñeiro, Carlos Soriano
Translations:
Khaled Hosny [ar], Piotr Drąg [pl], Yosef Or Boczko [he],
Antonio Fernandes C. Neto [pt_BR], Marek Černocký [cs], maria thukididu [el],
Andika Triwidada [id], Daniel Mustieles [es], Changwoo Ryu [ko],
Benjamin Steinwender [de], Sphinx Jiang [zh_CN],
Inaki Larranaga Murgoitio [eu], Marcus Lundblad [sv], Aurimas Černius [lt],
Stas Solovey [ru], Alexandre Franke [fr], Matej Urbančič [sl],
Fran Diéguez [gl], Pau Iranzo [ca], Luca Ferretti [it], Milo Casagrande [it],
Tiago S [pt], Victor Ibragimov [tg], Dirgita [id], Khoem Sokhem [km],
Rūdolfs Mazurs [lv], Balázs Úr [hu], Ask H. Larsen [da], Ikuya Awashiro [ja],
Мирослав Николић [sr, sr@latin]
3.12.0
======
* gdm: Reset greeter when coming back to login screen [Jasper; #726989]
Contributors:
Jasper St. Pierre
Translations:
Daniel Martinez [an], Yuri Myasoedov [ru], Inaki Larranaga Murgoitio [eu],
Abderrahim Kitouni [ar], Praveen Illa [te], Matej Urbančič [sl],
Chao-Hsiung Liao [zh_HK, zh_TW], Frédéric Péters [fr],
Мирослав Николић [sr, sr@latin], Ask H. Larsen [da], Kenneth Nielsen [da],
Jiro Matsuzawa [ja], Dušan Kazik [sk]
3.11.92
=======
* calendar: Grab key focus after changing day [Volker; #725606]
* gdm: Don't load user list if disabled [Florian; #725905]
* Don't show network-offline in the top bar [Jasper; #725340]
* Improve radial shade effect of modal dialogs [Giovanni; #725830]
* Fix broken suspend-on-idle functionality [Giovanni; #712706]
* Close wifi selection dialog when device disappears [Giovanni; #723935]
* Don't close chats when pressing Escape [Giovanni; #724178]
* Improve smartcard support in login/lock screen [Ray; #726262, #726263]
* Wake up screen when resuming from suspend [Giovanni; #726378]
* Make bluetooth and location items insensitive when locked [Florian; #726319]
* Don't show bluetooth icon when there is no adapter [Giovanni; #725057]
* Make sure to keep the OSK on top of modal dialogs [Rui; #719451]
* Misc. bug fixes and cleanups [Giovanni, Ray, Adel, Daniel, Jasper, Florian;
#725832, #725958, #722149, #724977, #724798, #725020, #723976, #726119,
#726238, #585500, #704844, #726323, #726322, #726120, #726414]
Contributors:
Giovanni Campagna, Daniel Drake, Adel Gadllah, Rui Matos, Florian Müllner,
Volker Sobek, Jasper St. Pierre, Ray Strode
Translations:
Fabio Tomat [fur], Rafael Ferreira [pt_BR], Fran Diéguez [gl],
Marek Černocký [cs], Baurzhan Muftakhidinov [kk], Andika Triwidada [id],
A S Alam [pa], Rūdolfs Mazurs [lv], Wylmer Wang [zh_CN],
Aurimas Černius [lt], Cheng-Chia Tseng [zh_TW], Stas Solovey [ru],
Tiagosdot [pt], Benjamin Steinwender [de], Frédéric Peters [fr],
Daniel Korostil [uk], Yaron Shahrabani [he], Ville-Pekka Vainio [fi],
maria thukididu [el], Victor Ibragimov [tg], Kjartan Maraas [nb],
Gábor Kelemen [hu], Ask H. Larsen [da]
3.11.91
=======
* Don't use network profile name in menu [Giovanni; #725586]
* calendar: Make date label clickable to return to current date [Vit; #641366]
* Misc. bug fixes [Florian, Zeeshan, Adel, Jasper, Dan, Volker; #724813,
#724686, #725082, #724870, #724779, #725533]
Contributors:
Zeeshan Ali (Khattak), Giovanni Campagna, Piotr Drąg, Adel Gadllah,
Florian Müllner, Volker Sobek, Vit Stanislav, Jasper St. Pierre, Dan Williams
Translations:
Victor Ibragimov [tg], Aurimas Černius [lt], Dimitris Spingos [el],
Andika Triwidada [id], Rafael Ferreira [pt_BR], Daniel Mustieles [es],
Baurzhan Muftakhidinov [kk], Marek Černocký [cs], Ihar Hrachyshka [be],
eternalhui [zh_CN], Yosef Or Boczko [he], Fran Diéguez [gl],
Khaled Hosny [ar], Ville-Pekka Vainio [fi], Piotr Drąg [pl],
Kjartan Maraas [nb], Changwoo Ryu [ko]
3.11.90
=======
* Stop showing two bluetooth entries [Giovanni; #709353]
* Improve styling of login/lock screen [Reda; #723833]
* Fix magnifier crosshairs [Magdalen; #723709]
* Make NetworkManager support optional [Michael; #669495]
* Make middle-click open a new instance [Florian; #695010]
* Scale the UI on high resolution displays [Cosimo, Adel; #705410, #724607]
* Remove notification counter on screen shield [Carlos; #709275]
* Improve app picker transition [Carlos; #722331]
* Add geolocation indicator to status menu [Zeeshan; #723684]
* Improve timestamps in chat notifications [Carlos; #708031, #715158]
* Improve network menus [Giovanni; #723570]
* Add "VPN Setting" item to VPN submenu [Giovanni; #709167]
* Improve appearance of disclosure arrows [Carlos; #720206]
* Add GSetting key to disable version validation of extensions [Adel; #724683]
* Delay auto-removing empty workspaces [Florian; #709064]
* Offer offline updates in the shutdown dialog [Kalev; #722898]
* Animate tile previews [Florian; #665758]
* Misc. bug fixes and cleanups [Giovanni, Ryan, Debarshi, Florian; #709128,
#722342, #723661, #724184, #724256, #724293, #724305, #722554, #724282,
#724690, #722928]
Contributors:
Zeeshan Ali (Khattak), Magdalen Berns, Michael Biebl, Giovanni Campagna,
Cosimo Cecchi, Adel Gadllah, Reda Lazri, Kalev Lember, Ryan Lortie,
Florian Müllner, Debarshi Ray, Carlos Soriano, Jasper St. Pierre,
Colin Walters
Translations:
Victor Ibragimov [tg], Daniel Mustieles [es], Khaled Hosny [ar],
Enrico Nicoletto [pt_BR], Yosef Or Boczko [he], Fran Diéguez [gl],
Marek Černocký [cs], Baurzhan Muftakhidinov [kk], Jorge Pérez Pérez [an],
Kjartan Maraas [nb], David Lüder [de], Daniel Korostil [uk], ngoswami [as],
Rafael Ferreira [pt_BR]
3.11.5
======
* Fix extension preference tool [Florian; #722334]
* Fix keyboard activation of legacy tray icons [Giovanni; #721267]
* Add radial background shade for modal dialogs [Giovanni; #669798]
* Show attached modal windows in the overview [Giovanni; #650843]
* Add support for desktop actions [Giovanni; #669603]
* Indicate in system status when location service is used [Zeeshan; #709372]
* Add support for extended app folder schema [Jasper; #723179]
* Show status icon for wired network connections [Jasper; #708966]
* Indicate airplane mode in network selection dialog [Giovanni; #709128]
* Misc bug fixes and cleanups [Florian, Sebastian, Giovanni, Tim, Matt, Jasper;
#722417, #722494, #722547, #722593, #722434, #722787, #722690, #722840,
#722660, #722812, #723197, #722927, #723306, #723308, #723523, #709685,
#723570]
Contributors:
Zeeshan Ali (Khattak), Magdalen Berns, Giovanni Campagna, William Jon McCann,
Sebastian Keller, Tim Lunn, Florian Müllner, Carlos Soriano,
Jasper St. Pierre, Rico Tzschichholz, Matt Watson
Translations:
Marek Černocký [cs], Mattias Põldaru [et], Tong Hui [zh_CN],
Victor Ibragimov [tg], Enrico Nicoletto [pt_BR], Daniel Mustieles [es],
Fran Diéguez [gl], Kjartan Maraas [nb], Nilamdyuti Goswami [as],
Aurimas Černius [lt], Stas Solovey [ru], Yosef Or Boczko [he],
Jorge Pérez Pérez [an], Dimitris Spingos [el], Baurzhan Muftakhidinov [kk],
Chao-Hsiung Liao [zh_HK, zh_TW], Shankar Prasad [kn], Yaron Shahrabani [he],
Andika Triwidada [id]
3.11.4 3.11.4
====== ======
* Fix removal of workspacaes that are not at the end [Giovanni; #721417] * Fix removal of workspacaes that are not at the end [Giovanni; #721417]

2
README
View File

@ -8,7 +8,7 @@ For more information about GNOME Shell, including instructions on how
to build GNOME Shell from source and how to get involved with the project, to build GNOME Shell from source and how to get involved with the project,
see: see:
https://wiki.gnome.org/Projects/GnomeShell http://live.gnome.org/GnomeShell
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell' Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
product. product.

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# Run this to generate all the initial makefiles, etc. # Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0` srcdir=`dirname $0`

View File

@ -41,8 +41,6 @@
#define PLUGIN_API_VERSION 5 #define PLUGIN_API_VERSION 5
#define EXTENSION_DISABLE_VERSION_CHECK_KEY "disable-extension-version-validation"
typedef struct { typedef struct {
GDBusProxy *proxy; GDBusProxy *proxy;
} PluginData; } PluginData;
@ -833,16 +831,6 @@ plugin_get_shell_version (PluginObject *obj,
return ret; return ret;
} }
static gboolean
plugin_get_version_validation_enabled (PluginObject *obj,
NPVariant *result)
{
gboolean is_enabled = !g_settings_get_boolean (obj->settings, EXTENSION_DISABLE_VERSION_CHECK_KEY);
BOOLEAN_TO_NPVARIANT(is_enabled, *result);
return TRUE;
}
#define METHODS \ #define METHODS \
METHOD (list_extensions) \ METHOD (list_extensions) \
METHOD (get_info) \ METHOD (get_info) \
@ -862,8 +850,6 @@ static NPIdentifier api_version_id;
static NPIdentifier shell_version_id; static NPIdentifier shell_version_id;
static NPIdentifier onextension_changed_id; static NPIdentifier onextension_changed_id;
static NPIdentifier onrestart_id; static NPIdentifier onrestart_id;
static NPIdentifier version_validation_enabled_id;
static bool static bool
plugin_object_has_method (NPObject *npobj, plugin_object_has_method (NPObject *npobj,
@ -906,8 +892,7 @@ plugin_object_has_property (NPObject *npobj,
return (name == onextension_changed_id || return (name == onextension_changed_id ||
name == onrestart_id || name == onrestart_id ||
name == api_version_id || name == api_version_id ||
name == shell_version_id || name == shell_version_id);
name == version_validation_enabled_id);
} }
static bool static bool
@ -925,8 +910,6 @@ plugin_object_get_property (NPObject *npobj,
return plugin_get_api_version (obj, result); return plugin_get_api_version (obj, result);
else if (name == shell_version_id) else if (name == shell_version_id)
return plugin_get_shell_version (obj, result); return plugin_get_shell_version (obj, result);
else if (name == version_validation_enabled_id)
return plugin_get_version_validation_enabled (obj, result);
else if (name == onextension_changed_id) else if (name == onextension_changed_id)
{ {
if (obj->listener) if (obj->listener)
@ -1005,7 +988,6 @@ init_methods_and_properties (void)
/* this is the JS public API; it is manipulated through NPIdentifiers for speed */ /* this is the JS public API; it is manipulated through NPIdentifiers for speed */
api_version_id = funcs.getstringidentifier ("apiVersion"); api_version_id = funcs.getstringidentifier ("apiVersion");
shell_version_id = funcs.getstringidentifier ("shellVersion"); shell_version_id = funcs.getstringidentifier ("shellVersion");
version_validation_enabled_id = funcs.getstringidentifier ("versionValidationEnabled");
get_info_id = funcs.getstringidentifier ("getExtensionInfo"); get_info_id = funcs.getstringidentifier ("getExtensionInfo");
list_extensions_id = funcs.getstringidentifier ("listExtensions"); list_extensions_id = funcs.getstringidentifier ("listExtensions");

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63) AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.12.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) AC_INIT([gnome-shell],[3.11.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c]) AC_CONFIG_SRCDIR([src/shell-global.c])
@ -76,7 +76,7 @@ AC_MSG_RESULT($enable_systemd)
CLUTTER_MIN_VERSION=1.15.90 CLUTTER_MIN_VERSION=1.15.90
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1 GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.39.0 GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.12.1 MUTTER_MIN_VERSION=3.11.1
GTK_MIN_VERSION=3.7.9 GTK_MIN_VERSION=3.7.9
GIO_MIN_VERSION=2.37.0 GIO_MIN_VERSION=2.37.0
LIBECAL_MIN_VERSION=3.5.3 LIBECAL_MIN_VERSION=3.5.3
@ -105,7 +105,9 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
libcanberra libcanberra-gtk3 libcanberra libcanberra-gtk3
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
polkit-agent-1 >= $POLKIT_MIN_VERSION polkit-agent-1 >= $POLKIT_MIN_VERSION
gcr-base-3 >= $GCR_MIN_VERSION" libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
libsecret-unstable gcr-base-3 >= $GCR_MIN_VERSION"
if test x$have_systemd = xyes; then if test x$have_systemd = xyes; then
SHARED_PCS="${SHARED_PCS} libsystemd-journal" SHARED_PCS="${SHARED_PCS} libsystemd-journal"
fi fi
@ -180,38 +182,6 @@ if test "$langinfo_ok" = "yes"; then
[Define if _NL_TIME_FIRST_WEEKDAY is available]) [Define if _NL_TIME_FIRST_WEEKDAY is available])
fi fi
AC_ARG_ENABLE(networkmanager,
AS_HELP_STRING([--disable-networkmanager],
[disable NetworkManager support @<:@default=auto@:>@]),,
[enable_networkmanager=auto])
if test "x$enable_networkmanager" != "xno"; then
PKG_CHECK_MODULES(NETWORKMANAGER,
[libnm-glib
libnm-util >= $NETWORKMANAGER_MIN_VERSION
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
libsecret-unstable],
[have_networkmanager=yes],
[have_networkmanager=no])
GNOME_SHELL_CFLAGS="$GNOME_SHELL_CFLAGS $NETWORKMANAGER_CFLAGS"
GNOME_SHELL_LIBS="$GNOME_SHELL_LIBS $NETWORKMANAGER_LIBS"
else
have_networkmanager="no (disabled)"
fi
if test "x$have_networkmanager" = "xyes"; then
AC_DEFINE(HAVE_NETWORKMANAGER, [1], [Define if we have NetworkManager])
AC_SUBST([HAVE_NETWORKMANAGER], [1])
else
if test "x$enable_networkmanager" = "xyes"; then
AC_MSG_ERROR([Couldn't find NetworkManager.])
fi
AC_SUBST([HAVE_NETWORKMANAGER], [0])
fi
AM_CONDITIONAL(HAVE_NETWORKMANAGER, test "$have_networkmanager" = "yes")
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS # Sets GLIB_GENMARSHAL and GLIB_MKENUMS
AM_PATH_GLIB_2_0() AM_PATH_GLIB_2_0()
@ -253,15 +223,3 @@ AC_CONFIG_FILES([
man/Makefile man/Makefile
]) ])
AC_OUTPUT AC_OUTPUT
echo "
Build configuration:
Prefix: ${prefix}
Source code location: ${srcdir}
Compiler: ${CC}
Compiler Warnings: $enable_compile_warnings
Support for NetworkManager: $have_networkmanager
Support for GStreamer recording: $build_recorder
"

View File

@ -39,7 +39,6 @@ dist_theme_DATA = \
theme/filter-selected-rtl.svg \ theme/filter-selected-rtl.svg \
theme/gnome-shell.css \ theme/gnome-shell.css \
theme/logged-in-indicator.svg \ theme/logged-in-indicator.svg \
theme/menu-arrow-symbolic.svg \
theme/message-tray-background.png \ theme/message-tray-background.png \
theme/more-results.svg \ theme/more-results.svg \
theme/noise-texture.png \ theme/noise-texture.png \

View File

@ -2,7 +2,7 @@
Type=Application Type=Application
_Name=GNOME Shell (wayland compositor) _Name=GNOME Shell (wayland compositor)
_Comment=Window management and application launching _Comment=Window management and application launching
Exec=@bindir@/mutter-launch -- gnome-shell-wayland --wayland --display-server Exec=@bindir@/mutter-launch -- gnome-shell-wayland --wayland
X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell X-GNOME-Bugzilla-Product=gnome-shell
X-GNOME-Bugzilla-Component=general X-GNOME-Bugzilla-Component=general

View File

@ -21,15 +21,6 @@
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell. EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
</_description> </_description>
</key> </key>
<key name="disable-extension-version-validation" type="b">
<default>false</default>
<_summary>Disables the validation of extension version compatibility</_summary>
<_description>
GNOME Shell will only load extensions that claim to support the current
running version. Enabling this option will disable this check and try to
load all extensions regardless of the versions they claim to support.
</_description>
</key>
<key name="favorite-apps" type="as"> <key name="favorite-apps" type="as">
<default>[ 'epiphany.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop' ]</default> <default>[ 'epiphany.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop' ]</default>
<_summary>List of desktop file IDs for favorite applications</_summary> <_summary>List of desktop file IDs for favorite applications</_summary>
@ -74,7 +65,6 @@
<child name="calendar" schema="org.gnome.shell.calendar"/> <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"/>
<child name="location" schema="org.gnome.shell.location"/>
</schema> </schema>
<schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/" <schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
@ -144,32 +134,6 @@
</key> </key>
</schema> </schema>
<enum id="org.gnome.shell.geoclue.AccuracyLevel">
<value value="0" nick="off"/>
<value value="1" nick="country"/>
<value value="4" nick="city"/>
<value value="5" nick="neighborhood"/>
<value value="6" nick="street"/>
<value value="8" nick="exact"/>
</enum>
<schema id="org.gnome.shell.location"
path="/org/gnome/shell/location/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="max-accuracy-level" enum="org.gnome.shell.geoclue.AccuracyLevel">
<default>'exact'</default>
<_summary>The maximum accuracy level of location.</_summary>
<_description>
Configures the maximum level of location accuracy applications are
allowed to see. Valid options are 'off' (disable location tracking),
'country', 'city', 'neighborhood', 'street', and 'exact' (typically
requires GPS receiver). Please keep in mind that this only controls
what GeoClue will allow applications to see and they can find user's
location on their own using network resources (albeit with street-level
accuracy at best).
</_description>
</key>
</schema>
<schema id="org.gnome.shell.app-switcher" <schema id="org.gnome.shell.app-switcher"
path="/org/gnome/shell/app-switcher/" path="/org/gnome/shell/app-switcher/"
gettext-domain="@GETTEXT_PACKAGE@"> gettext-domain="@GETTEXT_PACKAGE@">

View File

@ -157,9 +157,8 @@ StScrollBar StButton#vhandle:active {
min-width: 200px; min-width: 200px;
} }
.popup-menu-arrow { .unicode-arrow {
width: 16px; font-size: 120%;
height: 16px;
} }
.popup-submenu-menu-item:open { .popup-submenu-menu-item:open {
@ -290,20 +289,6 @@ StScrollBar StButton#vhandle:active {
spacing: 10px; spacing: 10px;
} }
.nm-dialog-airplane-box {
spacing: 12px;
}
.nm-dialog-airplane-headline {
font-size: 1.1em;
font-weight: bold;
text-align: center;
}
.nm-dialog-airplane-text {
color: #999999;
}
.nm-dialog-header-icon { .nm-dialog-header-icon {
icon-size: 32px; icon-size: 32px;
} }
@ -670,7 +655,7 @@ StScrollBar StButton#vhandle:active {
color: #e6e6e6; color: #e6e6e6;
border-radius: 32px; /* wish we could do 50% */ border-radius: 32px; /* wish we could do 50% */
padding: 13px; padding: 13px;
border: 2px solid #5f5f5f; /* using rgba() is flaky unfortunately */ border: 1px solid #5f5f5f; /* using rgba() is flaky unfortunately */
} }
.system-menu-action:hover, .system-menu-action:hover,
@ -678,7 +663,7 @@ StScrollBar StButton#vhandle:active {
color: white; color: white;
background-color: #4c4c4c; background-color: #4c4c4c;
border: none; border: none;
padding: 15px; padding: 14px;
} }
.system-menu-action:active { .system-menu-action:active {
@ -979,8 +964,6 @@ StScrollBar StButton#vhandle:active {
.app-folder-icon { .app-folder-icon {
padding: 5px; padding: 5px;
spacing-rows: 5px;
spacing-columns: 5px;
} }
.dash-item-container > StButton { .dash-item-container > StButton {
@ -1306,18 +1289,12 @@ StScrollBar StButton#vhandle:active {
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
color: #eeeeec; color: #eeeeec;
border-radius: 4px;
} }
.datemenu-date-label:hover,
.datemenu-date-label:focus { .datemenu-date-label:focus {
background-color: #999999; background-color: #999999;
} }
.datemenu-date-label:active {
background-color: #aaaaaa;
}
.calendar-day-base { .calendar-day-base {
font-size: 9pt; font-size: 9pt;
text-align: center; text-align: center;
@ -1476,10 +1453,6 @@ StScrollBar StButton#vhandle:active {
color: #999999; color: #999999;
} }
.no-networks-box {
spacing: 12px;
}
.notification { .notification {
border-radius: 10px 10px 0px 0px; border-radius: 10px 10px 0px 0px;
background: rgba(0,0,0,0.9); background: rgba(0,0,0,0.9);
@ -1657,8 +1630,8 @@ StScrollBar StButton#vhandle:active {
color: #888888; color: #888888;
} }
.chat-empty-line { .chat-group-sent, .chat-group-meta {
font-size: 4px; padding: 8px 0;
} }
.chat-received { .chat-received {
@ -1683,7 +1656,6 @@ StScrollBar StButton#vhandle:active {
.chat-meta-message { .chat-meta-message {
padding-left: 4px; padding-left: 4px;
font-size: 9pt; font-size: 9pt;
font-weight: bold;
color: #bbbbbb; color: #bbbbbb;
} }
@ -1885,27 +1857,6 @@ StScrollBar StButton#vhandle:active {
border-radius: 8px; border-radius: 8px;
} }
/* Tile previews */
.tile-preview {
background-color: rgba(74, 144, 217, 0.35);
border: 1px solid #4a90d9; /* Adwaita selected bg color */
}
.tile-preview-left.on-primary {
/* keep in sync with -panel-corner-radius */
border-radius: 6px 0 0 0;
}
.tile-preview-right.on-primary {
/* keep in sync with -panel-corner-radius */
border-radius: 0 6px 0 0;
}
.tile-preview-left.tile-preview-right.on-primary {
/* keep in sync with -panel-corner-radius */
border-radius: 6px 6px 0 0;
}
/* Modal Dialogs */ /* Modal Dialogs */
/* Dialog Subject Text Style */ /* Dialog Subject Text Style */
@ -1976,57 +1927,45 @@ StScrollBar StButton#vhandle:active {
padding-top: 20px; padding-top: 20px;
} }
.end-session-dialog-layout { .end-session-dialog-subject {
padding-left: 17px; padding-left: 17px;
padding-bottom: 20px;
} }
.end-session-dialog-layout:rtl { .end-session-dialog-subject:rtl {
padding-left: 0px;
padding-right: 17px; padding-right: 17px;
} }
.end-session-dialog-description { .end-session-dialog-description {
padding-left: 17px;
width: 28em; width: 28em;
padding-bottom: 10px;
} }
.end-session-dialog-description:rtl { .end-session-dialog-description:rtl {
width: 28em; padding-right: 17px;
padding-bottom: 10px;
text-align: right;
}
.end-session-dialog-warning {
width: 28em;
color: #f57900;
padding-top: 6px;
}
.end-session-dialog-warning:rtl {
width: 28em;
color: #f57900;
padding-top: 6px;
text-align: right; text-align: right;
} }
.end-session-dialog-logout-icon { .end-session-dialog-logout-icon {
border: 2px solid #8b8b8b; border: 2px solid #8b8b8b;
border-radius: 5px; border-radius: 5px;
width: 48px; width: 32px;
height: 48px; height: 32px;
background-size: contain; background-size: contain;
} }
.end-session-dialog-shutdown-icon { .end-session-dialog-shutdown-icon {
color: #bebebe; color: #bebebe;
width: 48px; width: 32px;
height: 48px; height: 32px;
} }
.end-session-dialog-inhibitor-layout { .end-session-dialog-inhibitor-layout {
spacing: 16px; spacing: 16px;
max-height: 200px; max-height: 200px;
padding-right: 65px; padding-right: 50px;
padding-left: 65px; padding-left: 50px;
} }
.end-session-dialog-session-list, .end-session-dialog-session-list,
@ -2449,13 +2388,12 @@ StScrollBar StButton#vhandle:active {
color: #E8E8E8; color: #E8E8E8;
} }
.login-dialog-username, .login-dialog-username {
.user-widget-label {
font-size: 16pt; font-size: 16pt;
font-weight: bold; font-weight: bold;
text-align: left; text-align: left;
padding-left: 15px; padding-left: 15px;
text-shadow: rgba(0, 0, 0, 0.5) 0px 2px 1px 0px; text-shadow: black 0px 4px 3px 0px;
} }
.login-dialog-prompt-layout { .login-dialog-prompt-layout {
@ -2547,6 +2485,11 @@ StScrollBar StButton#vhandle:active {
} }
.user-widget-label { .user-widget-label {
font-size: 20px;
font-weight: bold;
text-align: left;
color:white;
text-shadow: black 0px 4px 3px 0px;
} }
.user-widget-label:ltr { .user-widget-label:ltr {
@ -2569,7 +2512,7 @@ StScrollBar StButton#vhandle:active {
box-shadow: 0px 4px 8px rgba(0,0,0,0.9); box-shadow: 0px 4px 8px rgba(0,0,0,0.9);
} }
#lockDialogGroup { #systemGroup {
background: #2e3436 url(noise-texture.png); background: #2e3436 url(noise-texture.png);
background-repeat: repeat; background-repeat: repeat;
} }

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg3863"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="menu-arrow.svg">
<defs
id="defs3865" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="15.836083"
inkscape:cx="-3.1641676"
inkscape:cy="11.823817"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1366"
inkscape:window-height="702"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:snap-bbox="true">
<sodipodi:guide
orientation="1,0"
position="15.996443,16.922964"
id="guide3873" />
<sodipodi:guide
orientation="0,1"
position="28.041217,3.1256134"
id="guide3875" />
<sodipodi:guide
orientation="0,1"
position="-0.80372916,24.469088"
id="guide3877" />
<sodipodi:guide
orientation="1,0"
position="3.0363102,34.649657"
id="guide3879" />
<sodipodi:guide
orientation="1,0"
position="29.023553,28.577037"
id="guide3881" />
<inkscape:grid
type="xygrid"
id="grid2988" />
</sodipodi:namedview>
<metadata
id="metadata3868">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(0,-16)">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 4,23 8,0 -4,5 z"
id="path3883"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -17,15 +17,17 @@ packages. If you are interested in building GNOME Shell from source,
we would recommend building from version control using the build we would recommend building from version control using the build
script described at: script described at:
https://wiki.gnome.org/Projects/GnomeShell http://live.gnome.org/GnomeShell
Not only will that give you the very latest version of this rapidly Not only will that give you the very latest version of this rapidly
changing project, it will be much easier than get GNOME Shell and changing project, it will be much easier than get GNOME Shell and
its dependencies to build from tarballs.</description> its dependencies to build from tarballs.</description>
<homepage rdf:resource="https://wiki.gnome.org/Projects/GnomeShell" /> <!--
<homepage rdf:resource="http://live.gnome.org/GnomeShell" />
-->
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" /> <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
<download-page rdf:resource="http://download.gnome.org/sources/gnome-shell/" /> <download-page rdf:resource="http://download.gnome.org/sources/gnome-shell/" />
<bug-database rdf:resource="https://bugzilla.gnome.org/browse.cgi?product=gnome-shell" /> <bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=gnome-shell" />
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" /> <category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />

View File

@ -6,7 +6,6 @@ misc/config.js: misc/config.js.in Makefile
sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \ sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \
-e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \ -e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \
-e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \ -e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \
-e "s|[@]HAVE_NETWORKMANAGER@|$(HAVE_NETWORKMANAGER)|g" \
-e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \ -e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
-e "s|[@]datadir@|$(datadir)|g" \ -e "s|[@]datadir@|$(datadir)|g" \
-e "s|[@]libexecdir@|$(libexecdir)|g" \ -e "s|[@]libexecdir@|$(libexecdir)|g" \

View File

@ -450,7 +450,8 @@ const AuthPrompt = new Lang.Class({
// respond to the request with the username // respond to the request with the username
beginRequestType = BeginRequestType.PROVIDE_USERNAME; beginRequestType = BeginRequestType.PROVIDE_USERNAME;
} else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) || } else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) ||
this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { (this.smartcardDetected &&
this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME))) {
// We don't need to know the username if the user preempted the login screen // We don't need to know the username if the user preempted the login screen
// with a smartcard or with preauthenticated oVirt credentials // with a smartcard or with preauthenticated oVirt credentials
beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME; beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME;

View File

@ -36,7 +36,6 @@ const BoxPointer = imports.ui.boxpointer;
const CtrlAltTab = imports.ui.ctrlAltTab; const CtrlAltTab = imports.ui.ctrlAltTab;
const GdmUtil = imports.gdm.util; const GdmUtil = imports.gdm.util;
const Layout = imports.ui.layout; const Layout = imports.ui.layout;
const LoginManager = imports.misc.loginManager;
const Main = imports.ui.main; const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Realmd = imports.gdm.realmd; const Realmd = imports.gdm.realmd;
@ -275,7 +274,7 @@ const SessionMenuButton = new Lang.Class({
this.actor = new St.Bin({ child: this._button }); this.actor = new St.Bin({ child: this._button });
this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.TOP); this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.TOP);
Main.uiGroup.add_actor(this._menu.actor); Main.layoutManager.menuGroup.add_actor(this._menu.actor);
this._menu.actor.hide(); this._menu.actor.hide();
this._menu.connect('open-state-changed', this._menu.connect('open-state-changed',
@ -470,19 +469,6 @@ const LoginDialog = new Lang.Class({
this._sessionMenuButton.actor.show(); this._sessionMenuButton.actor.show();
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
this._disableUserList = undefined;
this._userListLoaded = false;
LoginManager.getLoginManager().getCurrentSessionProxy(Lang.bind(this, this._gotGreeterSessionProxy));
// If the user list is enabled, it should take key focus; make sure the
// screen shield is initialized first to prevent it from stealing the
// focus later
Main.layoutManager.connect('startup-complete',
Lang.bind(this, this._updateDisableUserList));
},
_ensureUserListLoaded: function() {
if (!this._userManager.is_loaded) if (!this._userManager.is_loaded)
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
Lang.bind(this, function() { Lang.bind(this, function() {
@ -494,7 +480,8 @@ const LoginDialog = new Lang.Class({
})); }));
else else
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList)); GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList));
},
},
_updateDisableUserList: function() { _updateDisableUserList: function() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
@ -537,12 +524,9 @@ const LoginDialog = new Lang.Class({
return; return;
this._logoBin.destroy_all_children(); this._logoBin.destroy_all_children();
if (this._logoFileUri) { if (this._logoFileUri)
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri, this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri,
-1, _LOGO_ICON_HEIGHT, -1, _LOGO_ICON_HEIGHT));
scaleFactor));
}
}, },
_updateLogo: function() { _updateLogo: function() {
@ -641,36 +625,6 @@ const LoginDialog = new Lang.Class({
this._showPrompt(); this._showPrompt();
}, },
_loginScreenSessionActivated: function() {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_SUCCEEDED)
return;
Tweener.addTween(this.actor,
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad',
onUpdate: function() {
let children = Main.layoutManager.uiGroup.get_children();
for (let i = 0; i < children.length; i++) {
if (children[i] != Main.layoutManager.screenShieldGroup)
children[i].opacity = this.actor.opacity;
}
},
onUpdateScope: this,
onComplete: function() {
this._authPrompt.reset();
},
onCompleteScope: this });
},
_gotGreeterSessionProxy: function(proxy) {
proxy.connect('g-properties-changed', Lang.bind(this, function() {
if (proxy.Active)
this._loginScreenSessionActivated();
}));
},
_startSession: function(serviceName) { _startSession: function(serviceName) {
Tweener.addTween(this.actor, Tweener.addTween(this.actor,
{ opacity: 0, { opacity: 0,
@ -847,7 +801,6 @@ const LoginDialog = new Lang.Class({
}, },
_showUserList: function() { _showUserList: function() {
this._ensureUserListLoaded();
this._authPrompt.hide(); this._authPrompt.hide();
this._sessionMenuButton.close(); this._sessionMenuButton.close();
this._setUserListExpanded(true); this._setUserListExpanded(true);
@ -891,17 +844,14 @@ const LoginDialog = new Lang.Class({
}, },
_loadUserList: function() { _loadUserList: function() {
if (this._userListLoaded)
return GLib.SOURCE_REMOVE;
this._userListLoaded = true;
let users = this._userManager.list_users(); let users = this._userManager.list_users();
for (let i = 0; i < users.length; i++) { for (let i = 0; i < users.length; i++) {
this._userList.addUser(users[i]); this._userList.addUser(users[i]);
} }
this._updateDisableUserList();
this._userManager.connect('user-added', this._userManager.connect('user-added',
Lang.bind(this, function(userManager, user) { Lang.bind(this, function(userManager, user) {
this._userList.addUser(user); this._userList.addUser(user);
@ -911,8 +861,6 @@ const LoginDialog = new Lang.Class({
Lang.bind(this, function(userManager, user) { Lang.bind(this, function(userManager, user) {
this._userList.removeUser(user); this._userList.removeUser(user);
})); }));
return GLib.SOURCE_REMOVE;
}, },
open: function() { open: function() {

View File

@ -298,7 +298,7 @@ const ShellUserVerifier = new Lang.Class({
if (!this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY)) if (!this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
smartcardDetected = false; smartcardDetected = false;
else if (this._reauthOnly) else if (this.reauthenticating)
smartcardDetected = this._smartcardManager.hasInsertedLoginToken(); smartcardDetected = this._smartcardManager.hasInsertedLoginToken();
else else
smartcardDetected = this._smartcardManager.hasInsertedTokens(); smartcardDetected = this._smartcardManager.hasInsertedTokens();

View File

@ -6,8 +6,6 @@ const PACKAGE_NAME = '@PACKAGE_NAME@';
const PACKAGE_VERSION = '@PACKAGE_VERSION@'; const PACKAGE_VERSION = '@PACKAGE_VERSION@';
/* 1 if gnome-bluetooth is available, 0 otherwise */ /* 1 if gnome-bluetooth is available, 0 otherwise */
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@; const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
/* 1 if networkmanager is available, 0 otherwise */
const HAVE_NETWORKMANAGER = @HAVE_NETWORKMANAGER@;
/* gettext package */ /* gettext package */
const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@'; const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
/* locale dir */ /* locale dir */

View File

@ -39,7 +39,6 @@ const SystemdLoginSessionIface = '<node> \
<interface name="org.freedesktop.login1.Session"> \ <interface name="org.freedesktop.login1.Session"> \
<signal name="Lock" /> \ <signal name="Lock" /> \
<signal name="Unlock" /> \ <signal name="Unlock" /> \
<property name="Active" type="b" access="read" /> \
</interface> \ </interface> \
</node>'; </node>';

View File

@ -24,7 +24,7 @@ const WINDOW_PREVIEW_SIZE = 128;
const APP_ICON_SIZE = 96; const APP_ICON_SIZE = 96;
const APP_ICON_SIZE_SMALL = 48; const APP_ICON_SIZE_SMALL = 48;
const baseIconSizes = [96, 64, 48, 32, 22]; const iconSizes = [96, 64, 48, 32, 22];
const AppIconMode = { const AppIconMode = {
THUMBNAIL_ONLY: 1, THUMBNAIL_ONLY: 1,
@ -167,8 +167,6 @@ const AppSwitcherPopup = new Lang.Class({
this._select(this._selectedIndex, this._nextWindow()); this._select(this._selectedIndex, this._nextWindow());
else if (keysym == Clutter.Up) else if (keysym == Clutter.Up)
this._select(this._selectedIndex, null, true); this._select(this._selectedIndex, null, true);
else
return Clutter.EVENT_PROPAGATE;
} else { } else {
if (keysym == Clutter.Left) if (keysym == Clutter.Left)
this._select(this._previous()); this._select(this._previous());
@ -176,11 +174,7 @@ const AppSwitcherPopup = new Lang.Class({
this._select(this._next()); this._select(this._next());
else if (keysym == Clutter.Down) else if (keysym == Clutter.Down)
this._select(this._selectedIndex, 0); this._select(this._selectedIndex, 0);
else
return Clutter.EVENT_PROPAGATE;
} }
return Clutter.EVENT_STOP;
}, },
_scrollHandler: function(direction) { _scrollHandler: function(direction) {
@ -409,11 +403,7 @@ const WindowSwitcherPopup = new Lang.Class({
this._select(this._previous()); this._select(this._previous());
else if (keysym == Clutter.Right) else if (keysym == Clutter.Right)
this._select(this._next()); this._select(this._next());
else
return Clutter.EVENT_PROPAGATE;
} }
return Clutter.EVENT_STOP;
}, },
_finish: function() { _finish: function() {
@ -440,6 +430,7 @@ const AppIcon = new Lang.Class({
set_size: function(size) { set_size: function(size) {
this.icon = this.app.create_icon_texture(size); this.icon = this.app.create_icon_texture(size);
this._iconBin.set_size(size, size);
this._iconBin.child = this.icon; this._iconBin.child = this.icon;
} }
}); });
@ -488,13 +479,12 @@ const AppSwitcher = new Lang.Class({
Mainloop.source_remove(this._mouseTimeOutId); Mainloop.source_remove(this._mouseTimeOutId);
}, },
_setIconSize: function() { _getPreferredHeight: function (actor, forWidth, alloc) {
let j = 0; let j = 0;
while(this._items.length > 1 && this._items[j].style_class != 'item-box') { while(this._items.length > 1 && this._items[j].style_class != 'item-box') {
j++; j++;
} }
let themeNode = this._items[j].get_theme_node(); let themeNode = this._items[j].get_theme_node();
let iconPadding = themeNode.get_horizontal_padding(); let iconPadding = themeNode.get_horizontal_padding();
let iconBorder = themeNode.get_border_width(St.Side.LEFT) + themeNode.get_border_width(St.Side.RIGHT); let iconBorder = themeNode.get_border_width(St.Side.LEFT) + themeNode.get_border_width(St.Side.RIGHT);
let [iconMinHeight, iconNaturalHeight] = this.icons[j].label.get_preferred_height(-1); let [iconMinHeight, iconNaturalHeight] = this.icons[j].label.get_preferred_height(-1);
@ -505,22 +495,19 @@ const AppSwitcher = new Lang.Class({
let primary = Main.layoutManager.primaryMonitor; let primary = Main.layoutManager.primaryMonitor;
let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding(); let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding();
let availWidth = primary.width - parentPadding - this.actor.get_theme_node().get_horizontal_padding(); let availWidth = primary.width - parentPadding - this.actor.get_theme_node().get_horizontal_padding();
let height = 0;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; for(let i = 0; i < iconSizes.length; i++) {
let iconSizes = baseIconSizes.map(function(s) { this._iconSize = iconSizes[i];
return s * scaleFactor; height = iconSizes[i] + iconSpacing;
});
if (this._items.length == 1) {
this._iconSize = baseIconSizes[0];
} else {
for(let i = 0; i < baseIconSizes.length; i++) {
this._iconSize = baseIconSizes[i];
let height = iconSizes[i] + iconSpacing;
let w = height * this._items.length + totalSpacing; let w = height * this._items.length + totalSpacing;
if (w <= availWidth) if (w <= availWidth)
break; break;
} }
if (this._items.length == 1) {
this._iconSize = iconSizes[0];
height = iconSizes[0] + iconSpacing;
} }
for(let i = 0; i < this.icons.length; i++) { for(let i = 0; i < this.icons.length; i++) {
@ -528,11 +515,9 @@ const AppSwitcher = new Lang.Class({
break; break;
this.icons[i].set_size(this._iconSize); this.icons[i].set_size(this._iconSize);
} }
},
_getPreferredHeight: function (actor, forWidth, alloc) { alloc.min_size = height;
this._setIconSize(); alloc.natural_size = height;
this.parent(actor, forWidth, alloc);
}, },
_allocate: function (actor, box, flags) { _allocate: function (actor, box, flags) {
@ -665,19 +650,17 @@ const ThumbnailList = new Lang.Class({
totalPadding += this.actor.get_theme_node().get_horizontal_padding() + this.actor.get_theme_node().get_vertical_padding(); totalPadding += this.actor.get_theme_node().get_horizontal_padding() + this.actor.get_theme_node().get_vertical_padding();
let [labelMinHeight, labelNaturalHeight] = this._labels[0].get_preferred_height(-1); let [labelMinHeight, labelNaturalHeight] = this._labels[0].get_preferred_height(-1);
let spacing = this._items[0].child.get_theme_node().get_length('spacing'); let spacing = this._items[0].child.get_theme_node().get_length('spacing');
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let thumbnailSize = THUMBNAIL_DEFAULT_SIZE * scaleFactor;
availHeight = Math.min(availHeight - labelNaturalHeight - totalPadding - spacing, thumbnailSize); availHeight = Math.min(availHeight - labelNaturalHeight - totalPadding - spacing, THUMBNAIL_DEFAULT_SIZE);
let binHeight = availHeight + this._items[0].get_theme_node().get_vertical_padding() + this.actor.get_theme_node().get_vertical_padding() - spacing; let binHeight = availHeight + this._items[0].get_theme_node().get_vertical_padding() + this.actor.get_theme_node().get_vertical_padding() - spacing;
binHeight = Math.min(thumbnailSize, binHeight); binHeight = Math.min(THUMBNAIL_DEFAULT_SIZE, binHeight);
for (let i = 0; i < this._thumbnailBins.length; i++) { for (let i = 0; i < this._thumbnailBins.length; i++) {
let mutterWindow = this._windows[i].get_compositor_private(); let mutterWindow = this._windows[i].get_compositor_private();
if (!mutterWindow) if (!mutterWindow)
continue; continue;
let clone = _createWindowClone(mutterWindow, thumbnailSize); let clone = _createWindowClone(mutterWindow, THUMBNAIL_DEFAULT_SIZE);
this._thumbnailBins[i].set_height(binHeight); this._thumbnailBins[i].set_height(binHeight);
this._thumbnailBins[i].add_actor(clone); this._thumbnailBins[i].add_actor(clone);
this._clones.push(clone); this._clones.push(clone);

View File

@ -21,9 +21,7 @@ const Animation = new Lang.Class({
this._isPlaying = false; this._isPlaying = false;
this._timeoutId = 0; this._timeoutId = 0;
this._frame = 0; this._frame = 0;
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height,
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height, scaleFactor,
Lang.bind(this, this._animationsLoaded)); Lang.bind(this, this._animationsLoaded));
this.actor.set_child(this._animations); this.actor.set_child(this._animations);
}, },

View File

@ -46,9 +46,6 @@ const INDICATORS_ANIMATION_MAX_TIME = 0.75;
const PAGE_SWITCH_TRESHOLD = 0.2; const PAGE_SWITCH_TRESHOLD = 0.2;
const PAGE_SWITCH_TIME = 0.3; const PAGE_SWITCH_TIME = 0.3;
const VIEWS_SWITCH_TIME = 0.4;
const VIEWS_SWITCH_ANIMATION_DELAY = 0.1;
function _getCategories(info) { function _getCategories(info) {
let categoriesStr = info.get_categories(); let categoriesStr = info.get_categories();
if (!categoriesStr) if (!categoriesStr)
@ -56,6 +53,14 @@ function _getCategories(info) {
return categoriesStr.split(';'); return categoriesStr.split(';');
} }
function _isTerminal(app) {
let info = app.get_app_info();
if (!info)
return false;
let categories = _getCategories(info);
return categories.indexOf('TerminalEmulator') > -1;
}
function _listsIntersect(a, b) { function _listsIntersect(a, b) {
for (let itemA of a) for (let itemA of a)
if (b.indexOf(itemA) >= 0) if (b.indexOf(itemA) >= 0)
@ -99,9 +104,6 @@ const BaseAppView = new Lang.Class({
else else
this._grid = new IconGrid.IconGrid(gridParams); this._grid = new IconGrid.IconGrid(gridParams);
this._grid.connect('key-focus-in', Lang.bind(this, function(grid, actor) {
this._keyFocusIn(actor);
}));
// Standard hack for ClutterBinLayout // Standard hack for ClutterBinLayout
this._grid.actor.x_expand = true; this._grid.actor.x_expand = true;
@ -109,10 +111,6 @@ const BaseAppView = new Lang.Class({
this._allItems = []; this._allItems = [];
}, },
_keyFocusIn: function(actor) {
// Nothing by default
},
removeAll: function() { removeAll: function() {
this._grid.destroyAll(); this._grid.destroyAll();
this._items = {}; this._items = {};
@ -258,8 +256,7 @@ const PageIndicators = new Lang.Class({
Tweener.addTween(children[i], Tweener.addTween(children[i],
{ translation_x: 0, { translation_x: 0,
time: INDICATORS_BASE_TIME + delay * i, time: INDICATORS_BASE_TIME + delay * i,
transition: 'easeInOutQuad', transition: 'easeInOutQuad'
delay: VIEWS_SWITCH_ANIMATION_DELAY
}); });
} }
} }
@ -565,7 +562,7 @@ const AllView = new Lang.Class({
})); }));
}, },
_keyFocusIn: function(icon) { _ensureIconVisible: function(icon) {
let itemPage = this._grid.getItemPage(icon); let itemPage = this._grid.getItemPage(icon);
this.goToPage(itemPage); this.goToPage(itemPage);
}, },
@ -794,10 +791,8 @@ const AppDisplay = new Lang.Class({
_showView: function(activeIndex) { _showView: function(activeIndex) {
for (let i = 0; i < this._views.length; i++) { for (let i = 0; i < this._views.length; i++) {
let actor = this._views[i].view.actor; let actor = this._views[i].view.actor;
let params = { time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
let params = { time: VIEWS_SWITCH_TIME, opacity: (i == activeIndex) ? 255 : 0 };
opacity: (i == activeIndex) ? 255 : 0,
delay: (i == activeIndex) ? VIEWS_SWITCH_ANIMATION_DELAY : 0 };
if (i == activeIndex) if (i == activeIndex)
actor.visible = true; actor.visible = true;
else else
@ -893,7 +888,7 @@ const AppSearchProvider = new Lang.Class({
let app = this._appSys.lookup_app(result); let app = this._appSys.lookup_app(result);
let event = Clutter.get_current_event(); let event = Clutter.get_current_event();
let modifiers = event ? event.get_state() : 0; let modifiers = event ? event.get_state() : 0;
let openNewWindow = modifiers & Clutter.ModifierType.CONTROL_MASK; let openNewWindow = (modifiers & Clutter.ModifierType.CONTROL_MASK) || _isTerminal(app);
if (openNewWindow) if (openNewWindow)
app.open_new_window(-1); app.open_new_window(-1);
@ -936,27 +931,20 @@ const FolderView = new Lang.Class({
this.actor.add_action(action); this.actor.add_action(action);
}, },
_keyFocusIn: function(actor) {
Util.ensureActorVisibleInScrollView(this.actor, actor);
},
createFolderIcon: function(size) { createFolderIcon: function(size) {
let layout = new Clutter.TableLayout(); let icon = new St.Widget({ layout_manager: new Clutter.BinLayout(),
let icon = new St.Widget({ layout_manager: layout, style_class: 'app-folder-icon',
style_class: 'app-folder-icon' }); width: size, height: size });
layout.hookup_style(icon);
let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size); let subSize = Math.floor(FOLDER_SUBICON_FRACTION * size);
let numItems = this._allItems.length; let aligns = [ Clutter.ActorAlign.START, Clutter.ActorAlign.END ];
for (let i = 0; i < 4; i++) { for (let i = 0; i < Math.min(this._allItems.length, 4); i++) {
let bin; let texture = this._allItems[i].app.create_icon_texture(subSize);
if (i < numItems) { let bin = new St.Bin({ child: texture,
let texture = this._allItems[i].app.create_icon_texture(subSize); x_expand: true, y_expand: true });
bin = new St.Bin({ child: texture }); bin.set_x_align(aligns[i % 2]);
} else { bin.set_y_align(aligns[Math.floor(i / 2)]);
bin = new St.Bin({ width: subSize, height: subSize }); icon.add_actor(bin);
}
layout.pack(bin, i % 2, Math.floor(i / 2));
} }
return icon; return icon;
@ -1415,6 +1403,9 @@ const AppIcon = new Lang.Class({
if (button == 1) { if (button == 1) {
this._onActivate(Clutter.get_current_event()); this._onActivate(Clutter.get_current_event());
} else if (button == 2) { } else if (button == 2) {
// Last workspace is always empty
let launchWorkspace = global.screen.get_workspace_by_index(global.screen.n_workspaces - 1);
launchWorkspace.activate(global.get_current_time());
this.app.open_new_window(-1); this.app.open_new_window(-1);
Main.overview.hide(); Main.overview.hide();
} }
@ -1475,8 +1466,9 @@ const AppIcon = new Lang.Class({
_onActivate: function (event) { _onActivate: function (event) {
let modifiers = event.get_state(); let modifiers = event.get_state();
if (modifiers & Clutter.ModifierType.CONTROL_MASK if ((modifiers & Clutter.ModifierType.CONTROL_MASK
&& this.app.state == Shell.AppState.RUNNING) { && this.app.state == Shell.AppState.RUNNING)
|| _isTerminal(this.app)) {
this.app.open_new_window(-1); this.app.open_new_window(-1);
} else { } else {
this.app.activate(); this.app.activate();
@ -1533,7 +1525,7 @@ const AppIconMenu = new Lang.Class({
})); }));
source.actor.connect('destroy', Lang.bind(this, function () { this.actor.destroy(); })); source.actor.connect('destroy', Lang.bind(this, function () { this.actor.destroy(); }));
Main.uiGroup.add_actor(this.actor); Main.layoutManager.menuGroup.add_actor(this.actor);
}, },
_redisplay: function() { _redisplay: function() {

View File

@ -132,23 +132,44 @@ const BackgroundCache = new Lang.Class({
this._removeContent(this._images, content); this._removeContent(this._images, content);
}, },
_attachCallerToFileLoad: function(caller, fileLoad) { _loadImageContentInternal: function(filename, style) {
fileLoad.callers.push(caller); let cancellable = new Gio.Cancellable();
let content = new Meta.Background({ meta_screen: global.screen });
if (!caller.cancellable) let info = { filename: filename,
return; style: style,
cancellable: cancellable,
callers: [] };
caller.cancellable.connect(Lang.bind(this, function() { content.load_file_async(filename, style, cancellable, Lang.bind(this, function(object, result) {
let idx = fileLoad.callers.indexOf(caller); if (cancellable.is_cancelled())
fileLoad.callers.splice(idx, 1); return;
if (fileLoad.callers.length == 0) { try {
fileLoad.cancellable.cancel(); content.load_file_finish(result);
} catch(e) {
let idx = this._pendingFileLoads.indexOf(fileLoad); content = null;
this._pendingFileLoads.splice(idx, 1);
} }
if (content) {
this._monitorFile(filename);
info.callers.forEach(Lang.bind(this, function(caller) {
let newContent = content.copy(caller.monitorIndex, caller.effects);
this._images.push(newContent);
caller.onFinished(newContent);
}));
} else {
info.callers.forEach(Lang.bind(this, function(caller) {
caller.onFinished(null);
}));
}
let idx = this._pendingFileLoads.indexOf(info);
this._pendingFileLoads.splice(idx, 1);
})); }));
this._pendingFileLoads.push(info);
return info;
}, },
_loadImageContent: function(params) { _loadImageContent: function(params) {
@ -164,54 +185,33 @@ const BackgroundCache = new Lang.Class({
cancellable: params.cancellable, cancellable: params.cancellable,
onFinished: params.onFinished }; onFinished: params.onFinished };
let info = null;
for (let i = 0; i < this._pendingFileLoads.length; i++) { for (let i = 0; i < this._pendingFileLoads.length; i++) {
let fileLoad = this._pendingFileLoads[i]; let pendingLoad = this._pendingFileLoads[i];
if (pendingLoad.filename == params.filename && pendingLoad.style == params.style) {
if (fileLoad.filename == params.filename && info = pendingLoad;
fileLoad.style == params.style) { break;
this._attachCallerToFileLoad(caller, fileLoad);
return;
} }
} }
let fileLoad = { filename: params.filename, if (!info)
style: params.style, info = this._loadImageContentInternal(params.filename, params.style);
cancellable: new Gio.Cancellable(),
callers: [] };
this._attachCallerToFileLoad(caller, fileLoad);
let content = new Meta.Background({ meta_screen: global.screen }); info.callers.push(caller);
content.load_file_async(params.filename, if (caller.cancellable) {
params.style, caller.cancellable.connect(Lang.bind(this, function() {
params.cancellable, let idx = info.callers.indexOf(caller);
Lang.bind(this, info.callers.splice(idx, 1);
function(object, result) {
try {
content.load_file_finish(result);
this._monitorFile(params.filename); if (info.callers.length == 0) {
} catch(e) { info.cancellable.cancel();
content = null;
}
for (let i = 0; i < fileLoad.callers.length; i++) { let idx = this._pendingFileLoads.indexOf(info);
let caller = fileLoad.callers[i]; this._pendingFileLoads.splice(idx, 1);
if (caller.onFinished) { }
let newContent; }));
}
if (content) {
newContent = content.copy(caller.monitorIndex, caller.effects);
this._images.push(newContent);
}
caller.onFinished(newContent);
}
}
let idx = this._pendingFileLoads.indexOf(fileLoad);
this._pendingFileLoads.splice(idx, 1);
}));
}, },
getImageContent: function(params) { getImageContent: function(params) {
@ -261,7 +261,6 @@ const BackgroundCache = new Lang.Class({
monitorIndex: params.monitorIndex, monitorIndex: params.monitorIndex,
cancellable: params.cancellable, cancellable: params.cancellable,
onFinished: params.onFinished }); onFinished: params.onFinished });
} }
}, },
@ -635,31 +634,6 @@ const Background = new Lang.Class({
}); });
Signals.addSignalMethods(Background.prototype); Signals.addSignalMethods(Background.prototype);
const SystemBackground = new Lang.Class({
Name: 'SystemBackground',
_init: function() {
this._cache = getBackgroundCache();
this.actor = new Meta.BackgroundActor();
this._cache.getImageContent({ style: GDesktopEnums.BackgroundStyle.WALLPAPER,
filename: global.datadir + '/theme/noise-texture.png',
effects: Meta.BackgroundEffects.NONE,
onFinished: Lang.bind(this, function(content) {
this.actor.content = content;
this.emit('loaded');
})
});
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
},
_onDestroy: function() {
this._cache.removeImageContent(this.actor.content);
},
});
Signals.addSignalMethods(SystemBackground.prototype);
const Animation = new Lang.Class({ const Animation = new Lang.Class({
Name: 'Animation', Name: 'Animation',
@ -754,18 +728,17 @@ const BackgroundManager = new Lang.Class({
Lang.bind(this, function() { Lang.bind(this, function() {
newBackground.disconnect(newBackground.loadedSignalId); newBackground.disconnect(newBackground.loadedSignalId);
newBackground.loadedSignalId = 0; newBackground.loadedSignalId = 0;
if (this._newBackground != newBackground) {
/* Not interesting, we queued another load */
newBackground.actor.destroy();
return;
}
Tweener.addTween(this.background.actor, Tweener.addTween(this.background.actor,
{ opacity: 0, { opacity: 0,
time: FADE_ANIMATION_TIME, time: FADE_ANIMATION_TIME,
transition: 'easeOutQuad', transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() { onComplete: Lang.bind(this, function() {
if (this._newBackground != newBackground) {
/* Not interesting, we queued another load */
newBackground.actor.destroy();
return;
}
this.background.actor.destroy(); this.background.actor.destroy();
this.background = newBackground; this.background = newBackground;
this._newBackground = null; this._newBackground = null;

View File

@ -22,7 +22,7 @@ const BackgroundMenu = new Lang.Class({
this.actor.add_style_class_name('background-menu'); this.actor.add_style_class_name('background-menu');
layoutManager.uiGroup.add_actor(this.actor); layoutManager.menuGroup.add_actor(this.actor);
this.actor.hide(); this.actor.hide();
} }
}); });
@ -35,7 +35,7 @@ function addBackgroundMenu(actor, layoutManager) {
function openMenu() { function openMenu() {
let [x, y] = global.get_pointer(); let [x, y] = global.get_pointer();
Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0); Main.layoutManager.setDummyCursorPosition(x, y);
actor._backgroundMenu.open(BoxPointer.PopupAnimation.NONE); actor._backgroundMenu.open(BoxPointer.PopupAnimation.NONE);
} }

View File

@ -403,8 +403,6 @@ const Calendar = new Lang.Class({
// Start off with the current date // Start off with the current date
this._selectedDate = new Date(); this._selectedDate = new Date();
this._shouldDateGrabFocus = false;
this.actor = new St.Table({ homogeneous: false, this.actor = new St.Table({ homogeneous: false,
style_class: 'calendar', style_class: 'calendar',
reactive: true }); reactive: true });
@ -420,10 +418,8 @@ const Calendar = new Lang.Class({
setEventSource: function(eventSource) { setEventSource: function(eventSource) {
this._eventSource = eventSource; this._eventSource = eventSource;
this._eventSource.connect('changed', Lang.bind(this, function() { this._eventSource.connect('changed', Lang.bind(this, function() {
this._rebuildCalendar();
this._update(); this._update();
})); }));
this._rebuildCalendar();
this._update(); this._update();
}, },
@ -552,7 +548,6 @@ const Calendar = new Lang.Class({
_onSettingsChange: function() { _onSettingsChange: function() {
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY); this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
this._buildHeader(); this._buildHeader();
this._rebuildCalendar();
this._update(); this._update();
}, },
@ -612,9 +607,7 @@ const Calendar = new Lang.Class({
button._date = new Date(iter); button._date = new Date(iter);
button.connect('clicked', Lang.bind(this, function() { button.connect('clicked', Lang.bind(this, function() {
this._shouldDateGrabFocus = true;
this.setDate(button._date); this.setDate(button._date);
this._shouldDateGrabFocus = false;
})); }));
let hasEvents = this._eventSource.hasEvents(iter); let hasEvents = this._eventSource.hasEvents(iter);
@ -680,11 +673,8 @@ const Calendar = new Lang.Class({
this._rebuildCalendar(); this._rebuildCalendar();
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('active'); button.add_style_pseudo_class('active');
if (this._shouldDateGrabFocus)
button.grab_key_focus();
}
else else
button.remove_style_pseudo_class('active'); button.remove_style_pseudo_class('active');
})); }));

View File

@ -373,12 +373,6 @@ const VPNRequestHandler = new Lang.Class({
argv.push('-i'); argv.push('-i');
if (flags & NMClient.SecretAgentGetSecretsFlags.REQUEST_NEW) if (flags & NMClient.SecretAgentGetSecretsFlags.REQUEST_NEW)
argv.push('-r'); argv.push('-r');
if (authHelper.supportsHints) {
for (let i = 0; i < hints.length; i++) {
argv.push('-t');
argv.push(hints[i]);
}
}
this._newStylePlugin = authHelper.externalUIMode; this._newStylePlugin = authHelper.externalUIMode;
@ -516,12 +510,10 @@ const VPNRequestHandler = new Lang.Class({
_showNewStyleDialog: function() { _showNewStyleDialog: function() {
let keyfile = new GLib.KeyFile(); let keyfile = new GLib.KeyFile();
let data;
let contentOverride; let contentOverride;
try { try {
data = this._dataStdout.peek_buffer(); let data = this._dataStdout.peek_buffer();
keyfile.load_from_data(data.toString(), data.length, keyfile.load_from_data(data.toString(), data.length,
GLib.KeyFileFlags.NONE); GLib.KeyFileFlags.NONE);
@ -554,16 +546,13 @@ const VPNRequestHandler = new Lang.Class({
} }
} }
} catch(e) { } catch(e) {
// No output is a valid case it means "both secrets are stored" logError(e, 'error while reading VPN plugin output keyfile');
if (data.length > 0) {
logError(e, 'error while reading VPN plugin output keyfile');
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR); this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return; return;
}
} }
if (contentOverride && contentOverride.secrets.length) { if (contentOverride.secrets.length) {
// Only show the dialog if we actually have something to ask // Only show the dialog if we actually have something to ask
this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], contentOverride); this._shellDialog = new NetworkSecretDialog(this._agent, this._requestId, this._connection, 'vpn', [], contentOverride);
this._shellDialog.open(global.get_current_time()); this._shellDialog.open(global.get_current_time());
@ -597,15 +586,7 @@ const NetworkAgent = new Lang.Class({
Name: 'NetworkAgent', Name: 'NetworkAgent',
_init: function() { _init: function() {
try { this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent' });
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
capabilities: NMClient.SecretAgentCapabilities.VPN_HINTS
});
} catch(e) {
// Support older versions without NetworkAgent:capabilities
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent'
});
}
this._dialogs = { }; this._dialogs = { };
this._vpnRequests = { }; this._vpnRequests = { };
@ -705,23 +686,16 @@ const NetworkAgent = new Lang.Class({
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;
let hints = false;
try { try {
externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode'); externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode');
} catch(e) { } // ignore errors if key does not exist } catch(e) { } // ignore errors if key does not exist
try {
hints = keyfile.get_boolean('GNOME', 'supports-hints');
} catch(e) { } // ignore errors if key does not exist
let path = binary; let path = binary;
if (!GLib.path_is_absolute(path)) { if (!GLib.path_is_absolute(path)) {
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 };
else 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) {

View File

@ -1,6 +1,5 @@
// -*- 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 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;
@ -29,8 +28,6 @@ const SCROLLBACK_HISTORY_LINES = 10;
// See Notification._onEntryChanged // See Notification._onEntryChanged
const COMPOSING_STOP_TIMEOUT = 5; const COMPOSING_STOP_TIMEOUT = 5;
const CLOCK_FORMAT_KEY = 'clock-format';
const NotificationDirection = { const NotificationDirection = {
SENT: 'chat-sent', SENT: 'chat-sent',
RECEIVED: 'chat-received' RECEIVED: 'chat-received'
@ -908,14 +905,14 @@ const ChatNotification = new Lang.Class({
let group = props.group; let group = props.group;
if (group != this._lastGroup) { if (group != this._lastGroup) {
let style = 'chat-group-' + group;
this._lastGroup = group; this._lastGroup = group;
let emptyLine = new St.Label({ style_class: 'chat-empty-line' }); this._lastGroupActor = new St.BoxLayout({ style_class: style,
this.addActor(emptyLine); vertical: true });
this.addActor(this._lastGroupActor);
} }
this._lastMessageBox = new St.BoxLayout({ vertical: false }); this._lastGroupActor.add(body, props.childProps);
this._lastMessageBox.add(body, props.childProps);
this.addActor(this._lastMessageBox);
this.updated(); this.updated();
@ -944,81 +941,32 @@ const ChatNotification = new Lang.Class({
let format; let format;
let desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' }); // Show only the hour if date is on today
let clockFormat = desktopSettings.get_string(CLOCK_FORMAT_KEY); if(daysAgo < 1){
format = "<b>%H:%M</b>";
switch (clockFormat) {
case '24h':
// Show only the time if date is on today
if(daysAgo < 1){
/* Translators: Time in 24h format */
format = _("%H\u2236%M");
}
// Show the word "Yesterday" and time if date is on yesterday
else if(daysAgo <2){
/* Translators: this is the word "Yesterday" followed by a
time string in 24h format. i.e. "Yesterday, 14:30" */
// xgettext:no-c-format
format = _("Yesterday, %H\u2236%M");
}
// Show a week day and time if date is in the last week
else if (daysAgo < 7) {
/* Translators: this is the week day name followed by a time
string in 24h format. i.e. "Monday, 14:30" */
// xgettext:no-c-format
format = _("%A, %H\u2236%M");
} else if (date.getYear() == now.getYear()) {
/* Translators: this is the month name and day number
followed by a time string in 24h format.
i.e. "May 25, 14:30" */
// xgettext:no-c-format
format = _("%B %d, %H\u2236%M");
} else {
/* Translators: this is the month name, day number, year
number followed by a time string in 24h format.
i.e. "May 25 2012, 14:30" */
// xgettext:no-c-format
format = _("%B %d %Y, %H\u2236%M");
}
break;
default:
/* explicit fall-through */
case '12h':
// Show only the time if date is on today
if(daysAgo < 1){
/* Translators: Time in 24h format */
format = _("%l\u2236%M %p");
}
// Show the word "Yesterday" and time if date is on yesterday
else if(daysAgo <2){
/* Translators: this is the word "Yesterday" followed by a
time string in 12h format. i.e. "Yesterday, 2:30 pm" */
// xgettext:no-c-format
format = _("Yesterday, %l\u2236%M %p");
}
// Show a week day and time if date is in the last week
else if (daysAgo < 7) {
/* Translators: this is the week day name followed by a time
string in 12h format. i.e. "Monday, 2:30 pm" */
// xgettext:no-c-format
format = _("%A, %l\u2236%M %p");
} else if (date.getYear() == now.getYear()) {
/* Translators: this is the month name and day number
followed by a time string in 12h format.
i.e. "May 25, 2:30 pm" */
// xgettext:no-c-format
format = _("%B %d, %l\u2236%M %p");
} else {
/* Translators: this is the month name, day number, year
number followed by a time string in 12h format.
i.e. "May 25 2012, 2:30 pm"*/
// xgettext:no-c-format
format = _("%B %d %Y, %l\u2236%M %p");
}
break;
} }
// Show the word "Yesterday" and time if date is on yesterday
else if(daysAgo <2){
/* Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"*/
// xgettext:no-c-format
format = _("<b>Yesterday</b>, <b>%H:%M</b>");
}
// Show a week day and time if date is in the last week
else if (daysAgo < 7) {
/* Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30*/
// xgettext:no-c-format
format = _("<b>%A</b>, <b>%H:%M</b>");
} else if (date.getYear() == now.getYear()) {
/* Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"*/
// xgettext:no-c-format
format = _("<b>%B</b> <b>%d</b>, <b>%H:%M</b>");
} else {
/* Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"*/
// xgettext:no-c-format
format = _("<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> ");
}
return date.toLocaleFormat(format); return date.toLocaleFormat(format);
}, },
@ -1028,14 +976,13 @@ const ChatNotification = new Lang.Class({
let lastMessageTime = this._history[0].time; let lastMessageTime = this._history[0].time;
let lastMessageDate = new Date(lastMessageTime * 1000); let lastMessageDate = new Date(lastMessageTime * 1000);
let timeLabel = new St.Label({ text: this._formatTimestamp(lastMessageDate), let timeLabel = this._append({ body: this._formatTimestamp(lastMessageDate),
style_class: 'chat-meta-message', group: 'meta',
x_expand: true, styles: ['chat-meta-message'],
y_expand: true, childProps: { expand: true, x_fill: false,
x_align: Clutter.ActorAlign.END, x_align: St.Align.END },
y_align: Clutter.ActorAlign.END }); noTimestamp: true,
timestamp: lastMessageTime });
this._lastMessageBox.add_actor(timeLabel);
this._filterMessages(); this._filterMessages();
@ -1270,8 +1217,7 @@ const SubscriptionRequestNotification = new Lang.Class({
if (file) { if (file) {
let uri = file.get_uri(); let uri = file.get_uri();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; iconBox.child = textureCache.load_uri_async(uri, iconBox._size, iconBox._size);
iconBox.child = textureCache.load_uri_async(uri, iconBox._size, iconBox._size, scaleFactor);
} }
else { else {
iconBox.child = new St.Icon({ icon_name: 'avatar-default', iconBox.child = new St.Icon({ icon_name: 'avatar-default',
@ -1422,12 +1368,7 @@ const AccountNotification = new Lang.Class({
if (status == Tp.ConnectionStatus.CONNECTED) { if (status == Tp.ConnectionStatus.CONNECTED) {
this.destroy(); this.destroy();
} else if (status == Tp.ConnectionStatus.DISCONNECTED) { } else if (status == Tp.ConnectionStatus.DISCONNECTED) {
let connectionError = account.connection_error; this.update(this.title, this._getMessage(account.connection_error));
if (connectionError == Tp.error_get_dbus_name(Tp.Error.CANCELLED))
this.destroy();
else
this.update(this.title, this._getMessage(connectionError));
} }
})); }));
}, },

View File

@ -165,10 +165,6 @@ const CtrlAltTabPopup = new Lang.Class({
this._select(this._previous()); this._select(this._previous());
else if (keysym == Clutter.Right) else if (keysym == Clutter.Right)
this._select(this._next()); this._select(this._next());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}, },
_finish : function(time) { _finish : function(time) {

View File

@ -381,8 +381,6 @@ const DashActor = new Lang.Class({
} }
}); });
const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
const Dash = new Lang.Class({ const Dash = new Lang.Class({
Name: 'Dash', Name: 'Dash',
@ -634,24 +632,25 @@ const Dash = new Lang.Class({
let minHeight, natHeight; let minHeight, natHeight;
// Enforce the current icon size during the size request // Enforce the current icon size during the size request
firstIcon.setIconSize(this.iconSize); let [currentWidth, currentHeight] = firstIcon.icon.get_size();
firstIcon.icon.set_size(this.iconSize, this.iconSize);
[minHeight, natHeight] = firstButton.get_preferred_height(-1); [minHeight, natHeight] = firstButton.get_preferred_height(-1);
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; firstIcon.icon.set_size(currentWidth, currentHeight);
let iconSizes = baseIconSizes.map(function(s) {
return s * scaleFactor;
});
// Subtract icon padding and box spacing from the available height // Subtract icon padding and box spacing from the available height
availHeight -= iconChildren.length * (natHeight - this.iconSize * scaleFactor) + availHeight -= iconChildren.length * (natHeight - this.iconSize) +
(iconChildren.length - 1) * spacing; (iconChildren.length - 1) * spacing;
let availSize = availHeight / iconChildren.length; let availSize = availHeight / iconChildren.length;
let newIconSize = baseIconSizes[0]; let iconSizes = [ 16, 22, 24, 32, 48, 64 ];
let newIconSize = 16;
for (let i = 0; i < iconSizes.length; i++) { for (let i = 0; i < iconSizes.length; i++) {
if (iconSizes[i] < availSize) if (iconSizes[i] < availSize)
newIconSize = baseIconSizes[i]; newIconSize = iconSizes[i];
} }
if (newIconSize == this.iconSize) if (newIconSize == this.iconSize)

View File

@ -63,14 +63,9 @@ const DateMenuButton = new Lang.Class({
hbox.add(vbox); hbox.add(vbox);
// Date // Date
this._date = new St.Button({ style_class: 'datemenu-date-label', this._date = new St.Label({ style_class: 'datemenu-date-label',
can_focus: true, can_focus: true });
}); vbox.add(this._date);
this._date.connect('clicked',
Lang.bind(this, function() {
this._calendar.setDate(new Date(), false);
}));
vbox.add(this._date, { x_fill: false });
this._eventList = new Calendar.EventsList(); this._eventList = new Calendar.EventsList();
this._calendar = new Calendar.Calendar(); this._calendar = new Calendar.Calendar();
@ -191,7 +186,7 @@ const DateMenuButton = new Lang.Class({
*/ */
let dateFormat = _("%A %B %e, %Y"); let dateFormat = _("%A %B %e, %Y");
let displayDate = new Date(); let displayDate = new Date();
this._date.set_label(displayDate.toLocaleFormat(dateFormat)); this._date.set_text(displayDate.toLocaleFormat(dateFormat));
}, },
_getCalendarApp: function() { _getCalendarApp: function() {
@ -207,7 +202,7 @@ const DateMenuButton = new Lang.Class({
}, },
_getClockApp: function() { _getClockApp: function() {
return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop'); return Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
}, },
_onOpenCalendarActivate: function() { _onOpenCalendarActivate: function() {

View File

@ -46,7 +46,7 @@ let dragMonitors = [];
function _getEventHandlerActor() { function _getEventHandlerActor() {
if (!eventHandlerActor) { if (!eventHandlerActor) {
eventHandlerActor = new Clutter.Actor({ width: 0, height: 0 }); eventHandlerActor = new Clutter.Actor({ width: 0, height: 0 });
Main.uiGroup.add_actor(eventHandlerActor); Main.layoutManager.sessionGroup.add_actor(eventHandlerActor);
// We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen // We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen
// when you've grabbed the pointer. // when you've grabbed the pointer.
eventHandlerActor.connect('event', eventHandlerActor.connect('event',
@ -236,7 +236,7 @@ const _Draggable = new Lang.Class({
if (this.actor._delegate && this.actor._delegate.getDragActor) { if (this.actor._delegate && this.actor._delegate.getDragActor) {
this._dragActor = this.actor._delegate.getDragActor(); this._dragActor = this.actor._delegate.getDragActor();
Main.uiGroup.add_child(this._dragActor); Main.layoutManager.sessionGroup.add_child(this._dragActor);
this._dragActor.raise_top(); this._dragActor.raise_top();
Shell.util_set_hidden_from_pick(this._dragActor, true); Shell.util_set_hidden_from_pick(this._dragActor, true);
@ -276,7 +276,7 @@ const _Draggable = new Lang.Class({
this._dragOrigScale = this._dragActor.scale_x; this._dragOrigScale = this._dragActor.scale_x;
// Set the actor's scale such that it will keep the same // Set the actor's scale such that it will keep the same
// transformed size when it's reparented to the uiGroup // transformed size when it's reparented to the sessionGroup
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size(); let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
this._dragActor.set_scale(scaledWidth / this.actor.width, this._dragActor.set_scale(scaledWidth / this.actor.width,
scaledHeight / this.actor.height); scaledHeight / this.actor.height);
@ -286,7 +286,7 @@ const _Draggable = new Lang.Class({
this._dragOffsetY = actorStageY - this._dragStartY; this._dragOffsetY = actorStageY - this._dragStartY;
this._dragOrigParent.remove_actor(this._dragActor); this._dragOrigParent.remove_actor(this._dragActor);
Main.uiGroup.add_child(this._dragActor); Main.layoutManager.sessionGroup.add_child(this._dragActor);
this._dragActor.raise_top(); this._dragActor.raise_top();
Shell.util_set_hidden_from_pick(this._dragActor, true); Shell.util_set_hidden_from_pick(this._dragActor, true);
} }
@ -448,7 +448,7 @@ const _Draggable = new Lang.Class({
event.get_time())) { event.get_time())) {
// If it accepted the drop without taking the actor, // If it accepted the drop without taking the actor,
// handle it ourselves. // handle it ourselves.
if (this._dragActor.get_parent() == Main.uiGroup) { if (this._dragActor.get_parent() == Main.layoutManager.sessionGroup) {
if (this._restoreOnSuccess) { if (this._restoreOnSuccess) {
this._restoreDragActor(event.get_time()); this._restoreDragActor(event.get_time());
return true; return true;
@ -557,7 +557,7 @@ const _Draggable = new Lang.Class({
_onAnimationComplete : function (dragActor, eventTime) { _onAnimationComplete : function (dragActor, eventTime) {
if (this._dragOrigParent) { if (this._dragOrigParent) {
Main.uiGroup.remove_child(this._dragActor); Main.layoutManager.sessionGroup.remove_child(this._dragActor);
this._dragOrigParent.add_actor(this._dragActor); this._dragOrigParent.add_actor(this._dragActor);
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale); dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
dragActor.set_position(this._dragOrigX, this._dragOrigY); dragActor.set_position(this._dragOrigX, this._dragOrigY);

View File

@ -25,11 +25,9 @@ const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk; const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango; const Pango = imports.gi.Pango;
const Polkit = imports.gi.Polkit;
const St = imports.gi.St; const St = imports.gi.St;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const CheckBox = imports.ui.checkBox;
const GnomeSession = imports.misc.gnomeSession; const GnomeSession = imports.misc.gnomeSession;
const LoginManager = imports.misc.loginManager; const LoginManager = imports.misc.loginManager;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
@ -38,10 +36,8 @@ const UserWidget = imports.ui.userWidget;
let _endSessionDialog = null; let _endSessionDialog = null;
const TRIGGER_OFFLINE_UPDATE = '/usr/libexec/pk-trigger-offline-update';
const _ITEM_ICON_SIZE = 48; const _ITEM_ICON_SIZE = 48;
const _DIALOG_ICON_SIZE = 48; const _DIALOG_ICON_SIZE = 32;
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2; const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
@ -75,7 +71,6 @@ const logoutDialogContent = {
"You will be logged out automatically in %d seconds.", "You will be logged out automatically in %d seconds.",
seconds).format(seconds); seconds).format(seconds);
}, },
showBatteryWarning: false,
confirmButtons: [{ signal: 'ConfirmedLogout', confirmButtons: [{ signal: 'ConfirmedLogout',
label: C_("button", "Log Out") }], label: C_("button", "Log Out") }],
iconStyleClass: 'end-session-dialog-logout-icon', iconStyleClass: 'end-session-dialog-logout-icon',
@ -84,14 +79,11 @@ const logoutDialogContent = {
const shutdownDialogContent = { const shutdownDialogContent = {
subject: C_("title", "Power Off"), subject: C_("title", "Power Off"),
subjectWithUpdates: C_("title", "Install Updates & Power Off"),
description: function(seconds) { description: function(seconds) {
return ngettext("The system will power off automatically in %d second.", return ngettext("The system will power off automatically in %d second.",
"The system will power off automatically in %d seconds.", "The system will power off automatically in %d seconds.",
seconds).format(seconds); seconds).format(seconds);
}, },
checkBoxText: C_("checkbox", "Install pending software updates"),
showBatteryWarning: true,
confirmButtons: [{ signal: 'ConfirmedReboot', confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart") }, label: C_("button", "Restart") },
{ signal: 'ConfirmedShutdown', { signal: 'ConfirmedShutdown',
@ -108,7 +100,6 @@ const restartDialogContent = {
"The system will restart automatically in %d seconds.", "The system will restart automatically in %d seconds.",
seconds).format(seconds); seconds).format(seconds);
}, },
showBatteryWarning: false,
confirmButtons: [{ signal: 'ConfirmedReboot', confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart") }], label: C_("button", "Restart") }],
iconName: 'view-refresh-symbolic', iconName: 'view-refresh-symbolic',
@ -124,11 +115,8 @@ const restartInstallDialogContent = {
"The system will automatically restart and install updates in %d seconds.", "The system will automatically restart and install updates in %d seconds.",
seconds).format(seconds); seconds).format(seconds);
}, },
showBatteryWarning: true,
confirmButtons: [{ signal: 'ConfirmedReboot', confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart &amp; Install") }], label: C_("button", "Restart & Install") }],
unusedFutureButtonForTranslation: C_("button", "Install &amp; Power Off"),
unusedFutureCheckBoxForTranslation: C_("checkbox", "Power off after updates are installed"),
iconName: 'view-refresh-symbolic', iconName: 'view-refresh-symbolic',
iconStyleClass: 'end-session-dialog-shutdown-icon', iconStyleClass: 'end-session-dialog-shutdown-icon',
showOtherSessions: true, showOtherSessions: true,
@ -155,14 +143,6 @@ const LogindSessionIface = '<node> \
const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface); const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
const UPowerIface = '<node> \
<interface name="org.freedesktop.UPower"> \
<property name="OnBattery" type="b" access="read"/> \
</interface> \
</node>';
const UPowerProxy = Gio.DBusProxy.makeProxyWrapper(UPowerIface);
function findAppFromInhibitor(inhibitor) { function findAppFromInhibitor(inhibitor) {
let desktopFile; let desktopFile;
try { try {
@ -215,18 +195,6 @@ function _setLabelText(label, text) {
} }
} }
function _setCheckBoxLabel(checkBox, text) {
let label = checkBox.getLabelActor();
if (text) {
label.set_text(text);
checkBox.actor.show();
} else {
label.set_text('');
checkBox.actor.hide();
}
}
function init() { function init() {
// This always returns the same singleton object // This always returns the same singleton object
// By instantiating it initially, we register the // By instantiating it initially, we register the
@ -246,20 +214,6 @@ const EndSessionDialog = new Lang.Class({
this._userManager = AccountsService.UserManager.get_default(); this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name()); this._user = this._userManager.get_user(GLib.get_user_name());
this._updatesFile = Gio.File.new_for_path('/system-update'); this._updatesFile = Gio.File.new_for_path('/system-update');
this._preparedUpdateFile = Gio.File.new_for_path('/var/lib/PackageKit/prepared-update');
this._powerProxy = new UPowerProxy(Gio.DBus.system,
'org.freedesktop.UPower',
'/org/freedesktop/UPower',
Lang.bind(this, function(proxy, error) {
if (error) {
log(error.message);
return;
}
this._powerProxy.connect('g-properties-changed',
Lang.bind(this, this._sync));
this._sync();
}));
this._secondsLeft = 0; this._secondsLeft = 0;
this._totalSecondsToStayOpen = 0; this._totalSecondsToStayOpen = 0;
@ -286,8 +240,7 @@ const EndSessionDialog = new Lang.Class({
x_align: St.Align.END, x_align: St.Align.END,
y_align: St.Align.START }); y_align: St.Align.START });
let messageLayout = new St.BoxLayout({ vertical: true, let messageLayout = new St.BoxLayout({ vertical: true });
style_class: 'end-session-dialog-layout' });
mainContentLayout.add(messageLayout, mainContentLayout.add(messageLayout,
{ y_align: St.Align.START }); { y_align: St.Align.START });
@ -307,16 +260,6 @@ const EndSessionDialog = new Lang.Class({
{ y_fill: true, { y_fill: true,
y_align: St.Align.START }); y_align: St.Align.START });
this._checkBox = new CheckBox.CheckBox();
this._checkBox.actor.connect('clicked', Lang.bind(this, this._sync));
messageLayout.add(this._checkBox.actor);
this._batteryWarning = new St.Label({ style_class: 'end-session-dialog-warning',
text: _("Running on battery power: please plug in before installing updates.") });
this._batteryWarning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._batteryWarning.clutter_text.line_wrap = true;
messageLayout.add(this._batteryWarning);
this._scrollView = new St.ScrollView({ style_class: 'end-session-dialog-list' }); this._scrollView = new St.ScrollView({ style_class: 'end-session-dialog-list' });
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.contentLayout.add(this._scrollView, this.contentLayout.add(this._scrollView,
@ -342,12 +285,6 @@ const EndSessionDialog = new Lang.Class({
this._inhibitorSection.add_actor(this._sessionHeader); this._inhibitorSection.add_actor(this._sessionHeader);
this._inhibitorSection.add_actor(this._sessionList); this._inhibitorSection.add_actor(this._sessionList);
try {
this._updatesPermission = Polkit.Permission.new_sync("org.freedesktop.packagekit.trigger-offline-update", null, null);
} catch(e) {
log('No permission to trigger offline updates: %s'.format(e.toString()));
}
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this); this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog'); this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
}, },
@ -362,22 +299,13 @@ const EndSessionDialog = new Lang.Class({
if (!open) if (!open)
return; return;
if (this._type == 2 && this._updatesFile.query_exists(null))
this._type = 3;
let dialogContent = DialogContent[this._type]; let dialogContent = DialogContent[this._type];
let subject = dialogContent.subject; let subject = dialogContent.subject;
// Use different title when we are installing updates
if (dialogContent.subjectWithUpdates && this._checkBox.actor.checked)
subject = dialogContent.subjectWithUpdates;
if (dialogContent.showBatteryWarning) {
// Warn when running on battery power
if (this._powerProxy.OnBattery && this._checkBox.actor.checked)
this._batteryWarning.opacity = 255;
else
this._batteryWarning.opacity = 0;
}
let description; let description;
let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen, let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
this._secondsLeft, this._secondsLeft,
@ -460,75 +388,15 @@ const EndSessionDialog = new Lang.Class({
}, },
_confirm: function(signal) { _confirm: function(signal) {
let callback = Lang.bind(this, function() { this._fadeOutDialog();
this._fadeOutDialog(); this._stopTimer();
this._stopTimer(); this._dbusImpl.emit_signal(signal, null);
this._dbusImpl.emit_signal(signal, null);
});
// Offline update not available; just emit the signal
if (!this._checkBox.actor.visible) {
callback();
return;
}
// Trigger the offline update as requested
if (this._checkBox.actor.checked) {
switch (signal) {
case "ConfirmedReboot":
this._triggerOfflineUpdateReboot(callback);
break;
case "ConfirmedShutdown":
// To actually trigger the offline update, we need to
// reboot to do the upgrade. When the upgrade is complete,
// the computer will shut down automatically.
signal = "ConfirmedReboot";
this._triggerOfflineUpdateShutdown(callback);
break;
default:
callback();
break;
}
} else {
this._triggerOfflineUpdateCancel(callback);
}
}, },
_onOpened: function() { _onOpened: function() {
this._sync(); this._sync();
}, },
_triggerOfflineUpdateReboot: function(callback) {
this._pkexecSpawn([TRIGGER_OFFLINE_UPDATE, 'reboot'], callback);
},
_triggerOfflineUpdateShutdown: function(callback) {
this._pkexecSpawn([TRIGGER_OFFLINE_UPDATE, 'power-off'], callback);
},
_triggerOfflineUpdateCancel: function(callback) {
this._pkexecSpawn([TRIGGER_OFFLINE_UPDATE, '--cancel'], callback);
},
_pkexecSpawn: function(argv, callback) {
let ret, pid;
try {
[ret, pid] = GLib.spawn_async(null, ['pkexec'].concat(argv), null,
GLib.SpawnFlags.DO_NOT_REAP_CHILD | GLib.SpawnFlags.SEARCH_PATH,
null);
} catch (e) {
log('Error spawning "pkexec %s": %s'.format(argv.join(' '), e.toString()));
callback();
return;
}
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
GLib.spawn_close_pid(pid);
callback();
});
},
_startTimer: function() { _startTimer: function() {
let startTime = GLib.get_monotonic_time(); let startTime = GLib.get_monotonic_time();
this._secondsLeft = this._totalSecondsToStayOpen; this._secondsLeft = this._totalSecondsToStayOpen;
@ -676,9 +544,6 @@ const EndSessionDialog = new Lang.Class({
this._totalSecondsToStayOpen = totalSecondsToStayOpen; this._totalSecondsToStayOpen = totalSecondsToStayOpen;
this._type = type; this._type = type;
if (this._type == 2 && this._updatesFile.query_exists(null))
this._type = 3;
this._applications = []; this._applications = [];
this._applicationList.destroy_all_children(); this._applicationList.destroy_all_children();
@ -691,8 +556,6 @@ const EndSessionDialog = new Lang.Class({
return; return;
} }
let dialogContent = DialogContent[this._type];
for (let i = 0; i < inhibitorObjectPaths.length; i++) { for (let i = 0; i < inhibitorObjectPaths.length; i++) {
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) { let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) {
this._onInhibitorLoaded(proxy); this._onInhibitorLoaded(proxy);
@ -701,23 +564,9 @@ const EndSessionDialog = new Lang.Class({
this._applications.push(inhibitor); this._applications.push(inhibitor);
} }
if (dialogContent.showOtherSessions) if (DialogContent[type].showOtherSessions)
this._loadSessions(); this._loadSessions();
let preparedUpdate = this._preparedUpdateFile.query_exists(null);
let updateAlreadyTriggered = this._updatesFile.query_exists(null);
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText);
this._checkBox.actor.visible = (dialogContent.checkBoxText && preparedUpdate && updatesAllowed);
this._checkBox.actor.checked = (preparedUpdate && updateAlreadyTriggered);
// We show the warning either together with the checkbox, or when
// updates have already been triggered, but the user doesn't have
// enough permissions to cancel them.
this._batteryWarning.visible = (dialogContent.showBatteryWarning &&
(this._checkBox.actor.visible || preparedUpdate && updateAlreadyTriggered && !updatesAllowed));
this._updateButtons(); this._updateButtons();
if (!this.open(timestamp)) { if (!this.open(timestamp)) {

View File

@ -5,8 +5,6 @@ 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';
imports.gi.versions.Gtk = '3.0'; imports.gi.versions.Gtk = '3.0';
imports.gi.versions.TelepathyGLib = '0.12';
imports.gi.versions.TelepathyLogger = '0.2';
const Clutter = imports.gi.Clutter;; const Clutter = imports.gi.Clutter;;
const Gettext = imports.gettext; const Gettext = imports.gettext;

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 EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
var initted = false; var initted = false;
var enabled; var enabled;
@ -157,9 +156,7 @@ function loadExtension(extension) {
// Default to error, we set success as the last step // Default to error, we set success as the last step
extension.state = ExtensionState.ERROR; extension.state = ExtensionState.ERROR;
let checkVersion = !global.settings.get_boolean(EXTENSION_DISABLE_VERSION_CHECK_KEY); if (ExtensionUtils.isOutOfDate(extension)) {
if (checkVersion && ExtensionUtils.isOutOfDate(extension)) {
extension.state = ExtensionState.OUT_OF_DATE; extension.state = ExtensionState.OUT_OF_DATE;
} else { } else {
let enabled = enabledExtensions.indexOf(extension.uuid) != -1; let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
@ -270,19 +267,8 @@ function onEnabledExtensionsChanged() {
enabledExtensions = newEnabledExtensions; enabledExtensions = newEnabledExtensions;
} }
function _onVersionValidationChanged() {
if (Main.sessionMode.allowExtensions) {
enabledExtensions.forEach(function(uuid) {
if (ExtensionUtils.extensions[uuid])
reloadExtension(ExtensionUtils.extensions[uuid]);
});
}
}
function _loadExtensions() { function _loadExtensions() {
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged); global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
global.settings.connect('changed::' + EXTENSION_DISABLE_VERSION_CHECK_KEY, _onVersionValidationChanged);
enabledExtensions = getEnabledExtensions(); enabledExtensions = getEnabledExtensions();
let finder = new ExtensionUtils.ExtensionFinder(); let finder = new ExtensionUtils.ExtensionFinder();

View File

@ -32,11 +32,9 @@ const FocusCaretTracker = new Lang.Class({
Name: 'FocusCaretTracker', Name: 'FocusCaretTracker',
_init: function() { _init: function() {
Atspi.init();
Atspi.set_timeout(250, 250);
this._atspiListener = Atspi.EventListener.new(Lang.bind(this, this._onChanged)); this._atspiListener = Atspi.EventListener.new(Lang.bind(this, this._onChanged));
this._atspiInited = false;
this._focusListenerRegistered = false;
this._caretListenerRegistered = false;
}, },
_onChanged: function(event) { _onChanged: function(event) {
@ -46,50 +44,22 @@ const FocusCaretTracker = new Lang.Class({
this.emit('caret-moved', event); this.emit('caret-moved', event);
}, },
_initAtspi: function() {
if (!this._atspiInited) {
Atspi.init();
Atspi.set_timeout(250, 250);
this._atspiInited = true;
}
},
registerFocusListener: function() { registerFocusListener: function() {
if (this._focusListenerRegistered) return this._atspiListener.register(STATECHANGED + ':focused') &&
return; this._atspiListener.register(STATECHANGED + ':selected');
this._initAtspi();
this._atspiListener.register(STATECHANGED + ':focused');
this._atspiListener.register(STATECHANGED + ':selected');
this._focusListenerRegistered = true;
}, },
registerCaretListener: function() { registerCaretListener: function() {
if (this._caretListenerRegistered) return this._atspiListener.register(CARETMOVED);
return;
this._initAtspi();
this._atspiListener.register(CARETMOVED);
this._caretListenerRegistered = true;
}, },
deregisterFocusListener: function() { deregisterFocusListener: function() {
if (!this._focusListenerRegistered) return this._atspiListener.deregister(STATECHANGED + ':focused') &&
return; this._atspiListener.deregister(STATECHANGED + ':selected');
this._atspiListener.deregister(STATECHANGED + ':focused');
this._atspiListener.deregister(STATECHANGED + ':selected');
this._focusListenerRegistered = false;
}, },
deregisterCaretListener: function() { deregisterCaretListener: function() {
if (!this._caretListenerRegistered) return this._atspiListener.deregister(CARETMOVED);
return;
this._atspiListener.deregister(CARETMOVED);
this._caretListenerRegistered = false;
} }
}); });
Signals.addSignalMethods(FocusCaretTracker.prototype); Signals.addSignalMethods(FocusCaretTracker.prototype);

View File

@ -155,7 +155,7 @@ const CandidatePopup = new Lang.Class({
panelService.connect('set-cursor-location', panelService.connect('set-cursor-location',
Lang.bind(this, function(ps, x, y, w, h) { Lang.bind(this, function(ps, x, y, w, h) {
Main.layoutManager.setDummyCursorGeometry(x, y, w, h); Main.layoutManager.setDummyCursorPosition(x, y);
if (this._boxPointer.actor.visible) if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0); this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
})); }));

View File

@ -143,6 +143,11 @@ const BaseIcon = new Lang.Class({
this.icon = this.createIcon(this.iconSize); this.icon = this.createIcon(this.iconSize);
this._iconBin.child = this.icon; this._iconBin.child = this.icon;
// The icon returned by createIcon() might actually be smaller than
// the requested icon size (for instance StTextureCache does this
// for fallback icons), so set the size explicitly.
this._iconBin.set_size(this.iconSize, this.iconSize);
}, },
_onStyleChanged: function() { _onStyleChanged: function() {
@ -214,20 +219,6 @@ const IconGrid = new Lang.Class({
this._grid.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth)); this._grid.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this._grid.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight)); this._grid.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this._grid.connect('allocate', Lang.bind(this, this._allocate)); this._grid.connect('allocate', Lang.bind(this, this._allocate));
this._grid.connect('actor-added', Lang.bind(this, this._childAdded));
this._grid.connect('actor-removed', Lang.bind(this, this._childRemoved));
},
_keyFocusIn: function(actor) {
this.emit('key-focus-in', actor);
},
_childAdded: function(grid, child) {
child._iconGridKeyFocusInId = child.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
},
_childRemoved: function(grid, child) {
child.disconnect(child._iconGridKeyFocusInId);
}, },
_getPreferredWidth: function (grid, forHeight, alloc) { _getPreferredWidth: function (grid, forHeight, alloc) {
@ -541,7 +532,6 @@ const IconGrid = new Lang.Class({
} }
} }
}); });
Signals.addSignalMethods(IconGrid.prototype);
const PaginatedIconGrid = new Lang.Class({ const PaginatedIconGrid = new Lang.Class({
Name: 'PaginatedIconGrid', Name: 'PaginatedIconGrid',

View File

@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject; const GObject = imports.gi.GObject;
const Lang = imports.lang; const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Signals = imports.signals; const Signals = imports.signals;
@ -161,9 +162,9 @@ const LayoutManager = new Lang.Class({
this._startingUp = true; this._startingUp = true;
// Normally, the stage is always covered so Clutter doesn't need to clear // Normally, the stage is always covered so Clutter doesn't need to clear
// it; however it becomes visible during the startup animation // it; however it becomes visible when using the magnifier.
// See the comment below for a longer explanation
global.stage.color = DEFAULT_BACKGROUND_COLOR; global.stage.color = DEFAULT_BACKGROUND_COLOR;
global.stage.no_clear_hint = true;
// Set up stage hierarchy to group all UI actors under one container. // Set up stage hierarchy to group all UI actors under one container.
this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' }); this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
@ -183,52 +184,72 @@ const LayoutManager = new Lang.Class({
let height = global.stage.height; let height = global.stage.height;
[alloc.min_size, alloc.natural_size] = [height, height]; [alloc.min_size, alloc.natural_size] = [height, height];
}); });
global.stage.add_child(this.uiGroup);
this.systemGroup = new St.Widget({ name: 'systemGroup',
layout_manager: new Clutter.BinLayout() });
this.uiGroup.add_actor(this.systemGroup);
this.sessionGroup = new St.Widget({ name: 'sessionGroup' });
this.uiGroup.add_child(this.sessionGroup);
global.stage.remove_actor(global.window_group); global.stage.remove_actor(global.window_group);
this.uiGroup.add_actor(global.window_group); this.sessionGroup.add_actor(global.window_group);
global.stage.add_child(this.uiGroup);
this.overviewGroup = new St.Widget({ name: 'overviewGroup', this.overviewGroup = new St.Widget({ name: 'overviewGroup',
visible: false }); visible: false });
this.addChrome(this.overviewGroup); this.addChrome(this.overviewGroup);
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup', this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
visible: false,
clip_to_allocation: true, clip_to_allocation: true,
layout_manager: new Clutter.BinLayout(), layout_manager: new Clutter.BinLayout(),
}); });
this.addChrome(this.screenShieldGroup); this.uiGroup.add_child(this.screenShieldGroup);
this.panelBox = new St.BoxLayout({ name: 'panelBox',
vertical: true });
this.addChrome(this.panelBox, { affectsStruts: true,
trackFullscreen: true });
this.panelBox.connect('allocation-changed',
Lang.bind(this, this._panelBoxChanged));
this.trayBox = new St.Widget({ name: 'trayBox', this.trayBox = new St.Widget({ name: 'trayBox',
layout_manager: new Clutter.BinLayout() }); layout_manager: new Clutter.BinLayout() });
this.addChrome(this.trayBox); this.addChrome(this.trayBox);
this._setupTrayPressure(); this._setupTrayPressure();
this.modalDialogGroup = new St.Widget({ name: 'modalDialogGroup',
layout_manager: new Clutter.BinLayout() });
this.uiGroup.add_actor(this.modalDialogGroup);
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox', this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
reactive: true, reactive: true,
track_hover: true }); track_hover: true });
this.addChrome(this.keyboardBox); this.addChrome(this.keyboardBox);
this._keyboardHeightNotifyId = 0; this._keyboardHeightNotifyId = 0;
// A dummy actor that tracks the mouse or text cursor, based on the this.osdGroup = new St.Widget();
// position and size set in setDummyCursorGeometry. this.sessionGroup.add_child(this.osdGroup);
this.dummyCursor = new St.Widget({ width: 0, height: 0 });
this.uiGroup.add_actor(this.dummyCursor);
global.stage.remove_actor(global.top_window_group); this.switcherPopupGroup = new St.Widget();
this.uiGroup.add_actor(global.top_window_group); this.sessionGroup.add_child(this.switcherPopupGroup);
this.dialogGroup = new St.Widget();
this.sessionGroup.add_child(this.dialogGroup);
// A dummy actor that tracks the mouse or text cursor, based on the
// position set in setDummyCursorPosition.
this.dummyCursor = new St.Widget({ width: 0, height: 0 });
this.uiGroup.add_child(this.dummyCursor);
// The panel group isn't in the session, as it needs to go above the screen
// shield, and it isn't animated in the login animation.
this.panelGroup = new St.Widget({ name: 'panelGroup' });
this.uiGroup.add_child(this.panelGroup);
this._trackActor(this.panelGroup, { affectsStruts: true,
trackFullscreen: true });
this.panelGroup.connect('allocation-changed',
Lang.bind(this, this._panelGroupChanged));
this.overlayGroup = new St.Widget({ name: 'overlayGroup' });
this.uiGroup.add_child(this.overlayGroup);
this.menuGroup = new St.Widget();
this.overlayGroup.add_child(this.menuGroup);
this._topSessionGroup = new St.Widget();
this.overlayGroup.add_child(this._topSessionGroup);
global.stage.remove_child(global.top_window_group);
this._topSessionGroup.add_child(global.top_window_group);
this._backgroundGroup = new Meta.BackgroundGroup(); this._backgroundGroup = new Meta.BackgroundGroup();
global.window_group.add_child(this._backgroundGroup); global.window_group.add_child(this._backgroundGroup);
@ -250,8 +271,7 @@ const LayoutManager = new Lang.Class({
// This is called by Main after everything else is constructed // This is called by Main after everything else is constructed
init: function() { init: function() {
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
this._prepareStartupAnimation();
this._loadBackground();
}, },
showOverview: function() { showOverview: function() {
@ -260,6 +280,9 @@ const LayoutManager = new Lang.Class({
this._inOverview = true; this._inOverview = true;
this._updateVisibility(); this._updateVisibility();
this._updateRegions(); this._updateRegions();
global.window_group.hide();
global.top_window_group.hide();
}, },
hideOverview: function() { hideOverview: function() {
@ -268,6 +291,9 @@ const LayoutManager = new Lang.Class({
this._inOverview = false; this._inOverview = false;
this._updateVisibility(); this._updateVisibility();
this._queueUpdateRegions(); this._queueUpdateRegions();
global.window_group.show();
global.top_window_group.show();
}, },
_sessionUpdated: function() { _sessionUpdated: function() {
@ -309,7 +335,7 @@ const LayoutManager = new Lang.Class({
}); });
this.hotCorners = []; this.hotCorners = [];
let size = this.panelBox.height; let size = this.panelGroup.height;
// build new hot corners // build new hot corners
for (let i = 0; i < this.monitors.length; i++) { for (let i = 0; i < this.monitors.length; i++) {
@ -409,11 +435,11 @@ const LayoutManager = new Lang.Class({
}, },
_updateBoxes: function() { _updateBoxes: function() {
this.screenShieldGroup.set_position(0, 0); this.systemGroup.set_position(0, 0);
this.screenShieldGroup.set_size(global.screen_width, global.screen_height); this.systemGroup.set_size(global.screen_width, global.screen_height);
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y); this.panelGroup.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
this.panelBox.set_size(this.primaryMonitor.width, -1); this.panelGroup.set_size(this.primaryMonitor.width, -1);
if (this.keyboardIndex < 0) if (this.keyboardIndex < 0)
this.keyboardIndex = this.primaryIndex; this.keyboardIndex = this.primaryIndex;
@ -423,10 +449,10 @@ const LayoutManager = new Lang.Class({
this.trayBox.set_size(this.bottomMonitor.width, -1); this.trayBox.set_size(this.bottomMonitor.width, -1);
}, },
_panelBoxChanged: function() { _panelGroupChanged: function() {
this._updatePanelBarrier(); this._updatePanelBarrier();
let size = this.panelBox.height; let size = this.panelGroup.height;
this.hotCorners.forEach(function(corner) { this.hotCorners.forEach(function(corner) {
if (corner) if (corner)
corner.setBarrierSize(size); corner.setBarrierSize(size);
@ -439,12 +465,12 @@ const LayoutManager = new Lang.Class({
this._rightPanelBarrier = null; this._rightPanelBarrier = null;
} }
if (this.panelBox.height) { if (this.panelGroup.height) {
let primary = this.primaryMonitor; let primary = this.primaryMonitor;
this._rightPanelBarrier = new Meta.Barrier({ display: global.display, this._rightPanelBarrier = new Meta.Barrier({ display: global.display,
x1: primary.x + primary.width, y1: primary.y, x1: primary.x + primary.width, y1: primary.y,
x2: primary.x + primary.width, y2: primary.y + this.panelBox.height, x2: primary.x + primary.width, y2: primary.y + this.panelGroup.height,
directions: Meta.BarrierDirection.NEGATIVE_X }); directions: Meta.BarrierDirection.NEGATIVE_X });
} }
}, },
@ -550,25 +576,6 @@ const LayoutManager = new Lang.Class({
return this._keyboardIndex; return this._keyboardIndex;
}, },
_loadBackground: function() {
this._systemBackground = new Background.SystemBackground();
this._systemBackground.actor.hide();
global.stage.insert_child_below(this._systemBackground.actor, null);
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL });
this._systemBackground.actor.add_constraint(constraint);
let signalId = this._systemBackground.connect('loaded', Lang.bind(this, function() {
this._systemBackground.disconnect(signalId);
this._systemBackground.actor.show();
global.stage.show();
this._prepareStartupAnimation();
}));
},
// Startup Animations // Startup Animations
// //
// We have two different animations, depending on whether we're a greeter // We have two different animations, depending on whether we're a greeter
@ -589,6 +596,8 @@ const LayoutManager = new Lang.Class({
// screen. So, we set no_clear_hint at the end of the animation. // screen. So, we set no_clear_hint at the end of the animation.
_prepareStartupAnimation: function() { _prepareStartupAnimation: function() {
global.stage.show();
// During the initial transition, add a simple actor to block all events, // During the initial transition, add a simple actor to block all events,
// so they don't get delivered to X11 windows that have been transformed. // so they don't get delivered to X11 windows that have been transformed.
this._coverPane = new Clutter.Actor({ opacity: 0, this._coverPane = new Clutter.Actor({ opacity: 0,
@ -598,7 +607,7 @@ const LayoutManager = new Lang.Class({
this.addChrome(this._coverPane); this.addChrome(this._coverPane);
if (Main.sessionMode.isGreeter) { if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height; this.panelGroup.translation_y = -this.panelGroup.height;
} else { } else {
this._updateBackgrounds(); this._updateBackgrounds();
@ -613,10 +622,10 @@ const LayoutManager = new Lang.Class({
let x = monitor.x + monitor.width / 2.0; let x = monitor.x + monitor.width / 2.0;
let y = monitor.y + monitor.height / 2.0; let y = monitor.y + monitor.height / 2.0;
this.uiGroup.set_pivot_point(x / global.screen_width, this.sessionGroup.set_pivot_point(x / global.screen_width,
y / global.screen_height); y / global.screen_height);
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.75; this.sessionGroup.scale_x = this.sessionGroup.scale_y = 0.75;
this.uiGroup.opacity = 0; this.sessionGroup.opacity = 0;
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height); global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
} }
@ -642,7 +651,7 @@ const LayoutManager = new Lang.Class({
}, },
_startupAnimationGreeter: function() { _startupAnimationGreeter: function() {
Tweener.addTween(this.panelBox, Tweener.addTween(this.panelGroup,
{ translation_y: 0, { translation_y: 0,
time: STARTUP_ANIMATION_TIME, time: STARTUP_ANIMATION_TIME,
transition: 'easeOutQuad', transition: 'easeOutQuad',
@ -651,7 +660,7 @@ const LayoutManager = new Lang.Class({
}, },
_startupAnimationSession: function() { _startupAnimationSession: function() {
Tweener.addTween(this.uiGroup, Tweener.addTween(this.sessionGroup,
{ scale_x: 1, { scale_x: 1,
scale_y: 1, scale_y: 1,
opacity: 255, opacity: 255,
@ -662,16 +671,9 @@ const LayoutManager = new Lang.Class({
}, },
_startupAnimationComplete: function() { _startupAnimationComplete: function() {
// At this point, the UI group is covering everything, so
// we no longer need to clear the stage
global.stage.no_clear_hint = true;
this._coverPane.destroy(); this._coverPane.destroy();
this._coverPane = null; this._coverPane = null;
this._systemBackground.actor.destroy();
this._systemBackground = null;
this._startingUp = false; this._startingUp = false;
this.trayBox.show(); this.trayBox.show();
@ -728,7 +730,7 @@ const LayoutManager = new Lang.Class({
this._updateRegions(); this._updateRegions();
}, },
// setDummyCursorGeometry: // setDummyCursorPosition:
// //
// The cursor dummy is a standard widget commonly used for popup // The cursor dummy is a standard widget commonly used for popup
// menus and box pointers to track, as the box pointer API only // menus and box pointers to track, as the box pointer API only
@ -737,10 +739,9 @@ const LayoutManager = new Lang.Class({
// is what you should use. Given that the menu should not track // is what you should use. Given that the menu should not track
// the actual mouse pointer as it moves, you need to call this // the actual mouse pointer as it moves, you need to call this
// function before you show the menu to ensure it is at the right // function before you show the menu to ensure it is at the right
// position and has the right size. // position.
setDummyCursorGeometry: function(x, y, w, h) { setDummyCursorPosition: function(x, y) {
this.dummyCursor.set_position(Math.round(x), Math.round(y)); this.dummyCursor.set_position(Math.round(x), Math.round(y));
this.dummyCursor.set_size(Math.round(w), Math.round(h));
}, },
// addChrome: // addChrome:
@ -762,9 +763,9 @@ const LayoutManager = new Lang.Class({
// monitor (it will be hidden whenever a fullscreen window is visible, // monitor (it will be hidden whenever a fullscreen window is visible,
// and shown otherwise) // and shown otherwise)
addChrome: function(actor, params) { addChrome: function(actor, params) {
this.uiGroup.add_actor(actor); this.sessionGroup.add_actor(actor);
if (this.uiGroup.contains(global.top_window_group)) if (this.sessionGroup.contains(global.top_window_group))
this.uiGroup.set_child_below_sibling(actor, global.top_window_group); this.sessionGroup.set_child_below_sibling(actor, global.top_window_group);
this._trackActor(actor, params); this._trackActor(actor, params);
}, },
@ -815,7 +816,7 @@ const LayoutManager = new Lang.Class({
// //
// Removes @actor from the chrome // Removes @actor from the chrome
removeChrome: function(actor) { removeChrome: function(actor) {
this.uiGroup.remove_actor(actor); this.sessionGroup.remove_actor(actor);
this._untrackActor(actor); this._untrackActor(actor);
}, },
@ -838,8 +839,6 @@ const LayoutManager = new Lang.Class({
Lang.bind(this, this._queueUpdateRegions)); Lang.bind(this, this._queueUpdateRegions));
actorData.allocationId = actor.connect('notify::allocation', actorData.allocationId = actor.connect('notify::allocation',
Lang.bind(this, this._queueUpdateRegions)); Lang.bind(this, this._queueUpdateRegions));
actorData.destroyId = actor.connect('destroy',
Lang.bind(this, this._untrackActor));
// Note that destroying actor will unset its parent, so we don't // Note that destroying actor will unset its parent, so we don't
// need to connect to 'destroy' too. // need to connect to 'destroy' too.
@ -857,7 +856,7 @@ const LayoutManager = new Lang.Class({
this._trackedActors.splice(i, 1); this._trackedActors.splice(i, 1);
actor.disconnect(actorData.visibleId); actor.disconnect(actorData.visibleId);
actor.disconnect(actorData.allocationId); actor.disconnect(actorData.allocationId);
actor.disconnect(actorData.destroyId); actor.disconnect(actorData.parentSetId);
this._queueUpdateRegions(); this._queueUpdateRegions();
}, },
@ -865,9 +864,6 @@ const LayoutManager = new Lang.Class({
_updateVisibility: function() { _updateVisibility: function() {
let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview; let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
global.window_group.visible = windowsVisible;
global.top_window_group.visible = windowsVisible;
for (let i = 0; i < this._trackedActors.length; i++) { for (let i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i], visible; let actorData = this._trackedActors[i], visible;
if (!actorData.trackFullscreen) if (!actorData.trackFullscreen)
@ -911,8 +907,8 @@ const LayoutManager = new Lang.Class({
return; return;
if (!this._updateRegionIdle) if (!this._updateRegionIdle)
this._updateRegionIdle = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, this._updateRegionIdle = Mainloop.idle_add(Lang.bind(this, this._updateRegions),
Lang.bind(this, this._updateRegions)); Meta.PRIORITY_BEFORE_REDRAW);
}, },
_getWindowActorsForWorkspace: function(workspace) { _getWindowActorsForWorkspace: function(workspace) {
@ -943,7 +939,7 @@ const LayoutManager = new Lang.Class({
let rects = [], struts = [], i; let rects = [], struts = [], i;
if (this._updateRegionIdle) { if (this._updateRegionIdle) {
Meta.later_remove(this._updateRegionIdle); Mainloop.source_remove(this._updateRegionIdle);
delete this._updateRegionIdle; delete this._updateRegionIdle;
} }
@ -1017,39 +1013,19 @@ const LayoutManager = new Lang.Class({
continue; continue;
// Ensure that the strut rects goes all the way to the screen edge, // Ensure that the strut rects goes all the way to the screen edge,
// as this really what mutter expects. However skip this step // as this really what mutter expects.
// in cases where this would render an entire monitor unusable.
switch (side) { switch (side) {
case Meta.Side.TOP: case Meta.Side.TOP:
let hasMonitorsAbove = this.monitors.some(Lang.bind(this, y1 = 0;
function(mon) {
return this._isAboveOrBelowPrimary(mon) &&
mon.y < primary.y;
}));
if (!hasMonitorsAbove)
y1 = 0;
break; break;
case Meta.Side.BOTTOM: case Meta.Side.BOTTOM:
if (this.primaryIndex == this.bottomIndex) y2 = global.screen_height;
y2 = global.screen_height;
break; break;
case Meta.Side.LEFT: case Meta.Side.LEFT:
let hasMonitorsLeft = this.monitors.some(Lang.bind(this, x1 = 0;
function(mon) {
return !this._isAboveOrBelowPrimary(mon) &&
mon.x < primary.x;
}));
if (!hasMonitorsLeft)
x1 = 0;
break; break;
case Meta.Side.RIGHT: case Meta.Side.RIGHT:
let hasMonitorsRight = this.monitors.some(Lang.bind(this, x2 = global.screen_width;
function(mon) {
return !this._isAboveOrBelowPrimary(mon) &&
mon.x > primary.x;
}));
if (!hasMonitorsRight)
x2 = global.screen_width;
break; break;
} }
@ -1106,9 +1082,9 @@ const HotCorner = new Lang.Class({
this._ripple2 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false }); this._ripple2 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false });
this._ripple3 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false }); this._ripple3 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false });
layoutManager.uiGroup.add_actor(this._ripple1); layoutManager.sessionGroup.add_actor(this._ripple1);
layoutManager.uiGroup.add_actor(this._ripple2); layoutManager.sessionGroup.add_actor(this._ripple2);
layoutManager.uiGroup.add_actor(this._ripple3); layoutManager.sessionGroup.add_actor(this._ripple3);
}, },
setBarrierSize: function(size) { setBarrierSize: function(size) {

View File

@ -11,60 +11,30 @@ const Params = imports.misc.params;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const DEFAULT_FADE_FACTOR = 0.4; const DEFAULT_FADE_FACTOR = 0.4;
const VIGNETTE_BRIGHTNESS = 0.8;
const VIGNETTE_SHARPNESS = 0.7;
const VIGNETTE_DECLARATIONS = '\ const GLSL_DIM_EFFECT_DECLARATIONS = '\
uniform float brightness;\n\ float compute_dim_factor (const vec2 coords) {\
uniform float vignette_sharpness;\n'; vec2 dist = coords - vec2(0.5, 0.5); \
float elipse_radius = 0.5; \
const VIGNETTE_CODE = '\ /* interpolate darkening value, based on distance from screen center */ \
cogl_color_out.a = cogl_color_in.a;\n\ float val = min(length(dist), elipse_radius); \
cogl_color_out.rgb = vec3(0.0, 0.0, 0.0);\n\ return mix(0.3, 1.0, val / elipse_radius) * 0.4; \
vec2 position = cogl_tex_coord_in[0].xy - 0.5;\n\ }';
float t = length(2.0 * position);\n\ const GLSL_DIM_EFFECT_CODE = '\
t = clamp(t, 0.0, 1.0);\n\ float a = compute_dim_factor (cogl_tex_coord0_in.xy);\
float pixel_brightness = mix(1.0, 1.0 - vignette_sharpness, t);\n\ cogl_color_out = vec4(0, 0, 0, cogl_color_in.a * a);'
cogl_color_out.a = cogl_color_out.a * (1 - pixel_brightness * brightness);'; ;
const RadialShaderQuad = new Lang.Class({ const RadialShaderQuad = new Lang.Class({
Name: 'RadialShaderQuad', Name: 'RadialShaderQuad',
Extends: Shell.GLSLQuad, Extends: Shell.GLSLQuad,
_init: function(params) {
this.parent(params);
this._brightnessLocation = this.get_uniform_location('brightness');
this._sharpnessLocation = this.get_uniform_location('vignette_sharpness');
this.brightness = 1.0;
this.vignetteSharpness = 0.0;
},
vfunc_build_pipeline: function() { vfunc_build_pipeline: function() {
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT,
VIGNETTE_DECLARATIONS, VIGNETTE_CODE, true); GLSL_DIM_EFFECT_DECLARATIONS,
GLSL_DIM_EFFECT_CODE,
true);
}, },
get brightness() {
return this._brightness;
},
set brightness(v) {
this._brightness = v;
this.set_uniform_float(this._brightnessLocation,
1, [this._brightness]);
},
get vignetteSharpness() {
return this._sharpness;
},
set vignetteSharpness(v) {
this._sharpness = v;
this.set_uniform_float(this._sharpnessLocation,
1, [this._sharpness]);
}
}); });
/** /**
@ -105,15 +75,13 @@ const Lightbox = new Lang.Class({
this._container = container; this._container = container;
this._children = container.get_children(); this._children = container.get_children();
this._fadeFactor = params.fadeFactor; this._fadeFactor = params.fadeFactor;
this._radialEffect = Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL) && params.radialEffect; if (params.radialEffect)
if (this._radialEffect)
this.actor = new RadialShaderQuad({ x: 0, this.actor = new RadialShaderQuad({ x: 0,
y: 0, y: 0,
reactive: params.inhibitEvents }); reactive: params.inhibitEvents });
else else
this.actor = new St.Bin({ x: 0, this.actor = new St.Bin({ x: 0,
y: 0, y: 0,
opacity: 0,
style_class: 'lightbox', style_class: 'lightbox',
reactive: params.inhibitEvents }); reactive: params.inhibitEvents });
@ -165,18 +133,9 @@ const Lightbox = new Lang.Class({
fadeInTime = fadeInTime || 0; fadeInTime = fadeInTime || 0;
Tweener.removeTweens(this.actor); Tweener.removeTweens(this.actor);
if (this._radialEffect) { if (fadeInTime != 0) {
Tweener.addTween(this.actor, this.shown = false;
{ brightness: VIGNETTE_BRIGHTNESS, this.actor.opacity = 0;
vignetteSharpness: VIGNETTE_SHARPNESS,
time: fadeInTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.shown = true;
this.emit('shown');
})
});
} else {
Tweener.addTween(this.actor, Tweener.addTween(this.actor,
{ opacity: 255 * this._fadeFactor, { opacity: 255 * this._fadeFactor,
time: fadeInTime, time: fadeInTime,
@ -186,8 +145,11 @@ const Lightbox = new Lang.Class({
this.emit('shown'); this.emit('shown');
}) })
}); });
} else {
this.actor.opacity = 255 * this._fadeFactor;
this.shown = true;
this.emit('shown');
} }
this.actor.show(); this.actor.show();
}, },
@ -196,18 +158,7 @@ const Lightbox = new Lang.Class({
this.shown = false; this.shown = false;
Tweener.removeTweens(this.actor); Tweener.removeTweens(this.actor);
if (this._radialEffect) { if (fadeOutTime != 0) {
Tweener.addTween(this.actor,
{ brightness: 1.0,
vignetteSharpness: 0.0,
opacity: 0,
time: fadeOutTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.actor.hide();
})
});
} else {
Tweener.addTween(this.actor, Tweener.addTween(this.actor,
{ opacity: 0, { opacity: 0,
time: fadeOutTime, time: fadeOutTime,
@ -216,6 +167,8 @@ const Lightbox = new Lang.Class({
this.actor.hide(); this.actor.hide();
}) })
}); });
} else {
this.actor.hide();
} }
}, },

View File

@ -27,8 +27,6 @@ const CHEVRON = '>>> ';
/* Imports...feel free to add here as needed */ /* Imports...feel free to add here as needed */
var commandHeader = 'const Clutter = imports.gi.Clutter; ' + var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
'const GLib = imports.gi.GLib; ' + 'const GLib = imports.gi.GLib; ' +
'const GObject = imports.gi.GObject; ' +
'const Gio = imports.gi.Gio; ' +
'const Gtk = imports.gi.Gtk; ' + 'const Gtk = imports.gi.Gtk; ' +
'const Mainloop = imports.mainloop; ' + 'const Mainloop = imports.mainloop; ' +
'const Meta = imports.gi.Meta; ' + 'const Meta = imports.gi.Meta; ' +
@ -505,7 +503,7 @@ const Inspector = new Lang.Class({
let container = new Shell.GenericContainer({ width: 0, let container = new Shell.GenericContainer({ width: 0,
height: 0 }); height: 0 });
container.connect('allocate', Lang.bind(this, this._allocate)); container.connect('allocate', Lang.bind(this, this._allocate));
Main.uiGroup.add_actor(container); Main.layoutManager.sessionGroup.add_actor(container);
let eventHandler = new St.BoxLayout({ name: 'LookingGlassDialog', let eventHandler = new St.BoxLayout({ name: 'LookingGlassDialog',
vertical: false, vertical: false,
@ -803,16 +801,14 @@ const LookingGlass = new Lang.Class({
this._updateFont(); this._updateFont();
// We want it to appear to slide out from underneath the panel // We want it to appear to slide out from underneath the panel
Main.uiGroup.add_actor(this.actor); Main.layoutManager.sessionGroup.add_actor(this.actor);
Main.uiGroup.set_child_below_sibling(this.actor, Main.layoutManager.panelGroup.connect('allocation-changed',
Main.layoutManager.panelBox); Lang.bind(this, this._queueResize));
Main.layoutManager.panelBox.connect('allocation-changed',
Lang.bind(this, this._queueResize));
Main.layoutManager.keyboardBox.connect('allocation-changed', Main.layoutManager.keyboardBox.connect('allocation-changed',
Lang.bind(this, this._queueResize)); Lang.bind(this, this._queueResize));
this._objInspector = new ObjInspector(this); this._objInspector = new ObjInspector(this);
Main.uiGroup.add_actor(this._objInspector.actor); Main.layoutManager.sessionGroup.add_actor(this._objInspector.actor);
this._objInspector.actor.hide(); this._objInspector.actor.hide();
let toolbar = new St.BoxLayout({ name: 'Toolbar' }); let toolbar = new St.BoxLayout({ name: 'Toolbar' });
@ -1039,7 +1035,7 @@ const LookingGlass = new Lang.Class({
let availableHeight = primary.height - Main.layoutManager.keyboardBox.height; let availableHeight = primary.height - Main.layoutManager.keyboardBox.height;
let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9); let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9);
this.actor.x = primary.x + (primary.width - myWidth) / 2; this.actor.x = primary.x + (primary.width - myWidth) / 2;
this._hiddenY = primary.y + Main.layoutManager.panelBox.height - myHeight - 4; // -4 to hide the top corners this._hiddenY = primary.y + Main.layoutManager.panelGroup.height - myHeight - 4; // -4 to hide the top corners
this._targetY = this._hiddenY + myHeight; this._targetY = this._hiddenY + myHeight;
this.actor.y = this._hiddenY; this.actor.y = this._hiddenY;
this.actor.width = myWidth; this.actor.width = myWidth;

View File

@ -11,7 +11,6 @@ const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const Signals = imports.signals; const Signals = imports.signals;
const Background = imports.ui.background;
const FocusCaretTracker = imports.ui.focusCaretTracker; const FocusCaretTracker = imports.ui.focusCaretTracker;
const Main = imports.ui.main; const Main = imports.ui.main;
const MagnifierDBus = imports.ui.magnifierDBus; const MagnifierDBus = imports.ui.magnifierDBus;
@ -58,6 +57,20 @@ const Magnifier = new Lang.Class({
// Magnifier is a manager of ZoomRegions. // Magnifier is a manager of ZoomRegions.
this._zoomRegions = []; this._zoomRegions = [];
// Export to dbus.
magDBusService = new MagnifierDBus.ShellMagnifier();
let showAtLaunch = this._settingsInit();
this.setActive(showAtLaunch);
},
_initialize: function() {
if (this._initialized)
return;
this._initialized = true;
this._settingsInitLate();
// Create small clutter tree for the magnified mouse. // Create small clutter tree for the magnified mouse.
let cursorTracker = Meta.CursorTracker.get_for_screen(global.screen); let cursorTracker = Meta.CursorTracker.get_for_screen(global.screen);
this._mouseSprite = new Clutter.Texture(); this._mouseSprite = new Clutter.Texture();
@ -73,15 +86,11 @@ const Magnifier = new Lang.Class({
let aZoomRegion = new ZoomRegion(this, this._cursorRoot); let aZoomRegion = new ZoomRegion(this, this._cursorRoot);
this._zoomRegions.push(aZoomRegion); this._zoomRegions.push(aZoomRegion);
let showAtLaunch = this._settingsInit(aZoomRegion); this._settingsInitRegion(aZoomRegion);
aZoomRegion.scrollContentsTo(this.xMouse, this.yMouse); aZoomRegion.scrollContentsTo(this.xMouse, this.yMouse);
cursorTracker.connect('cursor-changed', Lang.bind(this, this._updateMouseSprite)); cursorTracker.connect('cursor-changed', Lang.bind(this, this._updateMouseSprite));
this._cursorTracker = cursorTracker; this._cursorTracker = cursorTracker;
// Export to dbus.
magDBusService = new MagnifierDBus.ShellMagnifier();
this.setActive(showAtLaunch);
}, },
/** /**
@ -106,21 +115,20 @@ const Magnifier = new Lang.Class({
* @activate: Boolean to activate or de-activate the magnifier. * @activate: Boolean to activate or de-activate the magnifier.
*/ */
setActive: function(activate) { setActive: function(activate) {
let isActive = this.isActive(); if (activate == this.isActive())
return;
if (activate)
this._initialize();
this._zoomRegions.forEach (function(zoomRegion, index, array) { this._zoomRegions.forEach (function(zoomRegion, index, array) {
zoomRegion.setActive(activate); zoomRegion.setActive(activate);
}); });
if (isActive != activate) { if (activate)
if (activate) { this.startTrackingMouse();
Meta.disable_unredirect_for_screen(global.screen); else
this.startTrackingMouse(); this.stopTrackingMouse();
} else {
Meta.enable_unredirect_for_screen(global.screen);
this.stopTrackingMouse();
}
}
// Make sure system mouse pointer is shown when all zoom regions are // Make sure system mouse pointer is shown when all zoom regions are
// invisible. // invisible.
@ -440,64 +448,68 @@ const Magnifier = new Lang.Class({
this._mouseSprite.set_anchor_point(xHot, yHot); this._mouseSprite.set_anchor_point(xHot, yHot);
}, },
_settingsInit: function(zoomRegion) { _settingsInitRegion: function(zoomRegion) {
// Mag factor is accurate to two decimal places.
let aPref = parseFloat(this._settings.get_double(MAG_FACTOR_KEY).toFixed(2));
if (aPref != 0.0)
zoomRegion.setMagFactor(aPref, aPref);
aPref = this._settings.get_enum(SCREEN_POSITION_KEY);
if (aPref)
zoomRegion.setScreenPosition(aPref);
zoomRegion.setLensMode(this._settings.get_boolean(LENS_MODE_KEY));
zoomRegion.setClampScrollingAtEdges(!this._settings.get_boolean(CLAMP_MODE_KEY));
aPref = this._settings.get_enum(MOUSE_TRACKING_KEY);
if (aPref)
zoomRegion.setMouseTrackingMode(aPref);
aPref = this._settings.get_enum(FOCUS_TRACKING_KEY);
if (aPref)
zoomRegion.setFocusTrackingMode(aPref);
aPref = this._settings.get_enum(CARET_TRACKING_KEY);
if (aPref)
zoomRegion.setCaretTrackingMode(aPref);
aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY);
if (aPref)
zoomRegion.setInvertLightness(aPref);
aPref = this._settings.get_double(COLOR_SATURATION_KEY);
if (aPref)
zoomRegion.setColorSaturation(aPref);
let bc = {};
bc.r = this._settings.get_double(BRIGHT_RED_KEY);
bc.g = this._settings.get_double(BRIGHT_GREEN_KEY);
bc.b = this._settings.get_double(BRIGHT_BLUE_KEY);
zoomRegion.setBrightness(bc);
bc.r = this._settings.get_double(CONTRAST_RED_KEY);
bc.g = this._settings.get_double(CONTRAST_GREEN_KEY);
bc.b = this._settings.get_double(CONTRAST_BLUE_KEY);
zoomRegion.setContrast(bc);
},
_settingsInit: function() {
this._appSettings = new Gio.Settings({ schema: APPLICATIONS_SCHEMA }); this._appSettings = new Gio.Settings({ schema: APPLICATIONS_SCHEMA });
this._settings = new Gio.Settings({ schema: MAGNIFIER_SCHEMA }); this._settings = new Gio.Settings({ schema: MAGNIFIER_SCHEMA });
if (zoomRegion) { this._appSettings.connect('changed::' + SHOW_KEY, Lang.bind(this, function() {
// Mag factor is accurate to two decimal places. let active = this._appSettings.get_boolean(SHOW_KEY);
let aPref = parseFloat(this._settings.get_double(MAG_FACTOR_KEY).toFixed(2)); this.setActive(active);
if (aPref != 0.0) }));
zoomRegion.setMagFactor(aPref, aPref);
aPref = this._settings.get_enum(SCREEN_POSITION_KEY); return this._appSettings.get_boolean(SHOW_KEY);
if (aPref) },
zoomRegion.setScreenPosition(aPref);
zoomRegion.setLensMode(this._settings.get_boolean(LENS_MODE_KEY));
zoomRegion.setClampScrollingAtEdges(!this._settings.get_boolean(CLAMP_MODE_KEY));
aPref = this._settings.get_enum(MOUSE_TRACKING_KEY);
if (aPref)
zoomRegion.setMouseTrackingMode(aPref);
aPref = this._settings.get_enum(FOCUS_TRACKING_KEY);
if (aPref)
zoomRegion.setFocusTrackingMode(aPref);
aPref = this._settings.get_enum(CARET_TRACKING_KEY);
if (aPref)
zoomRegion.setCaretTrackingMode(aPref);
aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY);
if (aPref)
zoomRegion.setInvertLightness(aPref);
aPref = this._settings.get_double(COLOR_SATURATION_KEY);
if (aPref)
zoomRegion.setColorSaturation(aPref);
let bc = {};
bc.r = this._settings.get_double(BRIGHT_RED_KEY);
bc.g = this._settings.get_double(BRIGHT_GREEN_KEY);
bc.b = this._settings.get_double(BRIGHT_BLUE_KEY);
zoomRegion.setBrightness(bc);
bc.r = this._settings.get_double(CONTRAST_RED_KEY);
bc.g = this._settings.get_double(CONTRAST_GREEN_KEY);
bc.b = this._settings.get_double(CONTRAST_BLUE_KEY);
zoomRegion.setContrast(bc);
}
_settingsInitLate: function() {
let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY); let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY);
this.addCrosshairs(); this.addCrosshairs();
this.setCrosshairsVisible(showCrosshairs); this.setCrosshairsVisible(showCrosshairs);
this._appSettings.connect('changed::' + SHOW_KEY,
Lang.bind(this, function() {
this.setActive(this._appSettings.get_boolean(SHOW_KEY));
}));
this._settings.connect('changed::' + SCREEN_POSITION_KEY, this._settings.connect('changed::' + SCREEN_POSITION_KEY,
Lang.bind(this, this._updateScreenPosition)); Lang.bind(this, this._updateScreenPosition));
this._settings.connect('changed::' + MAG_FACTOR_KEY, this._settings.connect('changed::' + MAG_FACTOR_KEY,
@ -561,7 +573,6 @@ const Magnifier = new Lang.Class({
Lang.bind(this, function() { Lang.bind(this, function() {
this.setCrosshairsClip(this._settings.get_boolean(CROSS_HAIRS_CLIP_KEY)); this.setCrosshairsClip(this._settings.get_boolean(CROSS_HAIRS_CLIP_KEY));
})); }));
return this._appSettings.get_boolean(SHOW_KEY);
}, },
_updateScreenPosition: function() { _updateScreenPosition: function() {
@ -720,16 +731,8 @@ const ZoomRegion = new Lang.Class({
let component = event.source.get_component_iface(); let component = event.source.get_component_iface();
if (!component || event.detail1 != 1) if (!component || event.detail1 != 1)
return; return;
let extents; let extents = component.get_extents(Atspi.CoordType.SCREEN);
try { [this._xFocus, this._yFocus] = [extents.x, extents.y]
extents = component.get_extents(Atspi.CoordType.SCREEN);
} catch(e) {
log('Failed to read extents of focused component: ' + e.message);
return;
}
[this._xFocus, this._yFocus] = [extents.x + (extents.width / 2),
extents.y + (extents.height / 2)];
this._centerFromFocusPosition(); this._centerFromFocusPosition();
}, },
@ -737,14 +740,7 @@ const ZoomRegion = new Lang.Class({
let text = event.source.get_text_iface(); let text = event.source.get_text_iface();
if (!text) if (!text)
return; return;
let extents; let extents = text.get_character_extents(text.get_caret_offset(), 0);
try {
extents = text.get_character_extents(text.get_caret_offset(), 0);
} catch(e) {
log('Failed to read extents of text caret: ' + e.message);
return;
}
[this._xCaret, this._yCaret] = [extents.x, extents.y]; [this._xCaret, this._yCaret] = [extents.x, extents.y];
this._centerFromCaretPosition(); this._centerFromCaretPosition();
}, },
@ -767,9 +763,6 @@ const ZoomRegion = new Lang.Class({
} else { } else {
this._destroyActors(); this._destroyActors();
} }
this._syncCaretTracking();
this._syncFocusTracking();
}, },
/** /**
@ -829,7 +822,10 @@ const ZoomRegion = new Lang.Class({
*/ */
setFocusTrackingMode: function(mode) { setFocusTrackingMode: function(mode) {
this._focusTrackingMode = mode; this._focusTrackingMode = mode;
this._syncFocusTracking(); if (this._focusTrackingMode == GDesktopEnums.MagnifierFocusTrackingMode.NONE)
this._focusCaretTracker.deregisterFocusListener();
else
this._focusCaretTracker.registerFocusListener();
}, },
/** /**
@ -838,27 +834,10 @@ const ZoomRegion = new Lang.Class({
*/ */
setCaretTrackingMode: function(mode) { setCaretTrackingMode: function(mode) {
this._caretTrackingMode = mode; this._caretTrackingMode = mode;
this._syncCaretTracking(); if (this._caretTrackingMode == GDesktopEnums.MagnifierCaretTrackingMode.NONE)
},
_syncFocusTracking: function() {
let enabled = this._focusTrackingMode != GDesktopEnums.MagnifierFocusTrackingMode.NONE &&
this.isActive();
if (enabled)
this._focusCaretTracker.registerFocusListener();
else
this._focusCaretTracker.deregisterFocusListener();
},
_syncCaretTracking: function() {
let enabled = this._caretTrackingMode != GDesktopEnums.MagnifierCaretTrackingMode.NONE &&
this.isActive();
if (enabled)
this._focusCaretTracker.registerCaretListener();
else
this._focusCaretTracker.deregisterCaretListener(); this._focusCaretTracker.deregisterCaretListener();
else
this._focusCaretTracker.registerCaretListener();
}, },
/** /**
@ -1199,17 +1178,13 @@ const ZoomRegion = new Lang.Class({
// Add a background for when the magnified uiGroup is scrolled // Add a background for when the magnified uiGroup is scrolled
// out of view (don't want to see desktop showing through). // out of view (don't want to see desktop showing through).
this._background = new Clutter.Actor({ background_color: Main.DEFAULT_BACKGROUND_COLOR, this._background = new Clutter.Actor({ background_color: Main.DEFAULT_BACKGROUND_COLOR,
layout_manager: new Clutter.BinLayout(),
width: global.screen_width, width: global.screen_width,
height: global.screen_height }); height: global.screen_height });
let noiseTexture = (new Background.SystemBackground()).actor;
this._background.add_actor(noiseTexture);
mainGroup.add_actor(this._background); mainGroup.add_actor(this._background);
// Clone the group that contains all of UI on the screen. This is the // Clone the group that contains all of UI on the screen. This is the
// chrome, the windows, etc. // chrome, the windows, etc.
this._uiGroupClone = new Clutter.Clone({ source: Main.uiGroup, this._uiGroupClone = new Clutter.Clone({ source: Main.layoutManager.uiGroup });
clip_to_allocation: true });
mainGroup.add_actor(this._uiGroupClone); mainGroup.add_actor(this._uiGroupClone);
// Add either the given mouseSourceActor to the ZoomRegion, or a clone of // Add either the given mouseSourceActor to the ZoomRegion, or a clone of

View File

@ -64,7 +64,6 @@ let screencastService = null;
let modalCount = 0; let modalCount = 0;
let keybindingMode = Shell.KeyBindingMode.NONE; let keybindingMode = Shell.KeyBindingMode.NONE;
let modalActorFocusStack = []; let modalActorFocusStack = [];
let uiGroup = null;
let magnifier = null; let magnifier = null;
let xdndHandler = null; let xdndHandler = null;
let keyboard = null; let keyboard = null;
@ -150,11 +149,6 @@ function _initializeUI() {
// Setup the stage hierarchy early // Setup the stage hierarchy early
layoutManager = new Layout.LayoutManager(); layoutManager = new Layout.LayoutManager();
// Various parts of the codebase still refers to Main.uiGroup
// instead using the layoutManager. This keeps that code
// working until it's updated.
uiGroup = layoutManager.uiGroup;
screencastService = new Screencast.ScreencastService(); screencastService = new Screencast.ScreencastService();
xdndHandler = new XdndHandler.XdndHandler(); xdndHandler = new XdndHandler.XdndHandler();
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
@ -172,6 +166,19 @@ function _initializeUI() {
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler(); windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
componentManager = new Components.ComponentManager(); componentManager = new Components.ComponentManager();
if (sessionMode.isGreeter && screenShield) {
layoutManager.connect('startup-prepared', function() {
screenShield.showDialog();
});
}
layoutManager.connect('startup-complete', function() {
if (keybindingMode == Shell.KeyBindingMode.NONE)
keybindingMode = Shell.KeyBindingMode.NORMAL;
if (screenShield)
screenShield.lockIfWasLocked();
});
layoutManager.init(); layoutManager.init();
overview.init(); overview.init();
@ -202,21 +209,6 @@ function _initializeUI() {
ExtensionDownloader.init(); ExtensionDownloader.init();
ExtensionSystem.init(); ExtensionSystem.init();
if (sessionMode.isGreeter && screenShield) {
layoutManager.connect('startup-prepared', function() {
screenShield.showDialog();
});
}
layoutManager.connect('startup-complete', function() {
if (keybindingMode == Shell.KeyBindingMode.NONE) {
keybindingMode = Shell.KeyBindingMode.NORMAL;
}
if (screenShield) {
screenShield.lockIfWasLocked();
}
});
} }
function _loadDefaultStylesheet() { function _loadDefaultStylesheet() {

View File

@ -1162,12 +1162,32 @@ const SourceActor = new Lang.Class({
})); }));
this._actorDestroyed = false; this._actorDestroyed = false;
let scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor; this._counterLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
this._iconBin = new St.Bin({ x_fill: true, x_expand: true,
height: size * scale_factor, y_align: Clutter.ActorAlign.CENTER,
width: size * scale_factor }); y_expand: true });
this._counterBin = new St.Bin({ style_class: 'summary-source-counter',
child: this._counterLabel,
layout_manager: new Clutter.BinLayout() });
this._counterBin.hide();
this._counterBin.connect('style-changed', Lang.bind(this, function() {
let themeNode = this._counterBin.get_theme_node();
this._counterBin.translation_x = themeNode.get_length('-shell-counter-overlap-x');
this._counterBin.translation_y = themeNode.get_length('-shell-counter-overlap-y');
}));
this._iconBin = new St.Bin({ width: size,
height: size,
x_fill: true,
y_fill: true });
this.actor.add_actor(this._iconBin); this.actor.add_actor(this._iconBin);
this.actor.add_actor(this._counterBin);
this._source.connect('count-updated', Lang.bind(this, this._updateCount));
this._updateCount();
this._source.connect('icon-updated', Lang.bind(this, this._updateIcon)); this._source.connect('icon-updated', Lang.bind(this, this._updateIcon));
this._updateIcon(); this._updateIcon();
@ -1191,48 +1211,6 @@ const SourceActor = new Lang.Class({
_allocate: function(actor, box, flags) { _allocate: function(actor, box, flags) {
// the iconBin should fill our entire box // the iconBin should fill our entire box
this._iconBin.allocate(box, flags); this._iconBin.allocate(box, flags);
},
_updateIcon: function() {
if (this._actorDestroyed)
return;
if (!this._iconSet)
this._iconBin.child = this._source.createIcon(this._size);
}
});
const SourceActorWithLabel = new Lang.Class({
Name: 'SourceActorWithLabel',
Extends: SourceActor,
_init: function(source, size) {
this.parent(source, size);
this._counterLabel = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_align: Clutter.ActorAlign.CENTER,
y_expand: true });
this._counterBin = new St.Bin({ style_class: 'summary-source-counter',
child: this._counterLabel,
layout_manager: new Clutter.BinLayout() });
this._counterBin.hide();
this._counterBin.connect('style-changed', Lang.bind(this, function() {
let themeNode = this._counterBin.get_theme_node();
this._counterBin.translation_x = themeNode.get_length('-shell-counter-overlap-x');
this._counterBin.translation_y = themeNode.get_length('-shell-counter-overlap-y');
}));
this.actor.add_actor(this._counterBin);
this._source.connect('count-updated', Lang.bind(this, this._updateCount));
this._updateCount();
},
_allocate: function(actor, box, flags) {
this.parent(actor, box, flags);
let childBox = new Clutter.ActorBox(); let childBox = new Clutter.ActorBox();
@ -1255,6 +1233,14 @@ const SourceActorWithLabel = new Lang.Class({
this._counterBin.allocate(childBox, flags); this._counterBin.allocate(childBox, flags);
}, },
_updateIcon: function() {
if (this._actorDestroyed)
return;
if (!this._iconSet)
this._iconBin.child = this._source.createIcon(this._size);
},
_updateCount: function() { _updateCount: function() {
if (this._actorDestroyed) if (this._actorDestroyed)
return; return;
@ -1367,7 +1353,7 @@ const Source = new Lang.Class({
if (this._mainIcon) if (this._mainIcon)
return; return;
this._mainIcon = new SourceActorWithLabel(this, this.SOURCE_ICON_SIZE); this._mainIcon = new SourceActor(this, this.SOURCE_ICON_SIZE);
}, },
// Unlike createIcon, this always returns the same actor; // Unlike createIcon, this always returns the same actor;
@ -1625,7 +1611,7 @@ const MessageTrayMenu = new Lang.Class({
this._accountManager.prepare_async(null, Lang.bind(this, this._onIMPresenceChanged)); this._accountManager.prepare_async(null, Lang.bind(this, this._onIMPresenceChanged));
this.actor.hide(); this.actor.hide();
Main.layoutManager.addChrome(this.actor); Main.layoutManager.menuGroup.add_child(this.actor);
this._busyItem = new PopupMenu.PopupSwitchMenuItem(_("Notifications")); this._busyItem = new PopupMenu.PopupSwitchMenuItem(_("Notifications"));
this._busyItem.connect('toggled', Lang.bind(this, this._updatePresence)); this._busyItem.connect('toggled', Lang.bind(this, this._updatePresence));
@ -2027,18 +2013,13 @@ const MessageTray = new Lang.Class({
_onNotificationKeyRelease: function(actor, event) { _onNotificationKeyRelease: function(actor, event) {
if (event.get_key_symbol() == Clutter.KEY_Escape && event.get_state() == 0) { if (event.get_key_symbol() == Clutter.KEY_Escape && event.get_state() == 0) {
this._expireNotification(); this._closeNotification();
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} }
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
}, },
_expireNotification: function() {
this._notificationExpired = true;
this._updateState();
},
_closeNotification: function() { _closeNotification: function() {
if (this._notificationState == State.SHOWN) { if (this._notificationState == State.SHOWN) {
this._closeButton.hide(); this._closeButton.hide();
@ -2403,7 +2384,7 @@ const MessageTray = new Lang.Class({
this._notificationTimeoutId == 0 && this._notificationTimeoutId == 0 &&
this._notification.urgency != Urgency.CRITICAL && this._notification.urgency != Urgency.CRITICAL &&
!this._notification.focused && !this._notification.focused &&
!this._pointerInNotification) || this._notificationExpired; !this._pointerInNotification);
let mustClose = (this._notificationRemoved || !hasNotifications || expired || this._traySummoned); let mustClose = (this._notificationRemoved || !hasNotifications || expired || this._traySummoned);
if (mustClose) { if (mustClose) {
@ -2464,10 +2445,6 @@ const MessageTray = new Lang.Class({
this._hideDesktopClone(); this._hideDesktopClone();
this._updatingState = false; this._updatingState = false;
// Clean transient variables that are used to communicate actions
// to updateState()
this._notificationExpired = false;
}, },
_tween: function(actor, statevar, value, params) { _tween: function(actor, statevar, value, params) {
@ -2535,7 +2512,7 @@ const MessageTray = new Lang.Class({
let cloneSource = Main.overview.visible ? Main.layoutManager.overviewGroup : global.window_group; let cloneSource = Main.overview.visible ? Main.layoutManager.overviewGroup : global.window_group;
this._desktopClone = new Clutter.Clone({ source: cloneSource, this._desktopClone = new Clutter.Clone({ source: cloneSource,
clip: new Clutter.Geometry(this._bottomMonitorGeometry) }); clip: new Clutter.Geometry(this._bottomMonitorGeometry) });
Main.uiGroup.insert_child_above(this._desktopClone, cloneSource); Main.layoutManager.sessionGroup.insert_child_above(this._desktopClone, cloneSource);
this._desktopClone.x = 0; this._desktopClone.x = 0;
this._desktopClone.y = 0; this._desktopClone.y = 0;
this._desktopClone.show(); this._desktopClone.show();
@ -2790,12 +2767,7 @@ const MessageTray = new Lang.Class({
{ y: expandedY, { y: expandedY,
opacity: 255, opacity: 255,
time: ANIMATION_TIME, time: ANIMATION_TIME,
transition: 'easeOutQuad', transition: 'easeOutQuad'
// HACK: Drive the state machine here better,
// instead of overwriting tweens
onComplete: Lang.bind(this, function() {
this._notificationState = State.SHOWN;
}),
}); });
} }
}, },

View File

@ -41,6 +41,7 @@ const ModalDialog = new Lang.Class({
_init: function(params) { _init: function(params) {
params = Params.parse(params, { shellReactive: false, params = Params.parse(params, { shellReactive: false,
styleClass: null, styleClass: null,
parentActor: Main.layoutManager.dialogGroup,
keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL, keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL,
shouldFadeIn: true, shouldFadeIn: true,
destroyOnClose: true }); destroyOnClose: true });
@ -56,7 +57,7 @@ const ModalDialog = new Lang.Class({
x: 0, x: 0,
y: 0, y: 0,
accessible_role: Atk.Role.DIALOG }); accessible_role: Atk.Role.DIALOG });
Main.layoutManager.modalDialogGroup.add_actor(this._group); params.parentActor.add_actor(this._group);
let constraint = new Clutter.BindConstraint({ source: global.stage, let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.ALL }); coordinate: Clutter.BindCoordinate.ALL });

View File

@ -691,12 +691,6 @@ const FdoNotificationDaemonSource = new Lang.Class({
} }
}); });
const PRIORITY_URGENCY_MAP = {
low: MessageTray.Urgency.LOW,
normal: MessageTray.Urgency.NORMAL,
high: MessageTray.Urgency.HIGH,
urgent: MessageTray.Urgency.CRITICAL
};
const GtkNotificationDaemonNotification = new Lang.Class({ const GtkNotificationDaemonNotification = new Lang.Class({
Name: 'GtkNotificationDaemonNotification', Name: 'GtkNotificationDaemonNotification',
@ -710,20 +704,12 @@ const GtkNotificationDaemonNotification = new Lang.Class({
"body": body, "body": body,
"icon": gicon, "icon": gicon,
"urgent": urgent, "urgent": urgent,
"priority": priority,
"buttons": buttons, "buttons": buttons,
"default-action": defaultAction, "default-action": defaultAction,
"default-action-target": defaultActionTarget } = notification; "default-action-target": defaultActionTarget } = notification;
if (priority) { this.setUrgency(urgent.unpack() ? MessageTray.Urgency.CRITICAL
let urgency = PRIORITY_URGENCY_MAP[priority.unpack()]; : MessageTray.Urgency.NORMAL);
this.setUrgency(urgency != undefined ? urgency : MessageTray.Urgency.NORMAL);
} else if (urgent) {
this.setUrgency(urgent.unpack() ? MessageTray.Urgency.CRITICAL
: MessageTray.Urgency.NORMAL);
} else {
this.setUrgency(MessageTray.Urgency.NORMAL);
}
if (buttons) { if (buttons) {
buttons.deep_unpack().forEach(Lang.bind(this, function(button) { buttons.deep_unpack().forEach(Lang.bind(this, function(button) {

View File

@ -110,7 +110,7 @@ const OsdWindow = new Lang.Class({
Lang.bind(this, this._monitorsChanged)); Lang.bind(this, this._monitorsChanged));
this._monitorsChanged(); this._monitorsChanged();
Main.uiGroup.add_child(this.actor); Main.layoutManager.osdGroup.add_child(this.actor);
}, },
setIcon: function(icon) { setIcon: function(icon) {
@ -125,7 +125,7 @@ const OsdWindow = new Lang.Class({
setLevel: function(level) { setLevel: function(level) {
this._level.actor.visible = (level != undefined); this._level.actor.visible = (level != undefined);
if (level != undefined) { if (level) {
if (this.actor.visible) if (this.actor.visible)
Tweener.addTween(this._level, Tweener.addTween(this._level,
{ level: level, { level: level,
@ -200,9 +200,8 @@ const OsdWindow = new Lang.Class({
let scale = Math.min(scalew, scaleh); let scale = Math.min(scalew, scaleh);
this._popupSize = 110 * Math.max(1, scale); this._popupSize = 110 * Math.max(1, scale);
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._icon.icon_size = this._popupSize / (2 * scaleFactor);
this._box.translation_y = monitor.height / 4; this._box.translation_y = monitor.height / 4;
this._icon.icon_size = this._popupSize / 2;
this._box.style_changed(); this._box.style_changed();
}, },
@ -218,10 +217,7 @@ const OsdWindow = new Lang.Class({
let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder; let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder;
let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder; let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder;
// minWidth/minHeight here are in real pixels, this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight));
// 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);
}, },
setMonitor: function(index) { setMonitor: function(index) {

View File

@ -14,7 +14,6 @@ const Gdk = imports.gi.Gdk;
const Background = imports.ui.background; const Background = imports.ui.background;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const LayoutManager = imports.ui.layout; const LayoutManager = imports.ui.layout;
const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main; const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
const OverviewControls = imports.ui.overviewControls; const OverviewControls = imports.ui.overviewControls;
@ -197,7 +196,11 @@ const Overview = new Lang.Class({
Tweener.addTween(background, Tweener.addTween(background,
{ brightness: 1.0, { brightness: 1.0,
vignetteSharpness: 0.0, time: SHADE_ANIMATION_TIME,
transition: 'easeOutQuad'
});
Tweener.addTween(background,
{ vignetteSharpness: 0.0,
time: SHADE_ANIMATION_TIME, time: SHADE_ANIMATION_TIME,
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
@ -210,8 +213,12 @@ const Overview = new Lang.Class({
let background = backgrounds[i]._delegate; let background = backgrounds[i]._delegate;
Tweener.addTween(background, Tweener.addTween(background,
{ brightness: Lightbox.VIGNETTE_BRIGHTNESS, { brightness: 0.8,
vignetteSharpness: Lightbox.VIGNETTE_SHARPNESS, time: SHADE_ANIMATION_TIME,
transition: 'easeOutQuad'
});
Tweener.addTween(background,
{ vignetteSharpness: 0.7,
time: SHADE_ANIMATION_TIME, time: SHADE_ANIMATION_TIME,
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
@ -486,13 +493,8 @@ const Overview = new Lang.Class({
}, },
fadeOutDesktop: function() { fadeOutDesktop: function() {
if (!this._desktopFade.get_n_children()) { if (!this._desktopFade.get_n_children())
let clone = this._getDesktopClone(); this._desktopFade.add_child(this._getDesktopClone());
if (!clone)
return;
this._desktopFade.add_child(clone);
}
this._desktopFade.opacity = 255; this._desktopFade.opacity = 255;
this._desktopFade.show(); this._desktopFade.show();
@ -620,7 +622,7 @@ const Overview = new Lang.Class({
this.animationInProgress = true; this.animationInProgress = true;
this.visibleTarget = false; this.visibleTarget = false;
this.viewSelector.zoomFromOverview(); this.viewSelector.leaveOverview();
// Make other elements fade out. // Make other elements fade out.
Tweener.addTween(this._stack, Tweener.addTween(this._stack,

View File

@ -213,7 +213,7 @@ const AppMenuButton = new Lang.Class({
this._label = new TextShadower(); this._label = new TextShadower();
this._label.actor.y_align = Clutter.ActorAlign.CENTER; this._label.actor.y_align = Clutter.ActorAlign.CENTER;
this._hbox.add_actor(this._label.actor); this._hbox.add_actor(this._label.actor);
this._arrow = PopupMenu.arrowIcon(St.Side.BOTTOM); this._arrow = PopupMenu.unicodeArrow(St.Side.BOTTOM);
this._hbox.add_actor(this._arrow); this._hbox.add_actor(this._arrow);
this._iconBottomClip = 0; this._iconBottomClip = 0;
@ -812,11 +812,7 @@ const AggregateMenu = new Lang.Class({
this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' }); this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' });
this.actor.add_child(this._indicators); this.actor.add_child(this._indicators);
if (Config.HAVE_NETWORKMANAGER) { this._network = new imports.ui.status.network.NMApplet();
this._network = new imports.ui.status.network.NMApplet();
} else {
this._network = null;
}
if (Config.HAVE_BLUETOOTH) { if (Config.HAVE_BLUETOOTH) {
this._bluetooth = new imports.ui.status.bluetooth.Indicator(); this._bluetooth = new imports.ui.status.bluetooth.Indicator();
} else { } else {
@ -833,27 +829,22 @@ const AggregateMenu = new Lang.Class({
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);
if (this._network) { this._indicators.add_child(this._network.indicators);
this._indicators.add_child(this._network.indicators);
}
if (this._bluetooth) { if (this._bluetooth) {
this._indicators.add_child(this._bluetooth.indicators); this._indicators.add_child(this._bluetooth.indicators);
} }
this._indicators.add_child(this._rfkill.indicators); this._indicators.add_child(this._rfkill.indicators);
this._indicators.add_child(this._volume.indicators); this._indicators.add_child(this._volume.indicators);
this._indicators.add_child(this._power.indicators); this._indicators.add_child(this._power.indicators);
this._indicators.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM)); this._indicators.add_child(PopupMenu.unicodeArrow(St.Side.BOTTOM));
this.menu.addMenuItem(this._volume.menu); this.menu.addMenuItem(this._volume.menu);
this.menu.addMenuItem(this._brightness.menu); this.menu.addMenuItem(this._brightness.menu);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
if (this._network) { this.menu.addMenuItem(this._network.menu);
this.menu.addMenuItem(this._network.menu);
}
if (this._bluetooth) { if (this._bluetooth) {
this.menu.addMenuItem(this._bluetooth.menu); this.menu.addMenuItem(this._bluetooth.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(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -910,7 +901,7 @@ const Panel = new Lang.Class({
this.actor.remove_style_pseudo_class('overview'); this.actor.remove_style_pseudo_class('overview');
})); }));
Main.layoutManager.panelBox.add(this.actor); Main.layoutManager.panelGroup.add_child(this.actor);
Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'emblem-system-symbolic', Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'emblem-system-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.TOP }); { sortGroup: CtrlAltTab.SortGroup.TOP });

View File

@ -130,7 +130,7 @@ const Button = new Lang.Class({
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged)); this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress)); this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
Main.uiGroup.add_actor(this.menu.actor); Main.layoutManager.menuGroup.add_child(this.menu.actor);
this.menu.actor.hide(); this.menu.actor.hide();
} }
}, },

View File

@ -45,35 +45,28 @@ function isPopupMenuItemVisible(child) {
/** /**
* @side Side to which the arrow points. * @side Side to which the arrow points.
*/ */
function arrowIcon(side) { function unicodeArrow(side) {
let rotation; let arrowChar;
switch (side) { switch (side) {
case St.Side.TOP: case St.Side.TOP:
rotation = 180; arrowChar = '\u25B4';
break; break;
case St.Side.RIGHT: case St.Side.RIGHT:
rotation = - 90; arrowChar = '\u25B8';
break; break;
case St.Side.BOTTOM: case St.Side.BOTTOM:
rotation = 0; arrowChar = '\u25BE';
break; break;
case St.Side.LEFT: case St.Side.LEFT:
rotation = 90; arrowChar = '\u25C2';
break; break;
} }
let gicon = new Gio.FileIcon({ file: Gio.File.new_for_path(global.datadir + return new St.Label({ text: arrowChar,
'/theme/menu-arrow-symbolic.svg') }); style_class: 'unicode-arrow',
accessible_role: Atk.Role.ARROW,
let arrow = new St.Icon({ style_class: 'popup-menu-arrow', y_expand: true,
gicon: gicon, y_align: Clutter.ActorAlign.CENTER });
accessible_role: Atk.Role.ARROW,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
arrow.rotation_angle_z = rotation;
return arrow;
} }
const PopupBaseMenuItem = new Lang.Class({ const PopupBaseMenuItem = new Lang.Class({
@ -118,7 +111,6 @@ const PopupBaseMenuItem = new Lang.Class({
this.actor.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn)); this.actor.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
this.actor.connect('key-focus-out', Lang.bind(this, this._onKeyFocusOut)); this.actor.connect('key-focus-out', Lang.bind(this, this._onKeyFocusOut));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
}, },
_getTopMenu: function() { _getTopMenu: function() {
@ -200,9 +192,6 @@ const PopupBaseMenuItem = new Lang.Class({
destroy: function() { destroy: function() {
this.actor.destroy(); this.actor.destroy();
},
_onDestroy: function() {
this.emit('destroy'); this.emit('destroy');
}, },
@ -879,14 +868,14 @@ const PopupSubMenu = new Lang.Class({
if (animate) { if (animate) {
let [minHeight, naturalHeight] = this.actor.get_preferred_height(-1); let [minHeight, naturalHeight] = this.actor.get_preferred_height(-1);
this.actor.height = 0; this.actor.height = 0;
this.actor._arrowRotation = this._arrow.rotation_angle_z; this.actor._arrow_rotation = this._arrow.rotation_angle_z;
Tweener.addTween(this.actor, Tweener.addTween(this.actor,
{ _arrowRotation: this.actor._arrowRotation + 90, { _arrow_rotation: 90,
height: naturalHeight, height: naturalHeight,
time: 0.25, time: 0.25,
onUpdateScope: this, onUpdateScope: this,
onUpdate: function() { onUpdate: function() {
this._arrow.rotation_angle_z = this.actor._arrowRotation; this._arrow.rotation_angle_z = this.actor._arrow_rotation;
}, },
onCompleteScope: this, onCompleteScope: this,
onComplete: function() { onComplete: function() {
@ -894,7 +883,7 @@ const PopupSubMenu = new Lang.Class({
} }
}); });
} else { } else {
this._arrow.rotation_angle_z = this.actor._arrowRotation + 90; this._arrow.rotation_angle_z = 90;
} }
}, },
@ -912,14 +901,14 @@ const PopupSubMenu = new Lang.Class({
animate = false; animate = false;
if (animate) { if (animate) {
this.actor._arrowRotation = this._arrow.rotation_angle_z; this.actor._arrow_rotation = this._arrow.rotation_angle_z;
Tweener.addTween(this.actor, Tweener.addTween(this.actor,
{ _arrowRotation: this.actor._arrowRotation - 90, { _arrow_rotation: 0,
height: 0, height: 0,
time: 0.25, time: 0.25,
onUpdateScope: this, onUpdateScope: this,
onUpdate: function() { onUpdate: function() {
this._arrow.rotation_angle_z = this.actor._arrowRotation; this._arrow.rotation_angle_z = this.actor._arrow_rotation;
}, },
onCompleteScope: this, onCompleteScope: this,
onComplete: function() { onComplete: function() {
@ -928,7 +917,7 @@ const PopupSubMenu = new Lang.Class({
}, },
}); });
} else { } else {
this._arrow.rotation_angle_z = this.actor._arrowRotation - 90; this._arrow.rotation_angle_z = 0;
this.actor.hide(); this.actor.hide();
} }
}, },
@ -1000,7 +989,7 @@ const PopupSubMenuMenuItem = new Lang.Class({
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER });
this.actor.add_child(this.status); this.actor.add_child(this.status);
this._triangle = arrowIcon(St.Side.RIGHT); this._triangle = unicodeArrow(St.Side.RIGHT);
this._triangle.pivot_point = new Clutter.Point({ x: 0.5, y: 0.6 }); this._triangle.pivot_point = new Clutter.Point({ x: 0.5, y: 0.6 });
this._triangleBin = new St.Widget({ y_expand: true, this._triangleBin = new St.Widget({ y_expand: true,

View File

@ -301,7 +301,7 @@ const NotificationsBox = new Lang.Class({
}); });
this._updateVisibility(); this._updateVisibility();
this.emit('wake-up-screen'); Shell.util_wake_up_screen();
} }
}, },
@ -327,7 +327,7 @@ const NotificationsBox = new Lang.Class({
this._updateVisibility(); this._updateVisibility();
if (obj.sourceBox.visible) if (obj.sourceBox.visible)
this.emit('wake-up-screen'); Shell.util_wake_up_screen();
}, },
_visibleChanged: function(source, obj) { _visibleChanged: function(source, obj) {
@ -342,7 +342,7 @@ const NotificationsBox = new Lang.Class({
this._updateVisibility(); this._updateVisibility();
if (obj.sourceBox.visible) if (obj.sourceBox.visible)
this.emit('wake-up-screen'); Shell.util_wake_up_screen();
}, },
_detailedChanged: function(source, obj) { _detailedChanged: function(source, obj) {
@ -380,7 +380,6 @@ const NotificationsBox = new Lang.Class({
this._sources.delete(source); this._sources.delete(source);
}, },
}); });
Signals.addSignalMethods(NotificationsBox.prototype);
const Arrow = new Lang.Class({ const Arrow = new Lang.Class({
Name: 'Arrow', Name: 'Arrow',
@ -457,8 +456,6 @@ const ScreenShield = new Lang.Class({
Name: 'ScreenShield', Name: 'ScreenShield',
_init: function() { _init: function() {
this.actor = Main.layoutManager.screenShieldGroup;
this._lockScreenState = MessageTray.State.HIDDEN; this._lockScreenState = MessageTray.State.HIDDEN;
this._lockScreenGroup = new St.Widget({ x_expand: true, this._lockScreenGroup = new St.Widget({ x_expand: true,
y_expand: true, y_expand: true,
@ -467,6 +464,7 @@ const ScreenShield = new Lang.Class({
name: 'lockScreenGroup', name: 'lockScreenGroup',
visible: false, visible: false,
}); });
this._lockScreenGroup.connect('key-press-event', this._lockScreenGroup.connect('key-press-event',
Lang.bind(this, this._onLockScreenKeyPress)); Lang.bind(this, this._onLockScreenKeyPress));
this._lockScreenGroup.connect('scroll-event', this._lockScreenGroup.connect('scroll-event',
@ -517,10 +515,9 @@ const ScreenShield = new Lang.Class({
reactive: true, reactive: true,
pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }), pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }),
name: 'lockDialogGroup' }); name: 'lockDialogGroup' });
Main.layoutManager.systemGroup.add_child(this._lockDialogGroup);
this.actor.add_actor(this._lockDialogGroup); Main.layoutManager.screenShieldGroup.add_child(this._lockScreenGroup);
this.actor.add_actor(this._lockScreenGroup);
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) { this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
if (error) { if (error) {
logError(error, 'Error while reading gnome-session presence'); logError(error, 'Error while reading gnome-session presence');
@ -537,7 +534,7 @@ const ScreenShield = new Lang.Class({
this._smartcardManager = SmartcardManager.getSmartcardManager(); this._smartcardManager = SmartcardManager.getSmartcardManager();
this._smartcardManager.connect('smartcard-inserted', this._smartcardManager.connect('smartcard-inserted',
Lang.bind(this, function(manager, token) { Lang.bind(this, function(token) {
if (this._isLocked && token.UsedToLogin) if (this._isLocked && token.UsedToLogin)
this._liftShield(true, 0); this._liftShield(true, 0);
})); }));
@ -578,19 +575,27 @@ const ScreenShield = new Lang.Class({
// The "long" lightbox is used for the longer (20 seconds) fade from session // The "long" lightbox is used for the longer (20 seconds) fade from session
// to idle status, the "short" is used for quickly fading to black when locking // to idle status, the "short" is used for quickly fading to black when locking
// manually // manually
this._longLightbox = new Lightbox.Lightbox(Main.uiGroup, this._longLightbox = new Lightbox.Lightbox(Main.layoutManager.overlayGroup,
{ inhibitEvents: true, { inhibitEvents: true,
fadeFactor: 1 }); fadeFactor: 1 });
this._longLightbox.connect('shown', Lang.bind(this, this._onLongLightboxShown)); this._longLightbox.connect('shown', Lang.bind(this, this._onLongLightboxShown));
this._shortLightbox = new Lightbox.Lightbox(Main.uiGroup, this._shortLightbox = new Lightbox.Lightbox(Main.layoutManager.overlayGroup,
{ inhibitEvents: true, { inhibitEvents: true,
fadeFactor: 1 }); fadeFactor: 1 });
this._shortLightbox.connect('shown', Lang.bind(this, this._onShortLightboxShown)); this._shortLightbox.connect('shown', Lang.bind(this, this._onShortLightboxShown));
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._monitorsChanged));
this._monitorsChanged();
this.idleMonitor = Meta.IdleMonitor.get_core(); this.idleMonitor = Meta.IdleMonitor.get_core();
this._cursorTracker = Meta.CursorTracker.get_for_screen(global.screen); this._cursorTracker = Meta.CursorTracker.get_for_screen(global.screen);
}, },
_monitorsChanged: function() {
this._longLightbox.actor.set_size(global.screen_width, global.screen_height);
this._shortLightbox.actor.set_size(global.screen_width, global.screen_height);
},
_createBackground: function(monitorIndex) { _createBackground: function(monitorIndex) {
let monitor = Main.layoutManager.monitors[monitorIndex]; let monitor = Main.layoutManager.monitors[monitorIndex];
let widget = new St.Widget({ style_class: 'screen-shield-background', let widget = new St.Widget({ style_class: 'screen-shield-background',
@ -648,14 +653,14 @@ const ScreenShield = new Lang.Class({
if (this._isModal) if (this._isModal)
return true; return true;
this._isModal = Main.pushModal(this.actor, { keybindingMode: Shell.KeyBindingMode.LOCK_SCREEN }); this._isModal = Main.pushModal(this._lockDialogGroup, { keybindingMode: Shell.KeyBindingMode.LOCK_SCREEN });
if (this._isModal) if (this._isModal)
return true; return true;
// We failed to get a pointer grab, it means that // We failed to get a pointer grab, it means that
// something else has it. Try with a keyboard grab only // something else has it. Try with a keyboard grab only
this._isModal = Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED, this._isModal = Main.pushModal(this._lockDialogGroup, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED,
keybindingMode: Shell.KeyBindingMode.LOCK_SCREEN }); keybindingMode: Shell.KeyBindingMode.LOCK_SCREEN });
return this._isModal; return this._isModal;
}, },
@ -729,7 +734,7 @@ const ScreenShield = new Lang.Class({
} else { } else {
this._inhibitSuspend(); this._inhibitSuspend();
this._wakeUpScreen(); this._onUserBecameActive();
} }
}, },
@ -901,13 +906,19 @@ const ScreenShield = new Lang.Class({
}, },
showDialog: function() { showDialog: function() {
if (!this._becomeModal()) { // Ensure that the stage window is mapped, before taking a grab
// In the login screen, this is a hard error. Fail-whale // otherwise X errors out
log('Could not acquire modal grab for the login screen. Aborting login process.'); Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
Meta.quit(Meta.ExitCode.ERROR); if (!this._becomeModal()) {
} // In the login screen, this is a hard error. Fail-whale
log('Could not acquire modal grab for the login screen. Aborting login process.');
Meta.quit(Meta.ExitCode.ERROR);
}
this.actor.show(); return false;
}));
this._lockDialogGroup.show();
this._isGreeter = Main.sessionMode.isGreeter; this._isGreeter = Main.sessionMode.isGreeter;
this._isLocked = true; this._isLocked = true;
if (this._ensureUnlockDialog(true, true)) if (this._ensureUnlockDialog(true, true))
@ -997,6 +1008,7 @@ const ScreenShield = new Lang.Class({
return; return;
this._ensureLockScreen(); this._ensureLockScreen();
this._lockDialogGroup.hide();
this._lockDialogGroup.scale_x = 1; this._lockDialogGroup.scale_x = 1;
this._lockDialogGroup.scale_y = 1; this._lockDialogGroup.scale_y = 1;
@ -1095,8 +1107,10 @@ const ScreenShield = new Lang.Class({
})); }));
this._cursorTracker.set_pointer_visible(false); this._cursorTracker.set_pointer_visible(false);
this._lockScreenState = MessageTray.State.SHOWN; this._lockDialogGroup.show();
this._lockScreenGroup.fixed_position_set = false; this._lockScreenGroup.fixed_position_set = false;
this._lockScreenState = MessageTray.State.SHOWN;
Main.layoutManager.sessionGroup.hide();
this._lockScreenScrollCounter = 0; this._lockScreenScrollCounter = 0;
if (params.fadeToBlack && params.animateFade) { if (params.fadeToBlack && params.animateFade) {
@ -1146,7 +1160,6 @@ const ScreenShield = new Lang.Class({
this._lockScreenContents.add_actor(this._lockScreenContentsBox); this._lockScreenContents.add_actor(this._lockScreenContentsBox);
this._notificationsBox = new NotificationsBox(); this._notificationsBox = new NotificationsBox();
this._wakeUpScreenId = this._notificationsBox.connect('wake-up-screen', Lang.bind(this, this._wakeUpScreen));
this._lockScreenContentsBox.add(this._notificationsBox.actor, { x_fill: true, this._lockScreenContentsBox.add(this._notificationsBox.actor, { x_fill: true,
y_fill: true, y_fill: true,
expand: true }); expand: true });
@ -1154,17 +1167,11 @@ const ScreenShield = new Lang.Class({
this._hasLockScreen = true; this._hasLockScreen = true;
}, },
_wakeUpScreen: function() {
this._onUserBecameActive();
this.emit('wake-up-screen');
},
_clearLockScreen: function() { _clearLockScreen: function() {
this._clock.destroy(); this._clock.destroy();
this._clock = null; this._clock = null;
if (this._notificationsBox) { if (this._notificationsBox) {
this._notificationsBox.disconnect(this._wakeUpScreenId);
this._notificationsBox.destroy(); this._notificationsBox.destroy();
this._notificationsBox = null; this._notificationsBox = null;
} }
@ -1226,10 +1233,11 @@ const ScreenShield = new Lang.Class({
this._dialog.popModal(); this._dialog.popModal();
if (this._isModal) { if (this._isModal) {
Main.popModal(this.actor); Main.popModal(this._lockDialogGroup);
this._isModal = false; this._isModal = false;
} }
Main.layoutManager.sessionGroup.show();
Tweener.addTween(this._lockDialogGroup, { Tweener.addTween(this._lockDialogGroup, {
scale_x: 0, scale_x: 0,
scale_y: 0, scale_y: 0,
@ -1248,7 +1256,7 @@ const ScreenShield = new Lang.Class({
this._longLightbox.hide(); this._longLightbox.hide();
this._shortLightbox.hide(); this._shortLightbox.hide();
this.actor.hide(); this._lockScreenGroup.hide();
if (this._becameActiveId != 0) { if (this._becameActiveId != 0) {
this.idleMonitor.remove_watch(this._becameActiveId); this.idleMonitor.remove_watch(this._becameActiveId);
@ -1272,7 +1280,7 @@ const ScreenShield = new Lang.Class({
if (this._activationTime == 0) if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time(); this._activationTime = GLib.get_monotonic_time();
this.actor.show(); this._lockScreenGroup.show();
if (Main.sessionMode.currentMode != 'unlock-dialog' && if (Main.sessionMode.currentMode != 'unlock-dialog' &&
Main.sessionMode.currentMode != 'lock-screen') { Main.sessionMode.currentMode != 'lock-screen') {

View File

@ -67,13 +67,6 @@ const ScreenshotService = new Lang.Class({
Gio.DBus.session.own_name('org.gnome.Shell.Screenshot', Gio.BusNameOwnerFlags.REPLACE, null, null); Gio.DBus.session.own_name('org.gnome.Shell.Screenshot', Gio.BusNameOwnerFlags.REPLACE, null, null);
}, },
_checkArea: function(x, y, width, height) {
return x >= 0 && y >= 0 &&
width > 0 && height > 0 &&
x + width <= global.screen_width &&
y + height <= global.screen_height;
},
_onScreenshotComplete: function(obj, result, area, filenameUsed, flash, invocation) { _onScreenshotComplete: function(obj, result, area, filenameUsed, flash, invocation) {
if (flash && result) { if (flash && result) {
let flashspot = new Flashspot(area); let flashspot = new Flashspot(area);
@ -84,31 +77,13 @@ const ScreenshotService = new Lang.Class({
invocation.return_value(retval); invocation.return_value(retval);
}, },
_scaleArea: function(x, y, width, height) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
x *= scaleFactor;
y *= scaleFactor;
width *= scaleFactor;
height *= scaleFactor;
return [x, y, width, height];
},
_unscaleArea: function(x, y, width, height) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
x /= scaleFactor;
y /= scaleFactor;
width /= scaleFactor;
height /= scaleFactor;
return [x, y, width, height];
},
ScreenshotAreaAsync : function (params, invocation) { ScreenshotAreaAsync : function (params, invocation) {
let [x, y, width, height, flash, filename, callback] = params; let [x, y, width, height, flash, filename, callback] = params;
[x, y, width, height] = this._scaleArea(x, y, width, height); if (x < 0 || y < 0 ||
if (!this._checkArea(x, y, width, height)) { width <= 0 || height <= 0 ||
invocation.return_error_literal(Gio.IOErrorEnum, x + width > global.screen_width || y + height > global.screen_height) {
Gio.IOErrorEnum.CANCELLED, invocation.return_error_literal(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
"Invalid params"); "Invalid params");
return; return;
} }
let screenshot = new Shell.Screenshot(); let screenshot = new Shell.Screenshot();
@ -139,9 +114,9 @@ const ScreenshotService = new Lang.Class({
selectArea.connect('finished', Lang.bind(this, selectArea.connect('finished', Lang.bind(this,
function(selectArea, areaRectangle) { function(selectArea, areaRectangle) {
if (areaRectangle) { if (areaRectangle) {
let retRectangle = this._unscaleArea(areaRectangle.x, areaRectangle.y, let retval = GLib.Variant.new('(iiii)',
areaRectangle.width, areaRectangle.height); [areaRectangle.x, areaRectangle.y,
let retval = GLib.Variant.new('(iiii)', retRectangle); areaRectangle.width, areaRectangle.height]);
invocation.return_value(retval); invocation.return_value(retval);
} else { } else {
invocation.return_error_literal(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED, invocation.return_error_literal(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
@ -150,18 +125,9 @@ const ScreenshotService = new Lang.Class({
})); }));
}, },
FlashAreaAsync: function(params, invocation) { FlashArea: function(x, y, width, height) {
let [x, y, width, height] = params;
[x, y, width, height] = this._scaleArea(x, y, width, height);
if (!this._checkArea(x, y, width, height)) {
invocation.return_error_literal(Gio.IOErrorEnum,
Gio.IOErrorEnum.CANCELLED,
"Invalid params");
return;
}
let flashspot = new Flashspot({ x : x, y : y, width: width, height: height}); let flashspot = new Flashspot({ x : x, y : y, width: width, height: height});
flashspot.fire(); flashspot.fire();
invocation.return_value(null);
} }
}); });
@ -180,7 +146,7 @@ const SelectArea = new Lang.Class({
reactive: true, reactive: true,
x: 0, x: 0,
y: 0 }); y: 0 });
Main.uiGroup.add_actor(this._group); Main.layoutManager.osdGroup.add_actor(this._group);
this._group.connect('button-press-event', this._group.connect('button-press-event',
Lang.bind(this, this._onButtonPress)); Lang.bind(this, this._onButtonPress));
@ -293,9 +259,9 @@ const Flashspot = new Lang.Class({
Extends: Lightbox.Lightbox, Extends: Lightbox.Lightbox,
_init: function(area) { _init: function(area) {
this.parent(Main.uiGroup, { inhibitEvents: true, this.parent(Main.layoutManager.osdGroup, { inhibitEvents: true,
width: area.width, width: area.width,
height: area.height }); height: area.height });
this.actor.style_class = 'flashspot'; this.actor.style_class = 'flashspot';
this.actor.set_position(area.x, area.y); this.actor.set_position(area.x, area.y);

View File

@ -68,9 +68,6 @@ const SearchSystem = new Lang.Class({
_unregisterProvider: function (provider) { _unregisterProvider: function (provider) {
let index = this._providers.indexOf(provider); let index = this._providers.indexOf(provider);
this._providers.splice(index, 1); this._providers.splice(index, 1);
if (provider.display)
provider.display.destroy();
}, },
getProviders: function() { getProviders: function() {
@ -318,8 +315,6 @@ const SearchResultsBase = new Lang.Class({
}, },
clear: function() { clear: function() {
for (let resultId in this._resultDisplays)
this._resultDisplays[resultId].actor.destroy();
this._resultDisplays = {}; this._resultDisplays = {};
this._clearResultDisplay(); this._clearResultDisplay();
this.actor.hide(); this.actor.hide();
@ -343,22 +338,12 @@ const SearchResultsBase = new Lang.Class({
})); }));
if (metasNeeded.length === 0) { if (metasNeeded.length === 0) {
callback(true); callback();
} else { } else {
this._cancellable.cancel(); this._cancellable.cancel();
this._cancellable.reset(); this._cancellable.reset();
this.provider.getResultMetas(metasNeeded, Lang.bind(this, function(metas) { this.provider.getResultMetas(metasNeeded, Lang.bind(this, function(metas) {
if (metas.length == 0) {
callback(false);
return;
}
if (metas.length != metasNeeded.length) {
log('Wrong number of result metas returned by search provider');
callback(false);
return;
}
metasNeeded.forEach(Lang.bind(this, function(resultId, i) { metasNeeded.forEach(Lang.bind(this, function(resultId, i) {
let meta = metas[i]; let meta = metas[i];
let display = this._createResultDisplay(meta); let display = this._createResultDisplay(meta);
@ -366,7 +351,7 @@ const SearchResultsBase = new Lang.Class({
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn)); display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
this._resultDisplays[resultId] = display; this._resultDisplays[resultId] = display;
})); }));
callback(true); callback();
}), this._cancellable); }), this._cancellable);
} }
}, },
@ -383,10 +368,8 @@ const SearchResultsBase = new Lang.Class({
let results = this.provider.filterResults(providerResults, maxResults); let results = this.provider.filterResults(providerResults, maxResults);
let hasMoreResults = results.length < providerResults.length; let hasMoreResults = results.length < providerResults.length;
this._ensureResultActors(results, Lang.bind(this, function(successful) { this._ensureResultActors(results, Lang.bind(this, function() {
this._clearResultDisplay(); this._clearResultDisplay();
if (!successful)
return;
// To avoid CSS transitions causing flickering when // To avoid CSS transitions causing flickering when
// the first search result stays the same, we hide the // the first search result stays the same, we hide the
@ -632,11 +615,8 @@ const SearchResults = new Lang.Class({
if (newDefaultResult != this._defaultResult) { if (newDefaultResult != this._defaultResult) {
if (this._defaultResult) if (this._defaultResult)
this._defaultResult.setSelected(false); this._defaultResult.setSelected(false);
if (newDefaultResult) { if (newDefaultResult)
newDefaultResult.setSelected(this._highlightDefault); newDefaultResult.setSelected(this._highlightDefault);
if (this._highlightDefault)
Util.ensureActorVisibleInScrollView(this._scrollView, newDefaultResult.actor);
}
this._defaultResult = newDefaultResult; this._defaultResult = newDefaultResult;
} }
@ -673,11 +653,8 @@ const SearchResults = new Lang.Class({
highlightDefault: function(highlight) { highlightDefault: function(highlight) {
this._highlightDefault = highlight; this._highlightDefault = highlight;
if (this._defaultResult) { if (this._defaultResult)
this._defaultResult.setSelected(highlight); this._defaultResult.setSelected(highlight);
if (highlight)
Util.ensureActorVisibleInScrollView(this._scrollView, this._defaultResult.actor);
}
}, },
navigateFocus: function(direction) { navigateFocus: function(direction) {

View File

@ -10,8 +10,6 @@ const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main; const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const Config = imports.misc.config;
const DEFAULT_MODE = 'restrictive'; const DEFAULT_MODE = 'restrictive';
const _modes = { const _modes = {
@ -94,12 +92,8 @@ const _modes = {
isLocked: false, isLocked: false,
isPrimary: true, isPrimary: true,
unlockDialog: imports.ui.unlockDialog.UnlockDialog, unlockDialog: imports.ui.unlockDialog.UnlockDialog,
components: Config.HAVE_NETWORKMANAGER ? components: ['networkAgent', 'polkitAgent', 'telepathyClient',
['networkAgent', 'polkitAgent', 'telepathyClient',
'keyring', 'autorunManager', 'automountManager'] :
['polkitAgent', 'telepathyClient',
'keyring', 'autorunManager', 'automountManager'], 'keyring', 'autorunManager', 'automountManager'],
panel: { panel: {
left: ['activities', 'appMenu'], left: ['activities', 'appMenu'],
center: ['dateMenu'], center: ['dateMenu'],

View File

@ -69,7 +69,6 @@ const ScreenSaverIface = '<node> \
<signal name="ActiveChanged"> \ <signal name="ActiveChanged"> \
<arg name="new_value" type="b" /> \ <arg name="new_value" type="b" /> \
</signal> \ </signal> \
<signal name="WakeUpScreen" /> \
</interface> \ </interface> \
</node>'; </node>';
@ -372,10 +371,8 @@ const GnomeShellExtensions = new Lang.Class({
LaunchExtensionPrefs: function(uuid) { LaunchExtensionPrefs: function(uuid) {
let appSys = Shell.AppSystem.get_default(); let appSys = Shell.AppSystem.get_default();
let app = appSys.lookup_app('gnome-shell-extension-prefs.desktop'); let app = appSys.lookup_app('gnome-shell-extension-prefs.desktop');
let info = app.get_app_info(); app.launch(global.display.get_current_time_roundtrip(),
let timestamp = global.display.get_current_time_roundtrip(); ['extension:///' + uuid], -1, null);
info.launch_uris(['extension:///' + uuid],
global.create_app_launch_context(timestamp, -1));
}, },
ReloadExtension: function(uuid) { ReloadExtension: function(uuid) {
@ -408,9 +405,6 @@ const ScreenSaverDBus = new Lang.Class({
screenShield.connect('active-changed', Lang.bind(this, function(shield) { screenShield.connect('active-changed', Lang.bind(this, function(shield) {
this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [shield.active])); this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [shield.active]));
})); }));
screenShield.connect('wake-up-screen', Lang.bind(this, function(shield) {
this._dbusImpl.emit_signal('WakeUpScreen', null);
}));
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenSaverIface, this); this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenSaverIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/ScreenSaver'); this._dbusImpl.export(Gio.DBus.session, '/org/gnome/ScreenSaver');

View File

@ -36,7 +36,7 @@ const EntryMenu = new Lang.Class({
this._passwordItem = null; this._passwordItem = null;
Main.uiGroup.add_actor(this.actor); Main.layoutManager.menuGroup.add_actor(this.actor);
this.actor.hide(); this.actor.hide();
}, },

View File

@ -1,11 +1,11 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Atk = imports.gi.Atk;
const Cairo = imports.cairo; const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Lang = imports.lang; const Lang = imports.lang;
const St = imports.gi.St; const St = imports.gi.St;
const Signals = imports.signals; const Signals = imports.signals;
const Atk = imports.gi.Atk;
const SLIDER_SCROLL_STEP = 0.05; /* Slider scrolling step in % */ const SLIDER_SCROLL_STEP = 0.05; /* Slider scrolling step in % */

View File

@ -44,7 +44,7 @@ const ATIndicator = new Lang.Class({
this._hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' }); this._hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
this._hbox.add_child(new St.Icon({ style_class: 'system-status-icon', this._hbox.add_child(new St.Icon({ style_class: 'system-status-icon',
icon_name: 'preferences-desktop-accessibility-symbolic' })); icon_name: 'preferences-desktop-accessibility-symbolic' }));
this._hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM)); this._hbox.add_child(PopupMenu.unicodeArrow(St.Side.BOTTOM));
this.actor.add_child(this._hbox); this.actor.add_child(this._hbox);

View File

@ -17,7 +17,6 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Rfkill';
const RfkillManagerInterface = '<node> \ const RfkillManagerInterface = '<node> \
<interface name="org.gnome.SettingsDaemon.Rfkill"> \ <interface name="org.gnome.SettingsDaemon.Rfkill"> \
<property name="BluetoothAirplaneMode" type="b" access="readwrite" /> \ <property name="BluetoothAirplaneMode" type="b" access="readwrite" /> \
<property name="BluetoothHasAirplaneMode" type="b" access="read" /> \
</interface> \ </interface> \
</node>'; </node>';
@ -39,10 +38,7 @@ const Indicator = new Lang.Class({
log(error.message); log(error.message);
return; return;
} }
this._sync();
})); }));
this._proxy.connect('g-properties-changed', Lang.bind(this, this._sync));
// The Bluetooth menu only appears when Bluetooth is in use, // The Bluetooth menu only appears when Bluetooth is in use,
// so just statically build it with a "Turn Off" menu item. // so just statically build it with a "Turn Off" menu item.
@ -59,7 +55,6 @@ const Indicator = new Lang.Class({
this._model.connect('row-changed', Lang.bind(this, this._sync)); this._model.connect('row-changed', Lang.bind(this, this._sync));
this._model.connect('row-deleted', Lang.bind(this, this._sync)); this._model.connect('row-deleted', Lang.bind(this, this._sync));
this._model.connect('row-inserted', Lang.bind(this, this._sync)); this._model.connect('row-inserted', Lang.bind(this, this._sync));
Main.sessionMode.connect('updated', Lang.bind(this, this._sync));
this._sync(); this._sync();
}, },
@ -94,15 +89,12 @@ const Indicator = new Lang.Class({
_sync: function() { _sync: function() {
let nDevices = this._getNConnectedDevices(); let nDevices = this._getNConnectedDevices();
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
this.menu.setSensitive(sensitive); let on = nDevices > 0;
this._indicator.visible = nDevices > 0; this._indicator.visible = on;
this._item.actor.visible = this._proxy.BluetoothHasAirplaneMode && !this._proxy.BluetoothAirplaneMode; this._item.actor.visible = on;
if (nDevices > 0) if (on)
this._item.status.text = ngettext("%d Connected Device", "%d Connected Devices", nDevices).format(nDevices); this._item.status.text = ngettext("%d Connected Device", "%d Connected Devices", nDevices).format(nDevices);
else
this._item.status.text = _("Not Connected");
}, },
}); });

View File

@ -292,10 +292,6 @@ const InputSourcePopup = new Lang.Class({
this._select(this._previous()); this._select(this._previous());
else if (keysym == Clutter.Right) else if (keysym == Clutter.Right)
this._select(this._next()); this._select(this._next());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}, },
_finish : function() { _finish : function() {
@ -345,7 +341,7 @@ const InputSourceIndicator = new Lang.Class({
this._hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' }); this._hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
this._hbox.add_child(this._container); this._hbox.add_child(this._container);
this._hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM)); this._hbox.add_child(PopupMenu.unicodeArrow(St.Side.BOTTOM));
this.actor.add_child(this._hbox); this.actor.add_child(this._hbox);
this.actor.add_style_class_name('panel-status-button'); this.actor.add_style_class_name('panel-status-button');

View File

@ -1,41 +1,18 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Lang = imports.lang; const Lang = imports.lang;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu; const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Shell = imports.gi.Shell;
const LOCATION_SCHEMA = 'org.gnome.shell.location';
const MAX_ACCURACY_LEVEL = 'max-accuracy-level';
var GeoclueIface = '<node> \ var GeoclueIface = '<node> \
<interface name="org.freedesktop.GeoClue2.Manager"> \ <interface name="org.freedesktop.GeoClue2.Manager"> \
<property name="InUse" type="b" access="read"/> \ <property name="InUse" type="b" access="read"/> \
<property name="AvailableAccuracyLevel" type="u" access="read"/> \
<method name="AddAgent"> \
<arg name="id" type="s" direction="in"/> \
</method> \
</interface> \ </interface> \
</node>'; </node>';
const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface); const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface);
var AgentIface = '<node> \
<interface name="org.freedesktop.GeoClue2.Agent"> \
<property name="MaxAccuracyLevel" type="u" access="read"/> \
<method name="AuthorizeApp"> \
<arg name="desktop_id" type="s" direction="in"/> \
<arg name="req_accuracy_level" type="u" direction="in"/> \
<arg name="authorized" type="b" direction="out"/> \
<arg name="allowed_accuracy_level" type="u" direction="out"/> \
</method> \
</interface> \
</node>';
const Indicator = new Lang.Class({ const Indicator = new Lang.Class({
Name: 'LocationIndicator', Name: 'LocationIndicator',
Extends: PanelMenu.SystemIndicator, Extends: PanelMenu.SystemIndicator,
@ -43,159 +20,39 @@ const Indicator = new Lang.Class({
_init: function() { _init: function() {
this.parent(); this.parent();
this._settings = new Gio.Settings({ schema: LOCATION_SCHEMA });
this._settings.connect('changed::' + MAX_ACCURACY_LEVEL,
Lang.bind(this, this._onMaxAccuracyLevelChanged));
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._indicator.icon_name = 'find-location-symbolic'; this._indicator.icon_name = 'find-location-symbolic';
this._sync();
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Location"), true);
this._item.icon.icon_name = 'find-location-symbolic';
this._agent = Gio.DBusExportedObject.wrapJSObject(AgentIface, this);
this._agent.export(Gio.DBus.system, '/org/freedesktop/GeoClue2/Agent');
this._item.status.text = _("Enabled");
this._onOffAction = this._item.menu.addAction(_("Disable"), Lang.bind(this, this._onOnOffAction));
this.menu.addMenuItem(this._item);
this._watchId = Gio.bus_watch_name(Gio.BusType.SYSTEM, this._watchId = Gio.bus_watch_name(Gio.BusType.SYSTEM,
'org.freedesktop.GeoClue2', 'org.freedesktop.GeoClue2',
0, 0,
Lang.bind(this, this._connectToGeoclue), Lang.bind(this, this._onGeoclueAppeared),
Lang.bind(this, this._onGeoclueVanished)); Lang.bind(this, this._onGeoclueVanished));
Main.sessionMode.connect('updated', Lang.bind(this, this._onSessionUpdated));
this._onSessionUpdated();
this._onMaxAccuracyLevelChanged();
this._connectToGeoclue();
}, },
get MaxAccuracyLevel() { _sync: function() {
return this._getMaxAccuracyLevel();
},
// We (and geoclue) have currently no way to reliably identifying apps so
// for now, lets just authorize all apps as long as they provide a valid
// desktop ID. We also ensure they don't get more accuracy than global max.
AuthorizeApp: function(desktop_id, reqAccuracyLevel) {
var appSystem = Shell.AppSystem.get_default();
var app = appSystem.lookup_app(desktop_id + ".desktop");
if (app == null) {
return [false, 0];
}
let allowedAccuracyLevel = clamp(reqAccuracyLevel, 0, this._getMaxAccuracyLevel());
return [true, allowedAccuracyLevel];
},
_syncIndicator: function() {
if (this._proxy == null) { if (this._proxy == null) {
this._indicator.visible = false; this._indicator.visible = false;
return; return;
} }
this._indicator.visible = this._proxy.InUse; this._indicator.visible = this._proxy.InUse;
this._updateMenuLabels();
}, },
_connectToGeoclue: function() { _onGeoclueAppeared: function() {
if (this._proxy != null || this._connecting) // FIXME: This should be done async
return false; this._proxy = new GeoclueManager(Gio.DBus.system,
'org.freedesktop.GeoClue2',
'/org/freedesktop/GeoClue2/Manager');
this._proxy.connect('g-properties-changed', Lang.bind(this, this._sync));
this._connecting = true; this._sync();
new GeoclueManager(Gio.DBus.system,
'org.freedesktop.GeoClue2',
'/org/freedesktop/GeoClue2/Manager',
Lang.bind(this, this._onProxyReady));
return true;
},
_onProxyReady: function(proxy, error) {
if (error != null) {
log(error.message);
this._connecting = false;
return;
}
this._proxy = proxy;
this._propertiesChangedId = this._proxy.connect('g-properties-changed',
Lang.bind(this, this._onGeocluePropsChanged));
this._availableAccuracyLevel = this._proxy.AvailableAccuracyLevel;
this._syncIndicator();
this._proxy.AddAgentRemote('gnome-shell', Lang.bind(this, this._onAgentRegistered));
},
_onAgentRegistered: function(result, error) {
this._connecting = false;
this._notifyMaxAccuracyLevel();
if (error != null)
log(error.message);
}, },
_onGeoclueVanished: function() { _onGeoclueVanished: function() {
if (this._propertiesChangedId) {
this._proxy.disconnect(this._propertiesChangedId);
this._propertiesChangedId = 0;
}
this._proxy = null; this._proxy = null;
this._syncIndicator(); this._sync();
},
_onOnOffAction: function() {
if (this._getMaxAccuracyLevel() == 0)
this._settings.set_enum(MAX_ACCURACY_LEVEL, this._availableAccuracyLevel);
else
this._settings.set_enum(MAX_ACCURACY_LEVEL, 0);
},
_onSessionUpdated: function() {
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
this.menu.setSensitive(sensitive);
},
_updateMenuLabels: function() {
if (this._getMaxAccuracyLevel() == 0) {
this._item.status.text = _("Disabled");
this._onOffAction.label.text = _("Enable");
} else {
this._item.status.text = this._indicator.visible ? _("In Use") : _("Enabled");
this._onOffAction.label.text = _("Disable");
}
},
_onMaxAccuracyLevelChanged: function() {
this._updateMenuLabels();
// Gotta ensure geoclue is up and we are registered as agent to it
// before we emit the notify for this property change.
if (!this._connectToGeoclue())
this._notifyMaxAccuracyLevel();
},
_getMaxAccuracyLevel: function() {
return this._settings.get_enum(MAX_ACCURACY_LEVEL);
},
_notifyMaxAccuracyLevel: function() {
let variant = new GLib.Variant('u', this._getMaxAccuracyLevel());
this._agent.emit_property_changed('MaxAccuracyLevel', variant);
},
_onGeocluePropsChanged: function(proxy, properties) {
let unpacked = properties.deep_unpack();
if ("InUse" in unpacked)
this._syncIndicator();
if ("AvailableAccuracyLevel" in unpacked)
this._availableAccuracyLevel = this._proxy.AvailableAccuracyLevel;
} }
}); });
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}

View File

@ -9,17 +9,14 @@ 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;
const Signals = imports.signals; const Signals = imports.signals;
const Shell = imports.gi.Shell;
const St = imports.gi.St; const St = imports.gi.St;
const Animation = imports.ui.animation;
const Main = imports.ui.main; 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 MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const ModemManager = imports.misc.modemManager; const ModemManager = imports.misc.modemManager;
const Rfkill = imports.ui.status.rfkill;
const Util = imports.misc.util; const Util = imports.misc.util;
const NMConnectionCategory = { const NMConnectionCategory = {
@ -105,34 +102,18 @@ const NMConnectionItem = new Lang.Class({
this._activeConnection = null; this._activeConnection = null;
this._activeConnectionChangedId = 0; this._activeConnectionChangedId = 0;
this._buildUI();
this._sync();
},
_buildUI: function() {
this.labelItem = new PopupMenu.PopupMenuItem(''); this.labelItem = new PopupMenu.PopupMenuItem('');
this.labelItem.connect('activate', Lang.bind(this, this._toggle)); this.labelItem.connect('activate', Lang.bind(this, this._toggle));
this.radioItem = new PopupMenu.PopupMenuItem(this._connection.get_id(), false); this.switchItem = new PopupMenu.PopupSwitchMenuItem(connection.get_id(), false);
this.radioItem.connect('activate', Lang.bind(this, this._activate)); this.switchItem.connect('toggled', Lang.bind(this, this._toggle));
this._sync();
}, },
destroy: function() { destroy: function() {
this.labelItem.destroy(); this.labelItem.destroy();
this.radioItem.destroy(); this.switchItem.destroy();
},
updateForConnection: function(connection) {
// connection should always be the same object
// (and object path) as this._connection, but
// this can be false if NetworkManager was restarted
// and picked up connections in a different order
// Just to be safe, we set it here again
this._connection = connection;
this.radioItem.label.text = connection.get_id();
this._sync();
this.emit('name-changed');
}, },
getName: function() { getName: function() {
@ -148,8 +129,9 @@ const NMConnectionItem = new Lang.Class({
_sync: function() { _sync: function() {
let isActive = this.isActive(); let isActive = this.isActive();
this.labelItem.label.text = isActive ? _("Turn Off") : this._section.getConnectLabel(); this.labelItem.label.text = isActive ? _("Turn Off") : _("Connect");
this.radioItem.setOrnament(isActive ? PopupMenu.Ornament.DOT : PopupMenu.Ornament.NONE); this.switchItem.setToggleState(isActive);
this.switchItem.setStatus(this._getStatus());
this.emit('icon-changed'); this.emit('icon-changed');
}, },
@ -162,11 +144,8 @@ const NMConnectionItem = new Lang.Class({
this._sync(); this._sync();
}, },
_activate: function() { _getStatus: function() {
if (this._activeConnection == null) return null;
this._section.activateConnection(this._connection);
this._sync();
}, },
_connectionStateChanged: function(ac, newstate, reason) { _connectionStateChanged: function(ac, newstate, reason) {
@ -201,11 +180,11 @@ const NMConnectionSection = new Lang.Class({
this._connections = []; this._connections = [];
this._labelSection = new PopupMenu.PopupMenuSection(); this._labelSection = new PopupMenu.PopupMenuSection();
this._radioSection = new PopupMenu.PopupMenuSection(); this._switchSection = new PopupMenu.PopupMenuSection();
this.item = new PopupMenu.PopupSubMenuMenuItem('', true); this.item = new PopupMenu.PopupSubMenuMenuItem('', true);
this.item.menu.addMenuItem(this._labelSection); this.item.menu.addMenuItem(this._labelSection);
this.item.menu.addMenuItem(this._radioSection); this.item.menu.addMenuItem(this._switchSection);
this.connect('icon-changed', Lang.bind(this, this._sync)); this.connect('icon-changed', Lang.bind(this, this._sync));
}, },
@ -217,7 +196,7 @@ const NMConnectionSection = new Lang.Class({
_sync: function() { _sync: function() {
let nItems = this._connectionItems.size; let nItems = this._connectionItems.size;
this._radioSection.actor.visible = (nItems > 1); this._switchSection.actor.visible = (nItems > 1);
this._labelSection.actor.visible = (nItems == 1); this._labelSection.actor.visible = (nItems == 1);
this.item.status.text = this._getStatus(); this.item.status.text = this._getStatus();
@ -232,12 +211,18 @@ const NMConnectionSection = new Lang.Class({
this.item.label.text = ''; this.item.label.text = '';
}, },
_getMenuIcon: function() { _getStatus: function() {
return this.getIndicatorIcon(); let values = this._connectionItems.values();
for (let item of values) {
if (item.isActive())
return item.getName();
}
return _("Off");
}, },
getConnectLabel: function() { _hasConnection: function(connection) {
return _("Connect"); return this._connectionItems.has(connection.get_uuid());
}, },
_connectionValid: function(connection) { _connectionValid: function(connection) {
@ -245,7 +230,10 @@ const NMConnectionSection = new Lang.Class({
}, },
_connectionSortFunction: function(one, two) { _connectionSortFunction: function(one, two) {
return GLib.utf8_collate(one.get_id(), two.get_id()); if (one._timestamp == two._timestamp)
return GLib.utf8_collate(one.get_id(), two.get_id());
return two._timestamp - one._timestamp;
}, },
_makeConnectionItem: function(connection) { _makeConnectionItem: function(connection) {
@ -256,20 +244,10 @@ const NMConnectionSection = new Lang.Class({
if (!this._connectionValid(connection)) if (!this._connectionValid(connection))
return; return;
// This function is called everytime connection is added or updated if (this._hasConnection(connection))
// In the usual case, we already added this connection and UUID return;
// didn't change. So we need to check if we already have an item,
// and update it for properties in the connection that changed
// (the only one we care about is the name)
// But it's also possible we didn't know about this connection
// (eg, during coldplug, or because it was updated and suddenly
// it's valid for this device), in which case we add a new item
let item = this._connectionItems.get(connection.get_uuid()); this._addConnection(connection);
if (item)
item.updateForConnection(connection);
else
this._addConnection(connection);
}, },
_addConnection: function(connection) { _addConnection: function(connection) {
@ -283,23 +261,17 @@ const NMConnectionSection = new Lang.Class({
item.connect('activation-failed', Lang.bind(this, function(item, reason) { item.connect('activation-failed', Lang.bind(this, function(item, reason) {
this.emit('activation-failed', reason); this.emit('activation-failed', reason);
})); }));
item.connect('name-changed', Lang.bind(this, this._sync));
let pos = Util.insertSorted(this._connections, connection, Lang.bind(this, this._connectionSortFunction)); let pos = Util.insertSorted(this._connections, connection, Lang.bind(this, this._connectionSortFunction));
this._labelSection.addMenuItem(item.labelItem, pos); this._labelSection.addMenuItem(item.labelItem, pos);
this._radioSection.addMenuItem(item.radioItem, pos); this._switchSection.addMenuItem(item.switchItem, pos);
this._connectionItems.set(connection.get_uuid(), item); this._connectionItems.set(connection.get_uuid(), item);
this._sync(); this._sync();
}, },
removeConnection: function(connection) { removeConnection: function(connection) {
let uuid = connection.get_uuid(); this._connectionItems.get(connection.get_uuid()).destroy();
let item = this._connectionItems.get(uuid); this._connectionItems.delete(connection.get_uuid());
if (item == undefined)
return;
item.destroy();
this._connectionItems.delete(uuid);
let pos = this._connections.indexOf(connection); let pos = this._connections.indexOf(connection);
this._connections.splice(pos, 1); this._connections.splice(pos, 1);
@ -320,19 +292,11 @@ const NMConnectionDevice = new Lang.Class({
this._settings = settings; this._settings = settings;
this._autoConnectItem = this.item.menu.addAction(_("Connect"), Lang.bind(this, this._autoConnect)); this._autoConnectItem = this.item.menu.addAction(_("Connect"), Lang.bind(this, this._autoConnect));
this._deactivateItem = this._radioSection.addAction(_("Turn Off"), Lang.bind(this, this.deactivateConnection));
this._stateChangedId = this._device.connect('state-changed', Lang.bind(this, this._deviceStateChanged)); this._stateChangedId = this._device.connect('state-changed', Lang.bind(this, this._deviceStateChanged));
this._activeConnectionChangedId = this._device.connect('notify::active-connection', Lang.bind(this, this._activeConnectionChanged)); this._activeConnectionChangedId = this._device.connect('notify::active-connection', Lang.bind(this, this._activeConnectionChanged));
}, },
_canReachInternet: function() {
if (this._client.primary_connection != this._device.active_connection)
return true;
return this._client.connectivity == NetworkManager.ConnectivityState.FULL;
},
_autoConnect: function() { _autoConnect: function() {
let connection = new NetworkManager.Connection(); let connection = new NetworkManager.Connection();
this._client.add_and_activate_connection(connection, this._device, null, null); this._client.add_and_activate_connection(connection, this._device, null, null);
@ -407,7 +371,6 @@ const NMConnectionDevice = new Lang.Class({
_sync: function() { _sync: function() {
let nItems = this._connectionItems.size; let nItems = this._connectionItems.size;
this._autoConnectItem.actor.visible = (nItems == 0); this._autoConnectItem.actor.visible = (nItems == 0);
this._deactivateItem.actor.visible = this._device.state > NetworkManager.DeviceState.DISCONNECTED;
this.parent(); this.parent();
}, },
@ -419,7 +382,7 @@ const NMConnectionDevice = new Lang.Class({
case NetworkManager.DeviceState.DISCONNECTED: case NetworkManager.DeviceState.DISCONNECTED:
return _("Off"); return _("Off");
case NetworkManager.DeviceState.ACTIVATED: case NetworkManager.DeviceState.ACTIVATED:
return _("Connected"); return this.parent();
case NetworkManager.DeviceState.UNMANAGED: case NetworkManager.DeviceState.UNMANAGED:
/* Translators: this is for network devices that are physically present but are not /* Translators: this is for network devices that are physically present but are not
under NetworkManager's control (and thus cannot be used in the menu) */ under NetworkManager's control (and thus cannot be used in the menu) */
@ -467,33 +430,33 @@ const NMDeviceWired = new Lang.Class({
this.item.menu.addMenuItem(createSettingsAction(_("Wired Settings"), device)); this.item.menu.addMenuItem(createSettingsAction(_("Wired Settings"), device));
}, },
_hasCarrier: function() { _isConnected: function() {
if (this._device instanceof NMClient.DeviceEthernet) if (!this._device.active_connection)
return this._device.carrier; return false;
else
return true; let state = this._device.active_connection.state;
return state >= NetworkManager.ActiveConnectionState.ACTIVATING;
}, },
_sync: function() { _sync: function() {
this.item.actor.visible = this._hasCarrier(); this.item.actor.visible = this._isConnected();
this.parent(); this.parent();
}, },
getIndicatorIcon: function() { _getMenuIcon: function() {
if (this._device.active_connection) { if (this._device.active_connection)
let state = this._device.active_connection.state; return this.getIndicatorIcon();
else
return 'network-wired-disconnected-symbolic';
},
if (state == NetworkManager.ActiveConnectionState.ACTIVATING) { getIndicatorIcon: function() {
return 'network-wired-acquiring-symbolic'; let state = this._device.active_connection.state;
} else if (state == NetworkManager.ActiveConnectionState.ACTIVATED) { if (state == NetworkManager.ActiveConnectionState.ACTIVATING)
if (this._canReachInternet()) return 'network-wired-acquiring-symbolic';
return 'network-wired-symbolic'; else if (state == NetworkManager.ActiveConnectionState.ACTIVATED)
else return 'network-wired-symbolic';
return 'network-wired-no-route-symbolic'; else
} else {
return 'network-wired-disconnected-symbolic';
}
} else
return 'network-wired-disconnected-symbolic'; return 'network-wired-disconnected-symbolic';
} }
}); });
@ -560,20 +523,28 @@ const NMDeviceModem = new Lang.Class({
return this.parent(); return this.parent();
}, },
getIndicatorIcon: function() { _getMenuIcon: function() {
if (this._device.active_connection) { if (this._device.active_connection)
if (this._device.active_connection.state == NetworkManager.ActiveConnectionState.ACTIVATING) return this.getIndicatorIcon();
return 'network-cellular-acquiring-symbolic'; else
return this._getSignalIcon();
} else {
return 'network-cellular-signal-none-symbolic'; return 'network-cellular-signal-none-symbolic';
}
}, },
_getSignalIcon: function() { _getSignalIcon: function() {
return 'network-cellular-signal-' + signalToIcon(this._mobileDevice.signal_quality) + '-symbolic'; return 'network-cellular-signal-' + signalToIcon(this._mobileDevice.signal_quality) + '-symbolic';
}, },
getIndicatorIcon: function() {
if (this._device.active_connection.state == NetworkManager.ActiveConnectionState.ACTIVATING)
return 'network-cellular-acquiring-symbolic';
if (!this._mobileDevice) {
// this can happen for bluetooth in PAN mode
return 'network-cellular-connected-symbolic';
}
return this._getSignalIcon();
}
}); });
const NMDeviceBluetooth = new Lang.Class({ const NMDeviceBluetooth = new Lang.Class({
@ -587,26 +558,21 @@ const NMDeviceBluetooth = new Lang.Class({
this.item.menu.addMenuItem(createSettingsAction(_("Mobile Broadband Settings"), device)); this.item.menu.addMenuItem(createSettingsAction(_("Mobile Broadband Settings"), device));
}, },
_getDescription: function() { _getMenuIcon: function() {
return this._device.name; if (this._device.active_connection)
}, return this.getIndicatorIcon();
else
getConnectLabel: function() { return 'network-cellular-signal-none-symbolic';
return _("Use as Internet connection");
}, },
getIndicatorIcon: function() { getIndicatorIcon: function() {
if (this._device.active_connection) { let state = this._device.active_connection.state;
let state = this._device.active_connection.state; if (state == NetworkManager.ActiveConnectionState.ACTIVATING)
if (state == NetworkManager.ActiveConnectionState.ACTIVATING) return 'network-cellular-acquiring-symbolic';
return 'network-cellular-acquiring-symbolic'; else if (state == NetworkManager.ActiveConnectionState.ACTIVATED)
else if (state == NetworkManager.ActiveConnectionState.ACTIVATED) return 'network-cellular-connected-symbolic';
return 'network-cellular-connected-symbolic'; else
else
return 'network-cellular-signal-none-symbolic';
} else {
return 'network-cellular-signal-none-symbolic'; return 'network-cellular-signal-none-symbolic';
}
} }
}); });
@ -679,26 +645,16 @@ const NMWirelessDialog = new Lang.Class({
Name: 'NMWirelessDialog', Name: 'NMWirelessDialog',
Extends: ModalDialog.ModalDialog, Extends: ModalDialog.ModalDialog,
_init: function(client, device, settings) { _init: function(client, device) {
this.parent({ styleClass: 'nm-dialog' }); this.parent({ styleClass: 'nm-dialog' });
this._client = client; this._client = client;
this._device = device; this._device = device;
this._wirelessEnabledChangedId = this._client.connect('notify::wireless-enabled',
Lang.bind(this, this._syncView));
this._rfkill = Rfkill.getRfkillManager();
this._airplaneModeChangedId = this._rfkill.connect('airplane-mode-changed',
Lang.bind(this, this._syncView));
this._networks = []; this._networks = [];
this._buildLayout(); this._buildLayout();
let connections = settings.list_connections(); this._connections = device.get_available_connections();
this._connections = connections.filter(Lang.bind(this, function(connection) {
return device.connection_valid(connection);
}));
this._apAddedId = device.connect('access-point-added', Lang.bind(this, this._accessPointAdded)); this._apAddedId = device.connect('access-point-added', Lang.bind(this, this._accessPointAdded));
this._apRemovedId = device.connect('access-point-removed', Lang.bind(this, this._accessPointRemoved)); this._apRemovedId = device.connect('access-point-removed', Lang.bind(this, this._accessPointRemoved));
@ -713,12 +669,6 @@ const NMWirelessDialog = new Lang.Class({
this._selectedNetwork = null; this._selectedNetwork = null;
this._activeApChanged(); this._activeApChanged();
this._updateSensitivity(); this._updateSensitivity();
this._syncView();
if (accessPoints.length == 0) {
/* If there are no visible access points, request a scan */
this._device.request_scan_simple(null);
}
}, },
destroy: function() { destroy: function() {
@ -734,14 +684,6 @@ const NMWirelessDialog = new Lang.Class({
GObject.Object.prototype.disconnect.call(this._device, this._activeApChangedId); GObject.Object.prototype.disconnect.call(this._device, this._activeApChangedId);
this._activeApChangedId = 0; this._activeApChangedId = 0;
} }
if (this._wirelessEnabledChangedId) {
this._client.disconnect(this._wirelessEnabledChangedId);
this._wirelessEnabledChangedId = 0;
}
if (this._airplaneModeChangedId) {
this._rfkill.disconnect(this._airplaneModeChangedId);
this._airplaneModeChangedId = 0;
}
this.parent(); this.parent();
}, },
@ -763,44 +705,13 @@ const NMWirelessDialog = new Lang.Class({
}, },
_updateSensitivity: function() { _updateSensitivity: function() {
let connectSensitive = this._client.wireless_enabled && this._selectedNetwork && (this._selectedNetwork != this._activeNetwork); let connectSensitive = this._selectedNetwork && (this._selectedNetwork != this._activeNetwork);
this._connectButton.reactive = connectSensitive; this._connectButton.reactive = connectSensitive;
this._connectButton.can_focus = connectSensitive; this._connectButton.can_focus = connectSensitive;
}, },
_syncView: function() { _updateVisibility: function() {
if (this._rfkill.airplaneMode) { this._noNetworksLabel.visible = (this._networks.length == 0);
this._airplaneBox.show();
this._airplaneIcon.icon_name = 'airplane-mode-symbolic';
this._airplaneHeadline.text = _("Airplane Mode is On");
this._airplaneText.text = _("Wi-Fi is disabled when airplane mode is on.");
this._airplaneButton.label = _("Turn Off Airplane Mode");
this._airplaneButton.visible = !this._rfkill.hwAirplaneMode;
this._airplaneInactive.visible = this._rfkill.hwAirplaneMode;
this._noNetworksBox.hide();
} else if (!this._client.wireless_enabled) {
this._airplaneBox.show();
this._airplaneIcon.icon_name = 'dialog-information-symbolic';
this._airplaneHeadline.text = _("Wi-Fi is Off");
this._airplaneText.text = _("Wi-Fi needs to be turned on in order to connect to a network.");
this._airplaneButton.label = _("Turn On Wi-Fi");
this._airplaneButton.show();
this._airplaneInactive.hide();
this._noNetworksBox.hide();
} else {
this._airplaneBox.hide();
this._noNetworksBox.visible = (this._networks.length == 0);
}
if (this._noNetworksBox.visible)
this._noNetworksSpinner.play();
else
this._noNetworksSpinner.stop();
}, },
_buildLayout: function() { _buildLayout: function() {
@ -834,43 +745,11 @@ const NMWirelessDialog = new Lang.Class({
this._scrollView.add_actor(this._itemBox); this._scrollView.add_actor(this._itemBox);
this._stack.add_child(this._scrollView); this._stack.add_child(this._scrollView);
this._noNetworksBox = new St.BoxLayout({ vertical: true, this._noNetworksLabel = new St.Label({ style_class: 'no-networks-label',
style_class: 'no-networks-box',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
this._noNetworksSpinner = new Animation.AnimatedIcon(global.datadir + '/theme/process-working.svg', 24, 24);
this._noNetworksBox.add_actor(this._noNetworksSpinner.actor);
this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label',
text: _("No Networks") }));
this._stack.add_child(this._noNetworksBox);
this._airplaneBox = new St.BoxLayout({ vertical: true,
style_class: 'nm-dialog-airplane-box',
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER,
this._airplaneIcon = new St.Icon({ icon_size: 48 }); text: _("No Networks") });
this._airplaneHeadline = new St.Label({ style_class: 'nm-dialog-airplane-headline' }); this._stack.add_child(this._noNetworksLabel);
this._airplaneText = new St.Label({ style_class: 'nm-dialog-airplane-text' });
let airplaneSubStack = new St.Widget({ layout_manager: new Clutter.BinLayout });
this._airplaneButton = new St.Button({ style_class: 'modal-dialog-button' });
this._airplaneButton.connect('clicked', Lang.bind(this, function() {
if (this._rfkill.airplaneMode)
this._rfkill.airplaneMode = false;
else
this._client.wireless_enabled = true;
}));
airplaneSubStack.add_actor(this._airplaneButton);
this._airplaneInactive = new St.Label({ style_class: 'nm-dialog-airplane-text',
text: _("Use hardware switch to turn off") });
airplaneSubStack.add_actor(this._airplaneInactive);
this._airplaneBox.add(this._airplaneIcon, { x_align: St.Align.MIDDLE });
this._airplaneBox.add(this._airplaneHeadline, { x_align: St.Align.MIDDLE });
this._airplaneBox.add(this._airplaneText, { x_align: St.Align.MIDDLE });
this._airplaneBox.add(airplaneSubStack, { x_align: St.Align.MIDDLE });
this._stack.add_child(this._airplaneBox);
this.contentLayout.add(this._stack, { expand: true }); this.contentLayout.add(this._stack, { expand: true });
@ -1063,7 +942,7 @@ const NMWirelessDialog = new Lang.Class({
this._itemBox.insert_child_at_index(network.item.actor, newPos); this._itemBox.insert_child_at_index(network.item.actor, newPos);
} }
this._syncView(); this._updateVisibility();
}, },
_accessPointRemoved: function(device, accessPoint) { _accessPointRemoved: function(device, accessPoint) {
@ -1078,14 +957,14 @@ const NMWirelessDialog = new Lang.Class({
network.accessPoints.splice(res.ap, 1); network.accessPoints.splice(res.ap, 1);
if (network.accessPoints.length == 0) { if (network.accessPoints.length == 0) {
network.item.actor.destroy(); network.item.destroy();
this._networks.splice(res.network, 1); this._networks.splice(res.network, 1);
} else { } else {
network.item.updateBestAP(network.accessPoints[0]); network.item.updateBestAP(network.accessPoints[0]);
this._resortItems(); this._resortItems();
} }
this._syncView(); this._updateVisibility();
}, },
_resortItems: function() { _resortItems: function() {
@ -1125,10 +1004,9 @@ const NMDeviceWireless = new Lang.Class({
Name: 'NMDeviceWireless', Name: 'NMDeviceWireless',
category: NMConnectionCategory.WIRELESS, category: NMConnectionCategory.WIRELESS,
_init: function(client, device, settings) { _init: function(client, device) {
this._client = client; this._client = client;
this._device = device; this._device = device;
this._settings = settings;
this._description = ''; this._description = '';
@ -1170,10 +1048,6 @@ const NMDeviceWireless = new Lang.Class({
this._client.disconnect(this._wirelessHwEnabledChangedId); this._client.disconnect(this._wirelessHwEnabledChangedId);
this._wirelessHwEnabledChangedId = 0; this._wirelessHwEnabledChangedId = 0;
} }
if (this._dialog) {
this._dialog.destroy();
this._dialog = null;
}
this.item.destroy(); this.item.destroy();
}, },
@ -1200,7 +1074,7 @@ const NMDeviceWireless = new Lang.Class({
}, },
_showDialog: function() { _showDialog: function() {
this._dialog = new NMWirelessDialog(this._client, this._device, this._settings); this._dialog = new NMWirelessDialog(this._client, this._device);
this._dialog.connect('closed', Lang.bind(this, this._dialogClosed)); this._dialog.connect('closed', Lang.bind(this, this._dialogClosed));
this._dialog.open(); this._dialog.open();
}, },
@ -1247,12 +1121,7 @@ const NMDeviceWireless = new Lang.Class({
_getStatus: function() { _getStatus: function() {
let ap = this._device.active_access_point; let ap = this._device.active_access_point;
if (this._isHotSpotMaster()) if (ap)
return _("Hotspot Active");
else if (this._device.state >= NetworkManager.DeviceState.PREPARE &&
this._device.state < NetworkManager.DeviceState.ACTIVATED)
return _("Connecting");
else if (ap)
return ssidToLabel(ap.get_ssid()); return ssidToLabel(ap.get_ssid());
else if (!this._client.wireless_hardware_enabled) else if (!this._client.wireless_hardware_enabled)
return _("Hardware Disabled"); return _("Hardware Disabled");
@ -1271,52 +1140,20 @@ const NMDeviceWireless = new Lang.Class({
return 'network-wireless-signal-none-symbolic'; return 'network-wireless-signal-none-symbolic';
}, },
_canReachInternet: function() {
if (this._client.primary_connection != this._device.active_connection)
return true;
return this._client.connectivity == NetworkManager.ConnectivityState.FULL;
},
_isHotSpotMaster: function() {
if (!this._device.active_connection)
return false;
let connection = this._settings.get_connection_by_path(this._device.active_connection.connection);
if (!connection)
return false;
let ip4config = connection.get_setting_ip4_config();
if (!ip4config)
return false;
return ip4config.get_method() == NetworkManager.SETTING_IP4_CONFIG_METHOD_SHARED;
},
getIndicatorIcon: function() { getIndicatorIcon: function() {
if (this._device.state < NetworkManager.DeviceState.PREPARE) if (this._device.state >= NetworkManager.DeviceState.PREPARE &&
return 'network-wireless-disconnected-symbolic'; this._device.state < NetworkManager.DeviceState.ACTIVATED)
if (this._device.state < NetworkManager.DeviceState.ACTIVATED)
return 'network-wireless-acquiring-symbolic'; return 'network-wireless-acquiring-symbolic';
if (this._isHotSpotMaster())
return 'network-wireless-hotspot-symbolic';
let ap = this._device.active_access_point; let ap = this._device.active_access_point;
if (!ap) { if (!ap) {
if (this._device.mode != NM80211Mode.ADHOC) if (this._device.mode != NM80211Mode.ADHOC)
log('An active wireless connection, in infrastructure mode, involves no access point?'); log('An active wireless connection, in infrastructure mode, involves no access point?');
if (this._canReachInternet()) return 'network-wireless-connected-symbolic';
return 'network-wireless-connected-symbolic';
else
return 'network-wireless-no-route-symbolic';
} }
if (this._canReachInternet()) return 'network-wireless-signal-' + signalToIcon(ap.strength) + '-symbolic';
return 'network-wireless-signal-' + signalToIcon(ap.strength) + '-symbolic';
else
return 'network-wireless-no-route-symbolic';
}, },
}); });
Signals.addSignalMethods(NMDeviceWireless.prototype); Signals.addSignalMethods(NMDeviceWireless.prototype);
@ -1332,22 +1169,6 @@ const NMVPNConnectionItem = new Lang.Class({
return this._activeConnection.vpn_state != NetworkManager.VPNConnectionState.DISCONNECTED; return this._activeConnection.vpn_state != NetworkManager.VPNConnectionState.DISCONNECTED;
}, },
_buildUI: function() {
this.labelItem = new PopupMenu.PopupMenuItem('');
this.labelItem.connect('activate', Lang.bind(this, this._toggle));
this.radioItem = new PopupMenu.PopupSwitchMenuItem(this._connection.get_id(), false);
this.radioItem.connect('toggled', Lang.bind(this, this._toggle));
},
_sync: function() {
let isActive = this.isActive();
this.labelItem.label.text = isActive ? _("Turn Off") : this._section.getConnectLabel();
this.radioItem.setToggleState(isActive);
this.radioItem.setStatus(this._getStatus());
this.emit('icon-changed');
},
_getStatus: function() { _getStatus: function() {
if (this._activeConnection == null) if (this._activeConnection == null)
return null; return null;
@ -1417,53 +1238,19 @@ const NMVPNSection = new Lang.Class({
_init: function(client) { _init: function(client) {
this.parent(client); this.parent(client);
this._vpnSettings = new PopupMenu.PopupMenuItem('');
this.item.menu.addMenuItem(this._vpnSettings);
this._vpnSettings.connect('activate', Lang.bind(this, this._onSettingsActivate));
this._sync(); this._sync();
}, },
_sync: function() { _sync: function() {
let nItems = this._connectionItems.size; let nItems = this._connectionItems.size;
this.item.actor.visible = (nItems > 0); this.item.actor.visible = (nItems > 0);
if (nItems > 1)
this._vpnSettings.label.text = _("Network Settings");
else
this._vpnSettings.label.text = _("VPN Settings");
this.parent(); this.parent();
}, },
_onSettingsActivate: function() {
let nItems = this._connectionItems.size;
if (nItems > 1) {
let appSys = Shell.AppSystem.get_default();
let app = appSys.lookup_app('gnome-network-panel.desktop');
app.launch(0, -1);
} else {
let connection = this._connections[0];
Util.spawnApp(['gnome-control-center', 'network', 'show-device',
connection.get_path()]);
}
},
_getDescription: function() { _getDescription: function() {
return _("VPN"); return _("VPN");
}, },
_getStatus: function() {
let values = this._connectionItems.values();
for (let item of values) {
if (item.isActive())
return item.getName();
}
return _("Off");
},
_getMenuIcon: function() { _getMenuIcon: function() {
return this.getIndicatorIcon() || 'network-vpn-symbolic'; return this.getIndicatorIcon() || 'network-vpn-symbolic';
}, },
@ -1816,7 +1603,7 @@ const NMApplet = new Lang.Class({
_connectionRemoved: function(connection) { _connectionRemoved: function(connection) {
let pos = this._connections.indexOf(connection); let pos = this._connections.indexOf(connection);
if (pos != -1) if (pos != -1)
this._connections.splice(pos, 1); this._connections.splice(connection, 1);
let section = connection._section; let section = connection._section;
@ -1842,6 +1629,7 @@ const NMApplet = new Lang.Class({
let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME); let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
connection._type = connectionSettings.type; connection._type = connectionSettings.type;
connection._section = this._ctypes[connection._type] || NMConnectionCategory.INVALID; connection._section = this._ctypes[connection._type] || NMConnectionCategory.INVALID;
connection._timestamp = connectionSettings.timestamp;
let section = connection._section; let section = connection._section;
@ -1866,7 +1654,8 @@ const NMApplet = new Lang.Class({
_updateIcon: function() { _updateIcon: function() {
if (!this._client.networking_enabled || !this._mainConnection) { if (!this._client.networking_enabled || !this._mainConnection) {
this._primaryIndicator.visible = false; this._primaryIndicator.icon_name = 'network-offline-symbolic';
this._primaryIndicator.visible = true;
} else { } else {
let dev = this._mainConnection._primaryDevice; let dev = this._mainConnection._primaryDevice;
this._primaryIndicator.visible = (dev != null); this._primaryIndicator.visible = (dev != null);

View File

@ -2,9 +2,7 @@
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Lang = imports.lang; const Lang = imports.lang;
const Signals = imports.signals;
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;
@ -14,55 +12,11 @@ const OBJECT_PATH = '/org/gnome/SettingsDaemon/Rfkill';
const RfkillManagerInterface = '<node> \ const RfkillManagerInterface = '<node> \
<interface name="org.gnome.SettingsDaemon.Rfkill"> \ <interface name="org.gnome.SettingsDaemon.Rfkill"> \
<property name="AirplaneMode" type="b" access="readwrite" /> \ <property name="AirplaneMode" type="b" access="readwrite" /> \
<property name="HardwareAirplaneMode" type="b" access="read" /> \
</interface> \ </interface> \
</node>'; </node>';
const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface); const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface);
const RfkillManager = new Lang.Class({
Name: 'RfkillManager',
_init: function() {
this._proxy = new RfkillManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
Lang.bind(this, function(proxy, error) {
if (error) {
log(error.message);
return;
}
this._proxy.connect('g-properties-changed',
Lang.bind(this, this._changed));
this._changed();
}));
},
get airplaneMode() {
return this._proxy.AirplaneMode;
},
set airplaneMode(v) {
this._proxy.AirplaneMode = v;
},
get hwAirplaneMode() {
return this._proxy.HardwareAirplaneMode;
},
_changed: function() {
this.emit('airplane-mode-changed');
}
});
Signals.addSignalMethods(RfkillManager.prototype);
var _manager;
function getRfkillManager() {
if (_manager != null)
return _manager;
_manager = new RfkillManager();
return _manager;
}
const Indicator = new Lang.Class({ const Indicator = new Lang.Class({
Name: 'RfkillIndicator', Name: 'RfkillIndicator',
Extends: PanelMenu.SystemIndicator, Extends: PanelMenu.SystemIndicator,
@ -70,8 +24,16 @@ const Indicator = new Lang.Class({
_init: function() { _init: function() {
this.parent(); this.parent();
this._manager = getRfkillManager(); this._proxy = new RfkillManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
this._manager.connect('airplane-mode-changed', Lang.bind(this, this._sync)); Lang.bind(this, function(proxy, error) {
if (error) {
log(error.message);
return;
}
this._proxy.connect('g-properties-changed',
Lang.bind(this, this._sync));
this._sync();
}));
this._indicator = this._addIndicator(); this._indicator = this._addIndicator();
this._indicator.icon_name = 'airplane-mode-symbolic'; this._indicator.icon_name = 'airplane-mode-symbolic';
@ -83,34 +45,16 @@ const Indicator = new Lang.Class({
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Airplane Mode"), true); this._item = new PopupMenu.PopupSubMenuMenuItem(_("Airplane Mode"), true);
this._item.icon.icon_name = 'airplane-mode-symbolic'; this._item.icon.icon_name = 'airplane-mode-symbolic';
this._item.status.text = _("On"); this._item.status.text = _("On");
this._offItem = this._item.menu.addAction(_("Turn Off"), Lang.bind(this, function() { this._item.menu.addAction(_("Turn Off"), Lang.bind(this, function() {
this._manager.airplaneMode = false; this._proxy.AirplaneMode = false;
})); }));
this._item.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop'); this._item.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
this.menu.addMenuItem(this._item); this.menu.addMenuItem(this._item);
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
this._sessionUpdated();
},
_sessionUpdated: function() {
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
this.menu.setSensitive(sensitive);
}, },
_sync: function() { _sync: function() {
let airplaneMode = this._manager.airplaneMode; let airplaneMode = this._proxy.AirplaneMode;
let hwAirplaneMode = this._manager.hwAirplaneMode;
let changed = (airplaneMode != this._indicator.visible) ||
(hwAirplaneMode != this._offItem.actor.visible);
this._indicator.visible = airplaneMode; this._indicator.visible = airplaneMode;
this._item.actor.visible = airplaneMode; this._item.actor.visible = airplaneMode;
this._offItem.setSensitive(!hwAirplaneMode);
if (hwAirplaneMode)
this._offItem.label.text = _("Use hardware switch to turn off");
else
this._offItem.label.text = _("Turn Off");
}, },
}); });

View File

@ -56,10 +56,7 @@ const AltSwitcher = new Lang.Class({
} }
if (this.actor.get_child() != childToShow) { if (this.actor.get_child() != childToShow) {
let hasFocus = this.actor.contains(global.stage.get_key_focus());
this.actor.set_child(childToShow); this.actor.set_child(childToShow);
if (hasFocus)
childToShow.grab_key_focus();
// The actors might respond to hover, so // The actors might respond to hover, so
// sync the pointer to make sure they update. // sync the pointer to make sure they update.
@ -151,11 +148,11 @@ const Indicator = new Lang.Class({
Gio.DBus.session.watch_name('org.gnome.SettingsDaemon.Orientation', Gio.DBus.session.watch_name('org.gnome.SettingsDaemon.Orientation',
Gio.BusNameWatcherFlags.NONE, Gio.BusNameWatcherFlags.NONE,
Lang.bind(this, function() { Lang.bind(this, function() {
this._orientationExists = true; this._orentationExists = true;
this._updateOrientationLock(); this._updateOrientationLock();
}), }),
Lang.bind(this, function() { Lang.bind(this, function() {
this._orientationExists = false; this._orentationExists = false;
this._updateOrientationLock(); this._updateOrientationLock();
})); }));
this._updateOrientationLock(); this._updateOrientationLock();
@ -285,7 +282,7 @@ const Indicator = new Lang.Class({
let disabled = Main.sessionMode.isLocked || let disabled = Main.sessionMode.isLocked ||
(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._haveShutdown && !disabled;
this._updateActionsVisibility(); this._updateActionsVisibility();
}, },

View File

@ -54,7 +54,7 @@ const SwitcherPopup = new Lang.Class({
this.actor.connect('allocate', Lang.bind(this, this._allocate)); this.actor.connect('allocate', Lang.bind(this, this._allocate));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
Main.uiGroup.add_actor(this.actor); Main.layoutManager.switcherPopupGroup.add_child(this.actor);
this._haveModal = false; this._haveModal = false;
this._modifierMask = 0; this._modifierMask = 0;
@ -189,11 +189,10 @@ const SwitcherPopup = new Lang.Class({
this._disableHover(); this._disableHover();
if (this._keyPressHandler(keysym, backwards, action) != Clutter.EVENT_PROPAGATE)
return Clutter.EVENT_STOP;
if (keysym == Clutter.Escape) if (keysym == Clutter.Escape)
this.destroy(); this.destroy();
else
this._keyPressHandler(keysym, backwards, action);
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
}, },

View File

@ -118,13 +118,11 @@ const ViewSelector = new Lang.Class({
this._stageKeyPressId = 0; this._stageKeyPressId = 0;
Main.overview.connect('showing', Lang.bind(this, Main.overview.connect('showing', Lang.bind(this,
function () { function () {
this._resetShowAppsButton();
this._stageKeyPressId = global.stage.connect('key-press-event', this._stageKeyPressId = global.stage.connect('key-press-event',
Lang.bind(this, this._onStageKeyPress)); Lang.bind(this, this._onStageKeyPress));
})); }));
Main.overview.connect('hiding', Lang.bind(this, Main.overview.connect('hiding', Lang.bind(this,
function () { function () {
this._resetShowAppsButton();
if (this._stageKeyPressId != 0) { if (this._stageKeyPressId != 0) {
global.stage.disconnect(this._stageKeyPressId); global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0; this._stageKeyPressId = 0;
@ -160,19 +158,26 @@ const ViewSelector = new Lang.Class({
show: function() { show: function() {
this.reset(); this.reset();
this._showAppsBlocked = true;
this._showAppsButton.checked = false;
this._showAppsBlocked = false;
this._workspacesPage.opacity = 255;
this._workspacesDisplay.show(); this._workspacesDisplay.show();
this._activePage = null; this._activePage = null;
this._showPage(this._workspacesPage); this._syncActivePage();
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows()) if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
Main.overview.fadeOutDesktop(); Main.overview.fadeOutDesktop();
}, },
zoomFromOverview: function() { leaveOverview: function() {
this._workspacesDisplay.zoomFromOverview();
if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows()) if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
Main.overview.fadeInDesktop(); Main.overview.fadeInDesktop();
// If we're not on the windows page, don't zoom back the primary monitor.
let zoomPrimary = (this._activePage == this._workspacesPage);
this._workspacesDisplay.leaveOverview(zoomPrimary);
}, },
setWorkspacesFullGeometry: function(geom) { setWorkspacesFullGeometry: function(geom) {
@ -181,12 +186,16 @@ const ViewSelector = new Lang.Class({
hide: function() { hide: function() {
this._workspacesDisplay.hide(); this._workspacesDisplay.hide();
if (this._activePage)
this._activePage.hide();
this._activePage = null;
}, },
_addPage: function(actor, name, a11yIcon, params) { _addPage: function(actor, name, a11yIcon, params) {
params = Params.parse(params, { a11yFocus: null }); params = Params.parse(params, { a11yFocus: null });
let page = new St.Bin({ child: actor, let page = new St.Bin({ child: actor,
visible: false,
x_align: St.Align.START, x_align: St.Align.START,
y_align: St.Align.START, y_align: St.Align.START,
x_fill: true, x_fill: true,
@ -211,16 +220,16 @@ const ViewSelector = new Lang.Class({
oldPage.hide(); oldPage.hide();
this.emit('page-empty'); this.emit('page-empty');
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
this._activePage.show(); this._activePage.show();
Tweener.addTween(this._activePage, Tweener.addTween(this._activePage,
{ opacity: 255, { opacity: 255,
time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME, time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
}, },
_showPage: function(page, noFade) { _setActivePage: function(page) {
if (page == this._activePage) if (page == this._activePage)
return; return;
@ -228,7 +237,7 @@ const ViewSelector = new Lang.Class({
this._activePage = page; this._activePage = page;
this.emit('page-changed'); this.emit('page-changed');
if (oldPage && !noFade) if (oldPage)
Tweener.addTween(oldPage, Tweener.addTween(oldPage,
{ opacity: 0, { opacity: 0,
time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME, time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
@ -247,20 +256,25 @@ const ViewSelector = new Lang.Class({
page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
}, },
_onShowAppsButtonToggled: function() { _getActivePage: function() {
if (this._showAppsBlocked) if (this._searchActive)
return; return this._searchPage;
else if (this._showAppsButton.checked)
this._showPage(this._showAppsButton.checked ? return this._appsPage;
this._appsPage : this._workspacesPage); else
return this._workspacesPage;
}, },
_resetShowAppsButton: function() { _syncActivePage: function() {
this._showAppsBlocked = true; let activePage = this._getActivePage();
this._showAppsButton.checked = false; if (activePage == this._activePage)
this._showAppsBlocked = false; return;
this._setActivePage(activePage);
},
this._showPage(this._workspacesPage, true); _onShowAppsButtonToggled: function() {
if (!this._showAppsBlocked)
this._syncActivePage();
}, },
_onStageKeyPress: function(actor, event) { _onStageKeyPress: function(actor, event) {
@ -282,32 +296,10 @@ const ViewSelector = new Lang.Class({
return Clutter.EVENT_STOP; return Clutter.EVENT_STOP;
} else if (this._shouldTriggerSearch(symbol)) { } else if (this._shouldTriggerSearch(symbol)) {
this.startSearch(event); this.startSearch(event);
} else if (!this._searchActive && !global.stage.key_focus) {
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
return true;
} else if (symbol == Clutter.ISO_Left_Tab) {
this._activePage.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false);
return true;
}
} }
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
}, },
_searchCancelled: function() {
this._showPage(this._showAppsButton.checked ? this._appsPage
: this._workspacesPage);
// Leave the entry focused when it doesn't have any text;
// when replacing a selected search term, Clutter emits
// two 'text-changed' signals, one for deleting the previous
// text and one for the new one - the second one is handled
// incorrectly when we remove focus
// (https://bugzilla.gnome.org/show_bug.cgi?id=636341) */
if (this._text.text != '')
this.reset();
},
reset: function () { reset: function () {
global.stage.set_key_focus(null); global.stage.set_key_focus(null);
@ -398,8 +390,18 @@ const ViewSelector = new Lang.Class({
} }
this._entry.set_secondary_icon(null); this._entry.set_secondary_icon(null);
this._searchCancelled();
// Leave the entry focused when it doesn't have any text;
// when replacing a selected search term, Clutter emits
// two 'text-changed' signals, one for deleting the previous
// text and one for the new one - the second one is handled
// incorrectly when we remove focus
// (https://bugzilla.gnome.org/show_bug.cgi?id=636341) */
if (this._text.text != '')
this.reset();
} }
this._syncActivePage();
}, },
_onKeyPress: function(entry, event) { _onKeyPress: function(entry, event) {
@ -466,9 +468,7 @@ const ViewSelector = new Lang.Class({
this._searchTimeoutId = 0; this._searchTimeoutId = 0;
let terms = getTermsForSearchString(this._entry.get_text()); let terms = getTermsForSearchString(this._entry.get_text());
this._searchResults.setTerms(terms); this._searchResults.setTerms(terms);
this._showPage(this._searchPage);
return GLib.SOURCE_REMOVE; return GLib.SOURCE_REMOVE;
}, },

View File

@ -191,7 +191,6 @@ const WorkspaceTracker = new Lang.Class({
tracker.connect('startup-sequence-changed', Lang.bind(this, this._queueCheckWorkspaces)); tracker.connect('startup-sequence-changed', Lang.bind(this, this._queueCheckWorkspaces));
global.screen.connect('notify::n-workspaces', Lang.bind(this, this._nWorkspacesChanged)); global.screen.connect('notify::n-workspaces', Lang.bind(this, this._nWorkspacesChanged));
global.window_manager.connect('switch-workspace', Lang.bind(this, this._queueCheckWorkspaces));
global.screen.connect('window-entered-monitor', Lang.bind(this, this._windowEnteredMonitor)); global.screen.connect('window-entered-monitor', Lang.bind(this, this._windowEnteredMonitor));
global.screen.connect('window-left-monitor', Lang.bind(this, this._windowLeftMonitor)); global.screen.connect('window-left-monitor', Lang.bind(this, this._windowLeftMonitor));
@ -250,7 +249,13 @@ const WorkspaceTracker = new Lang.Class({
} }
let activeWorkspaceIndex = global.screen.get_active_workspace_index(); let activeWorkspaceIndex = global.screen.get_active_workspace_index();
emptyWorkspaces[activeWorkspaceIndex] = false; let removingCurrentWorkspace = (emptyWorkspaces[activeWorkspaceIndex] &&
activeWorkspaceIndex < emptyWorkspaces.length - 1);
if (removingCurrentWorkspace) {
// "Merge" the empty workspace we are removing with the one at the end
this._wm.blockAnimations();
}
// Delete other empty workspaces; do it from the end to avoid index changes // Delete other empty workspaces; do it from the end to avoid index changes
for (i = emptyWorkspaces.length - 2; i >= 0; i--) { for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
@ -258,6 +263,11 @@ const WorkspaceTracker = new Lang.Class({
global.screen.remove_workspace(this._workspaces[i], global.get_current_time()); global.screen.remove_workspace(this._workspaces[i], global.get_current_time());
} }
if (removingCurrentWorkspace) {
global.screen.get_workspace_by_index(global.screen.n_workspaces - 1).activate(global.get_current_time());
this._wm.unblockAnimations();
}
this._checkWorkspacesId = 0; this._checkWorkspacesId = 0;
return false; return false;
}, },
@ -358,93 +368,6 @@ const WorkspaceTracker = new Lang.Class({
} }
}); });
const TilePreview = new Lang.Class({
Name: 'TilePreview',
_init: function() {
this.actor = new St.Widget();
global.window_group.add_actor(this.actor);
this._reset();
this._showing = false;
},
show: function(window, tileRect, monitorIndex) {
let windowActor = window.get_compositor_private();
if (!windowActor)
return;
global.window_group.set_child_below_sibling(this.actor, windowActor);
if (this._rect && this._rect.equal(tileRect))
return;
let changeMonitor = (this._monitorIndex == -1 ||
this._monitorIndex != monitorIndex);
this._monitorIndex = monitorIndex;
this._rect = tileRect;
let monitor = Main.layoutManager.monitors[monitorIndex];
this._updateStyle(monitor);
if (!this._showing || changeMonitor) {
let monitorRect = new Meta.Rectangle({ x: monitor.x,
y: monitor.y,
width: monitor.width,
height: monitor.height });
let [, rect] = window.get_outer_rect().intersect(monitorRect);
this.actor.set_size(rect.width, rect.height);
this.actor.set_position(rect.x, rect.y);
this.actor.opacity = 0;
}
this._showing = true;
this.actor.show();
Tweener.addTween(this.actor,
{ x: tileRect.x,
y: tileRect.y,
width: tileRect.width,
height: tileRect.height,
opacity: 255,
time: WINDOW_ANIMATION_TIME,
transition: 'easeOutQuad'
});
},
hide: function() {
if (!this._showing)
return;
this._showing = false;
Tweener.addTween(this.actor,
{ opacity: 0,
time: WINDOW_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, this._reset)
});
},
_reset: function() {
this.actor.hide();
this._rect = null;
this._monitorIndex = -1;
},
_updateStyle: function(monitor) {
let styles = ['tile-preview'];
if (this._monitorIndex == Main.layoutManager.primaryIndex)
styles.push('on-primary');
if (this._rect.x == monitor.x)
styles.push('tile-preview-left');
if (this._rect.x + this._rect.width == monitor.x + monitor.width)
styles.push('tile-preview-right');
this.actor.style_class = styles.join(' ');
}
});
const WindowManager = new Lang.Class({ const WindowManager = new Lang.Class({
Name: 'WindowManager', Name: 'WindowManager',
@ -475,8 +398,6 @@ const WindowManager = new Lang.Class({
})); }));
this._shellwm.connect('switch-workspace', Lang.bind(this, this._switchWorkspace)); this._shellwm.connect('switch-workspace', Lang.bind(this, this._switchWorkspace));
this._shellwm.connect('show-tile-preview', Lang.bind(this, this._showTilePreview));
this._shellwm.connect('hide-tile-preview', Lang.bind(this, this._hideTilePreview));
this._shellwm.connect('minimize', Lang.bind(this, this._minimizeWindow)); this._shellwm.connect('minimize', Lang.bind(this, this._minimizeWindow));
this._shellwm.connect('maximize', Lang.bind(this, this._maximizeWindow)); this._shellwm.connect('maximize', Lang.bind(this, this._maximizeWindow));
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow)); this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
@ -486,8 +407,6 @@ const WindowManager = new Lang.Class({
this._shellwm.connect('confirm-display-change', Lang.bind(this, this._confirmDisplayChange)); this._shellwm.connect('confirm-display-change', Lang.bind(this, this._confirmDisplayChange));
this._workspaceSwitcherPopup = null; this._workspaceSwitcherPopup = null;
this._tilePreview = null;
this.setCustomKeybindingHandler('switch-to-workspace-left', this.setCustomKeybindingHandler('switch-to-workspace-left',
Shell.KeyBindingMode.NORMAL | Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW, Shell.KeyBindingMode.OVERVIEW,
@ -1137,18 +1056,6 @@ const WindowManager = new Lang.Class({
shellwm.completed_switch_workspace(); shellwm.completed_switch_workspace();
}, },
_showTilePreview: function(shellwm, window, tileRect, monitorIndex) {
if (!this._tilePreview)
this._tilePreview = new TilePreview();
this._tilePreview.show(window, tileRect, monitorIndex);
},
_hideTilePreview: function(shellwm) {
if (!this._tilePreview)
return;
this._tilePreview.hide();
},
_startAppSwitcher : function(display, screen, window, binding) { _startAppSwitcher : function(display, screen, window, binding) {
/* 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)

View File

@ -8,8 +8,6 @@ const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango; const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const St = imports.gi.St; const St = imports.gi.St;
const Atk = imports.gi.Atk;
const Signals = imports.signals; const Signals = imports.signals;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
@ -123,7 +121,6 @@ const WindowClone = new Lang.Class({
// the hierarchy that is sized to only the visible portion. // the hierarchy that is sized to only the visible portion.
this.actor = new St.Widget({ reactive: true, this.actor = new St.Widget({ reactive: true,
can_focus: true, can_focus: true,
accessible_role: Atk.Role.PUSH_BUTTON,
layout_manager: new WindowCloneLayout() }); layout_manager: new WindowCloneLayout() });
this.actor.add_child(this._windowClone); this.actor.add_child(this._windowClone);
@ -134,7 +131,7 @@ const WindowClone = new Lang.Class({
this._dragSlot = [0, 0, 0, 0]; this._dragSlot = [0, 0, 0, 0];
this._stackAbove = null; this._stackAbove = null;
this._windowClone._updateId = this.metaWindow.connect('size-changed', this._windowClone._updateId = this.realWindow.connect('size-changed',
Lang.bind(this, this._onRealWindowSizeChanged)); Lang.bind(this, this._onRealWindowSizeChanged));
this._windowClone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() { this._windowClone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() {
// First destroy the clone and then destroy everything // First destroy the clone and then destroy everything
@ -202,7 +199,7 @@ const WindowClone = new Lang.Class({
_doAddAttachedDialog: function(metaWin, realWin) { _doAddAttachedDialog: function(metaWin, realWin) {
let clone = new Clutter.Clone({ source: realWin }); let clone = new Clutter.Clone({ source: realWin });
clone._updateId = metaWin.connect('size-changed', Lang.bind(this, function() { clone._updateId = realWin.connect('size-changed', Lang.bind(this, function() {
this._computeBoundingBox(); this._computeBoundingBox();
this.emit('size-changed'); this.emit('size-changed');
})); }));
@ -298,7 +295,7 @@ const WindowClone = new Lang.Class({
else else
realWindow = child.source; realWindow = child.source;
realWindow.meta_window.disconnect(child._updateId); realWindow.disconnect(child._updateId);
realWindow.disconnect(child._destroyId); realWindow.disconnect(child._destroyId);
})); }));
}, },
@ -427,7 +424,6 @@ const WindowOverlay = new Lang.Class({
text: metaWindow.title }); text: metaWindow.title });
title.clutter_text.ellipsize = Pango.EllipsizeMode.END; title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
title._spacing = 0; title._spacing = 0;
windowClone.actor.label_actor = title;
this._updateCaptionId = metaWindow.connect('notify::title', this._updateCaptionId = metaWindow.connect('notify::title',
Lang.bind(this, function(w) { Lang.bind(this, function(w) {
@ -1525,34 +1521,39 @@ const Workspace = new Lang.Class({
this._recalculateWindowPositions(WindowPositionFlags.ANIMATE | WindowPositionFlags.INITIAL); this._recalculateWindowPositions(WindowPositionFlags.ANIMATE | WindowPositionFlags.INITIAL);
}, },
// Animates the return from Overview mode _leavingOverview: function() {
zoomFromOverview : function() {
let currentWorkspace = global.screen.get_active_workspace(); let currentWorkspace = global.screen.get_active_workspace();
if (this.metaWorkspace != null && this.metaWorkspace != currentWorkspace)
return false;
this.leavingOverview = true; this.leavingOverview = true;
this._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this,
this._doneLeavingOverview));
for (let i = 0; i < this._windows.length; i++) { for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i]; let clone = this._windows[i];
Tweener.removeTweens(clone.actor); Tweener.removeTweens(clone.actor);
let overlay = this._windowOverlays[i];
if (overlay)
overlay.hide();
} }
if (this._repositionWindowsId > 0) { if (this._repositionWindowsId > 0) {
Mainloop.source_remove(this._repositionWindowsId); Mainloop.source_remove(this._repositionWindowsId);
this._repositionWindowsId = 0; this._repositionWindowsId = 0;
} }
this._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this,
this._doneLeavingOverview));
if (this.metaWorkspace != null && this.metaWorkspace != currentWorkspace) return true;
},
// Animates the return from Overview mode
zoomFromOverview : function() {
if (!this._leavingOverview())
return; return;
// Position and scale the windows.
for (let i = 0; i < this._windows.length; i++) { for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i]; let clone = this._windows[i];
let overlay = this._windowOverlays[i];
if (overlay)
overlay.hide();
if (clone.metaWindow.showing_on_its_workspace()) { if (clone.metaWindow.showing_on_its_workspace()) {
let [origX, origY] = clone.getOriginalPosition(); let [origX, origY] = clone.getOriginalPosition();
@ -1579,6 +1580,31 @@ const Workspace = new Lang.Class({
} }
}, },
fadeFromOverview: function() {
if (!this._leavingOverview())
return;
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
if (clone.metaWindow.showing_on_its_workspace()) {
clone.actor.x = clone.origX;
clone.actor.y = clone.origY;
clone.actor.scale_x = 1.0;
clone.actor.scale_y = 1.0;
clone.actor.opacity = 0;
Tweener.addTween(clone.actor,
{ opacity: 255,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad'
});
} else {
clone.actor.hide();
}
}
},
destroy : function() { destroy : function() {
this.actor.destroy(); this.actor.destroy();
}, },

View File

@ -25,7 +25,7 @@ const WorkspaceSwitcherPopup = new Lang.Class({
width: global.screen_width, width: global.screen_width,
height: global.screen_height, height: global.screen_height,
style_class: 'workspace-switcher-group' }); style_class: 'workspace-switcher-group' });
Main.uiGroup.add_actor(this.actor); Main.layoutManager.osdGroup.add_child(this.actor);
this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' }); this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' });
this._list = new Shell.GenericContainer({ style_class: 'workspace-switcher' }); this._list = new Shell.GenericContainer({ style_class: 'workspace-switcher' });

View File

@ -68,7 +68,7 @@ const WindowClone = new Lang.Class({
this.realWindow = realWindow; this.realWindow = realWindow;
this.metaWindow = realWindow.meta_window; this.metaWindow = realWindow.meta_window;
this.clone._updateId = this.metaWindow.connect('position-changed', this.clone._updateId = this.realWindow.connect('position-changed',
Lang.bind(this, this._onPositionChanged)); Lang.bind(this, this._onPositionChanged));
this.clone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() { this.clone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() {
// First destroy the clone and then destroy everything // First destroy the clone and then destroy everything
@ -151,7 +151,7 @@ const WindowClone = new Lang.Class({
let clone = new Clutter.Clone({ source: realDialog }); let clone = new Clutter.Clone({ source: realDialog });
this._updateDialogPosition(realDialog, clone); this._updateDialogPosition(realDialog, clone);
clone._updateId = metaDialog.connect('position-changed', clone._updateId = realDialog.connect('position-changed',
Lang.bind(this, this._updateDialogPosition, clone)); Lang.bind(this, this._updateDialogPosition, clone));
clone._destroyId = realDialog.connect('destroy', Lang.bind(this, function() { clone._destroyId = realDialog.connect('destroy', Lang.bind(this, function() {
clone.destroy(); clone.destroy();
@ -176,7 +176,7 @@ const WindowClone = new Lang.Class({
this.actor.get_children().forEach(function(child) { this.actor.get_children().forEach(function(child) {
let realWindow = child.source; let realWindow = child.source;
realWindow.meta_window.disconnect(child._updateId); realWindow.disconnect(child._updateId);
realWindow.disconnect(child._destroyId); realWindow.disconnect(child._destroyId);
}); });
}, },
@ -804,25 +804,22 @@ const ThumbnailsBox = new Lang.Class({
[newWorkspaceIndex, this._dropPlaceholderPos] = [this._dropPlaceholderPos, -1]; [newWorkspaceIndex, this._dropPlaceholderPos] = [this._dropPlaceholderPos, -1];
// Nab all the windows below us. // Nab all the windows below us.
let windows = global.get_window_actors().filter(function(winActor) { let windows = global.get_window_actors().filter(function(win) {
// If the window is attached to an ancestor, we don't need/want to move it // If the window is attached to an ancestor, we don't need/want to move it
let window = winActor.meta_window; if (!!win.meta_window.get_transient_for())
if (window.get_transient_for() != null)
return false; return false;
if (isWindow) if (isWindow)
return window.get_workspace().index() >= newWorkspaceIndex && winActor != source; return win.get_workspace() >= newWorkspaceIndex && win != source;
else else
return window.get_workspace().index() >= newWorkspaceIndex; return win.get_workspace() >= newWorkspaceIndex;
}); });
this._spliceIndex = newWorkspaceIndex; this._spliceIndex = newWorkspaceIndex;
// ... move them down one. // ... move them down one.
windows.forEach(function(winActor) { windows.forEach(function(win) {
let window = winActor.meta_window; win.meta_window.change_workspace_by_index(win.get_workspace() + 1, true);
window.change_workspace_by_index(window.get_workspace().index() + 1, true);
}); });
if (isWindow) if (isWindow)
@ -902,10 +899,7 @@ const ThumbnailsBox = new Lang.Class({
}, },
_workspacesChanged: function() { _workspacesChanged: function() {
let validThumbnails = this._thumbnails.filter(function(t) { let oldNumWorkspaces = this._thumbnails.length;
return t.state <= ThumbnailState.NORMAL;
});
let oldNumWorkspaces = validThumbnails.length;
let newNumWorkspaces = global.screen.n_workspaces; let newNumWorkspaces = global.screen.n_workspaces;
let active = global.screen.get_active_workspace_index(); let active = global.screen.get_active_workspace_index();

View File

@ -145,11 +145,22 @@ const WorkspacesView = new Lang.Class({
this._updateWorkspaceActors(false); this._updateWorkspaceActors(false);
}, },
zoomFromOverview: function() { _leaveOverview: function() {
this.actor.remove_clip(); this.actor.remove_clip();
},
for (let w = 0; w < this._workspaces.length; w++) zoomFromOverview: function() {
this._workspaces[w].zoomFromOverview(); this._leaveOverview();
this._workspaces.forEach(function(w) {
w.zoomFromOverview();
});
},
fadeFromOverview: function() {
this._leaveOverview();
this._workspaces.forEach(function(w) {
w.fadeFromOverview();
});
}, },
syncStacking: function(stackIndices) { syncStacking: function(stackIndices) {
@ -365,6 +376,10 @@ const ExtraWorkspaceView = new Lang.Class({
this._workspace.zoomFromOverview(); this._workspace.zoomFromOverview();
}, },
fadeFromOverview: function() {
this._workspace.fadeFromOverview();
},
syncStacking: function(stackIndices) { syncStacking: function(stackIndices) {
this._workspace.syncStacking(stackIndices); this._workspace.syncStacking(stackIndices);
}, },
@ -466,9 +481,18 @@ const WorkspacesDisplay = new Lang.Class({
this._scrollEventId = Main.overview.connect('scroll-event', Lang.bind(this, this._onScrollEvent)); this._scrollEventId = Main.overview.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
}, },
zoomFromOverview: function() { leaveOverview: function(zoomPrimary) {
for (let i = 0; i < this._workspacesViews.length; i++) for (let i = 0; i < this._workspacesViews.length; i++) {
this._workspacesViews[i].zoomFromOverview(); let view = this._workspacesViews[i];
if (i == this._primaryIndex) {
if (zoomPrimary)
view.zoomFromOverview();
else
view.fadeFromOverview();
} else {
view.zoomFromOverview();
}
}
}, },
hide: function() { hide: function() {

View File

@ -18,7 +18,7 @@ const XdndHandler = new Lang.Class({
// Used as a drag actor in case we don't have a cursor window clone // Used as a drag actor in case we don't have a cursor window clone
this._dummy = new Clutter.Actor({ width: 1, height: 1, opacity: 0 }); this._dummy = new Clutter.Actor({ width: 1, height: 1, opacity: 0 });
Main.uiGroup.add_actor(this._dummy); Main.layoutManager.sessionGroup.add_actor(this._dummy);
this._dummy.hide(); this._dummy.hide();
if (!Meta.is_wayland_compositor()) if (!Meta.is_wayland_compositor())
@ -69,7 +69,7 @@ const XdndHandler = new Lang.Class({
source: cursorWindow}); source: cursorWindow});
this._cursorWindowClone = new Clutter.Clone({ source: cursorWindow }); this._cursorWindowClone = new Clutter.Clone({ source: cursorWindow });
Main.uiGroup.add_actor(this._cursorWindowClone); Main.layoutManager.sessionGroup.add_actor(this._cursorWindowClone);
// Make sure that the clone has the same position as the source // Make sure that the clone has the same position as the source
this._cursorWindowClone.add_constraint(constraint_position); this._cursorWindowClone.add_constraint(constraint_position);

View File

@ -30,11 +30,9 @@ hi
hu hu
ia ia
id id
is
it it
ja ja
kk kk
km
kn kn
ko ko
ku ku
@ -48,7 +46,6 @@ ms
nb nb
nl nl
nn nn
oc
or or
pa pa
pl pl

View File

@ -45,7 +45,6 @@ js/ui/status/accessibility.js
js/ui/status/bluetooth.js js/ui/status/bluetooth.js
js/ui/status/brightness.js js/ui/status/brightness.js
js/ui/status/keyboard.js js/ui/status/keyboard.js
js/ui/status/location.js
js/ui/status/network.js js/ui/status/network.js
js/ui/status/power.js js/ui/status/power.js
js/ui/status/rfkill.js js/ui/status/rfkill.js

663
po/an.po

File diff suppressed because it is too large Load Diff

757
po/ar.po

File diff suppressed because it is too large Load Diff

283
po/as.po
View File

@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n" "Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2014-02-11 08:31+0000\n" "POT-Creation-Date: 2014-01-17 21:35+0000\n"
"PO-Revision-Date: 2014-02-11 18:44+0630\n" "PO-Revision-Date: 2014-01-23 19:06+0630\n"
"Last-Translator: Nilamdyuti Goswami <ngoswami@redhat.com>\n" "Last-Translator: Nilamdyuti Goswami <ngoswami@redhat.com>\n"
"Language-Team: Assamese <kde-i18n-doc@kde.org>\n" "Language-Team: Assamese <kde-i18n-doc@kde.org>\n"
"Language: as_IN\n" "Language: as_IN\n"
@ -83,10 +83,16 @@ msgstr ""
"দিয়ে।" "দিয়ে।"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:3 #: ../data/org.gnome.shell.gschema.xml.in.in.h:3
#| msgid "Uuids of extensions to enable"
msgid "UUIDs of extensions to enable" msgid "UUIDs of extensions to enable"
msgstr "সামৰ্থবান কৰিব লগিয়া সম্প্ৰসাৰণসমূহৰ UUIDs" msgstr "সামৰ্থবান কৰিব লগিয়া সম্প্ৰসাৰণসমূহৰ UUIDs"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:4 #: ../data/org.gnome.shell.gschema.xml.in.in.h:4
#| msgid ""
#| "GNOME Shell extensions have a uuid property; this key lists extensions "
#| "which should be loaded. Any extension that wants to be loaded needs to be "
#| "in this list. You can also manipulate this list with the EnableExtension "
#| "and DisableExtension DBus methods on org.gnome.Shell."
msgid "" msgid ""
"GNOME Shell extensions have a UUID property; this key lists extensions which " "GNOME Shell extensions have a UUID property; this key lists extensions which "
"should be loaded. Any extension that wants to be loaded needs to be in this " "should be loaded. Any extension that wants to be loaded needs to be in this "
@ -120,17 +126,20 @@ msgid "History for the looking glass dialog"
msgstr "চোৱা কাঁচ ডাইলগৰ কাৰণে ইতিহাস" msgstr "চোৱা কাঁচ ডাইলগৰ কাৰণে ইতিহাস"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9 #: ../data/org.gnome.shell.gschema.xml.in.in.h:9
#| msgid "Always show the 'Log out' menuitem in the user menu."
msgid "Always show the 'Log out' menu item in the user menu." msgid "Always show the 'Log out' menu item in the user menu."
msgstr "ব্যৱহাৰকাৰী মেনুত 'লগ আউট' মেনু আইটেম সদায় দেখুৱাব।" msgstr "ব্যৱহাৰকাৰী মেনুত 'লগ আউট' মেনু আইটেম সদায় দেখুৱাব।"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10 #: ../data/org.gnome.shell.gschema.xml.in.in.h:10
#| msgid ""
#| "This key overrides the automatic hiding of the 'Log out' menuitem in "
#| "single-user, single-session situations."
msgid "" msgid ""
"This key overrides the automatic hiding of the 'Log out' menu item in single-" "This key overrides the automatic hiding of the 'Log out' menu item in single-"
"user, single-session situations." "user, single-session situations."
msgstr "" msgstr ""
"এই কি'য়ে এটা-ব্যৱহাৰকাৰী, এটা-অধিবেশন অৱস্থাবোৰত 'লগ আউট' মেনুআইটেম " "এই কি'য়ে এটা-ব্যৱহাৰকাৰী, এটা-অধিবেশন অৱস্থাবোৰত 'লগ আউট' মেনুআইটেম "
"স্বচালিতভাৱে " "স্বচালিতভাৱে লুকুৱা অভাৰৰাইড কৰে।"
"লুকুৱা অভাৰৰাইড কৰে।"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11 #: ../data/org.gnome.shell.gschema.xml.in.in.h:11
msgid "" msgid ""
@ -280,7 +289,7 @@ msgstr "উপৰত দিয়া কম্বোবাকচ ব্যৱহা
#: ../js/gdm/authPrompt.js:147 ../js/ui/components/networkAgent.js:136 #: ../js/gdm/authPrompt.js:147 ../js/ui/components/networkAgent.js:136
#: ../js/ui/components/polkitAgent.js:166 ../js/ui/endSessionDialog.js:357 #: ../js/ui/components/polkitAgent.js:166 ../js/ui/endSessionDialog.js:357
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
#: ../js/ui/status/network.js:857 #: ../js/ui/status/network.js:724
msgid "Cancel" msgid "Cancel"
msgstr "বাতিল কৰক" msgstr "বাতিল কৰক"
@ -338,30 +347,31 @@ msgstr "কমান্ড বিশ্লেষন কৰিব নোৱাৰ
#: ../js/misc/util.js:156 #: ../js/misc/util.js:156
#, javascript-format #, javascript-format
#| msgid "Execution of '%s' failed:"
msgid "Execution of “%s” failed:" msgid "Execution of “%s” failed:"
msgstr "“%s” ৰ প্ৰেৰণ ব্যৰ্থ হল:" msgstr "“%s” ৰ প্ৰেৰণ ব্যৰ্থ হল:"
#: ../js/ui/appDisplay.js:633 #: ../js/ui/appDisplay.js:540
msgid "Frequently used applications will appear here" msgid "Frequently used applications will appear here"
msgstr "সঘনে ব্যৱহাৰ কৰা এপ্লিকেচনসমূহ ইয়াত উপস্থিত হব" msgstr "সঘনে ব্যৱহাৰ কৰা এপ্লিকেচনসমূহ ইয়াত উপস্থিত হব"
#: ../js/ui/appDisplay.js:744 #: ../js/ui/appDisplay.js:660
msgid "Frequent" msgid "Frequent"
msgstr "সঘন" msgstr "সঘন"
#: ../js/ui/appDisplay.js:751 #: ../js/ui/appDisplay.js:667
msgid "All" msgid "All"
msgstr "সকলো" msgstr "সকলো"
#: ../js/ui/appDisplay.js:1558 #: ../js/ui/appDisplay.js:1498
msgid "New Window" msgid "New Window"
msgstr "নতুন উইন্ডো" msgstr "নতুন উইন্ডো"
#: ../js/ui/appDisplay.js:1580 ../js/ui/dash.js:285 #: ../js/ui/appDisplay.js:1501 ../js/ui/dash.js:285
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "পছন্দৰ পৰা আতৰাওক" msgstr "পছন্দৰ পৰা আতৰাওক"
#: ../js/ui/appDisplay.js:1586 #: ../js/ui/appDisplay.js:1502
msgid "Add to Favorites" msgid "Add to Favorites"
msgstr "পছন্দলে যোগ কৰক" msgstr "পছন্দলে যোগ কৰক"
@ -574,8 +584,8 @@ msgstr "পাছৱাৰ্ড:"
msgid "Type again:" msgid "Type again:"
msgstr "আকৌ টাইপ কৰক:" msgstr "আকৌ টাইপ কৰক:"
#: ../js/ui/components/networkAgent.js:131 ../js/ui/status/network.js:227 #: ../js/ui/components/networkAgent.js:131 ../js/ui/status/network.js:131
#: ../js/ui/status/network.js:300 ../js/ui/status/network.js:860 #: ../js/ui/status/network.js:293 ../js/ui/status/network.js:727
msgid "Connect" msgid "Connect"
msgstr "সংযোগ কৰক" msgstr "সংযোগ কৰক"
@ -609,6 +619,9 @@ msgstr "বেতাঁৰ নেটৱাৰ্কৰ দ্বাৰা প্
#: ../js/ui/components/networkAgent.js:312 #: ../js/ui/components/networkAgent.js:312
#, javascript-format #, javascript-format
#| msgid ""
#| "Passwords or encryption keys are required to access the wireless network "
#| "'%s'."
msgid "" msgid ""
"Passwords or encryption keys are required to access the wireless network " "Passwords or encryption keys are required to access the wireless network "
"“%s”." "“%s”."
@ -646,6 +659,7 @@ msgstr "মবাইল ব্ৰডবেণ্ড নেটৱাৰ্ক প
#: ../js/ui/components/networkAgent.js:339 #: ../js/ui/components/networkAgent.js:339
#, javascript-format #, javascript-format
#| msgid "A password is required to connect to '%s'."
msgid "A password is required to connect to “%s”." msgid "A password is required to connect to “%s”."
msgstr "“%s” লে সংযোগ কৰিবলে এটা পাছৱাৰ্ডৰ প্ৰয়োজন।" msgstr "“%s” লে সংযোগ কৰিবলে এটা পাছৱাৰ্ডৰ প্ৰয়োজন।"
@ -694,35 +708,35 @@ msgid "Mute"
msgstr "মোন কৰক" msgstr "মোন কৰক"
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"*/ #. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"*/
#: ../js/ui/components/telepathyClient.js:952 #: ../js/ui/components/telepathyClient.js:941
msgid "<b>Yesterday</b>, <b>%H:%M</b>" msgid "<b>Yesterday</b>, <b>%H:%M</b>"
msgstr "<b>যোৱাকালী</b>, <b>%H:%M</b>" msgstr "<b>যোৱাকালী</b>, <b>%H:%M</b>"
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30*/ #. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30*/
#: ../js/ui/components/telepathyClient.js:958 #: ../js/ui/components/telepathyClient.js:947
msgid "<b>%A</b>, <b>%H:%M</b>" msgid "<b>%A</b>, <b>%H:%M</b>"
msgstr "<b>%A</b>, <b>%H:%M</b>" msgstr "<b>%A</b>, <b>%H:%M</b>"
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"*/ #. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"*/
#: ../js/ui/components/telepathyClient.js:963 #: ../js/ui/components/telepathyClient.js:952
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>" msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
msgstr "<b>%B</b> <b>%d</b>, <b>%H:%M</b>" msgstr "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"*/ #. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"*/
#: ../js/ui/components/telepathyClient.js:967 #: ../js/ui/components/telepathyClient.js:956
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> " msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
msgstr "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> " msgstr "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
#. Translators: this is the other person changing their old IM name to their new #. Translators: this is the other person changing their old IM name to their new
#. IM name. */ #. IM name. */
#: ../js/ui/components/telepathyClient.js:998 #: ../js/ui/components/telepathyClient.js:987
#, javascript-format #, javascript-format
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "%s এতিয়া %s হিচাপে জনাজাত" msgstr "%s এতিয়া %s হিচাপে জনাজাত"
#. translators: argument is a room name like #. translators: argument is a room name like
#. * room@jabber.org for example. */ #. * room@jabber.org for example. */
#: ../js/ui/components/telepathyClient.js:1101 #: ../js/ui/components/telepathyClient.js:1090
#, javascript-format #, javascript-format
msgid "Invitation to %s" msgid "Invitation to %s"
msgstr "%s লে নিমন্ত্ৰণ" msgstr "%s লে নিমন্ত্ৰণ"
@ -730,38 +744,38 @@ msgstr "%s লে নিমন্ত্ৰণ"
#. translators: first argument is the name of a contact and the second #. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org #. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example. */ #. * for example. */
#: ../js/ui/components/telepathyClient.js:1109 #: ../js/ui/components/telepathyClient.js:1098
#, javascript-format #, javascript-format
msgid "%s is inviting you to join %s" msgid "%s is inviting you to join %s"
msgstr "%s এ আপোনাক %s ত অংশগ্ৰহণ কৰিবলে আমন্ত্ৰণ জনাইছে" msgstr "%s এ আপোনাক %s ত অংশগ্ৰহণ কৰিবলে আমন্ত্ৰণ জনাইছে"
#: ../js/ui/components/telepathyClient.js:1111 #: ../js/ui/components/telepathyClient.js:1100
#: ../js/ui/components/telepathyClient.js:1146 #: ../js/ui/components/telepathyClient.js:1135
#: ../js/ui/components/telepathyClient.js:1180 #: ../js/ui/components/telepathyClient.js:1169
#: ../js/ui/components/telepathyClient.js:1237 #: ../js/ui/components/telepathyClient.js:1226
msgid "Decline" msgid "Decline"
msgstr "নাকচ কৰক" msgstr "নাকচ কৰক"
#: ../js/ui/components/telepathyClient.js:1117 #: ../js/ui/components/telepathyClient.js:1106
#: ../js/ui/components/telepathyClient.js:1186 #: ../js/ui/components/telepathyClient.js:1175
#: ../js/ui/components/telepathyClient.js:1242 #: ../js/ui/components/telepathyClient.js:1231
msgid "Accept" msgid "Accept"
msgstr "গ্ৰহন কৰক" msgstr "গ্ৰহন কৰক"
#. translators: argument is a contact name like Alice for example. */ #. translators: argument is a contact name like Alice for example. */
#: ../js/ui/components/telepathyClient.js:1136 #: ../js/ui/components/telepathyClient.js:1125
#, javascript-format #, javascript-format
msgid "Video call from %s" msgid "Video call from %s"
msgstr "%s ৰ পৰা ভিডিঅ' কল" msgstr "%s ৰ পৰা ভিডিঅ' কল"
#. translators: argument is a contact name like Alice for example. */ #. translators: argument is a contact name like Alice for example. */
#: ../js/ui/components/telepathyClient.js:1139 #: ../js/ui/components/telepathyClient.js:1128
#, javascript-format #, javascript-format
msgid "Call from %s" msgid "Call from %s"
msgstr "%s ৰ পৰা কল" msgstr "%s ৰ পৰা কল"
#. translators: this is a button label (verb), not a noun */ #. translators: this is a button label (verb), not a noun */
#: ../js/ui/components/telepathyClient.js:1153 #: ../js/ui/components/telepathyClient.js:1142
msgid "Answer" msgid "Answer"
msgstr "উত্তৰ দিয়ক" msgstr "উত্তৰ দিয়ক"
@ -770,110 +784,110 @@ msgstr "উত্তৰ দিয়ক"
#. * file name. The string will be something #. * file name. The string will be something
#. * like: "Alice is sending you test.ogg" #. * like: "Alice is sending you test.ogg"
#. */ #. */
#: ../js/ui/components/telepathyClient.js:1174 #: ../js/ui/components/telepathyClient.js:1163
#, javascript-format #, javascript-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "%s এ আপোনাক %s পঠাই আছে" msgstr "%s এ আপোনাক %s পঠাই আছে"
#. To translators: The parameter is the contact's alias */ #. To translators: The parameter is the contact's alias */
#: ../js/ui/components/telepathyClient.js:1203 #: ../js/ui/components/telepathyClient.js:1192
#, javascript-format #, javascript-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "আপুনি কেতিয়া অনলাইন আছে চাবলে %s এ অনুমতি বিচাৰিব" msgstr "আপুনি কেতিয়া অনলাইন আছে চাবলে %s এ অনুমতি বিচাৰিব"
#: ../js/ui/components/telepathyClient.js:1288 #: ../js/ui/components/telepathyClient.js:1277
msgid "Network error" msgid "Network error"
msgstr "নেটৱাৰ্ক ত্ৰুটি" msgstr "নেটৱাৰ্ক ত্ৰুটি"
#: ../js/ui/components/telepathyClient.js:1290 #: ../js/ui/components/telepathyClient.js:1279
msgid "Authentication failed" msgid "Authentication failed"
msgstr "প্ৰমাণীকৰণ ব্যৰ্থ" msgstr "প্ৰমাণীকৰণ ব্যৰ্থ"
#: ../js/ui/components/telepathyClient.js:1292 #: ../js/ui/components/telepathyClient.js:1281
msgid "Encryption error" msgid "Encryption error"
msgstr "ইনক্ৰিপষণ ত্ৰুটি" msgstr "ইনক্ৰিপষণ ত্ৰুটি"
#: ../js/ui/components/telepathyClient.js:1294 #: ../js/ui/components/telepathyClient.js:1283
msgid "Certificate not provided" msgid "Certificate not provided"
msgstr "প্ৰমাণপত্ৰ প্ৰদান কৰা হোৱা নাই" msgstr "প্ৰমাণপত্ৰ প্ৰদান কৰা হোৱা নাই"
#: ../js/ui/components/telepathyClient.js:1296 #: ../js/ui/components/telepathyClient.js:1285
msgid "Certificate untrusted" msgid "Certificate untrusted"
msgstr "প্ৰমাণপত্ৰক ভৰষা কৰিব নোৱাৰি" msgstr "প্ৰমাণপত্ৰক ভৰষা কৰিব নোৱাৰি"
#: ../js/ui/components/telepathyClient.js:1298 #: ../js/ui/components/telepathyClient.js:1287
msgid "Certificate expired" msgid "Certificate expired"
msgstr "প্ৰমাণপত্ৰৰ অৱসান ঘটিছে" msgstr "প্ৰমাণপত্ৰৰ অৱসান ঘটিছে"
#: ../js/ui/components/telepathyClient.js:1300 #: ../js/ui/components/telepathyClient.js:1289
msgid "Certificate not activated" msgid "Certificate not activated"
msgstr "প্ৰমাণপত্ৰ সক্ৰিয় কৰা হোৱা নাই" msgstr "প্ৰমাণপত্ৰ সক্ৰিয় কৰা হোৱা নাই"
#: ../js/ui/components/telepathyClient.js:1302 #: ../js/ui/components/telepathyClient.js:1291
msgid "Certificate hostname mismatch" msgid "Certificate hostname mismatch"
msgstr "প্ৰমাণপত্ৰ হস্টনাম অমিল" msgstr "প্ৰমাণপত্ৰ হস্টনাম অমিল"
#: ../js/ui/components/telepathyClient.js:1304 #: ../js/ui/components/telepathyClient.js:1293
msgid "Certificate fingerprint mismatch" msgid "Certificate fingerprint mismatch"
msgstr "প্ৰমাণপত্ৰ ফিংগাৰপ্ৰিন্ট অমিল" msgstr "প্ৰমাণপত্ৰ ফিংগাৰপ্ৰিন্ট অমিল"
#: ../js/ui/components/telepathyClient.js:1306 #: ../js/ui/components/telepathyClient.js:1295
msgid "Certificate self-signed" msgid "Certificate self-signed"
msgstr "প্ৰমাণপত্ৰ স্ব-স্বাক্ষৰীত" msgstr "প্ৰমাণপত্ৰ স্ব-স্বাক্ষৰীত"
#: ../js/ui/components/telepathyClient.js:1308 #: ../js/ui/components/telepathyClient.js:1297
msgid "Status is set to offline" msgid "Status is set to offline"
msgstr "অৱস্থা অফলাইনলে সংহতি কৰা হৈছে" msgstr "অৱস্থা অফলাইনলে সংহতি কৰা হৈছে"
#: ../js/ui/components/telepathyClient.js:1310 #: ../js/ui/components/telepathyClient.js:1299
msgid "Encryption is not available" msgid "Encryption is not available"
msgstr "ইনক্ৰিপষণ উপলব্ধ নহয়" msgstr "ইনক্ৰিপষণ উপলব্ধ নহয়"
#: ../js/ui/components/telepathyClient.js:1312 #: ../js/ui/components/telepathyClient.js:1301
msgid "Certificate is invalid" msgid "Certificate is invalid"
msgstr "প্ৰমাণপত্ৰ অবৈধ" msgstr "প্ৰমাণপত্ৰ অবৈধ"
#: ../js/ui/components/telepathyClient.js:1314 #: ../js/ui/components/telepathyClient.js:1303
msgid "Connection has been refused" msgid "Connection has been refused"
msgstr "সংযোগ নাকচ কৰা হৈছে" msgstr "সংযোগ নাকচ কৰা হৈছে"
#: ../js/ui/components/telepathyClient.js:1316 #: ../js/ui/components/telepathyClient.js:1305
msgid "Connection can't be established" msgid "Connection can't be established"
msgstr "সংযোগ স্থাপন কৰিব নোৱাৰি" msgstr "সংযোগ স্থাপন কৰিব নোৱাৰি"
#: ../js/ui/components/telepathyClient.js:1318 #: ../js/ui/components/telepathyClient.js:1307
msgid "Connection has been lost" msgid "Connection has been lost"
msgstr "সংযোগ হেৰাইছে" msgstr "সংযোগ হেৰাইছে"
#: ../js/ui/components/telepathyClient.js:1320 #: ../js/ui/components/telepathyClient.js:1309
msgid "This account is already connected to the server" msgid "This account is already connected to the server"
msgstr "এই একাওন্ট ইতিমধ্যে চাৰ্ভাৰৰ সৈতে সংযোগিত" msgstr "এই একাওন্ট ইতিমধ্যে চাৰ্ভাৰৰ সৈতে সংযোগিত"
#: ../js/ui/components/telepathyClient.js:1322 #: ../js/ui/components/telepathyClient.js:1311
msgid "" msgid ""
"Connection has been replaced by a new connection using the same resource" "Connection has been replaced by a new connection using the same resource"
msgstr "সংযোগক একে সম্পদ ব্যৱহাৰ কৰি এটা নতুন সংযোগৰে প্ৰতিস্থাপন কৰা হৈছে" msgstr "সংযোগক একে সম্পদ ব্যৱহাৰ কৰি এটা নতুন সংযোগৰে প্ৰতিস্থাপন কৰা হৈছে"
#: ../js/ui/components/telepathyClient.js:1324 #: ../js/ui/components/telepathyClient.js:1313
msgid "The account already exists on the server" msgid "The account already exists on the server"
msgstr "একাওন্ট ইতিমধ্যে চাৰ্ভাৰত উপস্থিত" msgstr "একাওন্ট ইতিমধ্যে চাৰ্ভাৰত উপস্থিত"
#: ../js/ui/components/telepathyClient.js:1326 #: ../js/ui/components/telepathyClient.js:1315
msgid "Server is currently too busy to handle the connection" msgid "Server is currently too busy to handle the connection"
msgstr "চাৰ্ভাৰ সংযোগ ব্যৱস্থাপনা কৰিবলে বৰ্তমানে অতি ব্যস্ত" msgstr "চাৰ্ভাৰ সংযোগ ব্যৱস্থাপনা কৰিবলে বৰ্তমানে অতি ব্যস্ত"
#: ../js/ui/components/telepathyClient.js:1328 #: ../js/ui/components/telepathyClient.js:1317
msgid "Certificate has been revoked" msgid "Certificate has been revoked"
msgstr "প্ৰমাণপত্ৰ প্ৰত্যাহাৰ কৰা হৈছে" msgstr "প্ৰমাণপত্ৰ প্ৰত্যাহাৰ কৰা হৈছে"
#: ../js/ui/components/telepathyClient.js:1330 #: ../js/ui/components/telepathyClient.js:1319
msgid "" msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak" "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "" msgstr ""
"প্ৰমাণপত্ৰয় এটা অসুৰক্ষিত চিফাৰ এলগৰিথম ব্যৱহাৰ কৰে অথবা ক্ৰিপ্টোগ্ৰাফিয়ভাৱে " "প্ৰমাণপত্ৰয় এটা অসুৰক্ষিত চিফাৰ এলগৰিথম ব্যৱহাৰ কৰে অথবা ক্ৰিপ্টোগ্ৰাফিয়ভাৱে "
"দুৰ্বল" "দুৰ্বল"
#: ../js/ui/components/telepathyClient.js:1332 #: ../js/ui/components/telepathyClient.js:1321
msgid "" msgid ""
"The length of the server certificate, or the depth of the server certificate " "The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library" "chain, exceed the limits imposed by the cryptography library"
@ -882,22 +896,22 @@ msgstr ""
"ক্ৰিপ্টোগ্ৰাফী " "ক্ৰিপ্টোগ্ৰাফী "
"লাইব্ৰেৰীয়ে প্ৰণয়ন কৰা সীমাসমূহত অতিক্ৰম কৰে" "লাইব্ৰেৰীয়ে প্ৰণয়ন কৰা সীমাসমূহত অতিক্ৰম কৰে"
#: ../js/ui/components/telepathyClient.js:1334 #: ../js/ui/components/telepathyClient.js:1323
msgid "Internal error" msgid "Internal error"
msgstr "অভ্যন্তৰীক ত্ৰুটি" msgstr "অভ্যন্তৰীক ত্ৰুটি"
#. translators: argument is the account name, like #. translators: argument is the account name, like
#. * name@jabber.org for example. */ #. * name@jabber.org for example. */
#: ../js/ui/components/telepathyClient.js:1344 #: ../js/ui/components/telepathyClient.js:1333
#, javascript-format #, javascript-format
msgid "Unable to connect to %s" msgid "Unable to connect to %s"
msgstr "%s ৰ সৈতে সংযোগ কৰিবলে অক্ষম" msgstr "%s ৰ সৈতে সংযোগ কৰিবলে অক্ষম"
#: ../js/ui/components/telepathyClient.js:1349 #: ../js/ui/components/telepathyClient.js:1338
msgid "View account" msgid "View account"
msgstr "একাওন্ট দৰ্শন কৰক" msgstr "একাওন্ট দৰ্শন কৰক"
#: ../js/ui/components/telepathyClient.js:1381 #: ../js/ui/components/telepathyClient.js:1370
msgid "Unknown reason" msgid "Unknown reason"
msgstr "অজ্ঞাত কাৰণ" msgstr "অজ্ঞাত কাৰণ"
@ -1044,6 +1058,7 @@ msgstr "ইনস্টল কৰক"
#: ../js/ui/extensionDownloader.js:204 #: ../js/ui/extensionDownloader.js:204
#, javascript-format #, javascript-format
#| msgid "Download and install '%s' from extensions.gnome.org?"
msgid "Download and install “%s” from extensions.gnome.org?" msgid "Download and install “%s” from extensions.gnome.org?"
msgstr "extensions.gnome.org ৰ পৰা “%s” ক ডাউনল'ড আৰু ইনস্টল কৰিব নে?" msgstr "extensions.gnome.org ৰ পৰা “%s” ক ডাউনল'ড আৰু ইনস্টল কৰিব নে?"
@ -1077,7 +1092,7 @@ msgstr "সামৰ্থবান কৰা আছে"
#. because it's disabled by rfkill (airplane mode) */ #. because it's disabled by rfkill (airplane mode) */
#. translators: #. translators:
#. * The device has been disabled #. * The device has been disabled
#: ../js/ui/lookingGlass.js:717 ../js/ui/status/network.js:523 #: ../js/ui/lookingGlass.js:717 ../js/ui/status/network.js:470
#: ../src/gvc/gvc-mixer-control.c:1830 #: ../src/gvc/gvc-mixer-control.c:1830
msgid "Disabled" msgid "Disabled"
msgstr "অসামৰ্থবান কৰা আছে" msgstr "অসামৰ্থবান কৰা আছে"
@ -1102,43 +1117,43 @@ msgstr "উৎস দৰ্শন কৰক"
msgid "Web Page" msgid "Web Page"
msgstr "ৱেব পৃষ্ঠা" msgstr "ৱেব পৃষ্ঠা"
#: ../js/ui/messageTray.js:1312 #: ../js/ui/messageTray.js:1309
msgid "Open" msgid "Open"
msgstr "খোলক" msgstr "খোলক"
#: ../js/ui/messageTray.js:1319 #: ../js/ui/messageTray.js:1316
msgid "Remove" msgid "Remove"
msgstr "আতৰাওক" msgstr "আতৰাওক"
#: ../js/ui/messageTray.js:1616 #: ../js/ui/messageTray.js:1613
msgid "Notifications" msgid "Notifications"
msgstr "অধিসূচনাসমূহ" msgstr "অধিসূচনাসমূহ"
#: ../js/ui/messageTray.js:1623 #: ../js/ui/messageTray.js:1620
msgid "Clear Messages" msgid "Clear Messages"
msgstr "বাৰ্তাসমূহ পৰিষ্কাৰ কৰক" msgstr "বাৰ্তাসমূহ পৰিষ্কাৰ কৰক"
#: ../js/ui/messageTray.js:1642 #: ../js/ui/messageTray.js:1639
msgid "Notification Settings" msgid "Notification Settings"
msgstr "অধিসূচনা সংহতিসমূহ" msgstr "অধিসূচনা সংহতিসমূহ"
#: ../js/ui/messageTray.js:1695 #: ../js/ui/messageTray.js:1692
msgid "Tray Menu" msgid "Tray Menu"
msgstr "ট্ৰে মেনু" msgstr "ট্ৰে মেনু"
#: ../js/ui/messageTray.js:1912 #: ../js/ui/messageTray.js:1909
msgid "No Messages" msgid "No Messages"
msgstr "কোনো বাৰ্তা নাই" msgstr "কোনো বাৰ্তা নাই"
#: ../js/ui/messageTray.js:1950 #: ../js/ui/messageTray.js:1947
msgid "Message Tray" msgid "Message Tray"
msgstr "বাৰ্তা ট্ৰে" msgstr "বাৰ্তা ট্ৰে"
#: ../js/ui/messageTray.js:2934 #: ../js/ui/messageTray.js:2931
msgid "System Information" msgid "System Information"
msgstr "চিস্টেম তথ্য" msgstr "চিস্টেম তথ্য"
#: ../js/ui/notificationDaemon.js:515 ../src/shell-app.c:399 #: ../js/ui/notificationDaemon.js:515 ../src/shell-app.c:397
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "অজ্ঞাত" msgstr "অজ্ঞাত"
@ -1176,7 +1191,7 @@ msgstr "প্ৰস্থান কৰক"
msgid "Activities" msgid "Activities"
msgstr "কাৰ্য্যসমূহ" msgstr "কাৰ্য্যসমূহ"
#: ../js/ui/panel.js:905 #: ../js/ui/panel.js:903
msgid "Top Bar" msgid "Top Bar"
msgstr "উপৰৰ বাৰ" msgstr "উপৰৰ বাৰ"
@ -1205,19 +1220,19 @@ msgid_plural "%d new notifications"
msgstr[0] "%d নতুন অধিসূচনা" msgstr[0] "%d নতুন অধিসূচনা"
msgstr[1] "%d নতুন অধিসূচনাসমূহ" msgstr[1] "%d নতুন অধিসূচনাসমূহ"
#: ../js/ui/screenShield.js:473 ../js/ui/status/system.js:342 #: ../js/ui/screenShield.js:472 ../js/ui/status/system.js:342
msgid "Lock" msgid "Lock"
msgstr "লক কৰক" msgstr "লক কৰক"
#: ../js/ui/screenShield.js:707 #: ../js/ui/screenShield.js:706
msgid "GNOME needs to lock the screen" msgid "GNOME needs to lock the screen"
msgstr "GNOME এ পৰ্দা লক কৰিব লাগিব" msgstr "GNOME এ পৰ্দা লক কৰিব লাগিব"
#: ../js/ui/screenShield.js:834 ../js/ui/screenShield.js:1301 #: ../js/ui/screenShield.js:833 ../js/ui/screenShield.js:1300
msgid "Unable to lock" msgid "Unable to lock"
msgstr "লক কৰিবলে অক্ষম" msgstr "লক কৰিবলে অক্ষম"
#: ../js/ui/screenShield.js:835 ../js/ui/screenShield.js:1302 #: ../js/ui/screenShield.js:834 ../js/ui/screenShield.js:1301
msgid "Lock was blocked by an application" msgid "Lock was blocked by an application"
msgstr "লক কাৰ্য্য এটা এপ্লিকেচন দ্বাৰা প্ৰতিৰোধ কৰা হৈছিল" msgstr "লক কাৰ্য্য এটা এপ্লিকেচন দ্বাৰা প্ৰতিৰোধ কৰা হৈছিল"
@ -1297,31 +1312,26 @@ msgstr "উচ্চ কন্ট্ৰাস্ট"
msgid "Large Text" msgid "Large Text"
msgstr "ডাঙৰ লিখনী" msgstr "ডাঙৰ লিখনী"
#: ../js/ui/status/bluetooth.js:48 #: ../js/ui/status/bluetooth.js:45
msgid "Bluetooth" msgid "Bluetooth"
msgstr "ব্লুটুথ" msgstr "ব্লুটুথ"
#: ../js/ui/status/bluetooth.js:50 ../js/ui/status/network.js:134 #: ../js/ui/status/bluetooth.js:47 ../js/ui/status/network.js:131
#: ../js/ui/status/network.js:1209 ../js/ui/status/rfkill.js:85 #: ../js/ui/status/network.js:1081 ../js/ui/status/rfkill.js:48
#: ../js/ui/status/rfkill.js:105
msgid "Turn Off" msgid "Turn Off"
msgstr "বন্ধ কৰক" msgstr "বন্ধ কৰক"
#: ../js/ui/status/bluetooth.js:53 #: ../js/ui/status/bluetooth.js:50
msgid "Bluetooth Settings" msgid "Bluetooth Settings"
msgstr "ব্লুটুথ সংহতিসমূহ" msgstr "ব্লুটুথ সংহতিসমূহ"
#: ../js/ui/status/bluetooth.js:100 #: ../js/ui/status/bluetooth.js:98
#, javascript-format #, javascript-format
msgid "%d Connected Device" msgid "%d Connected Device"
msgid_plural "%d Connected Devices" msgid_plural "%d Connected Devices"
msgstr[0] "%d সংযুক্ত ডিভাইচ" msgstr[0] "%d সংযুক্ত ডিভাইচ"
msgstr[1] "%d সংযুক্ত ডিভাইচসমূহ" msgstr[1] "%d সংযুক্ত ডিভাইচসমূহ"
#: ../js/ui/status/bluetooth.js:102 ../js/ui/status/network.js:1232
msgid "Not Connected"
msgstr "সংযুক্ত নহয়"
#: ../js/ui/status/brightness.js:44 #: ../js/ui/status/brightness.js:44
msgid "Brightness" msgid "Brightness"
msgstr "উজ্জ্বলতা" msgstr "উজ্জ্বলতা"
@ -1330,136 +1340,103 @@ msgstr "উজ্জ্বলতা"
msgid "Show Keyboard Layout" msgid "Show Keyboard Layout"
msgstr "কিবৰ্ড বিন্যাস দেখুৱাওক" msgstr "কিবৰ্ড বিন্যাস দেখুৱাওক"
#: ../js/ui/status/network.js:73 #: ../js/ui/status/network.js:70
msgid "<unknown>" msgid "<unknown>"
msgstr "<unknown>" msgstr "<unknown>"
#: ../js/ui/status/network.js:223 ../js/ui/status/network.js:389 #: ../js/ui/status/network.js:220 ../js/ui/status/network.js:377
#: ../js/ui/status/network.js:1230 #: ../js/ui/status/network.js:1102
msgid "Off" msgid "Off"
msgstr "অফ" msgstr "অফ"
#. Translators: this is for network devices that are physically present but are not #. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu) */ #. under NetworkManager's control (and thus cannot be used in the menu) */
#: ../js/ui/status/network.js:395 #: ../js/ui/status/network.js:383
msgid "unmanaged" msgid "unmanaged"
msgstr "অব্যৱস্থাপিত" msgstr "অব্যৱস্থাপিত"
#: ../js/ui/status/network.js:397 #: ../js/ui/status/network.js:385
msgid "disconnecting..." msgid "disconnecting..."
msgstr "বিচ্ছিনিত কৰা হৈছে..." msgstr "বিচ্ছিনিত কৰা হৈছে..."
#: ../js/ui/status/network.js:403 ../js/ui/status/network.js:1284 #: ../js/ui/status/network.js:391 ../js/ui/status/network.js:1156
msgid "connecting..." msgid "connecting..."
msgstr "সংযোগ কৰা হৈছে..." msgstr "সংযোগ কৰা হৈছে..."
#. Translators: this is for network connections that require some kind of key or password */ #. Translators: this is for network connections that require some kind of key or password */
#: ../js/ui/status/network.js:406 ../js/ui/status/network.js:1287 #: ../js/ui/status/network.js:394 ../js/ui/status/network.js:1159
msgid "authentication required" msgid "authentication required"
msgstr "প্ৰমাণীকৰণৰ প্ৰয়োজন" msgstr "প্ৰমাণীকৰণৰ প্ৰয়োজন"
#. Translators: this is for devices that require some kind of firmware or kernel #. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing */ #. module, which is missing */
#: ../js/ui/status/network.js:414 #: ../js/ui/status/network.js:402
msgid "firmware missing" msgid "firmware missing"
msgstr "ফাৰ্মৱেৰ সন্ধানহীন" msgstr "ফাৰ্মৱেৰ সন্ধানহীন"
#. Translators: this is for a network device that cannot be activated (for example it #. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage */ #. is disabled by rfkill, or it has no coverage */
#: ../js/ui/status/network.js:418 #: ../js/ui/status/network.js:406
msgid "unavailable" msgid "unavailable"
msgstr "উপলব্ধ নাই" msgstr "উপলব্ধ নাই"
#: ../js/ui/status/network.js:420 ../js/ui/status/network.js:1289 #: ../js/ui/status/network.js:408 ../js/ui/status/network.js:1161
msgid "connection failed" msgid "connection failed"
msgstr "সংযোগ ব্যৰ্থ" msgstr "সংযোগ ব্যৰ্থ"
#: ../js/ui/status/network.js:436 #: ../js/ui/status/network.js:424 ../js/ui/status/network.js:510
#| msgid "Wi-Fi Settings" #| msgid "Mobile broadband"
msgid "Wired Settings"
msgstr "তাঁৰযুক্ত সংহতিসমূহ"
#: ../js/ui/status/network.js:477 ../js/ui/status/network.js:563
msgid "Mobile Broadband Settings" msgid "Mobile Broadband Settings"
msgstr "মবাইল ব্ৰডবেণ্ড সংহতিসমূহ" msgstr "মবাইল ব্ৰডবেণ্ড সংহতিসমূহ"
#: ../js/ui/status/network.js:519 ../js/ui/status/network.js:1228 #: ../js/ui/status/network.js:466 ../js/ui/status/network.js:1100
#| msgid "hardware disabled"
msgid "Hardware Disabled" msgid "Hardware Disabled"
msgstr "হাৰ্ডৱেৰ অসামৰ্থবান কৰা আছে" msgstr "হাৰ্ডৱেৰ অসামৰ্থবান কৰা আছে"
#: ../js/ui/status/network.js:578 #: ../js/ui/status/network.js:692
msgid "Use as Internet connection"
msgstr "ইন্টাৰনেট সংযোগ ৰূপে ব্যৱহাৰ কৰক"
#: ../js/ui/status/network.js:755
#| msgid "Airplane Mode"
msgid "Airplane Mode is On"
msgstr "বিমান অৱস্থা অন আছে"
#: ../js/ui/status/network.js:756
msgid "Wi-Fi is disabled when airplane mode is on."
msgstr "বিমান অৱস্থা অন থকা অৱস্থাত Wi-Fi অসামৰ্থবান থাকে।"
#: ../js/ui/status/network.js:757
#| msgid "Airplane Mode"
msgid "Turn Off Airplane Mode"
msgstr "বিমান অৱস্থা বন্ধ কৰক"
#: ../js/ui/status/network.js:766
#| msgid "Wi-Fi Settings"
msgid "Wi-Fi is Off"
msgstr "Wi-Fi অফ আছে"
#: ../js/ui/status/network.js:767
msgid "Wi-Fi needs to be turned on in order to connect to a network."
msgstr "এটা নেটৱাৰ্কৰ সৈতে সংযোগ কৰিবলে Wi-Fi অন কৰিব লাগিব।"
#: ../js/ui/status/network.js:768
#| msgid "Turn On"
msgid "Turn On Wi-Fi"
msgstr "Wi-Fi অন কৰক"
#: ../js/ui/status/network.js:793
msgid "Wi-Fi Networks" msgid "Wi-Fi Networks"
msgstr "Wi-Fi নেটৱাৰ্কসমূহ" msgstr "Wi-Fi নেটৱাৰ্কসমূহ"
#: ../js/ui/status/network.js:795 #: ../js/ui/status/network.js:694
msgid "Select a network" msgid "Select a network"
msgstr "এটা নেটৱাৰ্ক বাছক" msgstr "এটা নেটৱাৰ্ক বাছক"
#: ../js/ui/status/network.js:824 #: ../js/ui/status/network.js:718
msgid "No Networks" msgid "No Networks"
msgstr "কোনো নেটৱাৰ্ক নাই" msgstr "কোনো নেটৱাৰ্ক নাই"
#: ../js/ui/status/network.js:845 ../js/ui/status/rfkill.js:103 #: ../js/ui/status/network.js:987
msgid "Use hardware switch to turn off"
msgstr "বন্ধ কৰিবলে হাৰ্ডৱেৰ চুইচ ব্যৱহাৰ কৰক"
#: ../js/ui/status/network.js:1115
msgid "Select Network" msgid "Select Network"
msgstr "নেটৱাৰ্ক বাছক" msgstr "নেটৱাৰ্ক বাছক"
#: ../js/ui/status/network.js:1121 #: ../js/ui/status/network.js:993
#| msgid "Settings"
msgid "Wi-Fi Settings" msgid "Wi-Fi Settings"
msgstr "Wi-Fi সংহতিসমূহ" msgstr "Wi-Fi সংহতিসমূহ"
#: ../js/ui/status/network.js:1209 #: ../js/ui/status/network.js:1081
msgid "Turn On" msgid "Turn On"
msgstr "অন কৰক" msgstr "অন কৰক"
#: ../js/ui/status/network.js:1352 #: ../js/ui/status/network.js:1104
#| msgid "Connect"
msgid "Not Connected"
msgstr "সংযুক্ত নহয়"
#: ../js/ui/status/network.js:1224
msgid "VPN" msgid "VPN"
msgstr "VPN" msgstr "VPN"
#: ../js/ui/status/network.js:1495 #: ../js/ui/status/network.js:1364
msgid "Network Manager" msgid "Network Manager"
msgstr "নেটৱাৰ্ক ব্যৱস্থাপক" msgstr "নেটৱাৰ্ক ব্যৱস্থাপক"
#: ../js/ui/status/network.js:1534 #: ../js/ui/status/network.js:1403
msgid "Connection failed" msgid "Connection failed"
msgstr "সংযোগ ব্যৰ্থ" msgstr "সংযোগ ব্যৰ্থ"
#: ../js/ui/status/network.js:1535 #: ../js/ui/status/network.js:1404
msgid "Activation of network connection failed" msgid "Activation of network connection failed"
msgstr "নেটৱাৰ্ক সংযোগ সক্ৰিয়কৰণ ব্যৰ্থ হল" msgstr "নেটৱাৰ্ক সংযোগ সক্ৰিয়কৰণ ব্যৰ্থ হল"
@ -1493,15 +1470,15 @@ msgstr "UPS"
msgid "Battery" msgid "Battery"
msgstr "বেটাৰি" msgstr "বেটাৰি"
#: ../js/ui/status/rfkill.js:82 #: ../js/ui/status/rfkill.js:45
msgid "Airplane Mode" msgid "Airplane Mode"
msgstr "বিমান অৱস্থা" msgstr "বিমান অৱস্থা"
#: ../js/ui/status/rfkill.js:84 #: ../js/ui/status/rfkill.js:47
msgid "On" msgid "On"
msgstr "অন" msgstr "অন"
#: ../js/ui/status/rfkill.js:88 #: ../js/ui/status/rfkill.js:51
msgid "Network Settings" msgid "Network Settings"
msgstr "নেটৱাৰ্ক সংহতিসমূহ" msgstr "নেটৱাৰ্ক সংহতিসমূহ"
@ -1555,6 +1532,7 @@ msgstr "সন্ধান কৰক"
#: ../js/ui/windowAttentionHandler.js:19 #: ../js/ui/windowAttentionHandler.js:19
#, javascript-format #, javascript-format
#| msgid "'%s' is ready"
msgid "“%s” is ready" msgid "“%s” is ready"
msgstr "“%s” প্ৰস্তুত" msgstr "“%s” প্ৰস্তুত"
@ -1622,8 +1600,9 @@ msgstr "লগিন পৰ্দাৰ বাবে এটা বিশেষ
msgid "List possible modes" msgid "List possible modes"
msgstr "সম্ভাব্য অৱস্থাসমূহ তালিকাভুক্ত কৰক" msgstr "সম্ভাব্য অৱস্থাসমূহ তালিকাভুক্ত কৰক"
#: ../src/shell-app.c:642 #: ../src/shell-app.c:640
#, c-format #, c-format
#| msgid "Failed to launch '%s'"
msgid "Failed to launch “%s”" msgid "Failed to launch “%s”"
msgstr "“%s” লঞ্চ কৰিবলে ব্যৰ্থ" msgstr "“%s” লঞ্চ কৰিবলে ব্যৰ্থ"

902
po/be.po

File diff suppressed because it is too large Load Diff

982
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

648
po/cs.po

File diff suppressed because it is too large Load Diff

1277
po/da.po

File diff suppressed because it is too large Load Diff

692
po/de.po

File diff suppressed because it is too large Load Diff

751
po/el.po

File diff suppressed because it is too large Load Diff

696
po/es.po

File diff suppressed because it is too large Load Diff

1039
po/eu.po

File diff suppressed because it is too large Load Diff

923
po/fi.po

File diff suppressed because it is too large Load Diff

1247
po/fr.po

File diff suppressed because it is too large Load Diff

2016
po/fur.po

File diff suppressed because it is too large Load Diff

872
po/gl.po

File diff suppressed because it is too large Load Diff

720
po/he.po

File diff suppressed because it is too large Load Diff

1039
po/hu.po

File diff suppressed because it is too large Load Diff

664
po/id.po

File diff suppressed because it is too large Load Diff

1724
po/is.po

File diff suppressed because it is too large Load Diff

906
po/it.po

File diff suppressed because it is too large Load Diff

1208
po/ja.po

File diff suppressed because it is too large Load Diff

664
po/kk.po

File diff suppressed because it is too large Load Diff

1759
po/km.po

File diff suppressed because it is too large Load Diff

726
po/kn.po

File diff suppressed because it is too large Load Diff

1502
po/ko.po

File diff suppressed because it is too large Load Diff

632
po/lt.po

File diff suppressed because it is too large Load Diff

1056
po/lv.po

File diff suppressed because it is too large Load Diff

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