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
378 changed files with 75870 additions and 115520 deletions

20
.gitignore vendored
View File

@ -16,18 +16,18 @@ config.log
config.status
config
configure
data/org.gnome.Shell.desktop
data/org.gnome.Shell.desktop.in
data/50-gnome-shell-*.xml
data/gnome-shell.desktop
data/gnome-shell.desktop.in
data/gnome-shell-wayland.desktop
data/gnome-shell-wayland.desktop.in
data/gnome-shell-extension-prefs.desktop
data/gnome-shell-extension-prefs.desktop.in
data/gnome-shell-theme.gresource
data/gschemas.compiled
data/perf-background.xml
data/org.gnome.shell.gschema.xml
data/org.gnome.shell.gschema.valid
data/org.gnome.Shell.PortalHelper.desktop
data/org.gnome.Shell.PortalHelper.service
data/theme/.sass-cache
data/org.gnome.shell.evolution.calendar.gschema.xml
data/org.gnome.shell.evolution.calendar.gschema.valid
docs/reference/*/*.args
docs/reference/*/*.bak
docs/reference/*/*.hierarchy
@ -71,17 +71,19 @@ src/*-marshal.[ch]
src/Makefile
src/Makefile.in
src/calendar-server/evolution-calendar.desktop
src/calendar-server/evolution-calendar.desktop.in
src/calendar-server/org.gnome.Shell.CalendarServer.service
src/gnome-shell
src/gnome-shell-calendar-server
src/gnome-shell-extension-prefs
src/gnome-shell-extension-tool
src/gnome-shell-hotplug-sniffer
src/gnome-shell-jhbuild
src/gnome-shell-perf-helper
src/gnome-shell-perf-tool
src/gnome-shell-portal-helper
src/gnome-shell-real
src/gnome-shell-wayland
src/hotplug-sniffer/org.gnome.Shell.HotplugSniffer.service
src/org-gtk-application.[ch]
src/run-js-test
src/test-recorder
src/test-recorder.ogg

3
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "src/gvc"]
path = src/gvc
url = git://git.gnome.org/libgnome-volume-control
[submodule "data/theme/gnome-shell-sass"]
path = data/theme/gnome-shell-sass
url = git://git.gnome.org/gnome-shell-sass

1076
NEWS

File diff suppressed because it is too large Load Diff

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,
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'
product.

View File

@ -1,9 +1,11 @@
#!/bin/sh
#!/bin/bash
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
PKG_NAME="gnome-shell"
(test -f $srcdir/configure.ac \
&& test -d $srcdir/src) || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
@ -12,7 +14,7 @@ test -z "$srcdir" && srcdir=.
}
# Fetch submodules if needed
if test ! -f src/gvc/Makefile.am || test ! -f data/theme/gnome-shell-sass/COPYING;
if test ! -f src/gvc/Makefile.am;
then
echo "+ Setting up submodules"
git submodule init
@ -24,4 +26,4 @@ which gnome-autogen.sh || {
echo "your OS vendor's package manager)."
exit 1
}
. gnome-autogen.sh
USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh

View File

@ -3,10 +3,7 @@ mozillalibdir = $(BROWSER_PLUGIN_DIR)
mozillalib_LTLIBRARIES = libgnome-shell-browser-plugin.la
# Browsers can unload and reload the module while browsing, which is not supported by GObject.
# We pass -Wl,-z,nodelete to the linker to ensure the module is never unloaded.
# https://bugzilla.gnome.org/show_bug.cgi?id=737932
libgnome_shell_browser_plugin_la_LDFLAGS = -module -avoid-version -no-undefined -Wl,-z,nodelete
libgnome_shell_browser_plugin_la_LDFLAGS = -module -avoid-version -no-undefined
libgnome_shell_browser_plugin_la_LIBADD = \
$(BROWSER_PLUGIN_LIBS)

View File

@ -33,15 +33,17 @@
#include <json-glib/json-glib.h>
#define ORIGIN "extensions.gnome.org"
#define PLUGIN_NAME "GNOME Shell Integration"
#define PLUGIN_DESCRIPTION "This plugin provides integration with GNOME Shell " \
#define PLUGIN_NAME "Gnome Shell Integration"
#define PLUGIN_DESCRIPTION "This plugin provides integration with Gnome Shell " \
"for live extension enabling and disabling. " \
"It can be used only by extensions.gnome.org"
#define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::GNOME Shell Integration Dummy Content-Type";
#define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::Gnome Shell Integration Dummy Content-Type";
#define PLUGIN_API_VERSION 5
#define EXTENSION_DISABLE_VERSION_CHECK_KEY "disable-extension-version-validation"
typedef struct {
GDBusProxy *proxy;
} PluginData;
static NPNetscapeFuncs funcs;
@ -141,6 +143,121 @@ check_origin_and_protocol (NPP instance)
return ret;
}
/* =============== public entry points =================== */
NPError
NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
{
/* global initialization routine, called once when plugin
is loaded */
g_debug ("plugin loaded");
memcpy (&funcs, pfuncs, sizeof (funcs));
plugin->size = sizeof(NPPluginFuncs);
plugin->newp = NPP_New;
plugin->destroy = NPP_Destroy;
plugin->getvalue = NPP_GetValue;
plugin->setwindow = NPP_SetWindow;
return NPERR_NO_ERROR;
}
NPError
NP_Shutdown(void)
{
return NPERR_NO_ERROR;
}
const char*
NP_GetMIMEDescription(void)
{
return PLUGIN_MIME_STRING;
}
NPError
NP_GetValue(void *instance,
NPPVariable variable,
void *value)
{
switch (variable) {
case NPPVpluginNameString:
*(char**)value = PLUGIN_NAME;
break;
case NPPVpluginDescriptionString:
*(char**)value = PLUGIN_DESCRIPTION;
break;
default:
;
}
return NPERR_NO_ERROR;
}
NPError
NPP_New(NPMIMEType mimetype,
NPP instance,
uint16_t mode,
int16_t argc,
char **argn,
char **argv,
NPSavedData *saved)
{
/* instance initialization function */
PluginData *data;
GError *error = NULL;
g_debug ("plugin created");
if (!check_origin_and_protocol (instance))
return NPERR_GENERIC_ERROR;
data = g_slice_new (PluginData);
instance->pdata = data;
data->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_NONE,
NULL, /* interface info */
"org.gnome.Shell",
"/org/gnome/Shell",
"org.gnome.Shell.Extensions",
NULL, /* GCancellable */
&error);
if (!data->proxy)
{
/* ignore error if the shell is not running, otherwise warn */
if (error->domain != G_DBUS_ERROR ||
error->code != G_DBUS_ERROR_NAME_HAS_NO_OWNER)
{
g_warning ("Failed to set up Shell proxy: %s", error->message);
}
g_clear_error (&error);
return NPERR_GENERIC_ERROR;
}
g_debug ("plugin created successfully");
return NPERR_NO_ERROR;
}
NPError
NPP_Destroy(NPP instance,
NPSavedData **saved)
{
/* instance finalization function */
PluginData *data = instance->pdata;
g_debug ("plugin destroyed");
g_object_unref (data->proxy);
g_slice_free (PluginData, data);
return NPERR_NO_ERROR;
}
/* =================== scripting interface =================== */
typedef struct {
@ -211,18 +328,45 @@ static NPObject *
plugin_object_allocate (NPP instance,
NPClass *klass)
{
PluginObject *obj = (PluginObject *) funcs.memalloc (sizeof (PluginObject));
PluginData *data = instance->pdata;
PluginObject *obj = g_slice_new0 (PluginObject);
memset (obj, 0, sizeof (PluginObject));
obj->instance = instance;
obj->proxy = g_object_ref (data->proxy);
obj->settings = g_settings_new (SHELL_SCHEMA);
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
G_CALLBACK (on_shell_signal), obj);
return (NPObject*) obj;
obj->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
"org.gnome.Shell",
G_BUS_NAME_WATCHER_FLAGS_NONE,
on_shell_appeared,
NULL,
obj,
NULL);
g_debug ("plugin object created");
return (NPObject*)obj;
}
static void
plugin_object_deallocate (NPObject *npobj)
{
funcs.memfree (npobj);
PluginObject *obj = (PluginObject*)npobj;
g_signal_handler_disconnect (obj->proxy, obj->signal_id);
g_object_unref (obj->proxy);
if (obj->listener)
funcs.releaseobject (obj->listener);
if (obj->watch_name_id)
g_bus_unwatch_name (obj->watch_name_id);
g_debug ("plugin object destroyed");
g_slice_free (PluginObject, obj);
}
static inline gboolean
@ -687,16 +831,6 @@ plugin_get_shell_version (PluginObject *obj,
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 \
METHOD (list_extensions) \
METHOD (get_info) \
@ -716,8 +850,6 @@ static NPIdentifier api_version_id;
static NPIdentifier shell_version_id;
static NPIdentifier onextension_changed_id;
static NPIdentifier onrestart_id;
static NPIdentifier version_validation_enabled_id;
static bool
plugin_object_has_method (NPObject *npobj,
@ -760,8 +892,7 @@ plugin_object_has_property (NPObject *npobj,
return (name == onextension_changed_id ||
name == onrestart_id ||
name == api_version_id ||
name == shell_version_id ||
name == version_validation_enabled_id);
name == shell_version_id);
}
static bool
@ -779,8 +910,6 @@ plugin_object_get_property (NPObject *npobj,
return plugin_get_api_version (obj, result);
else if (name == shell_version_id)
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)
{
if (obj->listener)
@ -859,7 +988,6 @@ init_methods_and_properties (void)
/* this is the JS public API; it is manipulated through NPIdentifiers for speed */
api_version_id = funcs.getstringidentifier ("apiVersion");
shell_version_id = funcs.getstringidentifier ("shellVersion");
version_validation_enabled_id = funcs.getstringidentifier ("versionValidationEnabled");
get_info_id = funcs.getstringidentifier ("getExtensionInfo");
list_extensions_id = funcs.getstringidentifier ("listExtensions");
@ -873,149 +1001,6 @@ init_methods_and_properties (void)
onextension_changed_id = funcs.getstringidentifier ("onchange");
}
/* =============== public entry points =================== */
NPError
NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
{
/* global initialization routine, called once when plugin
is loaded */
g_debug ("plugin loaded");
memcpy (&funcs, pfuncs, sizeof (funcs));
plugin->size = sizeof(NPPluginFuncs);
plugin->newp = NPP_New;
plugin->destroy = NPP_Destroy;
plugin->getvalue = NPP_GetValue;
plugin->setwindow = NPP_SetWindow;
plugin->event = NPP_HandleEvent;
return NPERR_NO_ERROR;
}
NPError
NP_Shutdown(void)
{
return NPERR_NO_ERROR;
}
const char*
NP_GetMIMEDescription(void)
{
return PLUGIN_MIME_STRING;
}
NPError
NP_GetValue(void *instance,
NPPVariable variable,
void *value)
{
switch (variable) {
case NPPVpluginNameString:
*(char**)value = PLUGIN_NAME;
break;
case NPPVpluginDescriptionString:
*(char**)value = PLUGIN_DESCRIPTION;
break;
default:
;
}
return NPERR_NO_ERROR;
}
NPError
NPP_New(NPMIMEType mimetype,
NPP instance,
uint16_t mode,
int16_t argc,
char **argn,
char **argv,
NPSavedData *saved)
{
/* instance initialization function */
PluginObject *obj;
GError *error = NULL;
g_debug ("plugin created");
if (!check_origin_and_protocol (instance))
return NPERR_GENERIC_ERROR;
/* set windowless mode */
funcs.setvalue(instance, NPPVpluginWindowBool, NULL);
g_debug ("creating scriptable object");
init_methods_and_properties ();
obj = (PluginObject *) funcs.createobject (instance, &plugin_class);
instance->pdata = obj;
obj->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_NONE,
NULL, /* interface info */
"org.gnome.Shell",
"/org/gnome/Shell",
"org.gnome.Shell.Extensions",
NULL, /* GCancellable */
&error);
if (!obj->proxy)
{
/* ignore error if the shell is not running, otherwise warn */
if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
{
g_warning ("Failed to set up Shell proxy: %s", error->message);
}
g_clear_error (&error);
return NPERR_GENERIC_ERROR;
}
obj->settings = g_settings_new (SHELL_SCHEMA);
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
G_CALLBACK (on_shell_signal), obj);
obj->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
"org.gnome.Shell",
G_BUS_NAME_WATCHER_FLAGS_NONE,
on_shell_appeared,
NULL,
obj,
NULL);
g_debug ("plugin created successfully");
return NPERR_NO_ERROR;
}
NPError
NPP_Destroy(NPP instance,
NPSavedData **saved)
{
/* instance finalization function */
PluginObject *obj = (PluginObject *) instance->pdata;
if (!obj)
return NPERR_INVALID_INSTANCE_ERROR;
g_debug ("plugin destroyed");
g_signal_handler_disconnect (obj->proxy, obj->signal_id);
g_object_unref (obj->proxy);
if (obj->listener)
funcs.releaseobject (obj->listener);
if (obj->restart_listener)
funcs.releaseobject (obj->restart_listener);
if (obj->watch_name_id)
g_bus_unwatch_name (obj->watch_name_id);
funcs.releaseobject((NPObject *)obj);
return NPERR_NO_ERROR;
}
NPError
NPP_GetValue(NPP instance,
NPPVariable variable,
@ -1026,11 +1011,13 @@ NPP_GetValue(NPP instance,
switch (variable) {
case NPPVpluginScriptableNPObject:
g_debug ("creating scriptable object");
if (!instance->pdata)
return NPERR_INVALID_INSTANCE_ERROR;
init_methods_and_properties ();
funcs.retainobject (instance->pdata);
*(NPObject**)value = instance->pdata;
*(NPObject**)value = funcs.createobject (instance, &plugin_class);
break;
case NPPVpluginNeedsXEmbed:
*(bool *)value = TRUE;
break;
default:
@ -1048,11 +1035,3 @@ NPP_SetWindow(NPP instance,
{
return NPERR_NO_ERROR;
}
int16_t
NPP_HandleEvent(NPP instance,
void *event)
{
/* Ignore the event */
return FALSE;
}

View File

@ -1,6 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.22.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AX_IS_RELEASE([git-directory])
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_SRCDIR([src/shell-global.c])
@ -24,14 +23,13 @@ LT_PREREQ([2.2.6])
LT_INIT([disable-static])
# i18n
IT_PROG_INTLTOOL([0.40])
GETTEXT_PACKAGE=gnome-shell
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
[The prefix for our gettext translation domains.])
AM_GNU_GETTEXT_VERSION([0.19.6])
AM_GNU_GETTEXT([external])
PKG_PROG_PKG_CONFIG([0.22])
AC_PATH_PROG([XSLTPROC], [xsltproc])
@ -39,7 +37,7 @@ AC_PATH_PROG([XSLTPROC], [xsltproc])
GLIB_GSETTINGS
# Get a value to substitute into gnome-shell.in
AM_PATH_PYTHON([3])
AM_PATH_PYTHON([2.5])
AC_SUBST(PYTHON)
# We need at least this, since gst_plugin_register_static() was added
@ -53,7 +51,7 @@ if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then
AC_MSG_RESULT(yes)
build_recorder=true
recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11 gtk+-3.0"
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules mutter-clutter-1.0)
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0)
else
AC_MSG_RESULT(no)
fi
@ -65,8 +63,8 @@ AC_ARG_ENABLE([systemd],
[enable_systemd=$enableval],
[enable_systemd=auto])
AS_IF([test x$enable_systemd != xno], [
AC_MSG_CHECKING([for libsystemd])
PKG_CHECK_EXISTS([libsystemd],
AC_MSG_CHECKING([for libsystemd-journal])
PKG_CHECK_EXISTS([libsystemd-journal],
[have_systemd=yes
AC_DEFINE([HAVE_SYSTEMD], [1], [Define if we have systemd])],
[have_systemd=no])
@ -75,14 +73,14 @@ AS_IF([test x$enable_systemd != xno], [
AC_MSG_RESULT($enable_systemd)
CLUTTER_MIN_VERSION=1.21.5
GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1
CLUTTER_MIN_VERSION=1.15.90
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.22.1
GTK_MIN_VERSION=3.15.0
GIO_MIN_VERSION=2.45.3
MUTTER_MIN_VERSION=3.11.1
GTK_MIN_VERSION=3.7.9
GIO_MIN_VERSION=2.37.0
LIBECAL_MIN_VERSION=3.5.3
LIBEDATASERVER_MIN_VERSION=3.17.2
LIBEDATASERVER_MIN_VERSION=3.5.3
TELEPATHY_GLIB_MIN_VERSION=0.17.5
POLKIT_MIN_VERSION=0.100
STARTUP_NOTIFICATION_MIN_VERSION=0.11
@ -99,28 +97,39 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
gjs-internals-1.0 >= $GJS_MIN_VERSION
$recorder_modules
gdk-x11-3.0 libsoup-2.4
mutter-clutter-1.0 >= $CLUTTER_MIN_VERSION
mutter-cogl-pango-1.0
xtst
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
libcanberra libcanberra-gtk3
telepathy-glib >= $TELEPATHY_GLIB_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
SHARED_PCS="${SHARED_PCS} libsystemd"
SHARED_PCS="${SHARED_PCS} libsystemd-journal"
fi
PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS)
PKG_CHECK_MODULES(MUTTER, libmutter >= $MUTTER_MIN_VERSION)
PKG_CHECK_MODULES(MUTTER_WAYLAND, [libmutter-wayland >= $MUTTER_MIN_VERSION],
[MUTTER_WAYLAND_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter-wayland`
AC_SUBST(MUTTER_WAYLAND_TYPELIB_DIR)
have_mutter_wayland=yes],
[have_mutter_wayland=no])
AM_CONDITIONAL(HAVE_MUTTER_WAYLAND, test $have_mutter_wayland != no)
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, mutter-clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
PKG_CHECK_MODULES(TRAY, mutter-clutter-1.0 gtk+-3.0)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.21.3)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.4)
PKG_CHECK_MODULES(CARIBOU, caribou-1.0 >= 0.4.8)
AC_ARG_ENABLE(browser-plugin,
[AS_HELP_STRING([--enable-browser-plugin],
@ -173,38 +182,6 @@ if test "$langinfo_ok" = "yes"; then
[Define if _NL_TIME_FIRST_WEEKDAY is available])
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
AM_PATH_GLIB_2_0()
@ -222,29 +199,11 @@ if test "$enable_man" != no; then
fi
AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no)
AX_COMPILER_FLAGS()
case "$WARN_CFLAGS" in
*-Werror*)
WARN_CFLAGS="$WARN_CFLAGS -Wno-error=deprecated-declarations"
;;
esac
GNOME_COMPILE_WARNINGS([error])
AM_CFLAGS="$AM_CFLAGS $WARN_CFLAGS"
AC_SUBST(AM_CFLAGS)
if test -z "${BROWSER_PLUGIN_DIR}"; then
BROWSER_PLUGIN_DIR="\${libdir}/mozilla/plugins"
fi
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
AC_ARG_VAR([GDBUS_CODEGEN],[the gdbus-codegen programme])
AC_PATH_PROG([GDBUS_CODEGEN],[gdbus-codegen],[])
if test -z "$GDBUS_CODEGEN"; then
AC_MSG_ERROR([gdbus-codegen not found])
fi
AC_PATH_PROG([SASS],[sass],[])
AC_CONFIG_FILES([
Makefile
data/Makefile
@ -255,6 +214,7 @@ AC_CONFIG_FILES([
docs/reference/st/Makefile
docs/reference/st/st-docs.sgml
js/Makefile
src/calendar-server/evolution-calendar.desktop.in
src/Makefile
src/gvc/Makefile
browser-plugin/Makefile
@ -263,15 +223,3 @@ AC_CONFIG_FILES([
man/Makefile
])
AC_OUTPUT
echo "
Build configuration:
Prefix: ${prefix}
Source code location: ${srcdir}
Compiler: ${CC}
Compiler Warnings: $ax_enable_compile_warnings
Support for NetworkManager: $have_networkmanager
Support for GStreamer recording: $build_recorder
"

View File

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

View File

@ -1,29 +1,9 @@
CLEANFILES =
NULL =
desktopdir=$(datadir)/applications
desktop_DATA = org.gnome.Shell.desktop gnome-shell-extension-prefs.desktop
desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
if HAVE_MUTTER_WAYLAND
desktop_DATA += gnome-shell-wayland.desktop
endif HAVE_MUTTER_WAYLAND
if HAVE_NETWORKMANAGER
desktop_DATA += org.gnome.Shell.PortalHelper.desktop
portaldir = $(datadir)/xdg-desktop-portal/portals
portal_DATA = gnome-shell.portal
servicedir = $(datadir)/dbus-1/services
service_DATA = org.gnome.Shell.PortalHelper.service
CLEANFILES += \
org.gnome.Shell.PortalHelper.service \
org.gnome.Shell.PortalHelper.desktop \
org.gnome.Shell.PortalHelper.desktop.in \
$(NULL)
endif
%.service: %.service.in
$(AM_V_GEN) sed -e "s|@libexecdir[@]|$(libexecdir)|" \
$< > $@ || rm $@
# We substitute in bindir so it works as an autostart
# file when built in a non-system prefix
@ -32,65 +12,63 @@ endif
-e "s|@VERSION[@]|$(VERSION)|" \
$< > $@ || rm $@
%.desktop:%.desktop.in
$(AM_V_GEN) $(MSGFMT) --desktop --template $(builddir)/$< \
-d $(top_srcdir)/po -o $@
@INTLTOOL_DESKTOP_RULE@
introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = \
org.gnome.Shell.Screencast.xml \
org.gnome.Shell.Screenshot.xml \
org.gnome.ShellSearchProvider.xml \
org.gnome.ShellSearchProvider2.xml \
$(NULL)
org.gnome.ShellSearchProvider2.xml
theme_sources = \
theme/gnome-shell-high-contrast.scss \
theme/gnome-shell.scss \
theme/gnome-shell-sass/_colors.scss \
theme/gnome-shell-sass/_common.scss \
theme/gnome-shell-sass/_drawing.scss \
theme/gnome-shell-sass/_high-contrast-colors.scss \
$(NULL)
dist_theme_files = \
$(theme_sources) \
theme/Gemfile \
theme/HACKING \
theme/README \
theme/gnome-shell-sass/COPYING \
theme/gnome-shell-sass/HACKING \
theme/gnome-shell-sass/NEWS \
theme/gnome-shell-sass/README \
theme/gnome-shell-sass/gnome-shell-sass.doap \
theme/parse-sass.sh \
$(NULL)
%.css: %.scss $(theme_sources)
@if test -n "$(SASS)"; then \
if $(AM_V_P); then PS4= set -x; else echo " GEN $@"; fi; \
$(SASS) --sourcemap=none -f -q --update $<; \
fi
resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/theme --generate-dependencies $(srcdir)/gnome-shell-theme.gresource.xml)
gnome-shell-theme.gresource: gnome-shell-theme.gresource.xml $(resource_files)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir)/theme $<
resourcedir = $(pkgdatadir)
resource_DATA = gnome-shell-theme.gresource
backgrounddir = $(pkgdatadir)
background_DATA = perf-background.xml
perf-background.xml: perf-background.xml.in
$(AM_V_GEN) sed -e "s|@datadir[@]|$(datadir)|" \
$< > $@ || rm $@
themedir = $(pkgdatadir)/theme
dist_theme_DATA = \
theme/calendar-arrow-left.svg \
theme/calendar-arrow-right.svg \
theme/calendar-today.svg \
theme/checkbox-focused.svg \
theme/checkbox-off-focused.svg \
theme/checkbox-off.svg \
theme/checkbox.svg \
theme/close-window.svg \
theme/close.svg \
theme/corner-ripple-ltr.png \
theme/corner-ripple-rtl.png \
theme/dash-placeholder.svg \
theme/filter-selected-ltr.svg \
theme/filter-selected-rtl.svg \
theme/gnome-shell.css \
theme/logged-in-indicator.svg \
theme/message-tray-background.png \
theme/more-results.svg \
theme/noise-texture.png \
theme/page-indicator-active.svg \
theme/page-indicator-inactive.svg \
theme/page-indicator-checked.svg \
theme/page-indicator-hover.svg \
theme/panel-button-border.svg \
theme/panel-button-highlight-narrow.svg \
theme/panel-button-highlight-wide.svg \
theme/process-working.svg \
theme/running-indicator.svg \
theme/source-button-border.svg \
theme/summary-counter.svg \
theme/toggle-off-us.svg \
theme/toggle-off-intl.svg \
theme/toggle-on-us.svg \
theme/toggle-on-intl.svg \
theme/ws-switch-arrow-up.png \
theme/ws-switch-arrow-down.png
keysdir = @GNOME_KEYBINDINGS_KEYSDIR@
keys_DATA = 50-gnome-shell-system.xml
keys_in_files = 50-gnome-shell-system.xml.in
keys_DATA = $(keys_in_files:.xml.in=.xml)
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
%.gschema.xml: %.gschema.xml.in Makefile
@INTLTOOL_XML_NOMERGE_RULE@
%.gschema.xml.in: %.gschema.xml.in.in Makefile
$(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \
$< > $@ || rm $@
@ -107,29 +85,22 @@ convertdir = $(datadir)/GConf/gsettings
convert_DATA = gnome-shell-overrides.convert
EXTRA_DIST = \
org.gnome.Shell.desktop.in.in \
gnome-shell.desktop.in.in \
gnome-shell-wayland.desktop.in.in \
gnome-shell-extension-prefs.desktop.in.in \
$(portal_DATA) \
$(introspection_DATA) \
$(menu_DATA) \
$(convert_DATA) \
$(keys_DATA) \
$(dist_theme_files) \
perf-background.xml.in \
org.gnome.Shell.PortalHelper.desktop.in.in \
org.gnome.Shell.PortalHelper.service.in \
org.gnome.shell.gschema.xml.in \
gnome-shell-theme.gresource.xml \
$(resource_files) \
$(NULL)
$(keys_in_files) \
org.gnome.shell.gschema.xml.in.in
CLEANFILES += \
org.gnome.Shell.desktop.in \
CLEANFILES = \
gnome-shell.desktop.in \
gnome-shell-wayland.desktop.in \
gnome-shell-extension-prefs.in \
$(desktop_DATA) \
$(keys_DATA) \
$(gsettings_SCHEMAS) \
perf-background.xml \
gschemas.compiled \
org.gnome.shell.gschema.valid \
gnome-shell-theme.gresource \
$(NULL)
org.gnome.shell.gschema.xml.in

View File

@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=GNOME Shell Extension Preferences
Comment=Configure GNOME Shell Extensions
_Name=GNOME Shell Extension Preferences
_Comment=Configure GNOME Shell Extensions
Exec=@bindir@/gnome-shell-extension-prefs %u
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell

View File

@ -1,4 +1,5 @@
[org.gnome.shell.overrides]
attach-modal-dialogs = /desktop/gnome/shell/windows/attach_modal_dialogs
button-layout = /desktop/gnome/shell/windows/button_layout
edge-tiling = /desktop/gnome/shell/windows/edge_tiling
workspaces-only-on-primary = /desktop/gnome/shell/windows/workspaces_only_on_primary

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell/theme">
<file>calendar-arrow-left.svg</file>
<file>calendar-arrow-right.svg</file>
<file>calendar-today.svg</file>
<file>checkbox-focused.svg</file>
<file>checkbox-off-focused.svg</file>
<file>checkbox-off.svg</file>
<file>checkbox.svg</file>
<file>close-window.svg</file>
<file>close.svg</file>
<file>corner-ripple-ltr.png</file>
<file>corner-ripple-rtl.png</file>
<file>dash-placeholder.svg</file>
<file>filter-selected-ltr.svg</file>
<file>filter-selected-rtl.svg</file>
<file>gnome-shell.css</file>
<file>gnome-shell-high-contrast.css</file>
<file>logged-in-indicator.svg</file>
<file>more-results.svg</file>
<file>no-events.svg</file>
<file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>page-indicator-active.svg</file>
<file>page-indicator-inactive.svg</file>
<file>page-indicator-checked.svg</file>
<file>page-indicator-hover.svg</file>
<file>process-working.svg</file>
<file>running-indicator.svg</file>
<file>source-button-border.svg</file>
<file>summary-counter.svg</file>
<file>toggle-off-us.svg</file>
<file>toggle-off-intl.svg</file>
<file>toggle-off-hc.svg</file>
<file>toggle-on-us.svg</file>
<file>toggle-on-intl.svg</file>
<file>toggle-on-hc.svg</file>
<file>ws-switch-arrow-up.png</file>
<file>ws-switch-arrow-down.png</file>
</gresource>
</gresources>

View File

@ -0,0 +1,15 @@
[Desktop Entry]
Type=Application
_Name=GNOME Shell (wayland compositor)
_Comment=Window management and application launching
Exec=@bindir@/mutter-launch -- gnome-shell-wayland --wayland
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=@VERSION@
Categories=GNOME;GTK;Core;
OnlyShowIn=GNOME;
NoDisplay=true
X-GNOME-Autostart-Phase=DisplayServer
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=false

View File

@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=GNOME Shell
Comment=Window management and application launching
_Name=GNOME Shell
_Comment=Window management and application launching
Exec=@bindir@/gnome-shell
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
@ -10,7 +10,7 @@ X-GNOME-Bugzilla-Version=@VERSION@
Categories=GNOME;GTK;Core;
OnlyShowIn=GNOME;
NoDisplay=true
X-GNOME-Autostart-Phase=DisplayServer
X-GNOME-Autostart-Phase=WindowManager
X-GNOME-Provides=panel;windowmanager;
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=false

View File

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

View File

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

View File

@ -1,3 +0,0 @@
[D-BUS Service]
Name=org.gnome.Shell.PortalHelper
Exec=@libexecdir@/gnome-shell-portal-helper

View File

@ -38,6 +38,7 @@
<method name="Screencast">
<arg type="s" direction="in" name="file_template"/>
<arg type="a{sv}" direction="in" name="options"/>
<arg type="b" direction="in" name="flash"/>
<arg type="b" direction="out" name="success"/>
<arg type="s" direction="out" name="filename_used"/>
</method>

View File

@ -3,40 +3,31 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="development-tools" type="b">
<default>true</default>
<summary>
<_summary>
Enable internal tools useful for developers and testers from Alt-F2
</summary>
<description>
</_summary>
<_description>
Allows access to internal debugging and monitoring tools
using the Alt-F2 dialog.
</description>
</_description>
</key>
<key name="enabled-extensions" type="as">
<default>[]</default>
<summary>UUIDs of extensions to enable</summary>
<description>
<_summary>UUIDs of extensions to enable</_summary>
<_description>
GNOME Shell extensions have a UUID property; this key lists extensions
which should be loaded. Any extension that wants to be loaded needs
to be in this list. You can also manipulate this list with the
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
</description>
</key>
<key name="disable-extension-version-validation" type="b">
<default>true</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>
</_description>
</key>
<key name="favorite-apps" type="as">
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<summary>List of desktop file IDs for favorite applications</summary>
<description>
<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>
<_description>
The applications corresponding to these identifiers
will be displayed in the favorites area.
</description>
</_description>
</key>
<key name="app-picker-view" type="u">
<default>0</default>
@ -47,82 +38,83 @@
</key>
<key name="command-history" type="as">
<default>[]</default>
<summary>History for command (Alt-F2) dialog</summary>
<_summary>History for command (Alt-F2) dialog</_summary>
</key>
<key name="looking-glass-history" type="as">
<default>[]</default>
<!-- Translators: looking glass is a debugger and inspector tool, see https://wiki.gnome.org/Projects/GnomeShell/LookingGlass -->
<summary>History for the looking glass dialog</summary>
<_summary>History for the looking glass dialog</_summary>
</key>
<key name="always-show-log-out" type="b">
<default>false</default>
<summary>Always show the 'Log out' menu item in the user menu.</summary>
<description>
<_summary>Always show the 'Log out' menu item in the user menu.</_summary>
<_description>
This key overrides the automatic hiding of the 'Log out'
menu item in single-user, single-session situations.
</description>
</_description>
</key>
<key name="remember-mount-password" type="b">
<default>false</default>
<summary>Whether to remember password for mounting encrypted or remote filesystems</summary>
<description>
<_summary>Whether to remember password for mounting encrypted or remote filesystems</_summary>
<_description>
The shell will request a password when an encrypted device or a
remote filesystem is mounted. If the password can be saved for
future use a 'Remember Password' checkbox will be present.
This key sets the default state of the checkbox.
</description>
</key>
<key name="had-bluetooth-devices-setup" type="b">
<default>false</default>
<summary>Whether the default Bluetooth adapter had set up devices associated to it</summary>
<description>
The shell will only show a Bluetooth menu item if a Bluetooth
adapter is powered, or if there were devices set up associated
with the default adapter. This will be reset if the default
adapter is ever seen not to have devices associated to it.
</description>
</_description>
</key>
<child name="calendar" schema="org.gnome.shell.calendar"/>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
</schema>
<schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="show-weekdate" type="b">
<default>false</default>
<_summary>Show the week date in the calendar</_summary>
<_description>
If true, display the ISO week date in the calendar.
</_description>
</key>
</schema>
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
gettext-domain="@GETTEXT_PACKAGE@">
<key name="open-application-menu" type="as">
<default>["&lt;Super&gt;F10"]</default>
<summary>Keybinding to open the application menu</summary>
<description>
<_summary>Keybinding to open the application menu</_summary>
<_description>
Keybinding to open the application menu.
</description>
</_description>
</key>
<key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default>
<summary>Keybinding to open the "Show Applications" view</summary>
<description>
<_summary>Keybinding to open the "Show Applications" view</_summary>
<_description>
Keybinding to open the "Show Applications" view of the Activities
Overview.
</description>
</_description>
</key>
<key name="toggle-overview" type="as">
<default>["&lt;Super&gt;s"]</default>
<summary>Keybinding to open the overview</summary>
<description>
<_summary>Keybinding to open the overview</_summary>
<_description>
Keybinding to open the Activities Overview.
</description>
</_description>
</key>
<key name="toggle-message-tray" type="as">
<default>["&lt;Super&gt;v","&lt;Super&gt;m"]</default>
<summary>Keybinding to toggle the visibility of the notification list</summary>
<description>
Keybinding to toggle the visibility of the notification list.
</description>
<default>["&lt;Super&gt;m"]</default>
<_summary>Keybinding to toggle the visibility of the message tray</_summary>
<_description>
Keybinding to toggle the visibility of the message tray.
</_description>
</key>
<key name="focus-active-notification" type="as">
<default>["&lt;Super&gt;n"]</default>
<summary>Keybinding to focus the active notification</summary>
<description>
<_summary>Keybinding to focus the active notification</_summary>
<_description>
Keybinding to focus the active notification.
</description>
</_description>
</key>
<key name="pause-resume-tweens" type="as">
<default>[]</default>
@ -135,10 +127,10 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="keyboard-type" type="s">
<default>'touch'</default>
<summary>Which keyboard to use</summary>
<description>
<_summary>Which keyboard to use</_summary>
<_description>
The type of keyboard to use.
</description>
</_description>
</key>
</schema>
@ -165,12 +157,12 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="app-icon-mode" enum="org.gnome.shell.window-switcher.AppIconMode">
<default>'both'</default>
<summary>The application icon mode.</summary>
<description>
<_summary>The application icon mode.</_summary>
<_description>
Configures how the windows are shown in the switcher. Valid possibilities
are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-only'
(shows only the application icon) or 'both'.
</description>
</_description>
</key>
<key type="b" name="current-workspace-only">
<default>true</default>
@ -186,43 +178,52 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="attach-modal-dialogs" type="b">
<default>true</default>
<summary>Attach modal dialog to the parent window</summary>
<description>
<_summary>Attach modal dialog to the parent window</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running
GNOME Shell.
</description>
</_description>
</key>
<key name="button-layout" type="s">
<default>":close"</default>
<_summary>Arrangement of buttons on the titlebar</_summary>
<_description>
This key overrides the key in org.gnome.desktop.wm.preferences when
running GNOME Shell.
</_description>
</key>
<key name="edge-tiling" type="b">
<default>true</default>
<summary>Enable edge tiling when dropping windows on screen edges</summary>
<description>
<_summary>Enable edge tiling when dropping windows on screen edges</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="dynamic-workspaces" type="b">
<default>true</default>
<summary>Workspaces are managed dynamically</summary>
<description>
<_summary>Workspaces are managed dynamically</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="workspaces-only-on-primary" type="b">
<default>true</default>
<summary>Workspaces only on primary monitor</summary>
<description>
<_summary>Workspaces only on primary monitor</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="focus-change-on-pointer-rest" type="b">
<default>true</default>
<summary>Delay focus changes in mouse mode until the pointer stops moving</summary>
<description>
<_summary>Delay focus changes in mouse mode until the pointer stops moving</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
</schema>
</schemalist>

View File

@ -1,31 +0,0 @@
<!-- With an animated background, performance will differ depending on whether
one layer or two layers are being blended together. This messes up our
benchmarks. We could just benchmark a single image, but since blended
images are present for much of the day with the GNOME default background,
we want to make sure that also performs well; for that reason we ship
an "animated" background that animates super-slowly to use during
performance tests; it will be in the blended state until 2030. -->
<background>
<starttime>
<year>1990</year>
<month>1</month>
<day>1</day>
<hour>0</hour>
<minute>00</minute>
<second>00</second>
</starttime>
<!-- One transition that takes 40 years -->
<transition type="overlay">
<duration>1261440000.0</duration>
<from>@datadir@/backgrounds/gnome/adwaita-morning.jpg</from>
<to>@datadir@/backgrounds/gnome/adwaita-day.jpg</to>
</transition>
<!-- A single slide doesn't work, so another slide for 1 minute after 40 years -->
<static>
<duration>60</duration>
<file>/usr/share/backgrounds/gnome/Sandstone.jpg</file>
</static>
</background>

View File

@ -1 +0,0 @@
gem "sass", "~> 3.4.0"

View File

@ -1,3 +0,0 @@
To generate the css files, from the project directory:
sass --sourcemap=none --update .

View File

@ -1,36 +0,0 @@
Summary
-------
* Do not edit the CSS directly, edit the source SCSS files and process them with SASS (running
`make` should do that when you have the required software installed, as described below;
run `/.parse-sass.sh` manually if it doesn't)
* To be able to use the lates/adequate version of sass, install ruby, gem, sass & bundle.
On Fedora F20, this is done with `sudo dnf install rubygems && gem install bundle && bundle install`
from the same directory this README resides in.
How to tweak the theme
----------------------
Adwaita is a complex theme, so to keep it maintainable it's written and processed in SASS, the
generated CSS is then transformed into a gresource file during gtk build and used at runtime in a
non-legible or editable form.
It is very likely your change will happen in the _common.scss file. That's where all the widget
selectors are defined. Here's a rundown of the "supporting" stylesheets, that are unlikely to be the
right place for a drive by stylesheet fix:
_colors.scss - global color definitions. We keep the number of defined colors to a necessary minimum,
most colors are derived from a handful of basics. It is an exact copy of the gtk+
counterpart. Light theme is used for the classic theme and dark is for GNOME3 shell
default.
_drawing.scss - drawing helper mixings/functions to allow easier definition of widget drawing under
specific context. This is why Adwaita isn't 15000 LOC.
_common.scss - actual definitions of style for each widget. This is where you are likely to add/remove
your changes.
You can read about SASS at http://sass-lang.com/documentation/. Once you make your changes to the
_common.scss file, you can either run the ./parse-sass.sh script or keep SASS watching for changes as you
edit. This is done by running `bundle exec sass --watch --sourcemap=none .` If sass is out of date, or is
missing, you can install it with `bundle install`.

View File

@ -10,11 +10,11 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
width="29"
height="29"
id="svg10621"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:version="0.48.2 r9819"
sodipodi:docname="calendar-today.svg">
<defs
id="defs10623">
@ -118,6 +118,17 @@
fx="51"
fy="30"
r="42" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient34508-1-3"
id="radialGradient3113"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
cx="51"
cy="30"
fx="51"
fy="30"
r="42" />
</defs>
<sodipodi:namedview
id="base"
@ -126,23 +137,22 @@
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-23.537329"
inkscape:cy="-31.442864"
inkscape:zoom="15.839192"
inkscape:cx="20.652108"
inkscape:cy="11.839084"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="2133"
inkscape:window-height="1241"
inkscape:window-x="238"
inkscape:window-y="88"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false">
inkscape:window-width="1280"
inkscape:window-height="741"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true">
<inkscape:grid
type="xygrid"
id="grid3109"
@ -159,7 +169,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -167,12 +177,28 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-469.08263,-537.99307)">
<circle
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:0.23756906;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="path7305"
cx="481.57138"
cy="559.4649"
r="1.5" />
transform="translate(-469.08263,-532.99307)">
<path
sodipodi:type="arc"
style="opacity:0.4625;color:#000000;fill:url(#radialGradient3113);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path34506-3"
sodipodi:cx="51"
sodipodi:cy="30"
sodipodi:rx="42"
sodipodi:ry="16"
d="M 9,29.999999 A 42,16 0 0 1 93,30 l -42,0 z"
sodipodi:start="3.1415927"
sodipodi:end="6.2831853"
transform="matrix(0.43692393,0,0,1.3783114,461.29951,517.6437)"
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<rect
style="fill:#ffffff;fill-opacity:0.50196078;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
id="rect2996"
width="31"
height="3"
x="468.08264"
y="558.99304" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -14,7 +14,7 @@
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.5 r10040"
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox.svg">
<defs
id="defs3201">
@ -132,54 +132,51 @@
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8"
id="linearGradient11811"
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)"
x1="63.568954"
y1="127.16142"
x2="63.568954"
y2="152.6618" />
id="linearGradient14219-6"
xlink:href="#linearGradient15404-9"
inkscape:collect="always" />
<linearGradient
id="linearGradient5581-5-2-4-6-8-7-35-8">
id="linearGradient15404-9"
inkscape:collect="always">
<stop
id="stop5583-0-92-8-0-7-6-5-1"
id="stop15406-6"
offset="0"
style="stop-color:#454c4c;stop-opacity:1;" />
style="stop-color:#515151;stop-opacity:1" />
<stop
style="stop-color:#393f3f;stop-opacity:1;"
offset="0.40000001"
id="stop5585-4-7-2-7-9-9-92-0" />
<stop
id="stop5587-6-7-2-0-3-1-21-5"
id="stop15408-7"
offset="1"
style="stop-color:#2d3232;stop-opacity:1;" />
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#a2a2a2"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="22.627417"
inkscape:cx="9.6447897"
inkscape:cy="12.591409"
inkscape:zoom="1"
inkscape:cx="71.516955"
inkscape:cy="5.8710559"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="184"
inkscape:window-y="233"
inkscape:window-x="2635"
inkscape:window-y="226"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="true">
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
@ -206,56 +203,87 @@
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
style="display:inline"
id="use5671"
transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)">
<rect
transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)"
rx="4.4136767"
y="125.3458"
x="50.440369"
height="29.154205"
width="29.559635"
id="rect11803"
style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#3465a4;stroke-width:1.54426003000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
ry="4.4233952" />
<path
inkscape:connector-curvature="0"
id="path11809"
d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
<path
sodipodi:nodetypes="csssscssc"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
id="path11867"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path11869"
d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
transform="matrix(0.80230061,0,0,0.80230061,-87.624044,-453.10297)"
id="g14586-0"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9-6"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4-9"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219-6);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.24833274;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="1.0052766"
ry="1.0052764" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886-5"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new" />
</g>
<g
transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)"
id="g14586">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="enable-background:new" />
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="display:inline;enable-background:new">
<path
style="fill:none;stroke:url(#linearGradient5891-0-4);stroke-width:7.11431503;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
id="path5835"
inkscape:path-effect="#path-effect5837-4-6"
inkscape:original-d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
inkscape:original-d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
inkscape:path-effect="#path-effect5837-4-6"
id="path5880"
d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
style="fill:none;stroke:#4787c8;stroke-width:3.55715752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#7ea7d3;stroke-width:1.18571913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 197.45937,240.47455 c -0.17828,-0.29362 -0.20087,-0.67548 -0.0603,-0.98892 0.14055,-0.31344 0.43739,-0.54812 0.77144,-0.62817 0.33405,-0.08 0.69314,-0.01 0.99635,0.15175 0.30321,0.16144 0.55146,0.40727 0.79165,0.65284 l 3.66429,3.74643 12.87946,-12.98973 c 0.20796,-0.20974 0.42306,-0.41969 0.68548,-0.55522 0.26242,-0.13553 0.57293,-0.19052 0.85827,-0.11426 0.14267,0.0381 0.27708,0.10787 0.38874,0.20452 0.11167,0.0966 0.20021,0.22004 0.25479,0.35726 0.0546,0.13722 0.075,0.28793 0.0585,0.43468 -0.0165,0.14674 -0.07,0.28919 -0.15422,0.41052"
id="path5882"
inkscape:path-effect="#path-effect5884-4-7"
inkscape:original-d="m 197.45937,240.47455 c 0.65604,-0.56057 2.02485,-1.34847 2.49911,-0.8125 l 3.66429,3.74643 12.87946,-12.98973 c 0.6875,-0.6875 2.09152,0.7375 2.09152,0.7375"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccc" />
</g>
</g>
<rect
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect17347"
width="21.943846"
height="21.943846"
x="342.29913"
y="521.58435" />
<path
inkscape:connector-curvature="0"
style="opacity:0.8;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 359.97505,524.8252 -7.88606,7.71465 -2.57155,-2.57155 -2.91442,-0.0427 0,2.35727 4.02875,3.98587 c 0.80342,0.80309 2.111,0.80309 2.91442,0 l 8.18609,-8.22894 0,-0.38573 c 0,-1.24128 0.19944,-1.76801 -0.82915,-2.29836 z"
id="rect5147-9-1-5-7-6-5-8-7"
sodipodi:nodetypes="ccccccccscc" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:sans-serif;-inkscape-font-specification:sans-serif"
d="m 361.65223,524.52745 -9.5602,9.36735 -2.56345,-2.56344 -2.92846,-0.0214 0.0153,2.32639 4.02203,4.02206 c 0.80341,0.80309 2.10565,0.80309 2.90906,0 l 10.95049,-11.05765 0.003,-2.1502 z"
id="path12830-4-17-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -14,10 +14,22 @@
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.5 r10040"
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox-off.svg">
<defs
id="defs3201">
<linearGradient
id="linearGradient15404"
inkscape:collect="always">
<stop
id="stop15406"
offset="0"
style="stop-color:#515151;stop-opacity:1" />
<stop
id="stop15408"
offset="1"
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
@ -44,6 +56,16 @@
effect="spiro"
id="path-effect5884-4-7"
is_visible="true" />
<linearGradient
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
id="linearGradient14219"
xlink:href="#linearGradient15404"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient10013-4-63-6">
@ -88,55 +110,30 @@
id="linearGradient15376"
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8"
id="linearGradient11811"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)"
x1="63.568954"
y1="127.16142"
x2="63.568954"
y2="152.6618" />
<linearGradient
id="linearGradient5581-5-2-4-6-8-7-35-8">
<stop
id="stop5583-0-92-8-0-7-6-5-1"
offset="0"
style="stop-color:#454c4c;stop-opacity:1;" />
<stop
style="stop-color:#393f3f;stop-opacity:1;"
offset="0.40000001"
id="stop5585-4-7-2-7-9-9-92-0" />
<stop
id="stop5587-6-7-2-0-3-1-21-5"
offset="1"
style="stop-color:#2d3232;stop-opacity:1;" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#a2a2a2"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="5.6568542"
inkscape:cx="19.79113"
inkscape:cy="11.232334"
inkscape:zoom="1"
inkscape:cx="6.1225392"
inkscape:cy="3.6003241"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="184"
inkscape:window-y="233"
inkscape:window-x="2116"
inkscape:window-y="261"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="true">
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
@ -163,44 +160,39 @@
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
style="display:inline"
id="use5671"
transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)">
<rect
transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)"
rx="4.4136767"
y="125.3458"
x="50.440369"
height="29.154205"
width="29.559635"
id="rect11803"
style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#3465a4;stroke-width:1.54426003000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
ry="4.4233952" />
<path
inkscape:connector-curvature="0"
id="path11809"
d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
<path
sodipodi:nodetypes="csssscssc"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
id="path11867"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path11869"
d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
transform="matrix(0.80230061,0,0,0.80230061,-87.624044,-453.10297)"
id="g14586"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="stroke-width:1.18754292;stroke-miterlimit:4;stroke-dasharray:none;enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.24833274;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="1.0052766"
ry="1.0052764" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="stroke-width:2.3714385;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new" />
</g>
<rect
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect17347"
width="21.943846"
height="21.943846"
x="342.29913"
y="521.58435" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -14,10 +14,22 @@
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="checkbox-focused.svg">
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox.svg">
<defs
id="defs3201">
<linearGradient
id="linearGradient15404"
inkscape:collect="always">
<stop
id="stop15406"
offset="0"
style="stop-color:#515151;stop-opacity:1" />
<stop
id="stop15408"
offset="1"
style="stop-color:#292929;stop-opacity:1" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
@ -32,6 +44,27 @@
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5872-5-1"
id="linearGradient5891-0-4"
gradientUnits="userSpaceOnUse"
x1="205.84143"
y1="246.7094"
x2="206.74803"
y2="231.24142" />
<linearGradient
inkscape:collect="always"
id="linearGradient5872-5-1">
<stop
style="stop-color:#0b2e52;stop-opacity:1"
offset="0"
id="stop5874-4-4" />
<stop
style="stop-color:#1862af;stop-opacity:1"
offset="1"
id="stop5876-0-5" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect5837-4-6"
@ -44,6 +77,16 @@
effect="spiro"
id="path-effect5884-4-7"
is_visible="true" />
<linearGradient
y2="-388.72955"
x2="-93.031357"
y1="-396.34738"
x1="-93.031357"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.685418)"
gradientUnits="userSpaceOnUse"
id="linearGradient14219"
xlink:href="#linearGradient15404"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient10013-4-63-6">
@ -88,55 +131,30 @@
id="linearGradient15376"
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8"
id="linearGradient11811"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)"
x1="63.568954"
y1="127.16142"
x2="63.568954"
y2="152.6618" />
<linearGradient
id="linearGradient5581-5-2-4-6-8-7-35-8">
<stop
id="stop5583-0-92-8-0-7-6-5-1"
offset="0"
style="stop-color:#454c4c;stop-opacity:1;" />
<stop
style="stop-color:#393f3f;stop-opacity:1;"
offset="0.40000001"
id="stop5585-4-7-2-7-9-9-92-0" />
<stop
id="stop5587-6-7-2-0-3-1-21-5"
offset="1"
style="stop-color:#2d3232;stop-opacity:1;" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#a2a2a2"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="9.6447897"
inkscape:cy="12.591409"
inkscape:zoom="4"
inkscape:cx="71.247925"
inkscape:cy="33.339093"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="184"
inkscape:window-y="233"
inkscape:window-x="2116"
inkscape:window-y="261"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="true">
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
@ -163,44 +181,38 @@
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
style="display:inline"
id="use5671"
transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)">
<rect
transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)"
rx="4.4136767"
y="125.3458"
x="50.440369"
height="29.154205"
width="29.559635"
id="rect11803"
style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#1c1f1f;stroke-width:1.54426003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
ry="4.4233952" />
<path
inkscape:connector-curvature="0"
id="path11809"
d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
<path
sodipodi:nodetypes="csssscssc"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
id="path11867"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path11869"
d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)"
id="g14586">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#868686;stroke-width:0.59377144999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="0.95632279"
ry="0.95632273" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="display:inline;enable-background:new" />
</g>
<rect
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect17347"
width="21.943846"
height="21.943846"
x="342.29913"
y="521.58435" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -14,8 +14,8 @@
height="22"
id="svg3199"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="checkbox.svg">
inkscape:version="0.48.1 r9760"
sodipodi:docname="checkbox-focused.svg">
<defs
id="defs3201">
<linearGradient
@ -131,55 +131,30 @@
id="linearGradient15376"
xlink:href="#linearGradient10597-5"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5581-5-2-4-6-8-7-35-8"
id="linearGradient11811"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.0317573,0,0,1.0053174,-102.66338,-0.82153381)"
x1="63.568954"
y1="127.16142"
x2="63.568954"
y2="152.6618" />
<linearGradient
id="linearGradient5581-5-2-4-6-8-7-35-8">
<stop
id="stop5583-0-92-8-0-7-6-5-1"
offset="0"
style="stop-color:#454c4c;stop-opacity:1;" />
<stop
style="stop-color:#393f3f;stop-opacity:1;"
offset="0.40000001"
id="stop5585-4-7-2-7-9-9-92-0" />
<stop
id="stop5587-6-7-2-0-3-1-21-5"
offset="1"
style="stop-color:#2d3232;stop-opacity:1;" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#a2a2a2"
pagecolor="#000000"
bordercolor="#2d2d2d"
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-0.17876005"
inkscape:cy="11.944326"
inkscape:cx="64.516955"
inkscape:cy="13.871056"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1375"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="2635"
inkscape:window-y="226"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="true">
showborder="false">
<inkscape:grid
type="xygrid"
id="grid14843"
@ -196,7 +171,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@ -206,56 +181,63 @@
id="layer1"
transform="translate(-342.5,-521.36218)">
<g
style="display:inline"
id="use5671"
transform="matrix(1.3594109,0,0,1.3564242,319.2059,481.99447)">
<rect
transform="matrix(0.47304779,0,0,0.4807373,-6.3607039,-29.396216)"
rx="4.4136767"
y="125.3458"
x="50.440369"
height="29.154205"
width="29.559635"
id="rect11803"
style="color:#000000;fill:url(#linearGradient11811);fill-opacity:1;stroke:#1c1f1f;stroke-width:1.54426003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
ry="4.4233952" />
<path
inkscape:connector-curvature="0"
id="path11809"
d="m 17.87105,33.844107 0,-0.773112 c 0,-1.031264 0.807171,-1.836142 1.811982,-1.836142 l 9.612456,0 c 1.004811,0 1.787822,0.804878 1.787822,1.836142 l 0,0.773112 c 0,-1.031264 -0.783011,-1.836142 -1.787822,-1.836142 l -9.612456,0 c -1.004811,0 -1.811982,0.804878 -1.811982,1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
<path
sodipodi:nodetypes="csssscssc"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
d="m 17.87105,41.158551 0,0.773112 c 0,1.031264 0.807171,1.836142 1.811982,1.836142 l 9.612456,0 c 1.004811,0 1.787822,-0.804878 1.787822,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
id="path11867"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path11869"
d="m 17.87105,41.895784 0,0.773112 c 0,1.031264 0.644622,1.836142 1.649433,1.836142 l 10.067593,0 c 1.004811,0 1.495234,-0.804878 1.495234,-1.836142 l 0,-0.773112 c 0,1.031264 -0.783011,1.836142 -1.787822,1.836142 l -9.612456,0 c -1.004811,0 -1.811982,-0.804878 -1.811982,-1.836142 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.15;color:#000000;fill:#000000;fill-opacity:0.85253451;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:nodetypes="csssscssc" />
transform="matrix(0.84337,0,0,0.84337,-110.16632,-503.56182)"
id="g14586">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="matrix(1.9969286,0,0,1.9969286,-397.05491,877.00482)"
id="g15291-9"
style="display:inline;enable-background:new">
<g
transform="translate(877.50354,-102.83507)"
id="g16853-4"
style="enable-background:new">
<rect
transform="scale(1,-1)"
style="color:#000000;fill:url(#linearGradient14219);fill-opacity:1;fill-rule:nonzero;stroke:#868686;stroke-width:0.59377144999999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect6506-6"
width="11.281681"
height="11.26221"
x="-409.59354"
y="-284.40115"
rx="0.95632279"
ry="0.95632273" />
</g>
</g>
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/SparkleShare/gnome-mockups/boxes/interactive/img/checkbox-on.png"
transform="translate(343.99999,987.99997)"
id="g5886"
style="display:inline;enable-background:new">
<path
style="fill:none;stroke:url(#linearGradient5891-0-4);stroke-width:7.11431503;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
id="path5835"
inkscape:path-effect="#path-effect5837-4-6"
inkscape:original-d="m 198.5,240 5.25,5.25 13.98616,-14.43081"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
inkscape:original-d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
inkscape:path-effect="#path-effect5837-4-6"
id="path5880"
d="m 198.5,240 5.25,5.25 13.91205,-14.31964"
style="fill:none;stroke:#4787c8;stroke-width:3.55715752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#7ea7d3;stroke-width:1.18571913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 197.45937,240.47455 c -0.17828,-0.29362 -0.20087,-0.67548 -0.0603,-0.98892 0.14055,-0.31344 0.43739,-0.54812 0.77144,-0.62817 0.33405,-0.08 0.69314,-0.01 0.99635,0.15175 0.30321,0.16144 0.55146,0.40727 0.79165,0.65284 l 3.66429,3.74643 12.87946,-12.98973 c 0.20796,-0.20974 0.42306,-0.41969 0.68548,-0.55522 0.26242,-0.13553 0.57293,-0.19052 0.85827,-0.11426 0.14267,0.0381 0.27708,0.10787 0.38874,0.20452 0.11167,0.0966 0.20021,0.22004 0.25479,0.35726 0.0546,0.13722 0.075,0.28793 0.0585,0.43468 -0.0165,0.14674 -0.07,0.28919 -0.15422,0.41052"
id="path5882"
inkscape:path-effect="#path-effect5884-4-7"
inkscape:original-d="m 197.45937,240.47455 c 0.65604,-0.56057 2.02485,-1.34847 2.49911,-0.8125 l 3.66429,3.74643 12.87946,-12.98973 c 0.6875,-0.6875 2.09152,0.7375 2.09152,0.7375"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccc" />
</g>
</g>
<rect
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect17347"
width="21.943846"
height="21.943846"
x="342.29913"
y="521.58435" />
<path
inkscape:connector-curvature="0"
style="opacity:0.8;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 359.97505,524.8252 -7.88606,7.71465 -2.57155,-2.57155 -2.91442,-0.0427 0,2.35727 4.02875,3.98587 c 0.80342,0.80309 2.111,0.80309 2.91442,0 l 8.18609,-8.22894 0,-0.38573 c 0,-1.24128 0.19944,-1.76801 -0.82915,-2.29836 z"
id="rect5147-9-1-5-7-6-5-8-7"
sodipodi:nodetypes="ccccccccscc" />
<path
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:sans-serif;-inkscape-font-specification:sans-serif"
d="m 361.65223,524.52745 -9.5602,9.36735 -2.56345,-2.56344 -2.92846,-0.0214 0.0153,2.32639 4.02203,4.02206 c 0.80341,0.80309 2.10565,0.80309 2.90906,0 l 10.95049,-11.05765 0.003,-2.1502 z"
id="path12830-4-17-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
@import "gnome-shell-sass/_high-contrast-colors"; //use gtk colors
@import "gnome-shell-sass/_drawing";
@import "gnome-shell-sass/_common";
//force symbolic icons
stage {
-st-icon-style: symbolic;
}
.toggle-switch { width: 48px; }
.toggle-switch-us, .toggle-switch-intl {
background-image: url("resource:///org/gnome/shell/theme/toggle-off-hc.svg");
&:checked { background-image: url("resource:///org/gnome/shell/theme/toggle-on-hc.svg"); }
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
$variant: 'dark';
@import "gnome-shell-sass/_colors"; //use gtk colors
@import "gnome-shell-sass/_drawing";
@import "gnome-shell-sass/_common";

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,119 +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="64px"
height="64px"
id="svg3471"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="New document 5">
<defs
id="defs3473" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="32"
inkscape:cy="32"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1461"
inkscape:window-height="772"
inkscape:window-x="37"
inkscape:window-y="64"
inkscape:window-maximized="0" />
<metadata
id="metadata3476">
<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">
<g
transform="matrix(4,0,0,4,1.9999997,2.3636364)"
id="g19145"
style="fill:#bebebe;fill-opacity:1;display:inline">
<g
id="g19147"
inkscape:label="status"
style="fill:#bebebe;fill-opacity:1;display:inline"
transform="translate(-541.0002,-301)" />
<g
style="fill:#bebebe;fill-opacity:1"
id="g19149"
inkscape:label="devices"
transform="translate(-541.0002,-301)" />
<g
style="fill:#bebebe;fill-opacity:1"
id="g19151"
inkscape:label="apps"
transform="translate(-541.0002,-301)" />
<g
style="fill:#bebebe;fill-opacity:1"
id="g19153"
inkscape:label="places"
transform="translate(-541.0002,-301)" />
<g
style="fill:#bebebe;fill-opacity:1"
id="g19155"
inkscape:label="mimetypes"
transform="translate(-541.0002,-301)">
<path
inkscape:connector-curvature="0"
d="m 543.0002,301 c -1.05237,0 -2,0.84508 -2,1.9375 l 0,11.125 c 0,1.09242 0.94763,1.9375 2,1.9375 l 11,0 c 1.05237,0 2,-0.84508 2,-1.9375 l 0,-11.125 c 0,-1.09242 -0.94763,-1.9375 -2,-1.9375 l -11,0 z m 0,5 3.03125,0 0,2 -3.03125,0 0,-2 z m 4.03125,0 2.96875,0 0,2 -2.96875,0 0,-2 z m 3.96875,0 3,0 0,2 -3,0 0,-2 z m -8,3 3.03125,0 0,2 -3.03125,0 0,-2 z m 4.03125,0 2.96875,0 0,2 -2.96875,0 0,-2 z m 3.96875,0 3,0 0,2 -3,0 0,-2 z m -8,3 3.03125,0 0,2 -3.03125,0 0,-2 z m 4.03125,0 2.96875,0 0,2 -2.96875,0 0,-2 z m 3.96875,0 3,0 0,2 -3,0 0,-2 z"
id="path19157"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Sans;-inkscape-font-specification:Sans" />
<rect
height="1.9999993"
id="rect19159"
style="opacity:0.35;color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
width="2.9999993"
x="551.00018"
y="309" />
</g>
<g
id="g19161"
inkscape:label="emblems"
style="fill:#bebebe;fill-opacity:1;display:inline"
transform="translate(-541.0002,-301)" />
<g
id="g19163"
inkscape:label="emotes"
style="fill:#bebebe;fill-opacity:1;display:inline"
transform="translate(-541.0002,-301)" />
<g
id="g19165"
inkscape:label="categories"
style="fill:#bebebe;fill-opacity:1;display:inline"
transform="translate(-541.0002,-301)" />
<g
id="g19167"
inkscape:label="actions"
style="fill:#bebebe;fill-opacity:1;display:inline"
transform="translate(-541.0002,-301)" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,114 +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="64px"
height="64px"
id="svg3393"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="New document 2">
<defs
id="defs3395" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="32"
inkscape:cy="32"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="697"
inkscape:window-height="613"
inkscape:window-x="100"
inkscape:window-y="77"
inkscape:window-maximized="0" />
<metadata
id="metadata3398">
<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">
<g
style="display:inline"
transform="matrix(4,0,0,4,0.29733827,-0.35415646)"
id="g19245">
<g
id="g19247"
inkscape:label="status"
style="display:inline"
transform="translate(-323.02908,-649.02581)" />
<g
id="g19249"
inkscape:label="devices"
transform="translate(-323.02908,-649.02581)" />
<g
id="g19251"
inkscape:label="apps"
transform="translate(-323.02908,-649.02581)">
<path
inkscape:connector-curvature="0"
d="m 331.9377,653 c 0.0187,0.16677 0.0625,0.32822 0.0625,0.5 0,2.48528 -2.01472,4.5 -4.5,4.5 -0.11769,0 -0.22834,-0.0224 -0.34375,-0.0312 l 0,2.21875 c 0,1.00412 0.80838,1.8125 1.8125,1.8125 l 1.54511,-5e-5 2,2.04688 2.0625,-2.04688 1.61114,0 c 1.00413,0 1.8125,-0.80838 1.8125,-1.8125 l 0,-5.375 c 0,-1.00412 -0.80837,-1.8125 -1.8125,-1.8125 z"
id="path19253"
sodipodi:nodetypes="csscsscccssssc"
style="opacity:0.5;color:#000000;fill:#c3c3c3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
d="m 327.5002,650 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m -0.53125,1 1.03125,0 -0.0625,1.375 a 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.125,0.125 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 l 1.15625,-0.75 0.5,0.90625 -1.21875,0.625 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0.0937 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0625 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0312 l 1.25,0.625 -0.53125,0.90625 -1.15625,-0.781 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,0 0.19951718,0.19951718 0 0 0 -0.125,0.0937 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0,0.0625 l 0.0625,1.3751 -1.03125,0 0.0937,-1.375 a 0.19951718,0.19951718 0 0 0 -0.0312,-0.0937 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0937,0.0312 l -1.1875,0.78125 -0.5,-0.90625 1.25,-0.625 a 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0312,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 l -1.25,-0.625 0.5,-0.90625 1.1875,0.75 a 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 L 326.96895,651 z"
id="path19255"
style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
id="g19257"
inkscape:label="places"
transform="translate(-323.02908,-649.02581)" />
<g
id="g19259"
inkscape:label="mimetypes"
transform="translate(-323.02908,-649.02581)" />
<g
id="g19261"
inkscape:label="emblems"
style="display:inline"
transform="translate(-323.02908,-649.02581)" />
<g
id="g19263"
inkscape:label="emotes"
style="display:inline"
transform="translate(-323.02908,-649.02581)" />
<g
id="g19265"
inkscape:label="categories"
style="display:inline"
transform="translate(-323.02908,-649.02581)" />
<g
id="g19267"
inkscape:label="actions"
style="display:inline"
transform="translate(-323.02908,-649.02581)" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -0,0 +1,74 @@
<?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="17"
height="10"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="panel-button-border.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="44.8"
inkscape:cx="8.6594891"
inkscape:cy="5.7029946"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1440"
inkscape:window-height="843"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1"
guidetolerance="10000"
objecttolerance="10000">
<inkscape:grid
type="xygrid"
id="grid3792"
empspacing="10"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
id="rect3796"
width="7"
height="2"
x="5"
y="8" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,111 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30"
height="25"
id="svg10621"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="panel-button-highlight-narrow.svg">
<defs
id="defs10623">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient34508-1-3"
id="radialGradient99561-1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
cx="51"
cy="30"
fx="51"
fy="30"
r="42" />
<linearGradient
inkscape:collect="always"
id="linearGradient34508-1-3">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop34510-1-9" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop34512-4-5" />
</linearGradient>
<radialGradient
r="42"
fy="30"
fx="51"
cy="30"
cx="51"
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
gradientUnits="userSpaceOnUse"
id="radialGradient10592"
xlink:href="#linearGradient34508-1-3"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-171.36384"
inkscape:cy="-53.255157"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1440"
inkscape:window-height="843"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1" />
<metadata
id="metadata10626">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-468.08632,-537.03477)">
<path
sodipodi:type="arc"
style="opacity:0.4625;color:#000000;fill:url(#radialGradient10592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path34506-3"
sodipodi:cx="51"
sodipodi:cy="30"
sodipodi:rx="42"
sodipodi:ry="16"
d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z"
sodipodi:start="3.1415927"
sodipodi:end="6.2831853"
transform="matrix(0.35714286,0,0,1.5625,464.87203,515.15977)"
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,111 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="84"
height="25"
id="svg10621"
version="1.1"
inkscape:version="0.48.0 r9654"
sodipodi:docname="panel-button-highlight-wide.svg">
<defs
id="defs10623">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient34508-1-3"
id="radialGradient99561-1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
cx="51"
cy="30"
fx="51"
fy="30"
r="42" />
<linearGradient
inkscape:collect="always"
id="linearGradient34508-1-3">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop34510-1-9" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop34512-4-5" />
</linearGradient>
<radialGradient
r="42"
fy="30"
fx="51"
cy="30"
cx="51"
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
gradientUnits="userSpaceOnUse"
id="radialGradient10592"
xlink:href="#linearGradient34508-1-3"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-118.50071"
inkscape:cy="27.304508"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1440"
inkscape:window-height="843"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1" />
<metadata
id="metadata10626">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-441.08632,-537.03477)">
<path
sodipodi:type="arc"
style="opacity:0.4625;color:#000000;fill:url(#radialGradient10592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path34506-3"
sodipodi:cx="51"
sodipodi:cy="30"
sodipodi:rx="42"
sodipodi:ry="16"
d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z"
sodipodi:start="3.1415927"
sodipodi:end="6.2831853"
transform="matrix(1,0,0,1.5625,432.08632,515.15977)"
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -1,3 +0,0 @@
#!/usr/bin/bash
bundle exec sass --update --sourcemap=none .

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -1,133 +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="48"
height="22"
id="svg2857"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="toggle-off-hc.svg">
<defs
id="defs2859">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
<inkscape:perspective
id="perspective2843"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-6.1820581"
inkscape:cy="-16.463788"
inkscape:document-units="px"
inkscape:current-layer="g37994"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1364"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="true">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2862">
<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
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-444.64286,-781.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
<g
transform="matrix(1.5323214,0,0,1.2413968,-324.76058,489.69039)"
id="toggle-off"
inkscape:label="#g8477">
<circle
cy="1033.993"
cx="571.95966"
id="path8444"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#555753;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
r="7" />
<rect
ry="2.0108337"
rx="1.9562569"
y="1031.9885"
x="565.0083"
height="4.0216675"
width="34.850178"
id="rect8461"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#555753;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
</g>
<g
transform="matrix(1.5323214,0,0,1.2413968,-324.85635,491.16456)"
id="toggle-on"
inkscape:label="#g8481">
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect8475"
width="34.850178"
height="4.0216675"
x="565.0083"
y="1070.9279"
rx="1.9562569"
ry="2.0108337" />
<circle
transform="scale(-1,1)"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle8463"
cx="-591.0213"
cy="1072.9402"
r="9" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -7,127 +7,51 @@
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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="65"
height="22"
id="svg2857"
id="svg3273"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="toggle-off-us.svg">
inkscape:version="0.47 r22583"
sodipodi:docname="New document 14">
<defs
id="defs2859">
id="defs3275">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
id="perspective3281" />
<inkscape:perspective
id="perspective2843"
id="perspective3261"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4-0"
is_visible="true" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient37802-8"
id="linearGradient12311-3-1-0-5-4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
x1="610.13782"
y1="501.43866"
x2="610.13782"
y2="492.52756" />
<linearGradient
id="linearGradient37802-8"
inkscape:collect="always">
<stop
id="stop37804-1"
offset="0"
style="stop-color:#2c2c2c;stop-opacity:1" />
<stop
id="stop37806-8"
offset="1"
style="stop-color:#16191a;stop-opacity:1" />
</linearGradient>
<linearGradient
y2="492.52756"
x2="610.13782"
y1="501.43866"
x1="610.13782"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)"
gradientUnits="userSpaceOnUse"
id="linearGradient13602"
xlink:href="#linearGradient37802-8"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-5.0602834"
inkscape:cy="16.473273"
inkscape:zoom="0.35"
inkscape:cx="32.000004"
inkscape:cy="10.999997"
inkscape:document-units="px"
inkscape:current-layer="g37994"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1375"
inkscape:window-width="609"
inkscape:window-height="501"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
inkscape:window-y="26"
inkscape:window-maximized="0" />
<metadata
id="metadata2862">
id="metadata3278">
<rdf:RDF>
<cc:Work
rdf:about="">
@ -142,68 +66,61 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-444.64286,-781.36218)">
transform="translate(-343,-521.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
id="g17454"
transform="translate(-453,448.36218)"
style="display:inline">
<rect
transform="scale(-1,1)"
ry="4"
rx="4"
y="74.5"
x="-859.5"
height="19"
width="63.000004"
id="rect17456"
style="color:#000000;fill:none;stroke:#2e3436;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
transform="scale(-1,1)"
ry="4"
rx="4"
y="74"
x="-828"
height="20"
width="31"
id="rect17458"
style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
</g>
<g
transform="translate(-49.946213,-1.890275)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
transform="matrix(-1,0,0,1,1619.1239,-33.986291)"
id="g17460"
style="display:inline">
<path
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="m 803.6322,115.48629 0,4.29495"
id="path17462"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="m 806.62805,115.48629 0,4.29495"
id="path17464"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="m 809.6239,115.48629 0,4.29495"
id="path17466"
inkscape:connector-curvature="0" />
</g>
<path
sodipodi:type="arc"
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.15627193;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="path13479"
sodipodi:cx="16.4375"
sodipodi:cy="10.8125"
sodipodi:rx="4.3125"
sodipodi:ry="4.3125"
d="m 20.75,10.8125 a 4.3125,4.3125 0 1 1 -8.625,0 4.3125,4.3125 0 1 1 8.625,0 z"
transform="matrix(1.4212691,0,0,1.1514287,577.38488,1761.1138)" />
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.96875012;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path18722"
sodipodi:cx="47.6875"
sodipodi:cy="11.5625"
sodipodi:rx="3.9375"
sodipodi:ry="3.9375"
d="m 51.625,11.5625 c 0,2.174621 -1.762879,3.9375 -3.9375,3.9375 -2.174621,0 -3.9375,-1.762879 -3.9375,-3.9375 0,-2.1746212 1.762879,-3.9375 3.9375,-3.9375 2.174621,0 3.9375,1.7628788 3.9375,3.9375 z"
transform="matrix(1.0158729,0,0,1.0158729,795.55556,72.25399)" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -7,171 +7,51 @@
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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="65"
height="22"
id="svg2857"
id="svg3012"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="toggle-on-intl.svg">
inkscape:version="0.47 r22583"
sodipodi:docname="New document 6">
<defs
id="defs2859">
id="defs3014">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
id="perspective3020" />
<inkscape:perspective
id="perspective2843"
id="perspective2997"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient37802"
id="linearGradient12311-3-1-0-5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
x1="610.13782"
y1="501.43866"
x2="610.13782"
y2="492.52756" />
<linearGradient
id="linearGradient37802"
inkscape:collect="always">
<stop
id="stop37804"
offset="0"
style="stop-color:#2c2c2c;stop-opacity:1" />
<stop
id="stop37806"
offset="1"
style="stop-color:#16191a;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4-3"
id="linearGradient77680"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.0322581,717.71949,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4-3">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5-7" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0-9" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4-0"
is_visible="true" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient37802-8"
id="linearGradient12311-3-1-0-5-4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
x1="610.13782"
y1="501.43866"
x2="610.13782"
y2="492.52756" />
<linearGradient
id="linearGradient37802-8"
inkscape:collect="always">
<stop
id="stop37804-1"
offset="0"
style="stop-color:#2c2c2c;stop-opacity:1" />
<stop
id="stop37806-8"
offset="1"
style="stop-color:#16191a;stop-opacity:1" />
</linearGradient>
<linearGradient
y2="492.52756"
x2="610.13782"
y1="501.43866"
x1="610.13782"
gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)"
gradientUnits="userSpaceOnUse"
id="linearGradient13602"
xlink:href="#linearGradient37802-8"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="16.760995"
inkscape:cy="21.955673"
inkscape:zoom="0.35"
inkscape:cx="32.000004"
inkscape:cy="10.999997"
inkscape:document-units="px"
inkscape:current-layer="g37994"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1375"
inkscape:window-width="609"
inkscape:window-height="501"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
inkscape:window-y="26"
inkscape:window-maximized="0" />
<metadata
id="metadata2862">
id="metadata3017">
<rdf:RDF>
<cc:Work
rdf:about="">
@ -186,70 +66,73 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-444.64286,-781.36218)">
transform="translate(-343,-521.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
id="g17454"
transform="translate(-453,448.36218)"
style="display:inline">
<rect
transform="scale(-1,1)"
ry="4"
rx="4"
y="74.5"
x="-859.5"
height="19"
width="63.000004"
id="rect17456"
style="color:#000000;fill:none;stroke:#2e3436;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
transform="scale(-1,1)"
ry="4"
rx="4"
y="74"
x="-828"
height="20"
width="31"
id="rect17458"
style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new" />
transform="matrix(-1,0,0,1,1619.1239,-33.986291)"
id="g17460"
style="display:inline">
<path
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="m 803.6322,115.48629 0,4.29495"
id="path17462"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="m 806.62805,115.48629 0,4.29495"
id="path17464"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="m 809.6239,115.48629 0,4.29495"
id="path17466"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(-49.946213,-1.890275)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
style="font-size:8.95877075px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
id="text17468"
transform="translate(0.34375,0)">
<path
d="m 837.28518,80.750726 c 0.63282,6e-6 1.19566,0.123947 1.68852,0.371824 0.49284,0.247888 0.8807,0.609505 1.16359,1.084851 0.28287,0.472439 0.42431,1.022155 0.42431,1.649149 0,0.635748 -0.13853,1.200045 -0.41556,1.692892 -0.27706,0.489934 -0.66638,0.870507 -1.16797,1.141719 -0.5016,0.271213 -1.07756,0.406819 -1.72789,0.406819 -0.42869,0 -0.83551,-0.06562 -1.22045,-0.196848 -0.38495,-0.134148 -0.73053,-0.32808 -1.03674,-0.581795 -0.30329,-0.256631 -0.54534,-0.589085 -0.72615,-0.997363 -0.17789,-0.408276 -0.26684,-0.869045 -0.26683,-1.382311 -10e-6,-0.638658 0.13997,-1.200039 0.41994,-1.684144 0.27996,-0.487011 0.66782,-0.858835 1.16359,-1.115472 0.49576,-0.259541 1.06297,-0.389315 1.70164,-0.389321 m 0.57305,1.089225 c -0.20123,-0.05249 -0.40683,-0.07873 -0.61679,-0.07874 -0.20998,5e-6 -0.41412,0.02625 -0.61242,0.07874 -0.19831,0.04958 -0.38933,0.129779 -0.57305,0.240592 -0.18081,0.107907 -0.33974,0.242055 -0.47681,0.402445 -0.13706,0.160399 -0.24642,0.358705 -0.32808,0.594918 -0.0816,0.233306 -0.12248,0.491395 -0.12248,0.774269 0,0.67366 0.20851,1.214627 0.62554,1.622903 0.41702,0.408278 0.93758,0.612416 1.56166,0.612416 0.25954,0 0.51034,-0.04229 0.7524,-0.126858 0.24496,-0.08457 0.47097,-0.20997 0.67803,-0.376198 0.20705,-0.166226 0.37328,-0.392236 0.49868,-0.678032 0.12539,-0.285792 0.18809,-0.610956 0.1881,-0.975492 -10e-6,-0.297455 -0.0437,-0.568668 -0.13123,-0.813638 -0.0875,-0.247878 -0.20415,-0.453475 -0.34995,-0.61679 -0.14291,-0.163307 -0.31059,-0.301829 -0.50306,-0.415568 -0.18956,-0.11373 -0.38641,-0.195385 -0.59054,-0.244967"
style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
id="path18599"
inkscape:connector-curvature="0" />
<path
d="m 843.5362,81.831203 0,1.17917 2.94834,0 0,1.014861 -2.94834,0 0,3.00713 -1.10673,0 0,-6.216022 4.31754,0 0,1.014861 -3.21081,0"
style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
id="path18601"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
<path
d="m 849.71285,81.831203 0,1.17917 2.94834,0 0,1.014861 -2.94834,0 0,3.00713 -1.10672,0 0,-6.216022 4.31753,0 0,1.014861 -3.21081,0"
style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
id="path18603"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
</g>
<text
xml:space="preserve"
style="font-size:13.79166794px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
x="520.29974"
y="1997.0011"
id="text75614"
sodipodi:linespacing="125%"
transform="scale(1.1236771,0.88993537)"><tspan
sodipodi:role="line"
id="tspan75616"
x="520.29974"
y="1997.0011">OFF</tspan></text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -1,113 +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="48"
height="22"
id="svg2857"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="toggle-on-hc.svg">
<defs
id="defs2859">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
<inkscape:perspective
id="perspective2843"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-222.95215"
inkscape:cy="3.9378433"
inkscape:document-units="px"
inkscape:current-layer="g37994"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1364"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="true">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata2862">
<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
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-444.64286,-781.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
<g
transform="matrix(1.5323214,0,0,1.2413968,-324.85635,441.50868)"
id="toggle-on"
inkscape:label="#g8481">
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect8475"
width="34.850178"
height="4.0216675"
x="565.0083"
y="1070.9279"
rx="1.9562569"
ry="2.0108337" />
<circle
transform="scale(-1,1)"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle8463"
cx="-591.0213"
cy="1072.9402"
r="9" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -7,113 +7,51 @@
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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="65"
height="22"
id="svg2857"
id="svg3199"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:version="0.48.1 r9760"
sodipodi:docname="toggle-on-intl.svg">
<defs
id="defs2859">
id="defs3201">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2865" />
id="perspective3207" />
<inkscape:perspective
id="perspective2843"
id="perspective3187"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient77461"
id="linearGradient77551"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3066667,0,0,1,-841.64667,-483)"
x1="1164.7644"
y1="962.93695"
x2="1164.7644"
y2="970.51404" />
<linearGradient
id="linearGradient77461"
inkscape:collect="always">
<stop
id="stop77463"
offset="0"
style="stop-color:#182f4c;stop-opacity:1" />
<stop
id="stop77465"
offset="1"
style="stop-color:#205b9a;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="37.410841"
inkscape:cy="16.009314"
inkscape:cx="49.147112"
inkscape:cy="17.532036"
inkscape:document-units="px"
inkscape:current-layer="g37994"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-width="1412"
inkscape:window-height="1067"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
inkscape:window-y="26"
inkscape:window-maximized="0" />
<metadata
id="metadata2862">
id="metadata3204">
<rdf:RDF>
<cc:Work
rdf:about="">
@ -128,65 +66,57 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-444.64286,-781.36218)">
transform="translate(-342.5,-521.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient77551);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
transform="translate(2.0625,-2)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
</g>
style="display:inline"
transform="translate(-453.5,448.36218)"
id="g16453">
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
id="rect13678"
width="3.0646207"
height="12.414008"
x="554.77728"
y="1767.3566" />
style="color:#000000;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994000000003;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect16256-9-4"
width="63.000004"
height="19"
x="-859.5"
y="74.5"
rx="4"
ry="4"
transform="scale(-1,1)" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="rect16258-5-4"
width="31"
height="20"
x="-860"
y="74"
rx="4"
ry="4"
transform="scale(-1,1)" />
<g
style="display:inline"
id="g16298-3-6"
transform="matrix(-1,0,0,1,1651.1322,-33.986291)">
<path
inkscape:connector-curvature="0"
id="path16265-3-5"
d="m 803.6322,115.48629 0,4.29495"
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path16265-0-2-0"
d="m 806.62805,115.48629 0,4.29495"
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
<path
inkscape:connector-curvature="0"
id="path16265-8-7-1"
d="m 809.6239,115.48629 0,4.29495"
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
</g>
<path
style="color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 16,27.9375 0,10.125"
id="path19232"
inkscape:connector-curvature="0"
transform="translate(796,51.00002)" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -7,14 +7,13 @@
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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="65"
height="22"
id="svg2857"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:version="0.48.1 r9760"
sodipodi:docname="toggle-on-us.svg">
<defs
id="defs2859">
@ -32,96 +31,27 @@
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient76469-7-7-4"
id="linearGradient38024"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
x1="6"
y1="102.95528"
x2="6"
y2="84.505203" />
<linearGradient
inkscape:collect="always"
id="linearGradient76469-7-7-4">
<stop
style="stop-color:#2e3232;stop-opacity:1"
offset="0"
id="stop76471-7-1-5" />
<stop
style="stop-color:#3e4545;stop-opacity:1"
offset="1"
id="stop76473-9-0-0" />
</linearGradient>
<inkscape:path-effect
effect="spiro"
id="path-effect77541-4"
is_visible="true" />
<linearGradient
id="linearGradient77461-1"
inkscape:collect="always">
<stop
id="stop77463-1"
offset="0"
style="stop-color:#182f4c;stop-opacity:1" />
<stop
id="stop77465-4"
offset="1"
style="stop-color:#205b9a;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient77461-1"
id="linearGradient77551-6-5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8527367,0,0,0.80554422,-969.41608,-778.00299)"
x1="1164.7644"
y1="962.93695"
x2="1164.7644"
y2="970.51404" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient77461-1"
id="linearGradient11198"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3066667,0,0,1,-1066.3709,794.25325)"
x1="1322.5831"
y1="-312.51855"
x2="1322.5831"
y2="-306.53461" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-26.798898"
inkscape:cy="5.3753009"
inkscape:cx="19.689855"
inkscape:cy="2.0517979"
inkscape:document-units="px"
inkscape:current-layer="g37994"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:window-width="941"
inkscape:window-height="751"
inkscape:window-x="2577"
inkscape:window-y="206"
inkscape:window-maximized="0"
borderlayer="true"
inkscape:showpageshadow="false"
inkscape:snap-nodes="false"
inkscape:snap-bbox="true"
showborder="false">
<inkscape:grid
type="xygrid"
id="grid12954"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
inkscape:showpageshadow="false" />
<metadata
id="metadata2862">
<rdf:RDF>
@ -140,68 +70,61 @@
id="layer1"
transform="translate(-444.64286,-781.36218)">
<g
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
id="g37994">
style="display:inline"
transform="translate(-351.35714,708.36218)"
id="g16453">
<rect
style="color:#000000;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994000000003;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect16256-9-4"
width="63.000004"
height="19"
x="-859.5"
y="74.5"
rx="4"
ry="4"
transform="scale(-1,1)" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#5f5f5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="rect16258-5-4"
width="31"
height="20"
x="-860"
y="74"
rx="4"
ry="4"
transform="scale(-1,1)" />
<g
id="g37996"
transform="translate(-115,1277)">
<rect
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.19591837"
id="rect13475"
width="98"
height="25"
x="644.5"
y="484.61118"
rx="4.7429576"
ry="3.8424656" />
<rect
ry="3.8424656"
rx="4.7429576"
y="483.5"
x="644.5"
height="25"
width="98"
id="rect38000"
style="color:#000000;fill:url(#linearGradient11198);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;clip-rule:nonzero;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;filter-blend-mode:normal;filter-gaussianBlur-deviation:0;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto" />
style="display:inline"
id="g16298-3-6"
transform="matrix(-1,0,0,1,1651.1322,-33.986291)">
<path
inkscape:connector-curvature="0"
id="path16265-3-5"
d="m 803.6322,115.48629 0,4.29495"
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path16265-0-2-0"
d="m 806.62805,115.48629 0,4.29495"
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
<path
inkscape:connector-curvature="0"
id="path16265-8-7-1"
d="m 809.6239,115.48629 0,4.29495"
style="fill:none;stroke:#5f5f5f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
</g>
<g
transform="translate(2.0625,-2)"
id="g38002">
<g
transform="translate(-115,1247)"
style="display:inline"
id="g38004">
<rect
ry="3.7972314"
rx="4.6871223"
y="515.5"
x="694.53046"
height="25"
width="45.969578"
id="rect38006"
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cc"
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 699.09675,516.7365 36.86904,0"
id="path38016"
inkscape:path-effect="#path-effect77541-4"
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
inkscape:connector-curvature="0" />
</g>
style="font-size:8.95877075px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
id="text42229-3-0">
<path
d="m 808.01473,80.573953 c 0.63283,6e-6 1.19567,0.123947 1.68852,0.371824 0.49284,0.247888 0.88071,0.609505 1.16359,1.084851 0.28287,0.472439 0.42431,1.022155 0.42432,1.649149 -10e-6,0.635748 -0.13853,1.200045 -0.41557,1.692892 -0.27705,0.489934 -0.66637,0.870506 -1.16796,1.141719 -0.50161,0.271212 -1.07757,0.406819 -1.72789,0.406819 -0.4287,0 -0.83552,-0.06562 -1.22046,-0.196848 -0.38495,-0.134148 -0.73053,-0.32808 -1.03673,-0.581795 -0.3033,-0.256631 -0.54535,-0.589085 -0.72615,-0.997363 -0.1779,-0.408276 -0.26684,-0.869045 -0.26684,-1.382311 0,-0.638658 0.13998,-1.200039 0.41994,-1.684144 0.27996,-0.487011 0.66782,-0.858835 1.16359,-1.115472 0.49576,-0.259541 1.06298,-0.389315 1.70164,-0.389321 m 0.57305,1.089225 c -0.20123,-0.05249 -0.40682,-0.07873 -0.61679,-0.07874 -0.20998,5e-6 -0.41411,0.02625 -0.61242,0.07874 -0.19831,0.04958 -0.38932,0.129779 -0.57304,0.240592 -0.18081,0.107907 -0.33975,0.242055 -0.47681,0.402445 -0.13707,0.160399 -0.24643,0.358705 -0.32808,0.594918 -0.0817,0.233305 -0.12249,0.491395 -0.12249,0.774269 0,0.67366 0.20851,1.214627 0.62554,1.622902 0.41703,0.408279 0.93758,0.612417 1.56166,0.612416 0.25955,10e-7 0.51035,-0.04228 0.7524,-0.126857 0.24496,-0.08457 0.47097,-0.20997 0.67803,-0.376199 0.20705,-0.166225 0.37328,-0.392236 0.49868,-0.678031 0.1254,-0.285792 0.1881,-0.610956 0.1881,-0.975492 0,-0.297455 -0.0437,-0.568668 -0.13123,-0.813638 -0.0875,-0.247878 -0.20414,-0.453475 -0.34995,-0.61679 -0.1429,-0.163307 -0.31059,-0.301829 -0.50306,-0.415568 -0.18956,-0.11373 -0.38641,-0.195385 -0.59054,-0.244967"
style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
id="path18606" />
<path
d="m 813.15903,80.639569 1.21608,0 3.4689,4.776844 0,-4.776844 1.10235,0 0,6.216022 -1.22921,0 -3.45577,-4.785594 0,4.785594 -1.10235,0 0,-6.216022"
style="line-height:125%;fill:#ffffff;fill-opacity:1;marker:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
id="path18608" />
</g>
<text
transform="scale(1.1000946,0.90901274)"
sodipodi:linespacing="125%"
id="text38018"
y="1955.5205"
x="495.94223"
style="font-size:13.29953671px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
xml:space="preserve"><tspan
y="1955.5205"
x="495.94223"
id="tspan38020"
sodipodi:role="line">ON</tspan></text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -66,7 +66,6 @@ IGNORE_HFILES= \
gactionmuxer.h \
gactionobservable.h \
gactionobserver.h \
shell-network-agent.h \
shell-recorder-src.h
if !BUILD_RECORDER
@ -113,7 +112,7 @@ expand_content_files=
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS)
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la -rpath $(MUTTER_TYPELIB_DIR)
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make

View File

@ -17,6 +17,7 @@
<chapter>
<title>Actors</title>
<xi:include href="xml/shell-generic-container.xml"/>
<xi:include href="xml/shell-slicer.xml"/>
<xi:include href="xml/shell-stack.xml"/>
</chapter>
<chapter>
@ -45,10 +46,11 @@
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider.xml"/>
<xi:include href="doc-gen-org.gnome.Shell.SearchProvider2.xml"/>
<xi:include href="xml/shell-global.xml"/>
<xi:include href="xml/shell-action-modes.xml"/>
<xi:include href="xml/shell-keybinding-modes.xml"/>
<xi:include href="xml/shell-wm.xml"/>
<xi:include href="xml/shell-util.xml"/>
<xi:include href="xml/shell-mount-operation.xml"/>
<xi:include href="xml/shell-network-agent.xml"/>
<xi:include href="xml/shell-polkit-authentication-agent.xml"/>
<xi:include href="xml/shell-tp-client.xml"/>
</chapter>

View File

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

View File

@ -35,6 +35,7 @@
<xi:include href="xml/st-bin.xml"/>
<xi:include href="xml/st-box-layout.xml"/>
<xi:include href="xml/st-scroll-view.xml"/>
<xi:include href="xml/st-table.xml"/>
</chapter>
<chapter id="styling">

View File

@ -17,19 +17,19 @@ packages. If you are interested in building GNOME Shell from source,
we would recommend building from version control using the build
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
changing project, it will be much easier than get GNOME Shell and
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" />
<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#core" />
<programming-language>JavaScript</programming-language>
<programming-language>C</programming-language>
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
<maintainer>
<foaf:Person>

View File

@ -6,14 +6,13 @@ misc/config.js: misc/config.js.in Makefile
sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \
-e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \
-e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \
-e "s|[@]HAVE_NETWORKMANAGER@|$(HAVE_NETWORKMANAGER)|g" \
-e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
-e "s|[@]datadir@|$(datadir)|g" \
-e "s|[@]libexecdir@|$(libexecdir)|g" \
-e "s|[@]sysconfdir@|$(sysconfdir)|g" \
$< > $@
js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate-dependencies $(srcdir)/js-resources.gresource.xml)
js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/js-resources.gresource.xml)
js-resources.h: js-resources.gresource.xml $(js_resource_files) misc/config.js
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate --c-name shell_js_resources $<
js-resources.c: js-resources.gresource.xml $(js_resource_files) misc/config.js

View File

@ -46,9 +46,13 @@ const Application = new Lang.Class({
this._extensionPrefsModules = {};
this._extensionIters = {};
this._startupUuid = null;
this._loaded = false;
this._skipMainWindow = false;
},
_buildModel: function() {
this._model = new Gtk.ListStore();
this._model.set_column_types([GObject.TYPE_STRING, GObject.TYPE_STRING]);
},
_extensionAvailable: function(uuid) {
@ -57,12 +61,20 @@ const Application = new Lang.Class({
if (!extension)
return false;
if (ExtensionUtils.isOutOfDate(extension))
return false;
if (!extension.dir.get_child('prefs.js').query_exists(null))
return false;
return true;
},
_setExtensionInsensitive: function(layout, cell, model, iter, data) {
let uuid = model.get_value(iter, 0);
cell.set_sensitive(this._extensionAvailable(uuid));
},
_getExtensionPrefsModule: function(extension) {
let uuid = extension.metadata.uuid;
@ -92,23 +104,21 @@ const Application = new Lang.Class({
widget = this._buildErrorUI(extension, e);
}
let dialog = new Gtk.Dialog({ use_header_bar: true,
modal: true,
title: extension.metadata.name });
// Destroy the current prefs widget, if it exists
if (this._extensionPrefsBin.get_child())
this._extensionPrefsBin.get_child().destroy();
if (this._skipMainWindow) {
this.application.add_window(dialog);
if (this._window)
this._window.destroy();
this._window = dialog;
this._window.window_position = Gtk.WindowPosition.CENTER;
} else {
dialog.transient_for = this._window;
}
this._extensionPrefsBin.add(widget);
this._extensionSelector.set_active_iter(this._extensionIters[uuid]);
},
dialog.set_default_size(600, 400);
dialog.get_content_area().add(widget);
dialog.show();
_extensionSelected: function() {
let [success, iter] = this._extensionSelector.get_active_iter();
if (!success)
return;
let uuid = this._model.get_value(iter, 0);
this._selectExtension(uuid);
},
_buildErrorUI: function(extension, exc) {
@ -141,27 +151,48 @@ const Application = new Lang.Class({
_buildUI: function(app) {
this._window = new Gtk.ApplicationWindow({ application: app,
window_position: Gtk.WindowPosition.CENTER });
window_position: Gtk.WindowPosition.CENTER,
title: _("GNOME Shell Extension Preferences") });
this._window.set_size_request(800, 500);
this._window.set_size_request(600, 400);
this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
title: _("GNOME Shell Extensions") });
this._window.set_titlebar(this._titlebar);
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
this._window.add(vbox);
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER,
shadow_type: Gtk.ShadowType.IN,
halign: Gtk.Align.CENTER,
propagate_natural_width: true,
margin: 18 });
this._window.add(scroll);
let toolbar = new Gtk.Toolbar();
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR);
vbox.add(toolbar);
let toolitem;
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
this._extensionSelector.set_sort_func(Lang.bind(this, this._sortList));
this._extensionSelector.set_header_func(Lang.bind(this, this._updateHeader));
let label = new Gtk.Label({ label: '<b>' + _("Extension") + '</b>',
use_markup: true });
toolitem = new Gtk.ToolItem({ child: label });
toolbar.add(toolitem);
scroll.add(this._extensionSelector);
this._extensionSelector = new Gtk.ComboBox({ model: this._model,
margin_left: 8,
hexpand: true });
this._extensionSelector.get_style_context().add_class(Gtk.STYLE_CLASS_RAISED);
let renderer = new Gtk.CellRendererText();
this._extensionSelector.pack_start(renderer, true);
this._extensionSelector.add_attribute(renderer, 'text', 1);
this._extensionSelector.set_cell_data_func(renderer, Lang.bind(this, this._setExtensionInsensitive));
this._extensionSelector.connect('changed', Lang.bind(this, this._extensionSelected));
toolitem = new Gtk.ToolItem({ child: this._extensionSelector });
toolitem.set_expand(true);
toolbar.add(toolitem);
this._extensionPrefsBin = new Gtk.Frame();
vbox.add(this._extensionPrefsBin);
let label = new Gtk.Label({
label: _("Select an extension to configure using the combobox above."),
vexpand: true
});
this._extensionPrefsBin.add(label);
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) {
@ -172,20 +203,6 @@ const Application = new Lang.Class({
this._window.show_all();
},
_sortList: function(row1, row2) {
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
return name1.localeCompare(name2);
},
_updateHeader: function(row, before) {
if (!before || row.get_header())
return;
let sep = new Gtk.Separator({ orientation: Gtk.Orientation.HORIZONTAL });
row.set_header(sep);
},
_scanExtensions: function() {
let finder = new ExtensionUtils.ExtensionFinder();
finder.connect('extension-found', Lang.bind(this, this._extensionFound));
@ -194,24 +211,15 @@ const Application = new Lang.Class({
},
_extensionFound: function(finder, extension) {
let row = new ExtensionRow(extension.uuid);
row.prefsButton.visible = this._extensionAvailable(row.uuid);
row.prefsButton.connect('clicked', Lang.bind(this,
function() {
this._selectExtension(row.uuid);
}));
row.show_all();
this._extensionSelector.add(row);
let iter = this._model.append();
this._model.set(iter, [0, 1], [extension.uuid, extension.metadata.name]);
this._extensionIters[extension.uuid] = iter;
},
_extensionsLoaded: function() {
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
this._selectExtension(this._startupUuid);
this._startupUuid = null;
this._skipMainWindow = false;
this._loaded = true;
},
_onActivate: function() {
@ -219,6 +227,7 @@ const Application = new Lang.Class({
},
_onStartup: function(app) {
this._buildModel();
this._buildUI(app);
this._scanExtensions();
},
@ -226,129 +235,21 @@ const Application = new Lang.Class({
_onCommandLine: function(app, commandLine) {
app.activate();
let args = commandLine.get_arguments();
if (args.length) {
let uuid = args[0];
this._skipMainWindow = true;
// Strip off "extension:///" prefix which fakes a URI, if it exists
uuid = stripPrefix(uuid, "extension:///");
if (this._extensionAvailable(uuid))
this._selectExtension(uuid);
else if (!this._loaded)
this._startupUuid = uuid;
else
this._skipMainWindow = false;
this._startupUuid = uuid;
}
return 0;
}
});
const ExtensionRow = new Lang.Class({
Name: 'ExtensionRow',
Extends: Gtk.ListBoxRow,
_init: function(uuid) {
this.parent();
this.uuid = uuid;
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
this._settings.connect('changed::enabled-extensions', Lang.bind(this,
function() {
this._switch.state = this._isEnabled();
}));
this._settings.connect('changed::disable-extension-version-validation',
Lang.bind(this, function() {
this._switch.sensitive = this._canEnable();
}));
this._buildUI();
},
_buildUI: function() {
let extension = ExtensionUtils.extensions[this.uuid];
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
hexpand: true, margin: 12, spacing: 6 });
this.add(hbox);
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
spacing: 6, hexpand: true });
hbox.add(vbox);
let name = GLib.markup_escape_text(extension.metadata.name, -1);
let label = new Gtk.Label({ label: '<b>' + name + '</b>',
use_markup: true,
halign: Gtk.Align.START });
vbox.add(label);
let desc = extension.metadata.description.split('\n')[0];
label = new Gtk.Label({ label: desc,
ellipsize: Pango.EllipsizeMode.END,
halign: Gtk.Align.START });
vbox.add(label);
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
no_show_all: true });
button.add(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
icon_size: Gtk.IconSize.BUTTON,
visible: true }));
button.get_style_context().add_class('circular');
hbox.add(button);
this.prefsButton = button;
this._switch = new Gtk.Switch({ valign: Gtk.Align.CENTER,
sensitive: this._canEnable(),
state: this._isEnabled() });
this._switch.connect('notify::active', Lang.bind(this,
function() {
if (this._switch.active)
this._enable();
else
this._disable();
}));
this._switch.connect('state-set', function() { return true; });
hbox.add(this._switch);
},
_canEnable: function() {
let extension = ExtensionUtils.extensions[this.uuid];
let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
return !(checkVersion && ExtensionUtils.isOutOfDate(extension));
},
_isEnabled: function() {
let extensions = this._settings.get_strv('enabled-extensions');
return extensions.indexOf(this.uuid) != -1;
},
_enable: function() {
let extensions = this._settings.get_strv('enabled-extensions');
if (extensions.indexOf(this.uuid) != -1)
return;
extensions.push(this.uuid);
this._settings.set_strv('enabled-extensions', extensions);
},
_disable: function() {
let extensions = this._settings.get_strv('enabled-extensions');
let pos = extensions.indexOf(this.uuid);
if (pos == -1)
return;
do {
extensions.splice(pos, 1);
pos = extensions.indexOf(this.uuid);
} while (pos != -1);
this._settings.set_strv('enabled-extensions', extensions);
}
});
function initEnvironment() {
// Monkey-patch in a "global" object that fakes some Shell utilities
// that ExtensionUtils depends on.

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const St = imports.gi.St;
@ -14,7 +13,7 @@ const ShellEntry = imports.ui.shellEntry;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
const DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
const DEFAULT_BUTTON_WELL_ICON_SIZE = 24;
const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
@ -127,7 +126,7 @@ const AuthPrompt = new Lang.Class({
this._initButtons();
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
let spinnerIcon = global.datadir + '/theme/process-working.svg';
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.actor.opacity = 0;
this._spinner.actor.show();
@ -135,12 +134,13 @@ const AuthPrompt = new Lang.Class({
},
_onDestroy: function() {
this._userVerifier.destroy();
this._userVerifier.clear();
this._userVerifier.disconnectAll();
this._userVerifier = null;
},
_initButtons: function() {
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
@ -162,7 +162,7 @@ const AuthPrompt = new Lang.Class({
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this.nextButton = new St.Button({ style_class: 'modal-dialog-button button',
this.nextButton = new St.Button({ style_class: 'modal-dialog-button',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
reactive: true,
can_focus: true,
@ -189,21 +189,22 @@ const AuthPrompt = new Lang.Class({
this._updateNextButtonSensitivity(this._entry.text.length > 0);
}));
this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
if (this.nextButton.reactive)
this.emit('next');
this.emit('next');
}));
},
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
if (this._preemptiveAnswer) {
if (this._queryingService)
this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer);
this._preemptiveAnswer = null;
return;
}
if (this._queryingService)
this.clear();
this._queryingService = serviceName;
if (this._preemptiveAnswer) {
this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer);
this._preemptiveAnswer = null;
return;
}
this.setPasswordChar(passwordChar);
this.setQuestion(question);
@ -259,9 +260,7 @@ const AuthPrompt = new Lang.Class({
},
_onVerificationComplete: function() {
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
},
_onReset: function() {
@ -283,12 +282,6 @@ const AuthPrompt = new Lang.Class({
if (oldActor)
Tweener.removeTweens(oldActor);
let wasSpinner;
if (oldActor == this._spinner.actor)
wasSpinner = true;
else
wasSpinner = false;
let isSpinner;
if (actor == this._spinner.actor)
isSpinner = true;
@ -298,11 +291,6 @@ const AuthPrompt = new Lang.Class({
if (this._defaultButtonWellActor != actor && oldActor) {
if (!animate) {
oldActor.opacity = 0;
if (wasSpinner) {
if (this._spinner)
this._spinner.stop();
}
} else {
Tweener.addTween(oldActor,
{ opacity: 0,
@ -311,7 +299,7 @@ const AuthPrompt = new Lang.Class({
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (wasSpinner) {
if (isSpinner) {
if (this._spinner)
this._spinner.stop();
}
@ -414,7 +402,7 @@ const AuthPrompt = new Lang.Class({
},
updateSensitivity: function(sensitive) {
this._updateNextButtonSensitivity(sensitive && this._entry.text.length > 0);
this._updateNextButtonSensitivity(sensitive);
this._entry.reactive = sensitive;
this._entry.clutter_text.editable = sensitive;
},
@ -431,23 +419,19 @@ const AuthPrompt = new Lang.Class({
},
setUser: function(user) {
let oldChild = this._userWell.get_child();
if (oldChild)
oldChild.destroy();
if (user) {
let userWidget = new UserWidget.UserWidget(user);
this._userWell.set_child(userWidget.actor);
} else {
this._userWell.set_child(null);
}
},
reset: function() {
let oldStatus = this.verificationStatus;
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.cancelButton.reactive = true;
this.nextButton.label = _("Next");
if (this._userVerifier)
if (oldStatus == AuthPromptStatus.VERIFYING)
this._userVerifier.cancel();
this._queryingService = null;
@ -466,7 +450,8 @@ const AuthPrompt = new Lang.Class({
// respond to the request with the username
beginRequestType = BeginRequestType.PROVIDE_USERNAME;
} 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
// with a smartcard or with preauthenticated oVirt credentials
beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME;
@ -502,7 +487,6 @@ const AuthPrompt = new Lang.Class({
finish: function(onComplete) {
if (!this._userVerifier.hasPendingMessages) {
this._userVerifier.clear();
onComplete();
return;
}
@ -510,15 +494,11 @@ const AuthPrompt = new Lang.Class({
let signalId = this._userVerifier.connect('no-more-messages',
Lang.bind(this, function() {
this._userVerifier.disconnect(signalId);
this._userVerifier.clear();
onComplete();
}));
},
cancel: function() {
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
return;
}
this.reset();
this.emit('cancelled');
}

View File

@ -16,34 +16,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* In order for transformation animations to look good, they need to be
* incremental and have some order to them (e.g., fade out hidden items,
* then shrink to close the void left over). Chaining animations in this way can
* be error-prone and wordy using just Tweener callbacks.
*
* The classes in this file help with this:
*
* - Task. encapsulates schedulable work to be run in a specific scope.
*
* - ConsecutiveBatch. runs a series of tasks in order and completes
* when the last in the series finishes.
*
* - ConcurrentBatch. runs a set of tasks at the same time and completes
* when the last to finish completes.
*
* - Hold. prevents a batch from completing the pending task until
* the hold is released.
*
* The tasks associated with a batch are specified in a list at batch
* construction time as either task objects or plain functions.
* Batches are task objects, themselves, so they can be nested.
*
* These classes aren't specific to GDM, but were found to be unintuitive and so
* are not used elsewhere. These APIs may ultimately get dropped entirely and
* replaced by something else.
*/
const Lang = imports.lang;
const Signals = imports.signals;

View File

@ -22,12 +22,10 @@ const Clutter = imports.gi.Clutter;
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
@ -38,7 +36,6 @@ const BoxPointer = imports.ui.boxpointer;
const CtrlAltTab = imports.ui.ctrlAltTab;
const GdmUtil = imports.gdm.util;
const Layout = imports.ui.layout;
const LoginManager = imports.misc.loginManager;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const Realmd = imports.gdm.realmd;
@ -49,7 +46,8 @@ const _FADE_ANIMATION_TIME = 0.25;
const _SCROLL_ANIMATION_TIME = 0.5;
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
const _LOGO_ICON_HEIGHT = 48;
const _MAX_BOTTOM_MENU_ITEMS = 5;
let _loginDialog = null;
const UserListItem = new Lang.Class({
Name: 'UserListItem',
@ -67,15 +65,10 @@ const UserListItem = new Lang.Class({
reactive: true,
x_align: St.Align.START,
x_fill: true });
this.actor.connect('destroy',
Lang.bind(this, this._onDestroy));
this._userWidget = new UserWidget.UserWidget(this.user);
layout.add(this._userWidget.actor);
this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
GObject.BindingFlags.SYNC_CREATE);
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0 });
layout.add(this._timedLoginIndicator);
@ -95,10 +88,6 @@ const UserListItem = new Lang.Class({
this.actor.remove_style_pseudo_class('logged-in');
},
_onDestroy: function() {
this.user.disconnect(this._userChangedId);
},
_onClicked: function() {
this.emit('activate');
},
@ -212,10 +201,6 @@ const UserList = new Lang.Class({
return item;
},
containsUser: function(user) {
return this._items[user.get_user_name()] != null;
},
addUser: function(user) {
if (!user.is_loaded)
return;
@ -288,17 +273,8 @@ const SessionMenuButton = new Lang.Class({
this.actor = new St.Bin({ child: this._button });
let side = St.Side.TOP;
let align = 0;
if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) {
if (this.actor.text_direction == Clutter.TextDirection.RTL)
side = St.Side.RIGHT;
else
side = St.Side.LEFT;
align = 0.5;
}
this._menu = new PopupMenu.PopupMenu(this._button, align, side);
Main.uiGroup.add_actor(this._menu.actor);
this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.TOP);
Main.layoutManager.menuGroup.add_actor(this._menu.actor);
this._menu.actor.hide();
this._menu.connect('open-state-changed',
@ -383,19 +359,31 @@ const LoginDialog = new Lang.Class({
Name: 'LoginDialog',
_init: function(parentActor) {
this.actor = new Shell.GenericContainer({ style_class: 'login-dialog',
visible: false });
this.actor.get_accessible().set_role(Atk.Role.WINDOW);
this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW,
layout_manager: new Clutter.BinLayout(),
style_class: 'login-dialog',
visible: false });
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
this.actor.connect('allocate', Lang.bind(this, this._onAllocate));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
parentActor.add_child(this.actor);
this._userManager = AccountsService.UserManager.get_default()
this._gdmClient = new Gdm.Client();
let gdmClient = new Gdm.Client();
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
this._greeter = gdmClient.get_greeter_sync(null);
this._greeter.connect('default-session-name-changed',
Lang.bind(this, this._onDefaultSessionChanged));
this._greeter.connect('session-opened',
Lang.bind(this, this._onSessionOpened));
this._greeter.connect('timed-login-requested',
Lang.bind(this, this._onTimedLoginRequested));
}
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
Lang.bind(this, this._updateBanner));
@ -407,23 +395,30 @@ const LoginDialog = new Lang.Class({
Lang.bind(this, this._updateLogo));
this._textureCache = St.TextureCache.get_default();
this._updateLogoTextureId = this._textureCache.connect('texture-file-changed',
Lang.bind(this, this._updateLogoTexture));
this._textureCache.connect('texture-file-changed',
Lang.bind(this, this._updateLogoTexture));
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
x_expand: true,
y_expand: true,
vertical: true,
visible: false });
this.actor.add_child(this._userSelectionBox);
this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
text: '' });
this._userSelectionBox.add(this._bannerLabel);
this._updateBanner();
this._userList = new UserList();
this._userSelectionBox.add(this._userList.actor,
{ expand: true,
x_fill: true,
y_fill: true });
this._authPrompt = new AuthPrompt.AuthPrompt(this._gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted));
this._authPrompt.connect('reset', Lang.bind(this, this._onReset));
this._authPrompt.hide();
@ -451,25 +446,11 @@ const LoginDialog = new Lang.Class({
x_align: St.Align.START,
x_fill: true });
this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
opacity: 0,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER });
this.actor.add_child(this._bannerView);
let bannerBox = new St.BoxLayout({ vertical: true });
this._bannerView.add_actor(bannerBox);
this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
text: '' });
this._bannerLabel.clutter_text.line_wrap = true;
this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
bannerBox.add_child(this._bannerLabel);
this._updateBanner();
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.END });
y_align: Clutter.ActorAlign.END,
x_expand: true,
y_expand: true });
this.actor.add_child(this._logoBin);
this._updateLogo();
@ -488,208 +469,7 @@ const LoginDialog = new Lang.Class({
this._sessionMenuButton.actor.show();
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
this._disableUserList = undefined;
this._userListLoaded = false;
this._realmManager = new Realmd.Manager();
this._realmSignalId = this._realmManager.connect('login-format-changed',
Lang.bind(this, this._showRealmLoginHint));
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
this._startupCompleteId = Main.layoutManager.connect('startup-complete',
Lang.bind(this, this._updateDisableUserList));
},
_getBannerAllocation: function (dialogBox) {
let actorBox = new Clutter.ActorBox();
let [minWidth, minHeight, natWidth, natHeight] = this._bannerView.get_preferred_size();
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
actorBox.x1 = Math.floor(centerX - natWidth / 2);
actorBox.y1 = dialogBox.y1 + Main.layoutManager.panelBox.height;
actorBox.x2 = actorBox.x1 + natWidth;
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
},
_getLogoBinAllocation: function (dialogBox) {
let actorBox = new Clutter.ActorBox();
let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
actorBox.x1 = Math.floor(centerX - natWidth / 2);
actorBox.y1 = dialogBox.y2 - natHeight;
actorBox.x2 = actorBox.x1 + natWidth;
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
},
_getCenterActorAllocation: function (dialogBox, actor) {
let actorBox = new Clutter.ActorBox();
let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
natWidth = Math.min(natWidth, dialogBox.x2 - dialogBox.x1);
natHeight = Math.min(natHeight, dialogBox.y2 - dialogBox.y1);
actorBox.x1 = Math.floor(centerX - natWidth / 2);
actorBox.y1 = Math.floor(centerY - natHeight / 2);
actorBox.x2 = actorBox.x1 + natWidth;
actorBox.y2 = actorBox.y1 + natHeight;
return actorBox;
},
_onAllocate: function (actor, dialogBox, flags) {
let dialogWidth = dialogBox.x2 - dialogBox.x1;
let dialogHeight = dialogBox.y2 - dialogBox.y1;
// First find out what space the children require
let bannerAllocation = null;
let bannerHeight = 0;
let bannerWidth = 0;
if (this._bannerView.visible) {
bannerAllocation = this._getBannerAllocation(dialogBox, this._bannerView);
bannerHeight = bannerAllocation.y2 - bannerAllocation.y1;
bannerWidth = bannerAllocation.x2 - bannerAllocation.x1;
}
let authPromptAllocation = null;
let authPromptHeight = 0;
let authPromptWidth = 0;
if (this._authPrompt.actor.visible) {
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
authPromptHeight = authPromptAllocation.y2 - authPromptAllocation.y1;
authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
}
let userSelectionAllocation = null;
let userSelectionHeight = 0;
if (this._userSelectionBox.visible) {
userSelectionAllocation = this._getCenterActorAllocation(dialogBox, this._userSelectionBox);
userSelectionHeight = userSelectionAllocation.y2 - userSelectionAllocation.y1;
}
let logoAllocation = null;
let logoHeight = 0;
if (this._logoBin.visible) {
logoAllocation = this._getLogoBinAllocation(dialogBox);
logoHeight = logoAllocation.y2 - logoAllocation.y1;
}
// Then figure out if we're overly constrained and need to
// try a different layout, or if we have what extra space we
// can hand out
if (bannerAllocation) {
let bannerSpace;
if (authPromptAllocation)
bannerSpace = authPromptAllocation.y1 - bannerAllocation.y1;
else
bannerSpace = 0;
let leftOverYSpace = bannerSpace - bannerHeight;
if (leftOverYSpace > 0) {
// First figure out how much left over space is up top
let leftOverTopSpace = leftOverYSpace / 2;
// Then, shift the banner into the middle of that extra space
let yShift = Math.floor(leftOverTopSpace / 2);
bannerAllocation.y1 += yShift;
bannerAllocation.y2 += yShift;
} else {
// Then figure out how much space there would be if we switched to a
// wide layout with banner on one side and authprompt on the other.
let leftOverXSpace = dialogWidth - authPromptWidth;
// In a wide view, half of the available space goes to the banner,
// and the other half goes to the margins.
let wideBannerWidth = leftOverXSpace / 2;
let wideSpacing = leftOverXSpace - wideBannerWidth;
// If we do go with a wide layout, we need there to be at least enough
// space for the banner and the auth prompt to be the same width,
// so it doesn't look unbalanced.
if (authPromptWidth > 0 && wideBannerWidth > authPromptWidth) {
let centerX = dialogBox.x1 + dialogWidth / 2;
let centerY = dialogBox.y1 + dialogHeight / 2;
// A small portion of the spacing goes down the center of the
// screen to help delimit the two columns of the wide view
let centerGap = wideSpacing / 8;
// place the banner along the left edge of the center margin
bannerAllocation.x2 = Math.floor(centerX - centerGap / 2);
bannerAllocation.x1 = Math.floor(bannerAllocation.x2 - wideBannerWidth);
// figure out how tall it would like to be and try to accomodate
// but don't let it get too close to the logo
let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
let maxWideHeight = dialogHeight - 3 * logoHeight;
wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight);
bannerAllocation.y1 = Math.floor(centerY - wideBannerHeight / 2);
bannerAllocation.y2 = bannerAllocation.y1 + wideBannerHeight;
// place the auth prompt along the right edge of the center margin
authPromptAllocation.x1 = Math.floor(centerX + centerGap / 2);
authPromptAllocation.x2 = authPromptAllocation.x1 + authPromptWidth;
} else {
// If we aren't going to do a wide view, then we need to limit
// the height of the banner so it will present scrollbars
// First figure out how much space there is without the banner
leftOverYSpace += bannerHeight;
// Then figure out how much of that space is up top
let availableTopSpace = Math.floor(leftOverYSpace / 2);
// Then give all of that space to the banner
bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
}
}
} else if (userSelectionAllocation) {
// Grow the user list to fill the space
let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight;
if (leftOverYSpace > 0) {
let topExpansion = Math.floor(leftOverYSpace / 2);
let bottomExpansion = topExpansion;
userSelectionAllocation.y1 -= topExpansion;
userSelectionAllocation.y2 += bottomExpansion;
}
}
// Finally hand out the allocations
if (bannerAllocation) {
this._bannerView.allocate(bannerAllocation, flags);
}
if (authPromptAllocation)
this._authPrompt.actor.allocate(authPromptAllocation, flags);
if (userSelectionAllocation)
this._userSelectionBox.allocate(userSelectionAllocation, flags);
if (logoAllocation)
this._logoBin.allocate(logoAllocation, flags);
},
_ensureUserListLoaded: function() {
if (!this._userManager.is_loaded) {
if (!this._userManager.is_loaded)
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
Lang.bind(this, function() {
if (this._userManager.is_loaded) {
@ -698,11 +478,10 @@ const LoginDialog = new Lang.Class({
this._userManagerLoadedId = 0;
}
}));
} else {
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList));
GLib.Source.set_name_by_id(id, '[gnome-shell] _loadUserList');
}
},
else
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList));
},
_updateDisableUserList: function() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
@ -740,38 +519,21 @@ const LoginDialog = new Lang.Class({
}
},
_fadeInBannerView: function() {
this._bannerView.show();
Tweener.addTween(this._bannerView,
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
},
_hideBannerView: function() {
Tweener.removeTweens(this._bannerView);
this._bannerView.opacity = 0;
this._bannerView.hide();
},
_updateLogoTexture: function(cache, file) {
if (this._logoFile && !this._logoFile.equal(file))
_updateLogoTexture: function(cache, uri) {
if (this._logoFileUri != uri)
return;
this._logoBin.destroy_all_children();
if (this._logoFile) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
-1, _LOGO_ICON_HEIGHT,
scaleFactor));
}
if (this._logoFileUri)
this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri,
-1, _LOGO_ICON_HEIGHT));
},
_updateLogo: function() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
this._logoFile = path ? Gio.file_new_for_path(path) : null;
this._updateLogoTexture(this._textureCache, this._logoFile);
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
this._updateLogoTexture(this._textureCache, this._logoFileUri);
},
_onPrompted: function() {
@ -782,33 +544,11 @@ const LoginDialog = new Lang.Class({
this._showPrompt();
},
_resetGreeterProxy: function() {
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
if (this._greeter) {
this._greeter.run_dispose();
}
this._greeter = this._gdmClient.get_greeter_sync(null);
this._defaultSessionChangedId = this._greeter.connect('default-session-name-changed',
Lang.bind(this, this._onDefaultSessionChanged));
this._sessionOpenedId = this._greeter.connect('session-opened',
Lang.bind(this, this._onSessionOpened));
this._timedLoginRequestedId = this._greeter.connect('timed-login-requested',
Lang.bind(this, this._onTimedLoginRequested));
}
},
_onReset: function(authPrompt, beginRequest) {
this._resetGreeterProxy();
this._sessionMenuButton.updateSensitivity(true);
this._user = null;
if (this._nextSignalId) {
this._authPrompt.disconnect(this._nextSignalId);
this._nextSignalId = 0;
}
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
if (!this._disableUserList)
this._showUserList();
@ -843,7 +583,6 @@ const LoginDialog = new Lang.Class({
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
this._fadeInBannerView();
},
_showRealmLoginHint: function(realmManager, hint) {
@ -863,61 +602,29 @@ const LoginDialog = new Lang.Class({
this._authPrompt.setPasswordChar('');
this._authPrompt.setQuestion(_("Username: "));
this._showRealmLoginHint(this._realmManager.loginFormat);
let realmManager = new Realmd.Manager();
let realmSignalId = realmManager.connect('login-format-changed',
Lang.bind(this, this._showRealmLoginHint));
this._showRealmLoginHint(realmManager.loginFormat);
if (this._nextSignalId)
this._authPrompt.disconnect(this._nextSignalId);
this._nextSignalId = this._authPrompt.connect('next',
Lang.bind(this, function() {
this._authPrompt.disconnect(this._nextSignalId);
this._nextSignalId = 0;
this._authPrompt.updateSensitivity(false);
let answer = this._authPrompt.getAnswer();
this._user = this._userManager.get_user(answer);
this._authPrompt.clear();
this._authPrompt.startSpinning();
this._authPrompt.begin({ userName: answer });
this._updateCancelButton();
}));
let nextSignalId = this._authPrompt.connect('next',
Lang.bind(this, function() {
this._authPrompt.disconnect(nextSignalId);
this._authPrompt.updateSensitivity(false);
let answer = this._authPrompt.getAnswer();
this._user = this._userManager.get_user(answer);
this._authPrompt.clear();
this._authPrompt.startSpinning();
this._authPrompt.begin({ userName: answer });
this._updateCancelButton();
realmManager.disconnect(realmSignalId)
realmManager.release();
}));
this._updateCancelButton();
this._authPrompt.updateSensitivity(true);
this._showPrompt();
},
_loginScreenSessionActivated: function() {
if (this.actor.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
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() {
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
this._authPrompt.reset();
},
onCompleteScope: this });
},
_gotGreeterSessionProxy: function(proxy) {
this._greeterSessionProxy = proxy;
this._greeterSessionProxyChangedId =
proxy.connect('g-properties-changed', Lang.bind(this, function() {
if (proxy.Active)
this._loginScreenSessionActivated();
}));
},
_startSession: function(serviceName) {
Tweener.addTween(this.actor,
{ opacity: 0,
@ -933,7 +640,10 @@ const LoginDialog = new Lang.Class({
},
onUpdateScope: this,
onComplete: function() {
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
Mainloop.idle_add(Lang.bind(this, function() {
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
return GLib.SOURCE_REMOVE;
}));
},
onCompleteScope: this });
},
@ -989,7 +699,6 @@ const LoginDialog = new Lang.Class({
hold.release();
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginAnimationTime');
return hold;
},
@ -1092,9 +801,7 @@ const LoginDialog = new Lang.Class({
},
_showUserList: function() {
this._ensureUserListLoaded();
this._authPrompt.hide();
this._hideBannerView();
this._sessionMenuButton.close();
this._setUserListExpanded(true);
this._notListedButton.show();
@ -1113,11 +820,18 @@ const LoginDialog = new Lang.Class({
},
_onUserListActivated: function(activatedItem) {
let tasks = [function() {
return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
},
function() {
this._setUserListExpanded(false);
}];
this._user = activatedItem.user;
this._updateCancelButton();
let batch = new Batch.ConcurrentBatch(this, [GdmUtil.cloneAndFadeOutActor(this._userSelectionBox),
let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks),
this._beginVerificationForItem(activatedItem)]);
batch.run();
},
@ -1127,73 +841,26 @@ const LoginDialog = new Lang.Class({
this._userManager.disconnect(this._userManagerLoadedId);
this._userManagerLoadedId = 0;
}
if (this._userAddedId) {
this._userManager.disconnect(this._userAddedId);
this._userAddedId = 0;
}
if (this._userRemovedId) {
this._userManager.disconnect(this._userRemovedId);
this._userRemovedId = 0;
}
if (this._userChangedId) {
this._userManager.disconnect(this._userChangedId);
this._userChangedId = 0;
}
this._textureCache.disconnect(this._updateLogoTextureId);
Main.layoutManager.disconnect(this._startupCompleteId);
if (this._settings) {
this._settings.run_dispose();
this._settings = null;
}
if (this._greeter) {
this._greeter.disconnect(this._defaultSessionChangedId);
this._greeter.disconnect(this._sessionOpenedId);
this._greeter.disconnect(this._timedLoginRequestedId);
this._greeter = null;
}
if (this._greeterSessionProxy) {
this._greeterSessionProxy.disconnect(this._greeterSessionProxyChangedId);
this._greeterSessionProxy = null;
}
if (this._realmManager) {
this._realmManager.disconnect(this._realmSignalId);
this._realmSignalId = 0;
this._realmManager.release();
this._realmManager = null;
}
},
_loadUserList: function() {
if (this._userListLoaded)
return GLib.SOURCE_REMOVE;
this._userListLoaded = true;
let users = this._userManager.list_users();
for (let i = 0; i < users.length; i++) {
this._userList.addUser(users[i]);
}
this._userAddedId = this._userManager.connect('user-added',
Lang.bind(this, function(userManager, user) {
this._userList.addUser(user);
}));
this._updateDisableUserList();
this._userRemovedId = this._userManager.connect('user-removed',
Lang.bind(this, function(userManager, user) {
this._userList.removeUser(user);
}));
this._userManager.connect('user-added',
Lang.bind(this, function(userManager, user) {
this._userList.addUser(user);
}));
this._userChangedId = this._userManager.connect('user-changed',
Lang.bind(this, function(userManager, user) {
if (this._userList.containsUser(user) && user.locked)
this._userList.removeUser(user);
else if (!this._userList.containsUser(user) && !user.locked)
this._userList.addUser(user);
}));
return GLib.SOURCE_REMOVE;
this._userManager.connect('user-removed',
Lang.bind(this, function(userManager, user) {
this._userList.removeUser(user);
}));
},
open: function() {
@ -1205,8 +872,6 @@ const LoginDialog = new Lang.Class({
this.actor.show();
this.actor.opacity = 0;
Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
Tweener.addTween(this.actor,
{ opacity: 255,
time: 1,
@ -1216,8 +881,7 @@ const LoginDialog = new Lang.Class({
},
close: function() {
Main.popModal(this.actor);
Main.ctrlAltTabManager.removeGroup(this.actor);
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
},
cancel: function() {
@ -1225,7 +889,7 @@ const LoginDialog = new Lang.Class({
},
addCharacter: function(unichar) {
// Don't allow type ahead at the login screen
this._authPrompt.addCharacter(unichar);
},
finish: function(onComplete) {

View File

@ -35,8 +35,8 @@ const ALLOWED_FAILURES_KEY = 'allowed-failures';
const LOGO_KEY = 'logo';
const DISABLE_USER_LIST_KEY = 'disable-user-list';
// Give user 48ms to read each character of a PAM message
const USER_READ_TIME = 48
// Give user 16ms to read each character of a PAM message
const USER_READ_TIME = 16
const MessageType = {
NONE: 0,
@ -128,7 +128,7 @@ const ShellUserVerifier = new Lang.Class({
this._client = client;
this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed',
Lang.bind(this, this._updateDefaultService));
this._updateDefaultService();
@ -142,10 +142,10 @@ const ShellUserVerifier = new Lang.Class({
// after a user has been picked.
this._checkForSmartcard();
this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
Lang.bind(this, this._checkForSmartcard));
this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed',
Lang.bind(this, this._checkForSmartcard));
this._smartcardManager.connect('smartcard-inserted',
Lang.bind(this, this._checkForSmartcard));
this._smartcardManager.connect('smartcard-removed',
Lang.bind(this, this._checkForSmartcard));
this._messageQueue = [];
this._messageQueueTimeoutId = 0;
@ -159,8 +159,8 @@ const ShellUserVerifier = new Lang.Class({
if (this._oVirtCredentialsManager.hasToken())
this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
Lang.bind(this, this._oVirtUserAuthenticated));
this._oVirtCredentialsManager.connect('user-authenticated',
Lang.bind(this, this._oVirtUserAuthenticated));
},
begin: function(userName, hold) {
@ -191,37 +191,20 @@ const ShellUserVerifier = new Lang.Class({
}
},
_clearUserVerifier: function() {
if (this._userVerifier) {
this._userVerifier.run_dispose();
this._userVerifier = null;
}
},
clear: function() {
if (this._cancellable) {
this._cancellable.cancel();
this._cancellable = null;
}
this._clearUserVerifier();
if (this._userVerifier) {
this._userVerifier.run_dispose();
this._userVerifier = null;
}
this._clearMessageQueue();
},
destroy: function() {
this.clear();
this._settings.run_dispose();
this._settings = null;
this._smartcardManager.disconnect(this._smartcardInsertedId);
this._smartcardManager.disconnect(this._smartcardRemovedId);
this._smartcardManager = null;
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
this._oVirtCredentialsManager = null;
},
answerQuery: function(serviceName, answer) {
if (!this.hasPendingMessages) {
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
@ -269,7 +252,6 @@ const ShellUserVerifier = new Lang.Class({
this._queueMessageTimeout();
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
},
_queueMessage: function(message, messageType) {
@ -300,10 +282,9 @@ const ShellUserVerifier = new Lang.Class({
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this,
function(device, error) {
if (!error && device) {
if (!error && device)
this._haveFingerprintReader = true;
this._updateDefaultService();
}
}));
},
@ -317,7 +298,7 @@ const ShellUserVerifier = new Lang.Class({
if (!this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
smartcardDetected = false;
else if (this._reauthOnly)
else if (this.reauthenticating)
smartcardDetected = this._smartcardManager.hasInsertedLoginToken();
else
smartcardDetected = this._smartcardManager.hasInsertedTokens();
@ -344,7 +325,6 @@ const ShellUserVerifier = new Lang.Class({
_reauthenticationChannelOpened: function(client, result) {
try {
this._clearUserVerifier();
this._userVerifier = client.open_reauthentication_channel_finish(result);
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
return;
@ -368,7 +348,6 @@ const ShellUserVerifier = new Lang.Class({
_userVerifierGot: function(client, result) {
try {
this._clearUserVerifier();
this._userVerifier = client.get_user_verifier_finish(result);
} catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
return;
@ -410,7 +389,7 @@ const ShellUserVerifier = new Lang.Class({
_updateDefaultService: function() {
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
this._defaultService = PASSWORD_SERVICE_NAME;
else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
else if (this.smartcardDetected)
this._defaultService = SMARTCARD_SERVICE_NAME;
else if (this._haveFingerprintReader)
this._defaultService = FINGERPRINT_SERVICE_NAME;

View File

@ -16,9 +16,7 @@
<file>misc/fileUtils.js</file>
<file>misc/gnomeSession.js</file>
<file>misc/history.js</file>
<file>misc/ibusManager.js</file>
<file>misc/jsParse.js</file>
<file>misc/keyboardManager.js</file>
<file>misc/loginManager.js</file>
<file>misc/modemManager.js</file>
<file>misc/objectManager.js</file>
@ -27,16 +25,11 @@
<file>misc/util.js</file>
<file>perf/core.js</file>
<file>perf/hwtest.js</file>
<file>portalHelper/main.js</file>
<file>ui/accessDialog.js</file>
<file>ui/altTab.js</file>
<file>ui/animation.js</file>
<file>ui/appDisplay.js</file>
<file>ui/appFavorites.js</file>
<file>ui/audioDeviceSelection.js</file>
<file>ui/backgroundMenu.js</file>
<file>ui/background.js</file>
<file>ui/boxpointer.js</file>
@ -46,7 +39,6 @@
<file>ui/dash.js</file>
<file>ui/dateMenu.js</file>
<file>ui/dnd.js</file>
<file>ui/edgeDragAction.js</file>
<file>ui/endSessionDialog.js</file>
<file>ui/environment.js</file>
<file>ui/extensionDownloader.js</file>
@ -59,17 +51,13 @@
<file>ui/layout.js</file>
<file>ui/lightbox.js</file>
<file>ui/lookingGlass.js</file>
<file>ui/legacyTray.js</file>
<file>ui/magnifier.js</file>
<file>ui/magnifierDBus.js</file>
<file>ui/main.js</file>
<file>ui/messageTray.js</file>
<file>ui/messageList.js</file>
<file>ui/modalDialog.js</file>
<file>ui/mpris.js</file>
<file>ui/notificationDaemon.js</file>
<file>ui/osdWindow.js</file>
<file>ui/osdMonitorLabeler.js</file>
<file>ui/overview.js</file>
<file>ui/overviewControls.js</file>
<file>ui/panel.js</file>
@ -96,7 +84,6 @@
<file>ui/userWidget.js</file>
<file>ui/viewSelector.js</file>
<file>ui/windowAttentionHandler.js</file>
<file>ui/windowMenu.js</file>
<file>ui/windowManager.js</file>
<file>ui/workspace.js</file>
<file>ui/workspaceSwitcherPopup.js</file>

View File

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

View File

@ -43,7 +43,7 @@ function getCurrentExtension() {
let path = match[1];
let file = Gio.File.new_for_path(path);
// Walk up the directory tree, looking for an extension with
// Walk up the directory tree, looking for an extesion with
// the same UUID as a directory name.
while (file != null) {
let extension = extensions[file.get_basename()];

View File

@ -1,234 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Signals = imports.signals;
try {
var IBus = imports.gi.IBus;
_checkIBusVersion(1, 5, 2);
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
} catch (e) {
var IBus = null;
log(e);
}
let _ibusManager = null;
function _checkIBusVersion(requiredMajor, requiredMinor, requiredMicro) {
if ((IBus.MAJOR_VERSION > requiredMajor) ||
(IBus.MAJOR_VERSION == requiredMajor && IBus.MINOR_VERSION > requiredMinor) ||
(IBus.MAJOR_VERSION == requiredMajor && IBus.MINOR_VERSION == requiredMinor &&
IBus.MICRO_VERSION >= requiredMicro))
return;
throw "Found IBus version %d.%d.%d but required is %d.%d.%d".
format(IBus.MAJOR_VERSION, IBus.MINOR_VERSION, IBus.MINOR_VERSION,
requiredMajor, requiredMinor, requiredMicro);
}
function getIBusManager() {
if (_ibusManager == null)
_ibusManager = new IBusManager();
return _ibusManager;
}
const IBusManager = new Lang.Class({
Name: 'IBusManager',
// This is the longest we'll keep the keyboard frozen until an input
// source is active.
_MAX_INPUT_SOURCE_ACTIVATION_TIME: 4000, // ms
_PRELOAD_ENGINES_DELAY_TIME: 30, // sec
_init: function() {
if (!IBus)
return;
IBus.init();
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
this._panelService = null;
this._engines = {};
this._ready = false;
this._registerPropertiesId = 0;
this._currentEngineName = null;
this._preloadEnginesId = 0;
this._ibus = IBus.Bus.new_async();
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
// Need to set this to get 'global-engine-changed' emitions
this._ibus.set_watch_ibus_signal(true);
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
this._spawn();
},
_spawn: function() {
try {
Gio.Subprocess.new(['ibus-daemon', '--xim', '--panel', 'disable'],
Gio.SubprocessFlags.NONE);
} catch(e) {
log('Failed to launch ibus-daemon: ' + e.message);
}
},
_clear: function() {
if (this._panelService)
this._panelService.destroy();
this._panelService = null;
this._candidatePopup.setPanelService(null);
this._engines = {};
this._ready = false;
this._registerPropertiesId = 0;
this._currentEngineName = null;
this.emit('ready', false);
this._spawn();
},
_onConnected: function() {
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
this._ibus.request_name_async(IBus.SERVICE_PANEL,
IBus.BusNameFlag.REPLACE_EXISTING,
-1, null,
Lang.bind(this, this._initPanelService));
},
_initEngines: function(ibus, result) {
let enginesList = this._ibus.list_engines_async_finish(result);
if (enginesList) {
for (let i = 0; i < enginesList.length; ++i) {
let name = enginesList[i].get_name();
this._engines[name] = enginesList[i];
}
this._updateReadiness();
} else {
this._clear();
}
},
_initPanelService: function(ibus, result) {
let success = this._ibus.request_name_async_finish(result);
if (success) {
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
object_path: IBus.PATH_PANEL });
this._candidatePopup.setPanelService(this._panelService);
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
try {
// IBus versions older than 1.5.10 have a bug which
// causes spurious set-content-type emissions when
// switching input focus that temporarily lose purpose
// and hints defeating its intended semantics and
// confusing users. We thus don't use it in that case.
_checkIBusVersion(1, 5, 10);
this._panelService.connect('set-content-type', Lang.bind(this, this._setContentType));
} catch (e) {
}
// If an engine is already active we need to get its properties
this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
let engine;
try {
engine = this._ibus.get_global_engine_async_finish(result);
if (!engine)
return;
} catch(e) {
return;
}
this._engineChanged(this._ibus, engine.get_name());
}));
this._updateReadiness();
} else {
this._clear();
}
},
_updateReadiness: function() {
this._ready = (Object.keys(this._engines).length > 0 &&
this._panelService != null);
this.emit('ready', this._ready);
},
_engineChanged: function(bus, engineName) {
if (!this._ready)
return;
this._currentEngineName = engineName;
if (this._registerPropertiesId != 0)
return;
this._registerPropertiesId =
this._panelService.connect('register-properties', Lang.bind(this, function(p, props) {
if (!props.get(0))
return;
this._panelService.disconnect(this._registerPropertiesId);
this._registerPropertiesId = 0;
this.emit('properties-registered', this._currentEngineName, props);
}));
},
_updateProperty: function(panel, prop) {
this.emit('property-updated', this._currentEngineName, prop);
},
_setContentType: function(panel, purpose, hints) {
this.emit('set-content-type', purpose, hints);
},
activateProperty: function(key, state) {
this._panelService.property_activate(key, state);
},
getEngineDesc: function(id) {
if (!IBus || !this._ready)
return null;
return this._engines[id];
},
setEngine: function(id, callback) {
// Send id even if id == this._currentEngineName
// because 'properties-registered' signal can be emitted
// while this._ibusSources == null on a lock screen.
if (!IBus || !this._ready) {
if (callback)
callback();
return;
}
this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
null, callback);
},
preloadEngines: function(ids) {
if (!IBus || !this._ibus || ids.length == 0)
return;
if (this._preloadEnginesId != 0) {
Mainloop.source_remove(this._preloadEnginesId);
this._preloadEnginesId = 0;
}
this._preloadEnginesId =
Mainloop.timeout_add_seconds(this._PRELOAD_ENGINES_DELAY_TIME,
Lang.bind(this, function() {
this._ibus.preload_engines_async(
ids,
-1,
null,
null);
this._preloadEnginesId = 0;
return GLib.SOURCE_REMOVE;
}));
},
});
Signals.addSignalMethods(IBusManager.prototype);

View File

@ -1,153 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const GnomeDesktop = imports.gi.GnomeDesktop;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Main = imports.ui.main;
const DEFAULT_LOCALE = 'en_US';
const DEFAULT_LAYOUT = 'us';
const DEFAULT_VARIANT = '';
let _xkbInfo = null;
function getXkbInfo() {
if (_xkbInfo == null)
_xkbInfo = new GnomeDesktop.XkbInfo();
return _xkbInfo;
}
let _keyboardManager = null;
function getKeyboardManager() {
if (_keyboardManager == null)
_keyboardManager = new KeyboardManager();
return _keyboardManager;
}
function releaseKeyboard() {
if (Main.modalCount > 0)
global.display.unfreeze_keyboard(global.get_current_time());
else
global.display.ungrab_keyboard(global.get_current_time());
}
function holdKeyboard() {
global.display.freeze_keyboard(global.get_current_time());
}
const KeyboardManager = new Lang.Class({
Name: 'KeyboardManager',
// The XKB protocol doesn't allow for more that 4 layouts in a
// keymap. Wayland doesn't impose this limit and libxkbcommon can
// handle up to 32 layouts but since we need to support X clients
// even as a Wayland compositor, we can't bump this.
MAX_LAYOUTS_PER_GROUP: 4,
_init: function() {
this._xkbInfo = getXkbInfo();
this._current = null;
this._localeLayoutInfo = this._getLocaleLayout();
this._layoutInfos = {};
},
_applyLayoutGroup: function(group) {
let options = this._buildOptionsString();
let [layouts, variants] = this._buildGroupStrings(group);
Meta.get_backend().set_keymap(layouts, variants, options);
},
_applyLayoutGroupIndex: function(idx) {
Meta.get_backend().lock_layout_group(idx);
},
apply: function(id) {
let info = this._layoutInfos[id];
if (!info)
return;
if (this._current && this._current.group == info.group) {
if (this._current.groupIndex != info.groupIndex)
this._applyLayoutGroupIndex(info.groupIndex);
} else {
this._applyLayoutGroup(info.group);
this._applyLayoutGroupIndex(info.groupIndex);
}
this._current = info;
},
reapply: function() {
if (!this._current)
return;
this._applyLayoutGroup(this._current.group);
this._applyLayoutGroupIndex(this._current.groupIndex);
},
setUserLayouts: function(ids) {
this._current = null;
this._layoutInfos = {};
for (let i = 0; i < ids.length; ++i) {
let [found, , , _layout, _variant] = this._xkbInfo.get_layout_info(ids[i]);
if (found)
this._layoutInfos[ids[i]] = { id: ids[i], layout: _layout, variant: _variant };
}
let i = 0;
let group = [];
for (let id in this._layoutInfos) {
// We need to leave one slot on each group free so that we
// can add a layout containing the symbols for the
// language used in UI strings to ensure that toolkits can
// handle mnemonics like Alt+Ф even if the user is
// actually typing in a different layout.
let groupIndex = i % (this.MAX_LAYOUTS_PER_GROUP - 1);
if (groupIndex == 0)
group = [];
let info = this._layoutInfos[id];
group[groupIndex] = info;
info.group = group;
info.groupIndex = groupIndex;
i += 1;
}
},
_getLocaleLayout: function() {
let locale = GLib.get_language_names()[0];
if (locale.indexOf('_') == -1)
locale = DEFAULT_LOCALE;
let [found, , id] = GnomeDesktop.get_input_source_from_locale(locale);
if (!found)
[, , id] = GnomeDesktop.get_input_source_from_locale(DEFAULT_LOCALE);
let [found, , , _layout, _variant] = this._xkbInfo.get_layout_info(id);
if (found)
return { layout: _layout, variant: _variant };
else
return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT };
},
_buildGroupStrings: function(_group) {
let group = _group.concat(this._localeLayoutInfo);
let layouts = group.map(function(g) { return g.layout; }).join(',');
let variants = group.map(function(g) { return g.variant; }).join(',');
return [layouts, variants];
},
setKeyboardOptions: function(options) {
this._xkbOptions = options;
},
_buildOptionsString: function() {
let options = this._xkbOptions.join(',');
return options;
}
});

View File

@ -39,16 +39,38 @@ const SystemdLoginSessionIface = '<node> \
<interface name="org.freedesktop.login1.Session"> \
<signal name="Lock" /> \
<signal name="Unlock" /> \
<property name="Active" type="b" access="read" /> \
<method name="SetLockedHint"> \
<arg type="b" direction="in"/> \
</method> \
</interface> \
</node>';
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
const ConsoleKitManagerIface = '<node> \
<interface name="org.freedesktop.ConsoleKit.Manager"> \
<method name="CanRestart"> \
<arg type="b" direction="out"/> \
</method> \
<method name="CanStop"> \
<arg type="b" direction="out"/> \
</method> \
<method name="Restart" /> \
<method name="Stop" /> \
<method name="GetCurrentSession"> \
<arg type="o" direction="out" /> \
</method> \
</interface> \
</node>';
const ConsoleKitSessionIface = '<node> \
<interface name="org.freedesktop.ConsoleKit.Session"> \
<signal name="Lock" /> \
<signal name="Unlock" /> \
</interface> \
</node>';
const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
function haveSystemd() {
return GLib.access("/run/systemd/seats", 0) >= 0;
}
@ -78,7 +100,7 @@ function canLock() {
-1, null);
let version = result.deep_unpack()[0].deep_unpack();
return haveSystemd() && versionCompare('3.5.91', version);
return versionCompare('3.5.91', version);
} catch(e) {
return false;
}
@ -96,7 +118,7 @@ function getLoginManager() {
if (haveSystemd())
_loginManager = new LoginManagerSystemd();
else
_loginManager = new LoginManagerDummy();
_loginManager = new LoginManagerConsoleKit();
}
return _loginManager;
@ -113,6 +135,9 @@ const LoginManagerSystemd = new Lang.Class({
Lang.bind(this, this._prepareForSleep));
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function(callback) {
if (this._currentSession) {
callback (this._currentSession);
@ -134,13 +159,10 @@ const LoginManagerSystemd = new Lang.Class({
canSuspend: function(asyncCallback) {
this._proxy.CanSuspendRemote(function(result, error) {
if (error) {
asyncCallback(false, false);
} else {
let needsAuth = result[0] == 'challenge';
let canSuspend = needsAuth || result[0] == 'yes';
asyncCallback(canSuspend, needsAuth);
}
if (error)
asyncCallback(false);
else
asyncCallback(result[0] != 'no');
});
},
@ -168,7 +190,7 @@ const LoginManagerSystemd = new Lang.Class({
let fd = -1;
try {
let [outVariant, fdList] = proxy.call_with_unix_fd_list_finish(result);
fd = fdList.steal_fds()[0];
fd = fdList.steal_fds(outVariant.deep_unpack())[0];
callback(new Gio.UnixInputStream({ fd: fd }));
} catch(e) {
logError(e, "Error getting systemd inhibitor");
@ -183,17 +205,39 @@ const LoginManagerSystemd = new Lang.Class({
});
Signals.addSignalMethods(LoginManagerSystemd.prototype);
const LoginManagerDummy = new Lang.Class({
Name: 'LoginManagerDummy',
const LoginManagerConsoleKit = new Lang.Class({
Name: 'LoginManagerConsoleKit',
_init: function() {
this._proxy = new ConsoleKitManager(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager');
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function(callback) {
// we could return a DummySession object that fakes whatever callers
// expect (at the time of writing: connect() and connectSignal()
// methods), but just never calling the callback should be safer
if (this._currentSession) {
callback (this._currentSession);
return;
}
this._proxy.GetCurrentSessionRemote(Lang.bind(this,
function(result, error) {
if (error) {
logError(error, 'Could not get a proxy for the current session');
} else {
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
result[0]);
callback(this._currentSession);
}
}));
},
canSuspend: function(asyncCallback) {
asyncCallback(false, false);
asyncCallback(false);
},
listSessions: function(asyncCallback) {
@ -209,4 +253,4 @@ const LoginManagerDummy = new Lang.Class({
callback(null);
}
});
Signals.addSignalMethods(LoginManagerDummy.prototype);
Signals.addSignalMethods(LoginManagerConsoleKit.prototype);

View File

@ -4,12 +4,10 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const Params = imports.misc.params;
const SCROLL_TIME = 0.1;
@ -40,8 +38,6 @@ const _urlRegexp = new RegExp(
')' +
')', 'gi');
let _desktopSettings = null;
// findUrls:
// @str: string to find URLs in
//
@ -133,7 +129,7 @@ function trySpawn(argv)
// Dummy child watch; we don't want to double-fork internally
// because then we lose the parent-child relationship, which
// can break polkit. See https://bugzilla.redhat.com//show_bug.cgi?id=819275
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function () {});
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function () {}, null);
}
// trySpawnCommandLine:
@ -161,105 +157,6 @@ function _handleSpawnError(command, err) {
Main.notifyError(title, err.message);
}
function formatTime(time, params) {
let date;
// HACK: The built-in Date type sucks at timezones, which we need for the
// world clock; it's often more convenient though, so allow either
// Date or GLib.DateTime as parameter
if (time instanceof Date)
date = GLib.DateTime.new_from_unix_local(time.getTime() / 1000);
else
date = time;
let now = GLib.DateTime.new_now_local();
let daysAgo = now.difference(date) / (24 * 60 * 60 * 1000 * 1000);
let format;
if (_desktopSettings == null)
_desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
let clockFormat = _desktopSettings.get_string('clock-format');
let hasAmPm = date.format('%p') != '';
params = Params.parse(params, { timeOnly: false });
if (clockFormat == '24h' || !hasAmPm) {
// Show only the time if date is on today
if (daysAgo < 1 || params.timeOnly)
/* Translators: Time in 24h format */
format = N_("%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 = N_("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 = N_("%A, %H\u2236%M");
else if (date.get_year() == now.get_year())
/* 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 = N_("%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 = N_("%B %d %Y, %H\u2236%M");
} else {
// Show only the time if date is on today
if (daysAgo < 1 || params.timeOnly)
/* Translators: Time in 12h format */
format = N_("%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 = N_("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 = N_("%A, %l\u2236%M %p");
else if (date.get_year() == now.get_year())
/* 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 = N_("%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 = N_("%B %d %Y, %l\u2236%M %p");
}
return date.format(Shell.util_translate_time_string(format));
}
function createTimeLabel(date, params) {
if (_desktopSettings == null)
_desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
let label = new St.Label({ text: formatTime(date, params) });
let id = _desktopSettings.connect('changed::clock-format', function() {
label.text = formatTime(date, params);
});
label.connect('destroy', function() {
_desktopSettings.disconnect(id);
});
return label;
}
// lowerBound:
// @array: an array or array-like object, already sorted
// according to @cmp

View File

@ -72,9 +72,6 @@ function run() {
Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view");
Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view");
// Enable recording of timestamps for different points in the frame cycle
global.frame_timestamps = true;
Main.overview.connect('shown', function() {
Scripting.scriptEvent('overviewShowDone');
});
@ -90,10 +87,7 @@ function run() {
yield Scripting.destroyTestWindows();
for (let k = 0; k < config.count; k++)
yield Scripting.createTestWindow({ width: config.width,
height: config.height,
alpha: config.alpha,
maximized: config.maximized });
yield Scripting.createTestWindow(config.width, config.height, config.alpha, config.maximized);
yield Scripting.waitTestWindows();
yield Scripting.sleep(1000);

View File

@ -1,308 +0,0 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Main = imports.ui.main;
const Scripting = imports.ui.scripting;
const Shell = imports.gi.Shell;
let METRICS = {
timeToDesktop:
{ description: "Time from starting graphical.target to desktop showing",
units: "us" },
overviewShowTime:
{ description: "Time to switch to overview view, first time",
units: "us" },
applicationsShowTime:
{ description: "Time to switch to applications view, first time",
units: "us" },
mainViewRedrawTime:
{ description: "Time to redraw the main view, full screen",
units: "us" },
overviewRedrawTime:
{ description: "Time to redraw the overview, full screen, 5 windows",
units: "us" },
applicationRedrawTime:
{ description: "Time to redraw frame with a maximized application update",
units: "us" },
geditStartTime:
{ description: "Time from gedit launch to window drawn",
units: "us" },
}
function waitAndDraw(milliseconds) {
let cb;
let timeline = new Clutter.Timeline({ duration: milliseconds });
timeline.start();
timeline.connect('new-frame',
function(timeline, frame) {
global.stage.queue_redraw();
});
timeline.connect('completed',
function() {
timeline.stop();
if (cb)
cb();
});
return function(callback) {
cb = callback;
};
}
function waitSignal(object, signal) {
let cb;
let id = object.connect(signal, function() {
object.disconnect(id);
if (cb)
cb();
});
return function(callback) {
cb = callback;
};
}
function extractBootTimestamp() {
let sp = Gio.Subprocess.new(['journalctl', '-b',
'MESSAGE_ID=7d4958e842da4a758f6c1cdc7b36dcc5',
'UNIT=graphical.target',
'-o',
'json'],
Gio.SubprocessFlags.STDOUT_PIPE);
let result = null;
let datastream = Gio.DataInputStream.new(sp.get_stdout_pipe());
while (true) {
let [line, length] = datastream.read_line_utf8(null);
if (line === null)
break;
let fields = JSON.parse(line);
result = Number(fields['__MONOTONIC_TIMESTAMP']);
}
datastream.close(null);
return result;
}
function run() {
Scripting.defineScriptEvent("desktopShown", "Finished initial animation");
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view");
Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view");
Scripting.defineScriptEvent("mainViewDrawStart", "Drawing main view");
Scripting.defineScriptEvent("mainViewDrawDone", "Ending timing main view drawing");
Scripting.defineScriptEvent("overviewDrawStart", "Drawing overview");
Scripting.defineScriptEvent("overviewDrawDone", "Ending timing overview drawing");
Scripting.defineScriptEvent("redrawTestStart", "Drawing application window");
Scripting.defineScriptEvent("redrawTestDone", "Ending timing application window drawing");
Scripting.defineScriptEvent("collectTimings", "Accumulate frame timings from redraw tests");
Scripting.defineScriptEvent("geditLaunch", "gedit application launch");
Scripting.defineScriptEvent("geditFirstFrame", "first frame of gedit window drawn");
yield Scripting.waitLeisure();
Scripting.scriptEvent('desktopShown');
Gtk.Settings.get_default().gtk_enable_animations = false;
Scripting.scriptEvent('overviewShowStart');
Main.overview.show();
yield Scripting.waitLeisure();
Scripting.scriptEvent('overviewShowDone');
yield Scripting.sleep(1000);
Scripting.scriptEvent('applicationsShowStart');
Main.overview._dash.showAppsButton.checked = true;
yield Scripting.waitLeisure();
Scripting.scriptEvent('applicationsShowDone');
yield Scripting.sleep(1000);
Main.overview.hide();
yield Scripting.waitLeisure();
////////////////////////////////////////
// Tests of redraw speed
////////////////////////////////////////
global.frame_timestamps = true;
global.frame_finish_timestamp = true;
for (let k = 0; k < 5; k++)
yield Scripting.createTestWindow(640, 480,
{ maximized: true });
yield Scripting.waitTestWindows();
yield Scripting.sleep(1000);
Scripting.scriptEvent('mainViewDrawStart');
yield waitAndDraw(1000);
Scripting.scriptEvent('mainViewDrawDone');
Main.overview.show();
Scripting.waitLeisure();
yield Scripting.sleep(1500);
Scripting.scriptEvent('overviewDrawStart');
yield waitAndDraw(1000);
Scripting.scriptEvent('overviewDrawDone');
yield Scripting.destroyTestWindows();
Main.overview.hide();
yield Scripting.createTestWindow(640, 480,
{ maximized: true,
redraws: true});
yield Scripting.waitTestWindows();
yield Scripting.sleep(1000);
Scripting.scriptEvent('redrawTestStart');
yield Scripting.sleep(1000);
Scripting.scriptEvent('redrawTestDone');
yield Scripting.sleep(1000);
Scripting.scriptEvent('collectTimings');
yield Scripting.destroyTestWindows();
global.frame_timestamps = false;
global.frame_finish_timestamp = false;
yield Scripting.sleep(1000);
////////////////////////////////////////
let appSys = Shell.AppSystem.get_default();
let app = appSys.lookup_app('org.gnome.gedit.desktop');
Scripting.scriptEvent('geditLaunch');
app.activate();
let windows = app.get_windows();
if (windows.length > 0)
throw new Error('gedit was already running');
while (windows.length == 0) {
yield waitSignal(global.display, 'window-created');
windows = app.get_windows();
}
let actor = windows[0].get_compositor_private();
yield waitSignal(actor, 'first-frame');
Scripting.scriptEvent('geditFirstFrame');
yield Scripting.sleep(1000);
windows[0].delete(global.get_current_time());
yield Scripting.sleep(1000);
Gtk.Settings.get_default().gtk_enable_animations = true;
}
let overviewShowStart;
let applicationsShowStart;
let stagePaintStart;
let redrawTiming;
let redrawTimes = {};
let geditLaunchTime;
function script_desktopShown(time) {
let bootTimestamp = extractBootTimestamp();
METRICS.timeToDesktop.value = time - bootTimestamp;
}
function script_overviewShowStart(time) {
overviewShowStart = time;
}
function script_overviewShowDone(time) {
METRICS.overviewShowTime.value = time - overviewShowStart;
}
function script_applicationsShowStart(time) {
applicationsShowStart = time;
}
function script_applicationsShowDone(time) {
METRICS.applicationsShowTime.value = time - applicationsShowStart;
}
function script_mainViewDrawStart(time) {
redrawTiming = 'mainView';
}
function script_mainViewDrawDone(time) {
redrawTiming = null;
}
function script_overviewDrawStart(time) {
redrawTiming = 'overview';
}
function script_overviewDrawDone(time) {
redrawTiming = null;
}
function script_redrawTestStart(time) {
redrawTiming = 'application';
}
function script_redrawTestDone(time) {
redrawTiming = null;
}
function script_collectTimings(time) {
for (let timing in redrawTimes) {
let times = redrawTimes[timing];
times.sort(function(a, b) { return a - b });
let len = times.length;
let median;
if (len == 0)
median = -1;
else if (len % 2 == 1)
median = times[(len - 1)/ 2];
else
median = Math.round((times[len / 2 - 1] + times[len / 2]) / 2);
METRICS[timing + 'RedrawTime'].value = median;
}
}
function script_geditLaunch(time) {
geditLaunchTime = time;
}
function script_geditFirstFrame(time) {
METRICS.geditStartTime.value = time - geditLaunchTime;
}
function clutter_stagePaintStart(time) {
stagePaintStart = time;
}
function clutter_paintCompletedTimestamp(time) {
if (redrawTiming != null && stagePaintStart != null) {
if (!(redrawTiming in redrawTimes))
redrawTimes[redrawTiming] = [];
redrawTimes[redrawTiming].push(time - stagePaintStart);
}
stagePaintStart = null;
}

View File

@ -1,247 +0,0 @@
const Format = imports.format;
const Gettext = imports.gettext;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Pango = imports.gi.Pango;
const Soup = imports.gi.Soup;
const WebKit = imports.gi.WebKit2;
const _ = Gettext.gettext;
const Config = imports.misc.config;
const PortalHelperResult = {
CANCELLED: 0,
COMPLETED: 1,
RECHECK: 2
};
const INACTIVITY_TIMEOUT = 30000; //ms
const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
const HelperDBusInterface = '<node> \
<interface name="org.gnome.Shell.PortalHelper"> \
<method name="Authenticate"> \
<arg type="o" direction="in" name="connection" /> \
<arg type="s" direction="in" name="url" /> \
<arg type="u" direction="in" name="timestamp" /> \
</method> \
<method name="Close"> \
<arg type="o" direction="in" name="connection" /> \
</method> \
<method name="Refresh"> \
<arg type="o" direction="in" name="connection" /> \
</method> \
<signal name="Done"> \
<arg type="o" name="connection" /> \
<arg type="u" name="result" /> \
</signal> \
</interface> \
</node>';
const PortalWindow = new Lang.Class({
Name: 'PortalWindow',
Extends: Gtk.ApplicationWindow,
_init: function(application, url, timestamp, doneCallback) {
this.parent({ application: application });
if (!url) {
url = 'http://nmcheck.gnome.org';
this._originalUrlWasGnome = true;
} else {
this._originalUrlWasGnome = false;
}
this._uri = new Soup.URI(url);
this._everSeenRedirect = false;
this._originalUrl = url;
this._doneCallback = doneCallback;
this._lastRecheck = 0;
this._recheckAtExit = false;
this._webView = new WebKit.WebView();
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy));
this._webView.load_uri(url);
this._webView.connect('notify::title', Lang.bind(this, this._syncTitle));
this._syncTitle();
this.add(this._webView);
this._webView.show();
this.maximize();
this.present_with_time(timestamp);
},
_syncTitle: function() {
let title = this._webView.title;
if (title) {
this.title = title;
} else {
/* TRANSLATORS: this is the title of the wifi captive portal login
* window, until we know the title of the actual login page */
this.title = _("Web Authentication Redirect");
}
},
refresh: function() {
this._everSeenRedirect = false;
this._webView.load_uri(this._originalUrl);
},
vfunc_delete_event: function(event) {
if (this._recheckAtExit)
this._doneCallback(PortalHelperResult.RECHECK);
else
this._doneCallback(PortalHelperResult.CANCELLED);
return false;
},
_onDecidePolicy: function(view, decision, type) {
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
decision.ignore();
return true;
}
if (type != WebKit.PolicyDecisionType.NAVIGATION_ACTION)
return false;
let request = decision.get_request();
let uri = new Soup.URI(request.get_uri());
if (!uri.host_equal(this._uri) && this._originalUrlWasGnome) {
if (uri.get_host() == 'nmcheck.gnome.org' && this._everSeenRedirect) {
// Yay, we got to gnome!
decision.ignore();
this._doneCallback(PortalHelperResult.COMPLETED);
return true;
} else if (uri.get_host() != 'nmcheck.gnome.org') {
this._everSeenRedirect = true;
}
}
// We *may* have finished here, but we don't know for
// sure. Tell gnome-shell to run another connectivity check
// (but ratelimit the checks, we don't want to spam
// nmcheck.gnome.org for portals that have 10 or more internal
// redirects - and unfortunately they exist)
// If we hit the rate limit, we also queue a recheck
// when the window is closed, just in case we miss the
// final check and don't realize we're connected
// This should not be a problem in the cancelled logic,
// because if the user doesn't want to start the login,
// we should not see any redirect at all, outside this._uri
let now = GLib.get_monotonic_time();
let shouldRecheck = (now - this._lastRecheck) >
CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT;
if (shouldRecheck) {
this._lastRecheck = now;
this._recheckAtExit = false;
this._doneCallback(PortalHelperResult.RECHECK);
} else {
this._recheckAtExit = true;
}
// Update the URI, in case of chained redirects, so we still
// think we're doing the login until gnome-shell kills us
this._uri = uri;
decision.use();
return true;
},
});
const WebPortalHelper = new Lang.Class({
Name: 'WebPortalHelper',
Extends: Gtk.Application,
_init: function() {
this.parent({ application_id: 'org.gnome.Shell.PortalHelper',
flags: Gio.ApplicationFlags.IS_SERVICE,
inactivity_timeout: 30000 });
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(HelperDBusInterface, this);
this._queue = [];
},
vfunc_dbus_register: function(connection, path) {
this._dbusImpl.export(connection, path);
this.parent(connection, path);
return true;
},
vfunc_dbus_unregister: function(connection, path) {
this._dbusImpl.unexport_from_connection(connection);
this.parent(connection, path);
},
vfunc_activate: function() {
// If launched manually (for example for testing), force a dummy authentication
// session with the default url
this.Authenticate('/org/gnome/dummy', '', 0);
},
Authenticate: function(connection, url, timestamp) {
this._queue.push({ connection: connection, url: url, timestamp: timestamp });
this._processQueue();
},
Close: function(connection) {
for (let i = 0; i < this._queue.length; i++) {
let obj = this._queue[i];
if (obj.connection == connection) {
if (obj.window)
obj.window.destroy();
this._queue.splice(i, 1);
break;
}
}
this._processQueue();
},
Refresh: function(connection) {
for (let i = 0; i < this._queue.length; i++) {
let obj = this._queue[i];
if (obj.connection == connection) {
if (obj.window)
obj.window.refresh();
break;
}
}
},
_processQueue: function() {
if (this._queue.length == 0)
return;
let top = this._queue[0];
if (top.window != null)
return;
top.window = new PortalWindow(this, top.uri, top.timestamp, Lang.bind(this, function(result) {
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
}));
},
});
function initEnvironment() {
String.prototype.format = Format.format;
}
function main(argv) {
initEnvironment();
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
Gettext.textdomain(Config.GETTEXT_PACKAGE);
let app = new WebPortalHelper();
return app.run(argv);
}

View File

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

View File

@ -24,7 +24,7 @@ const WINDOW_PREVIEW_SIZE = 128;
const APP_ICON_SIZE = 96;
const APP_ICON_SIZE_SMALL = 48;
const baseIconSizes = [96, 64, 48, 32, 22];
const iconSizes = [96, 64, 48, 32, 22];
const AppIconMode = {
THUMBNAIL_ONLY: 1,
@ -33,9 +33,10 @@ const AppIconMode = {
};
function _createWindowClone(window, size) {
let [width, height] = window.get_size();
let windowTexture = window.get_texture();
let [width, height] = windowTexture.get_size();
let scale = Math.min(1.0, size / width, size / height);
return new Clutter.Clone({ source: window,
return new Clutter.Clone({ source: windowTexture,
width: width * scale,
height: height * scale,
x_align: Clutter.ActorAlign.CENTER,
@ -45,19 +46,6 @@ function _createWindowClone(window, size) {
y_expand: true });
};
function getWindows(workspace) {
// We ignore skip-taskbar windows in switchers, but if they are attached
// to their parent, their position in the MRU list may be more appropriate
// than the parent; so start with the complete list ...
let windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL,
workspace);
// ... map windows to their parent where appropriate ...
return windows.map(w => {
return w.is_attached_dialog() ? w.get_transient_for() : w;
// ... and filter out skip-taskbar windows and duplicates
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
}
const AppSwitcherPopup = new Lang.Class({
Name: 'AppSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
@ -70,14 +58,6 @@ const AppSwitcherPopup = new Lang.Class({
this._currentWindow = -1;
this.thumbnailsVisible = false;
let apps = Shell.AppSystem.get_default().get_running ();
if (apps.length == 0)
return;
this._switcherList = new AppSwitcher(apps, this);
this._items = this._switcherList.icons;
},
_allocate: function (actor, box, flags) {
@ -93,6 +73,7 @@ const AppSwitcherPopup = new Lang.Class({
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
let vPadding = this.actor.get_theme_node().get_vertical_padding();
let hPadding = leftPadding + rightPadding;
let icon = this._items[this._selectedIndex].actor;
@ -118,6 +99,20 @@ const AppSwitcherPopup = new Lang.Class({
}
},
_createSwitcher: function() {
let apps = Shell.AppSystem.get_default().get_running ();
if (apps.length == 0)
return false;
this._switcherList = new AppSwitcher(apps, this);
this._items = this._switcherList.icons;
if (this._items.length == 0)
return false;
return true;
},
_initialSelection: function(backward, binding) {
if (binding == 'switch-group') {
if (backward) {
@ -156,13 +151,13 @@ const AppSwitcherPopup = new Lang.Class({
this._items[this._selectedIndex].cachedWindows.length);
},
_keyPressHandler: function(keysym, action) {
_keyPressHandler: function(keysym, backwards, action) {
if (action == Meta.KeyBindingAction.SWITCH_GROUP) {
this._select(this._selectedIndex, this._nextWindow());
this._select(this._selectedIndex, backwards ? this._previousWindow() : this._nextWindow());
} else if (action == Meta.KeyBindingAction.SWITCH_GROUP_BACKWARD) {
this._select(this._selectedIndex, this._previousWindow());
} else if (action == Meta.KeyBindingAction.SWITCH_APPLICATIONS) {
this._select(this._next());
this._select(backwards ? this._previous() : this._next());
} else if (action == Meta.KeyBindingAction.SWITCH_APPLICATIONS_BACKWARD) {
this._select(this._previous());
} else if (this._thumbnailsFocused) {
@ -172,8 +167,6 @@ const AppSwitcherPopup = new Lang.Class({
this._select(this._selectedIndex, this._nextWindow());
else if (keysym == Clutter.Up)
this._select(this._selectedIndex, null, true);
else
return Clutter.EVENT_PROPAGATE;
} else {
if (keysym == Clutter.Left)
this._select(this._previous());
@ -181,11 +174,7 @@ const AppSwitcherPopup = new Lang.Class({
this._select(this._next());
else if (keysym == Clutter.Down)
this._select(this._selectedIndex, 0);
else
return Clutter.EVENT_PROPAGATE;
}
return Clutter.EVENT_STOP;
},
_scrollHandler: function(direction) {
@ -316,7 +305,6 @@ const AppSwitcherPopup = new Lang.Class({
this._thumbnailTimeoutId = Mainloop.timeout_add (
THUMBNAIL_POPUP_TIME,
Lang.bind(this, this._timeoutPopupThumbnails));
GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
}
},
@ -366,175 +354,48 @@ const AppSwitcherPopup = new Lang.Class({
}
});
const CyclerHighlight = new Lang.Class({
Name: 'CyclerHighlight',
_init: function() {
this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._clone = new Clutter.Clone();
this.actor.add_actor(this._clone);
this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
this.actor.add_actor(this._highlight);
let coordinate = Clutter.BindCoordinate.ALL;
let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
this._clone.bind_property('source', constraint, 'source', 0);
this.actor.add_constraint(constraint);
this.actor.connect('notify::allocation',
Lang.bind(this, this._onAllocationChanged));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
},
set window(w) {
if (this._window == w)
return;
this._window = w;
if (this._clone.source)
this._clone.source.sync_visibility();
let windowActor = this._window ? this._window.get_compositor_private()
: null;
if (windowActor)
windowActor.hide();
this._clone.source = windowActor;
},
_onAllocationChanged: function() {
if (!this._window) {
this._highlight.set_size(0, 0);
this._highlight.hide();
} else {
let [x, y] = this.actor.allocation.get_origin();
let rect = this._window.get_frame_rect();
this._highlight.set_size(rect.width, rect.height);
this._highlight.set_position(rect.x - x, rect.y - y);
this._highlight.show();
}
},
_onDestroy: function() {
this.window = null;
}
});
const CyclerPopup = new Lang.Class({
Name: 'CyclerPopup',
Extends: SwitcherPopup.SwitcherPopup,
Abstract: true,
_init : function() {
this.parent();
this._items = this._getWindows();
if (this._items.length == 0)
return;
this._highlight = new CyclerHighlight();
global.window_group.add_actor(this._highlight.actor);
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
this._switcherList = { actor: new St.Widget(),
highlight: Lang.bind(this, this._highlightItem),
connect: function() {} };
},
_highlightItem: function(index, justOutline) {
this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight.actor, null);
},
_finish: function() {
let window = this._items[this._selectedIndex];
let ws = window.get_workspace();
let activeWs = global.screen.get_active_workspace();
if (window.minimized) {
Main.wm.skipNextEffect(window.get_compositor_private());
window.unminimize();
}
if (activeWs == ws) {
Main.activateWindow(window);
} else {
// If the selected window is on a different workspace, we don't
// want it to disappear, then slide in with the workspace; instead,
// always activate it on the active workspace ...
activeWs.activate_with_focus(window, global.get_current_time());
// ... then slide it over to the original workspace if necessary
Main.wm.actionMoveWindow(window, ws);
}
this.parent();
},
_onDestroy: function() {
this._highlight.actor.destroy();
this.parent();
}
});
const GroupCyclerPopup = new Lang.Class({
Name: 'GroupCyclerPopup',
Extends: CyclerPopup,
_getWindows: function() {
let app = Shell.WindowTracker.get_default().focus_app;
return app ? app.get_windows() : [];
},
_keyPressHandler: function(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
this._select(this._next());
else if (action == Meta.KeyBindingAction.CYCLE_GROUP_BACKWARD)
this._select(this._previous());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
});
const WindowSwitcherPopup = new Lang.Class({
Name: 'WindowSwitcherPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init: function() {
this.parent();
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
let windows = this._getWindowList();
if (windows.length == 0)
return;
let mode = this._settings.get_enum('app-icon-mode');
this._switcherList = new WindowList(windows, mode);
this._items = this._switcherList.icons;
_init: function(items) {
this.parent(items);
this._settings = new Gio.Settings({ schema: 'org.gnome.shell.window-switcher' });
},
_getWindowList: function() {
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
return getWindows(workspace);
return global.display.get_tab_list(Meta.TabList.NORMAL, global.screen, workspace);
},
_keyPressHandler: function(keysym, action) {
_createSwitcher: function() {
let windows = this._getWindowList();
if (windows.length == 0)
return false;
let mode = this._settings.get_enum('app-icon-mode');
this._switcherList = new WindowList(windows, mode);
this._items = this._switcherList.icons;
if (this._items.length == 0)
return false;
return true;
},
_initialSelection: function(backward, binding) {
if (binding == 'switch-windows-backward' || backward)
this._select(this._items.length - 1);
else if (this._items.length == 1)
this._select(0);
else
this._select(1);
},
_keyPressHandler: function(keysym, backwards, action) {
if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
this._select(this._next());
this._select(backwards ? this._previous() : this._next());
} else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD) {
this._select(this._previous());
} else {
@ -542,11 +403,7 @@ const WindowSwitcherPopup = new Lang.Class({
this._select(this._previous());
else if (keysym == Clutter.Right)
this._select(this._next());
else
return Clutter.EVENT_PROPAGATE;
}
return Clutter.EVENT_STOP;
},
_finish: function() {
@ -556,32 +413,6 @@ const WindowSwitcherPopup = new Lang.Class({
}
});
const WindowCyclerPopup = new Lang.Class({
Name: 'WindowCyclerPopup',
Extends: CyclerPopup,
_init: function() {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
this.parent();
},
_getWindows: function() {
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
return getWindows(workspace);
},
_keyPressHandler: function(keysym, action) {
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
this._select(this._next());
else if (action == Meta.KeyBindingAction.CYCLE_WINDOWS_BACKWARD)
this._select(this._previous());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
}
});
const AppIcon = new Lang.Class({
Name: 'AppIcon',
@ -599,6 +430,7 @@ const AppIcon = new Lang.Class({
set_size: function(size) {
this.icon = this.app.create_icon_texture(size);
this._iconBin.set_size(size, size);
this._iconBin.child = this.icon;
}
});
@ -614,10 +446,11 @@ const AppSwitcher = new Lang.Class({
this._arrows = [];
let windowTracker = Shell.WindowTracker.get_default();
let settings = new Gio.Settings({ schema_id: 'org.gnome.shell.app-switcher' });
let settings = new Gio.Settings({ schema: 'org.gnome.shell.app-switcher' });
let workspace = settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace()
: null;
let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL,
global.screen, workspace);
// Construct the AppIcons, add to the popup
for (let i = 0; i < apps.length; i++) {
@ -629,6 +462,8 @@ const AppSwitcher = new Lang.Class({
});
if (appIcon.cachedWindows.length > 0)
this._addIcon(appIcon);
else if (workspace == null)
throw new Error('%s appears to be running, but doesn\'t have any windows'.format(appIcon.app.get_name()));
}
this._curApp = -1;
@ -644,13 +479,12 @@ const AppSwitcher = new Lang.Class({
Mainloop.source_remove(this._mouseTimeOutId);
},
_setIconSize: function() {
_getPreferredHeight: function (actor, forWidth, alloc) {
let j = 0;
while(this._items.length > 1 && this._items[j].style_class != 'item-box') {
j++;
}
let themeNode = this._items[j].get_theme_node();
let iconPadding = themeNode.get_horizontal_padding();
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);
@ -661,22 +495,19 @@ const AppSwitcher = new Lang.Class({
let primary = Main.layoutManager.primaryMonitor;
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 height = 0;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
let iconSizes = baseIconSizes.map(function(s) {
return s * scaleFactor;
});
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;
for(let i = 0; i < iconSizes.length; i++) {
this._iconSize = iconSizes[i];
height = iconSizes[i] + iconSpacing;
let w = height * this._items.length + totalSpacing;
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++) {
@ -684,11 +515,9 @@ const AppSwitcher = new Lang.Class({
break;
this.icons[i].set_size(this._iconSize);
}
},
_getPreferredHeight: function (actor, forWidth, alloc) {
this._setIconSize();
this.parent(actor, forWidth, alloc);
alloc.min_size = height;
alloc.natural_size = height;
},
_allocate: function (actor, box, flags) {
@ -722,7 +551,6 @@ const AppSwitcher = new Lang.Class({
this._mouseTimeOutId = 0;
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
} else
this._itemEntered(index);
},
@ -822,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();
let [labelMinHeight, labelNaturalHeight] = this._labels[0].get_preferred_height(-1);
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;
binHeight = Math.min(thumbnailSize, binHeight);
binHeight = Math.min(THUMBNAIL_DEFAULT_SIZE, binHeight);
for (let i = 0; i < this._thumbnailBins.length; i++) {
let mutterWindow = this._windows[i].get_compositor_private();
if (!mutterWindow)
continue;
let clone = _createWindowClone(mutterWindow, thumbnailSize);
let clone = _createWindowClone(mutterWindow, THUMBNAIL_DEFAULT_SIZE);
this._thumbnailBins[i].set_height(binHeight);
this._thumbnailBins[i].add_actor(clone);
this._clones.push(clone);
@ -866,17 +692,15 @@ const WindowIcon = new Lang.Class({
this._icon.destroy_all_children();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
switch (mode) {
case AppIconMode.THUMBNAIL_ONLY:
size = WINDOW_PREVIEW_SIZE;
this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor));
this._icon.add_actor(_createWindowClone(mutterWindow, WINDOW_PREVIEW_SIZE));
break;
case AppIconMode.BOTH:
size = WINDOW_PREVIEW_SIZE;
this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor));
this._icon.add_actor(_createWindowClone(mutterWindow, WINDOW_PREVIEW_SIZE));
if (this.app)
this._icon.add_actor(this._createAppIcon(this.app,
@ -888,7 +712,7 @@ const WindowIcon = new Lang.Class({
this._icon.add_actor(this._createAppIcon(this.app, size));
}
this._icon.set_size(size * scaleFactor, size * scaleFactor);
this._icon.set_size(size, size);
},
_createAppIcon: function(app, size) {

View File

@ -7,12 +7,12 @@ const St = imports.gi.St;
const Signals = imports.signals;
const Atk = imports.gi.Atk;
const ANIMATED_ICON_UPDATE_TIMEOUT = 16;
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const Animation = new Lang.Class({
Name: 'Animation',
_init: function(file, width, height, speed) {
_init: function(filename, width, height, speed) {
this.actor = new St.Bin();
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._speed = speed;
@ -21,9 +21,7 @@ const Animation = new Lang.Class({
this._isPlaying = false;
this._timeoutId = 0;
this._frame = 0;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height,
Lang.bind(this, this._animationsLoaded));
this.actor.set_child(this._animations);
},
@ -33,8 +31,7 @@ const Animation = new Lang.Class({
if (this._frame == 0)
this._showFrame(0);
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_LOW, this._speed, Lang.bind(this, this._update));
GLib.Source.set_name_by_id(this._timeoutId, '[gnome-shell] this._update');
this._timeoutId = Mainloop.timeout_add(this._speed, Lang.bind(this, this._update));
}
this._isPlaying = true;
@ -67,7 +64,7 @@ const Animation = new Lang.Class({
},
_animationsLoaded: function() {
this._isLoaded = this._animations.get_n_children() > 0;
this._isLoaded = true;
if (this._isPlaying)
this.play();
@ -82,7 +79,7 @@ const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon',
Extends: Animation,
_init: function(file, size) {
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
_init: function(filename, size) {
this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
}
});

File diff suppressed because it is too large Load Diff

View File

@ -6,39 +6,6 @@ const Signals = imports.signals;
const Main = imports.ui.main;
const RENAMED_DESKTOP_IDS = {
'baobab.desktop': 'org.gnome.baobab.desktop',
'cheese.desktop': 'org.gnome.Cheese.desktop',
'dconf-editor.desktop': 'ca.desrt.dconf-editor.desktop',
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
'gcalctool.desktop': 'gnome-calculator.desktop',
'geary.desktop': 'org.gnome.Geary.desktop',
'gedit.desktop': 'org.gnome.gedit.desktop',
'glchess.desktop': 'gnome-chess.desktop',
'glines.desktop': 'five-or-more.desktop',
'gnect.desktop': 'four-in-a-row.desktop',
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnobots2.desktop': 'gnome-robots.desktop',
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
'gnome-clocks.desktop': 'org.gnome.clocks.desktop',
'gnome-contacts.desktop': 'org.gnome.Contacts.desktop',
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop',
'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop',
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
'gnome-software.desktop': 'org.gnome.Software.desktop',
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop',
'gnomine.desktop': 'gnome-mines.desktop',
'gnotravex.desktop': 'gnome-tetravex.desktop',
'gnotski.desktop': 'gnome-klotski.desktop',
'gtali.desktop': 'tali.desktop',
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
'polari.desktop': 'org.gnome.Polari.desktop',
'totem.desktop': 'org.gnome.Totem.desktop',
};
const AppFavorites = new Lang.Class({
Name: 'AppFavorites',
@ -58,22 +25,6 @@ const AppFavorites = new Lang.Class({
reload: function() {
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
let appSys = Shell.AppSystem.get_default();
// Map old desktop file names to the current ones
let updated = false;
ids = ids.map(function (id) {
let newId = RENAMED_DESKTOP_IDS[id];
if (newId !== undefined &&
appSys.lookup_app(newId) != null) {
updated = true;
return newId;
}
return id;
});
// ... and write back the updated desktop file names
if (updated)
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
let apps = ids.map(function (id) {
return appSys.lookup_app(id);
}).filter(function (app) {

View File

@ -1,216 +0,0 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const AudioDevice = {
HEADPHONES: 1 << 0,
HEADSET: 1 << 1,
MICROPHONE: 1 << 2
};
const AudioDeviceSelectionIface = '<node> \
<interface name="org.gnome.Shell.AudioDeviceSelection"> \
<method name="Open"> \
<arg name="devices" direction="in" type="as" /> \
</method> \
<method name="Close"> \
</method> \
<signal name="DeviceSelected"> \
<arg name="device" type="s" /> \
</signal> \
</interface> \
</node>';
const AudioDeviceSelectionDialog = new Lang.Class({
Name: 'AudioDeviceSelectionDialog',
Extends: ModalDialog.ModalDialog,
_init: function(devices) {
this.parent({ styleClass: 'audio-device-selection-dialog' });
this._deviceItems = {};
this._buildLayout();
if (devices & AudioDevice.HEADPHONES)
this._addDevice(AudioDevice.HEADPHONES);
if (devices & AudioDevice.HEADSET)
this._addDevice(AudioDevice.HEADSET);
if (devices & AudioDevice.MICROPHONE)
this._addDevice(AudioDevice.MICROPHONE);
if (this._selectionBox.get_n_children() < 2)
throw new Error('Too few devices for a selection');
},
destroy: function() {
this.parent();
},
_buildLayout: function(devices) {
let title = new St.Label({ style_class: 'audio-selection-title',
text: _("Select Audio Device"),
x_align: Clutter.ActorAlign.CENTER });
this.contentLayout.style_class = 'audio-selection-content';
this.contentLayout.add(title);
this._selectionBox = new St.BoxLayout({ style_class: 'audio-selection-box' });
this.contentLayout.add(this._selectionBox, { expand: true });
this.addButton({ action: Lang.bind(this, this._openSettings),
label: _("Sound Settings") });
this.addButton({ action: Lang.bind(this, this.close),
label: _("Cancel"),
key: Clutter.Escape });
},
_getDeviceLabel: function(device) {
switch(device) {
case AudioDevice.HEADPHONES:
return _("Headphones");
case AudioDevice.HEADSET:
return _("Headset");
case AudioDevice.MICROPHONE:
return _("Microphone");
default:
return null;
}
},
_getDeviceIcon: function(device) {
switch(device) {
case AudioDevice.HEADPHONES:
return 'audio-headphones-symbolic';
case AudioDevice.HEADSET:
return 'audio-headset-symbolic';
case AudioDevice.MICROPHONE:
return 'audio-input-microphone-symbolic';
default:
return null;
}
},
_addDevice: function(device) {
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
vertical: true });
box.connect('notify::height',
function() {
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
function() {
box.width = box.height;
});
});
let icon = new St.Icon({ style_class: 'audio-selection-device-icon',
icon_name: this._getDeviceIcon(device) });
box.add(icon);
let label = new St.Label({ style_class: 'audio-selection-device-label',
text: this._getDeviceLabel(device),
x_align: Clutter.ActorAlign.CENTER });
box.add(label);
let button = new St.Button({ style_class: 'audio-selection-device',
can_focus: true,
child: box });
this._selectionBox.add(button);
button.connect('clicked', Lang.bind(this,
function() {
this.emit('device-selected', device);
this.close();
Main.overview.hide();
}));
},
_openSettings: function() {
let desktopFile = 'gnome-sound-panel.desktop'
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app) {
log('Settings panel for desktop file ' + desktopFile + ' could not be loaded!');
return;
}
this.close();
Main.overview.hide();
app.activate();
}
});
const AudioDeviceSelectionDBus = new Lang.Class({
Name: 'AudioDeviceSelectionDBus',
_init: function() {
this._audioSelectionDialog = null;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/AudioDeviceSelection');
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
_onDialogClosed: function() {
this._audioSelectionDialog = null;
},
_onDeviceSelected: function(dialog, device) {
let connection = this._dbusImpl.get_connection();
let info = this._dbusImpl.get_info();
let deviceName = Object.keys(AudioDevice).filter(
function(dev) {
return AudioDevice[dev] == device;
})[0].toLowerCase();
connection.emit_signal(this._audioSelectionDialog._sender,
this._dbusImpl.get_object_path(),
info ? info.name : null,
'DeviceSelected',
GLib.Variant.new('(s)', [deviceName]));
},
OpenAsync: function(params, invocation) {
if (this._audioSelectionDialog) {
invocation.return_value(null);
return;
}
let [deviceNames] = params;
let devices = 0;
deviceNames.forEach(function(n) {
devices |= AudioDevice[n.toUpperCase()];
});
let dialog;
try {
dialog = new AudioDeviceSelectionDialog(devices);
} catch(e) {
invocation.return_value(null);
return;
}
dialog._sender = invocation.get_sender();
dialog.connect('closed', Lang.bind(this, this._onDialogClosed));
dialog.connect('device-selected',
Lang.bind(this, this._onDeviceSelected));
dialog.open();
this._audioSelectionDialog = dialog;
invocation.return_value(null);
},
CloseAsync: function(params, invocation) {
if (this._audioSelectionDialog &&
this._audioSelectionDialog._sender == invocation.get_sender())
this._audioSelectionDialog.close();
invocation.return_value(null);
}
});

File diff suppressed because it is too large Load Diff

View File

@ -16,14 +16,13 @@ const BackgroundMenu = new Lang.Class({
_init: function(layoutManager) {
this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop');
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.addSettingsAction(_("Display Settings"), 'gnome-display-panel.desktop');
this.addSettingsAction(_("Settings"), 'gnome-control-center.desktop');
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop');
this.actor.add_style_class_name('background-menu');
layoutManager.uiGroup.add_actor(this.actor);
layoutManager.menuGroup.add_actor(this.actor);
this.actor.hide();
}
});
@ -34,40 +33,31 @@ function addBackgroundMenu(actor, layoutManager) {
actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor });
actor._backgroundManager.addMenu(actor._backgroundMenu);
function openMenu(x, y) {
Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0);
function openMenu() {
let [x, y] = global.get_pointer();
Main.layoutManager.setDummyCursorPosition(x, y);
actor._backgroundMenu.open(BoxPointer.PopupAnimation.NONE);
}
let clickAction = new Clutter.ClickAction();
clickAction.connect('long-press', function(action, actor, state) {
if (state == Clutter.LongPressState.QUERY)
return ((action.get_button() == 0 ||
action.get_button() == 1) &&
!actor._backgroundMenu.isOpen);
return action.get_button() == 1 && !actor._backgroundMenu.isOpen;
if (state == Clutter.LongPressState.ACTIVATE) {
let [x, y] = action.get_coords();
openMenu(x, y);
openMenu();
actor._backgroundManager.ignoreRelease();
}
return true;
});
clickAction.connect('clicked', function(action) {
if (action.get_button() == 3) {
let [x, y] = action.get_coords();
openMenu(x, y);
}
if (action.get_button() == 3)
openMenu();
});
actor.add_action(clickAction);
let grabOpBeginId = global.display.connect('grab-op-begin', function () {
clickAction.release();
});
actor.connect('destroy', function() {
actor._backgroundMenu.destroy();
actor._backgroundMenu = null;
actor._backgroundManager = null;
global.display.disconnect(grabOpBeginId);
});
}

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@ const AutomountManager = new Lang.Class({
Name: 'AutomountManager',
_init: function() {
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
this._volumeQueue = [];
this._session = new GnomeSession.SessionManager();
this._session.connectSignal('InhibitorAdded',
@ -43,7 +43,6 @@ const AutomountManager = new Lang.Class({
this._driveEjectButtonId = this._volumeMonitor.connect('drive-eject-button', Lang.bind(this, this._onDriveEjectButton));
this._mountAllId = Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
GLib.Source.set_name_by_id(this._mountAllId, '[gnome-shell] this._startupMountAll');
},
disable: function() {
@ -235,11 +234,10 @@ const AutomountManager = new Lang.Class({
},
_allowAutorunExpire: function(volume) {
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, function() {
Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, function() {
volume.allowAutorun = false;
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
}
});
const Component = AutomountManager;

View File

@ -24,11 +24,11 @@ const AutorunSetting = {
};
// misc utils
function shouldAutorunMount(mount) {
function shouldAutorunMount(mount, forTransient) {
let root = mount.get_root();
let volume = mount.get_volume();
if (!volume || !volume.allowAutorun)
if (!volume || (!volume.allowAutorun && forTransient))
return false;
if (root.is_native() && isMountRootHidden(root))
@ -96,7 +96,7 @@ const ContentTypeDiscoverer = new Lang.Class({
_init: function(callback) {
this._callback = callback;
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
},
guessContentTypes: function(mount) {
@ -167,43 +167,281 @@ const AutorunManager = new Lang.Class({
this._session = new GnomeSession.SessionManager();
this._volumeMonitor = Gio.VolumeMonitor.get();
this._dispatcher = new AutorunDispatcher(this);
this._transDispatcher = new AutorunTransientDispatcher(this);
},
_ensureResidentSource: function() {
if (this._residentSource)
return;
this._residentSource = new AutorunResidentSource(this);
let destroyId = this._residentSource.connect('destroy', Lang.bind(this, function() {
this._residentSource.disconnect(destroyId);
this._residentSource = null;
}));
},
enable: function() {
this._scanMounts();
this._mountAddedId = this._volumeMonitor.connect('mount-added', Lang.bind(this, this._onMountAdded));
this._mountRemovedId = this._volumeMonitor.connect('mount-removed', Lang.bind(this, this._onMountRemoved));
},
disable: function() {
if (this._residentSource)
this._residentSource.destroy();
this._volumeMonitor.disconnect(this._mountAddedId);
this._volumeMonitor.disconnect(this._mountRemovedId);
},
_processMount: function(mount, hotplug) {
let discoverer = new ContentTypeDiscoverer(Lang.bind(this, function(mount, apps, contentTypes) {
this._ensureResidentSource();
this._residentSource.addMount(mount, apps);
if (hotplug)
this._transDispatcher.addMount(mount, apps, contentTypes);
}));
discoverer.guessContentTypes(mount);
},
_scanMounts: function() {
let mounts = this._volumeMonitor.get_mounts();
mounts.forEach(Lang.bind(this, function(mount) {
this._processMount(mount, false);
}));
},
_onMountAdded: function(monitor, mount) {
// don't do anything if our session is not the currently
// active one
if (!this._session.SessionIsActive)
return;
let discoverer = new ContentTypeDiscoverer(Lang.bind(this, function(mount, apps, contentTypes) {
this._dispatcher.addMount(mount, apps, contentTypes);
}));
discoverer.guessContentTypes(mount);
this._processMount(mount, true);
},
_onMountRemoved: function(monitor, mount) {
this._dispatcher.removeMount(mount);
this._transDispatcher.removeMount(mount);
if (this._residentSource)
this._residentSource.removeMount(mount);
},
ejectMount: function(mount) {
let mountOp = new ShellMountOperation.ShellMountOperation(mount);
// first, see if we have a drive
let drive = mount.get_drive();
let volume = mount.get_volume();
if (drive &&
drive.get_start_stop_type() == Gio.DriveStartStopType.SHUTDOWN &&
drive.can_stop()) {
drive.stop(0, mountOp.mountOp, null,
Lang.bind(this, this._onStop));
} else {
if (mount.can_eject()) {
mount.eject_with_operation(0, mountOp.mountOp, null,
Lang.bind(this, this._onEject));
} else if (volume && volume.can_eject()) {
volume.eject_with_operation(0, mountOp.mountOp, null,
Lang.bind(this, this._onEject));
} else if (drive && drive.can_eject()) {
drive.eject_with_operation(0, mountOp.mountOp, null,
Lang.bind(this, this._onEject));
} else if (mount.can_unmount()) {
mount.unmount_with_operation(0, mountOp.mountOp, null,
Lang.bind(this, this._onUnmount));
}
}
},
_onUnmount: function(mount, res) {
try {
mount.unmount_with_operation_finish(res);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
log('Unable to eject the mount ' + mount.get_name()
+ ': ' + e.toString());
}
},
_onEject: function(source, res) {
try {
source.eject_with_operation_finish(res);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
log('Unable to eject the drive ' + source.get_name()
+ ': ' + e.toString());
}
},
_onStop: function(drive, res) {
try {
drive.stop_finish(res);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
log('Unable to stop the drive ' + drive.get_name()
+ ': ' + e.toString());
}
},
});
const AutorunResidentSource = new Lang.Class({
Name: 'AutorunResidentSource',
Extends: MessageTray.Source,
_init: function(manager) {
this.parent(_("Removable Devices"), 'media-removable');
this.resident = true;
this._mounts = [];
this._manager = manager;
this._notification = new AutorunResidentNotification(this._manager, this);
},
_createPolicy: function() {
return new MessageTray.NotificationPolicy({ showInLockScreen: false });
},
buildRightClickMenu: function() {
return null;
},
addMount: function(mount, apps) {
if (!shouldAutorunMount(mount, false))
return;
let filtered = this._mounts.filter(function (element) {
return (element.mount == mount);
});
if (filtered.length != 0)
return;
let element = { mount: mount, apps: apps };
this._mounts.push(element);
this._redisplay();
},
removeMount: function(mount) {
this._mounts =
this._mounts.filter(function (element) {
return (element.mount != mount);
});
this._redisplay();
},
_redisplay: function() {
if (this._mounts.length == 0) {
this._notification.destroy();
this.destroy();
return;
}
this._notification.updateForMounts(this._mounts);
// add ourselves as a source, and push the notification
if (!Main.messageTray.contains(this)) {
Main.messageTray.add(this);
this.pushNotification(this._notification);
}
}
});
const AutorunDispatcher = new Lang.Class({
Name: 'AutorunDispatcher',
const AutorunResidentNotification = new Lang.Class({
Name: 'AutorunResidentNotification',
Extends: MessageTray.Notification,
_init: function(manager, source) {
this.parent(source, source.title, null, { customContent: true });
// set the notification as resident
this.setResident(true);
this._layout = new St.BoxLayout ({ style_class: 'hotplug-resident-box',
vertical: true });
this._manager = manager;
this.addActor(this._layout,
{ x_expand: true,
x_fill: true });
},
updateForMounts: function(mounts) {
// remove all the layout content
this._layout.destroy_all_children();
for (let idx = 0; idx < mounts.length; idx++) {
let element = mounts[idx];
let actor = this._itemForMount(element.mount, element.apps);
this._layout.add(actor, { x_fill: true,
expand: true });
}
},
_itemForMount: function(mount, apps) {
let item = new St.BoxLayout();
// prepare the mount button content
let mountLayout = new St.BoxLayout();
let mountIcon = new St.Icon({ gicon: mount.get_icon(),
style_class: 'hotplug-resident-mount-icon' });
mountLayout.add_actor(mountIcon);
let labelBin = new St.Bin({ y_align: St.Align.MIDDLE });
let mountLabel =
new St.Label({ text: mount.get_name(),
style_class: 'hotplug-resident-mount-label',
track_hover: true,
reactive: true });
labelBin.add_actor(mountLabel);
mountLayout.add_actor(labelBin);
let mountButton = new St.Button({ child: mountLayout,
x_align: St.Align.START,
x_fill: true,
style_class: 'hotplug-resident-mount',
button_mask: St.ButtonMask.ONE });
item.add(mountButton, { x_align: St.Align.START,
expand: true });
let ejectIcon =
new St.Icon({ icon_name: 'media-eject-symbolic',
style_class: 'hotplug-resident-eject-icon' });
let ejectButton =
new St.Button({ style_class: 'hotplug-resident-eject-button',
button_mask: St.ButtonMask.ONE,
child: ejectIcon });
item.add(ejectButton, { x_align: St.Align.END });
// now connect signals
mountButton.connect('clicked', Lang.bind(this, function(actor, event) {
startAppForMount(apps[0], mount);
}));
ejectButton.connect('clicked', Lang.bind(this, function() {
this._manager.ejectMount(mount);
}));
return item;
},
});
const AutorunTransientDispatcher = new Lang.Class({
Name: 'AutorunTransientDispatcher',
_init: function(manager) {
this._manager = manager;
this._sources = [];
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
},
_getAutorunSettingForType: function(contentType) {
@ -244,7 +482,7 @@ const AutorunDispatcher = new Lang.Class({
return;
// add a new source
this._sources.push(new AutorunSource(this._manager, mount, apps));
this._sources.push(new AutorunTransientSource(this._manager, mount, apps));
},
addMount: function(mount, apps, contentTypes) {
@ -253,7 +491,7 @@ const AutorunDispatcher = new Lang.Class({
return;
// if the mount doesn't want to be autorun, return
if (!shouldAutorunMount(mount))
if (!shouldAutorunMount(mount, true))
return;
let setting = this._getAutorunSettingForType(contentTypes[0]);
@ -293,8 +531,8 @@ const AutorunDispatcher = new Lang.Class({
}
});
const AutorunSource = new Lang.Class({
Name: 'AutorunSource',
const AutorunTransientSource = new Lang.Class({
Name: 'AutorunTransientSource',
Extends: MessageTray.Source,
_init: function(manager, mount, apps) {
@ -304,7 +542,7 @@ const AutorunSource = new Lang.Class({
this.parent(mount.get_name());
this._notification = new AutorunNotification(this._manager, this);
this._notification = new AutorunTransientNotification(this._manager, this);
// add ourselves as a source, and popup the notification
Main.messageTray.add(this);
@ -313,35 +551,38 @@ const AutorunSource = new Lang.Class({
getIcon: function() {
return this.mount.get_icon();
},
_createPolicy: function() {
return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
}
});
const AutorunNotification = new Lang.Class({
Name: 'AutorunNotification',
const AutorunTransientNotification = new Lang.Class({
Name: 'AutorunTransientNotification',
Extends: MessageTray.Notification,
_init: function(manager, source) {
this.parent(source, source.title);
this.parent(source, source.title, null, { customContent: true });
this._manager = manager;
this._box = new St.BoxLayout({ style_class: 'hotplug-transient-box',
vertical: true });
this.addActor(this._box);
this._mount = source.mount;
},
createBanner: function() {
let banner = new MessageTray.NotificationBanner(this);
this.source.apps.forEach(Lang.bind(this, function (app) {
source.apps.forEach(Lang.bind(this, function (app) {
let actor = this._buttonForApp(app);
if (actor)
banner.addButton(actor);
this._box.add(actor, { x_fill: true,
x_align: St.Align.START });
}));
return banner;
this._box.add(this._buttonForEject(), { x_fill: true,
x_align: St.Align.START });
// set the notification to transient and urgent, so that it
// expands out
this.setTransient(true);
this.setUrgency(MessageTray.Urgency.CRITICAL);
},
_buttonForApp: function(app) {
@ -359,9 +600,8 @@ const AutorunNotification = new Lang.Class({
let button = new St.Button({ child: box,
x_fill: true,
x_align: St.Align.START,
x_expand: true,
button_mask: St.ButtonMask.ONE,
style_class: 'hotplug-notification-item button' });
style_class: 'hotplug-notification-item' });
button.connect('clicked', Lang.bind(this, function() {
startAppForMount(app, this._mount);
@ -371,11 +611,29 @@ const AutorunNotification = new Lang.Class({
return button;
},
activate: function() {
this.parent();
_buttonForEject: function() {
let box = new St.BoxLayout();
let icon = new St.Icon({ icon_name: 'media-eject-symbolic',
style_class: 'hotplug-notification-item-icon' });
box.add(icon);
let app = Gio.app_info_get_default_for_type('inode/directory', false);
startAppForMount(app, this._mount);
let label = new St.Bin({ y_align: St.Align.MIDDLE,
child: new St.Label
({ text: _("Eject") })
});
box.add(label);
let button = new St.Button({ child: box,
x_fill: true,
x_align: St.Align.START,
button_mask: St.ButtonMask.ONE,
style_class: 'hotplug-notification-item' });
button.connect('clicked', Lang.bind(this, function() {
this._manager.ejectMount(this._mount);
}));
return button;
}
});

View File

@ -9,15 +9,9 @@ const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gcr = imports.gi.Gcr;
const Animation = imports.ui.animation;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const CheckBox = imports.ui.checkBox;
const Tweener = imports.ui.tweener;
const WORK_SPINNER_ICON_SIZE = 16;
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
const WORK_SPINNER_ANIMATION_TIME = 0.3;
const KeyringDialog = new Lang.Class({
Name: 'KeyringDialog',
@ -47,7 +41,7 @@ const KeyringDialog = new Lang.Class({
mainContentBox.add(this._messageBox,
{ y_align: St.Align.START, expand: true, x_fill: true, y_fill: true });
let subject = new St.Label({ style_class: 'prompt-dialog-headline headline' });
let subject = new St.Label({ style_class: 'prompt-dialog-headline' });
this.prompt.bind_property('message', subject, 'text', GObject.BindingFlags.SYNC_CREATE);
this._messageBox.add(subject,
@ -64,107 +58,66 @@ const KeyringDialog = new Lang.Class({
{ y_fill: true,
y_align: St.Align.START });
this._workSpinner = null;
this._controlTable = null;
this._cancelButton = this.addButton({ label: '',
action: Lang.bind(this, this._onCancelButton),
key: Clutter.Escape });
key: Clutter.Escape },
{ expand: true, x_fill: false, x_align: St.Align.START });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._continueButton = this.addButton({ label: '',
action: Lang.bind(this, this._onContinueButton),
default: true });
default: true },
{ expand: false, x_fill: false, x_align: St.Align.END });
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
},
_setWorking: function(working) {
if (!this._workSpinner)
return;
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
_buildControlTable: function() {
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
let layout = new Clutter.TableLayout();
let table = new St.Widget({ style_class: 'keyring-dialog-control-table',
layout_manager: layout });
layout.hookup_style(table);
let rtl = table.get_text_direction() == Clutter.TextDirection.RTL;
let row = 0;
if (this.prompt.password_visible) {
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
let label = new St.Label({ style_class: 'prompt-dialog-password-label' });
label.set_text(_("Password:"));
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
layout.pack(label, 0, row);
layout.child_set(label, { x_expand: false, y_fill: false,
x_align: Clutter.TableAlignment.START });
this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true,
x_expand: true });
can_focus: true });
this._passwordEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onPasswordActivate));
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
if (rtl) {
layout.attach(this._workSpinner.actor, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(label, 2, row, 1, 1);
} else {
layout.attach(label, 0, row, 1, 1);
layout.attach(this._passwordEntry, 1, row, 1, 1);
layout.attach(this._workSpinner.actor, 2, row, 1, 1);
}
layout.pack(this._passwordEntry, 1, row);
row++;
} else {
this._workSpinner = null;
this._passwordEntry = null;
}
if (this.prompt.confirm_visible) {
var label = new St.Label(({ style_class: 'prompt-dialog-password-label',
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER }));
var label = new St.Label(({ style_class: 'prompt-dialog-password-label' }));
label.set_text(_("Type again:"));
layout.pack(label, 0, row);
layout.child_set(label, { x_expand: false, y_fill: false,
x_align: Clutter.TableAlignment.START });
this._confirmEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: '',
can_focus: true,
x_expand: true });
can_focus: true });
this._confirmEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
ShellEntry.addContextMenu(this._confirmEntry, { isPassword: true });
this._confirmEntry.clutter_text.connect('activate', Lang.bind(this, this._onConfirmActivate));
if (rtl) {
layout.attach(this._confirmEntry, 0, row, 1, 1);
layout.attach(label, 1, row, 1, 1);
} else {
layout.attach(label, 0, row, 1, 1);
layout.attach(this._confirmEntry, 1, row, 1, 1);
}
layout.pack(this._confirmEntry, 1, row);
row++;
} else {
this._confirmEntry = null;
@ -177,15 +130,15 @@ const KeyringDialog = new Lang.Class({
let choice = new CheckBox.CheckBox();
this.prompt.bind_property('choice-label', choice.getLabelActor(), 'text', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('choice-chosen', choice.actor, 'checked', GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL);
layout.attach(choice.actor, rtl ? 0 : 1, row, 1, 1);
layout.pack(choice.actor, 1, row);
row++;
}
let warning = new St.Label({ style_class: 'prompt-dialog-error-label',
x_align: Clutter.ActorAlign.START });
let warning = new St.Label({ style_class: 'prompt-dialog-error-label' });
warning.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
warning.clutter_text.line_wrap = true;
layout.attach(warning, rtl ? 0 : 1, row, 1, 1);
layout.pack(warning, 1, row);
layout.child_set(warning, { x_fill: false, x_align: Clutter.TableAlignment.START });
this.prompt.bind_property('warning-visible', warning, 'visible', GObject.BindingFlags.SYNC_CREATE);
this.prompt.bind_property('warning', warning, 'text', GObject.BindingFlags.SYNC_CREATE);
@ -211,7 +164,7 @@ const KeyringDialog = new Lang.Class({
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
this.setWorking(!sensitive);
},
_ensureOpen: function() {

View File

@ -12,8 +12,6 @@ const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Config = imports.misc.config;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const ModalDialog = imports.ui.modalDialog;
const PopupMenu = imports.ui.popupMenu;
const ShellEntry = imports.ui.shellEntry;
@ -56,7 +54,7 @@ const NetworkSecretDialog = new Lang.Class({
mainContentBox.add(messageBox,
{ y_align: St.Align.START });
let subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline headline',
let subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline',
text: this._content.title });
messageBox.add(subjectLabel,
{ y_fill: false,
@ -74,28 +72,24 @@ const NetworkSecretDialog = new Lang.Class({
expand: true });
}
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
let layout = new Clutter.TableLayout();
let secretTable = new St.Widget({ style_class: 'network-dialog-secret-table',
layout_manager: layout });
layout.hookup_style(secretTable);
let rtl = secretTable.get_text_direction() == Clutter.TextDirection.RTL;
let initialFocusSet = false;
let pos = 0;
for (let i = 0; i < this._content.secrets.length; i++) {
let secret = this._content.secrets[i];
let label = new St.Label({ style_class: 'prompt-dialog-password-label',
text: secret.label,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.CENTER });
text: secret.label });
label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
let reactive = secret.key != null;
secret.entry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
text: secret.value, can_focus: reactive,
reactive: reactive,
x_expand: true });
reactive: reactive });
ShellEntry.addContextMenu(secret.entry,
{ isPassword: secret.password });
@ -122,13 +116,10 @@ const NetworkSecretDialog = new Lang.Class({
} else
secret.valid = true;
if (rtl) {
layout.attach(secret.entry, 0, pos, 1, 1);
layout.attach(label, 1, pos, 1, 1);
} else {
layout.attach(label, 0, pos, 1, 1);
layout.attach(secret.entry, 1, pos, 1, 1);
}
layout.pack(label, 0, pos);
layout.child_set(label, { x_expand: false, y_fill: false,
x_align: Clutter.TableAlignment.START });
layout.pack(secret.entry, 1, pos);
pos++;
if (secret.password)
@ -340,7 +331,6 @@ const NetworkSecretDialog = new Lang.Class({
content.message = _("PIN code is needed for the mobile broadband device");
content.secrets.push({ label: _("PIN: "), key: 'pin',
value: gsmSetting.pin || '', password: true });
break;
}
// fall through
case 'cdma':
@ -383,12 +373,6 @@ const VPNRequestHandler = new Lang.Class({
argv.push('-i');
if (flags & NMClient.SecretAgentGetSecretsFlags.REQUEST_NEW)
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;
@ -526,12 +510,10 @@ const VPNRequestHandler = new Lang.Class({
_showNewStyleDialog: function() {
let keyfile = new GLib.KeyFile();
let data;
let contentOverride;
try {
data = this._dataStdout.peek_buffer();
let data = this._dataStdout.peek_buffer();
keyfile.load_from_data(data.toString(), data.length,
GLib.KeyFileFlags.NONE);
@ -564,16 +546,13 @@ const VPNRequestHandler = new Lang.Class({
}
}
} catch(e) {
// No output is a valid case it means "both secrets are stored"
if (data.length > 0) {
logError(e, 'error while reading VPN plugin output keyfile');
logError(e, 'error while reading VPN plugin output keyfile');
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return;
}
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return;
}
if (contentOverride && contentOverride.secrets.length) {
if (contentOverride.secrets.length) {
// 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.open(global.get_current_time());
@ -607,21 +586,10 @@ const NetworkAgent = new Lang.Class({
Name: 'NetworkAgent',
_init: function() {
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent',
capabilities: NMClient.SecretAgentCapabilities.VPN_HINTS
});
this._native = new Shell.NetworkAgent({ identifier: 'org.gnome.Shell.NetworkAgent' });
this._dialogs = { };
this._vpnRequests = { };
this._notifications = { };
this._pluginDir = Gio.file_new_for_path(GLib.build_filenamev([Config.SYSCONFDIR, 'NetworkManager/VPN']));
try {
let monitor = this._pluginDir.monitor(Gio.FileMonitorFlags.NONE, null);
monitor.connect('changed', () => { this._vpnCacheBuilt = false; });
} catch(e) {
log('Failed to create monitor for VPN plugin dir: ' + e.message);
}
this._native.connect('new-request', Lang.bind(this, this._newRequest));
this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest));
@ -644,92 +612,21 @@ const NetworkAgent = new Lang.Class({
this._vpnRequests[requestId].cancel(true);
this._vpnRequests = { };
for (requestId in this._notifications)
this._notifications[requestId].destroy();
this._notifications = { };
this._enabled = false;
},
_showNotification: function(requestId, connection, settingName, hints, flags) {
let source = new MessageTray.Source(_("Network Manager"), 'network-transmit-receive');
source.policy = new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
let title, body;
let connectionSetting = connection.get_setting_connection();
let connectionType = connectionSetting.get_connection_type();
switch (connectionType) {
case '802-11-wireless':
let wirelessSetting = connection.get_setting_wireless();
let ssid = NetworkManager.utils_ssid_to_utf8(wirelessSetting.get_ssid());
title = _("Authentication required by wireless network");
body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
break;
case '802-3-ethernet':
title = _("Wired 802.1X authentication");
body = _("A password is required to connect to “%s”.".format(connection.get_id()));
break;
case 'pppoe':
title = _("DSL authentication");
body = _("A password is required to connect to “%s”.".format(connection.get_id()));
break;
case 'gsm':
if (hints.indexOf('pin') != -1) {
let gsmSetting = connection.get_setting_gsm();
title = _("PIN code required");
message = _("PIN code is needed for the mobile broadband device");
break;
}
// fall through
case 'cdma':
case 'bluetooth':
title = _("Mobile broadband network password");
message = _("A password is required to connect to “%s”.").format(connectionSetting.get_id());
break;
default:
log('Invalid connection type: ' + connectionType);
this._native.respond(requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
return;
}
let notification = new MessageTray.Notification(source, title, body);
notification.connect('activated', Lang.bind(this, function() {
notification.answered = true;
this._handleRequest(requestId, connection, settingName, hints, flags);
}));
this._notifications[requestId] = notification;
notification.connect('destroy', Lang.bind(this, function() {
if (!notification.answered)
this._native.respond(requestId, Shell.NetworkAgentResponse.USER_CANCELED);
delete this._notifications[requestId];
}));
Main.messageTray.add(source);
source.notify(notification);
},
_newRequest: function(agent, requestId, connection, settingName, hints, flags) {
if (!this._enabled) {
agent.respond(requestId, Shell.NetworkAgentResponse.USER_CANCELED);
return;
}
if (!(flags & NMClient.SecretAgentGetSecretsFlags.USER_REQUESTED))
this._showNotification(requestId, connection, settingName, hints, flags);
else
this._handleRequest(requestId, connection, settingName, hints, flags);
},
_handleRequest: function(requestId, connection, settingName, hints, flags) {
if (settingName == 'vpn') {
this._vpnRequest(requestId, connection, hints, flags);
return;
}
let dialog = new NetworkSecretDialog(this._native, requestId, connection, settingName, hints);
let dialog = new NetworkSecretDialog(agent, requestId, connection, settingName, hints);
dialog.connect('destroy', Lang.bind(this, function() {
delete this._dialogs[requestId];
}));
@ -773,8 +670,9 @@ const NetworkAgent = new Lang.Class({
this._vpnCacheBuilt = true;
this._vpnBinaries = { };
let dir = Gio.file_new_for_path(GLib.build_filenamev([Config.SYSCONFDIR, 'NetworkManager/VPN']));
try {
let fileEnum = this._pluginDir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
let fileEnum = dir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
let info;
while ((info = fileEnum.next_file(null))) {
@ -784,40 +682,25 @@ const NetworkAgent = new Lang.Class({
try {
let keyfile = new GLib.KeyFile();
keyfile.load_from_file(this._pluginDir.get_child(name).get_path(), GLib.KeyFileFlags.NONE);
keyfile.load_from_file(dir.get_child(name).get_path(), GLib.KeyFileFlags.NONE);
let service = keyfile.get_string('VPN Connection', 'service');
let binary = keyfile.get_string('GNOME', 'auth-dialog');
let externalUIMode = false;
let hints = false;
try {
externalUIMode = keyfile.get_boolean('GNOME', 'supports-external-ui-mode');
} 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;
if (!GLib.path_is_absolute(path)) {
path = GLib.build_filenamev([Config.LIBEXECDIR, path]);
}
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) {
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
try {
let aliases = keyfile.get_string_list('VPN Connection', 'aliases');
for (let alias of aliases) {
this._vpnBinaries[alias] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
}
} catch(e) { } // ignore errors if key does not exist
} else {
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE))
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode };
else
throw new Error('VPN plugin at %s is not executable'.format(path));
}
} catch(e) {
log('Error \'%s\' while processing VPN keyfile \'%s\''.
format(e.message, this._pluginDir.get_child(name).get_path()));
format(e.message, dir.get_child(name).get_path()));
continue;
}
}

View File

@ -13,19 +13,13 @@ const Mainloop = imports.mainloop;
const Polkit = imports.gi.Polkit;
const PolkitAgent = imports.gi.PolkitAgent;
const Animation = imports.ui.animation;
const Components = imports.ui.components;
const ModalDialog = imports.ui.modalDialog;
const ShellEntry = imports.ui.shellEntry;
const UserWidget = imports.ui.userWidget;
const Tweener = imports.ui.tweener;
const DIALOG_ICON_SIZE = 48;
const WORK_SPINNER_ICON_SIZE = 16;
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
const WORK_SPINNER_ANIMATION_TIME = 0.3;
const AuthenticationDialog = new Lang.Class({
Name: 'AuthenticationDialog',
Extends: ModalDialog.ModalDialog,
@ -56,7 +50,7 @@ const AuthenticationDialog = new Lang.Class({
mainContentBox.add(messageBox,
{ expand: true, y_align: St.Align.START });
this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline headline',
this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline',
text: _("Authentication Required") });
messageBox.add(this._subjectLabel,
@ -142,13 +136,6 @@ const AuthenticationDialog = new Lang.Class({
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
this._passwordBox.add(this._passwordEntry,
{ expand: true });
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0;
this._passwordBox.add(this._workSpinner.actor);
this.setInitialKeyFocus(this._passwordEntry);
this._passwordBox.hide();
@ -178,10 +165,17 @@ const AuthenticationDialog = new Lang.Class({
this._cancelButton = this.addButton({ label: _("Cancel"),
action: Lang.bind(this, this.cancel),
key: Clutter.Escape });
key: Clutter.Escape },
{ expand: true, x_fill: false, x_align: St.Align.START });
this.placeSpinner({ expand: false,
x_fill: false,
y_fill: false,
x_align: St.Align.END,
y_align: St.Align.MIDDLE });
this._okButton = this.addButton({ label: _("Authenticate"),
action: Lang.bind(this, this._onAuthenticateButtonPressed),
default: true });
default: true },
{ expand: false, x_fill: false, x_align: St.Align.END });
this._doneEmitted = false;
@ -189,30 +183,6 @@ const AuthenticationDialog = new Lang.Class({
this._cookie = cookie;
},
_setWorking: function(working) {
Tweener.removeTweens(this._workSpinner.actor);
if (working) {
this._workSpinner.play();
Tweener.addTween(this._workSpinner.actor,
{ opacity: 255,
delay: WORK_SPINNER_ANIMATION_DELAY,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear'
});
} else {
Tweener.addTween(this._workSpinner.actor,
{ opacity: 0,
time: WORK_SPINNER_ANIMATION_TIME,
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (this._workSpinner)
this._workSpinner.stop();
}
});
}
},
performAuthentication: function() {
this.destroySession();
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
@ -259,7 +229,7 @@ const AuthenticationDialog = new Lang.Class({
this._okButton.can_focus = sensitive;
this._okButton.reactive = sensitive;
this._setWorking(!sensitive);
this.setWorking(!sensitive);
},
_onEntryActivate: function() {

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,8 @@ const CtrlAltTabManager = new Lang.Class({
_init: function() {
this._items = [];
this.addGroup(global.window_group, _("Windows"),
'focus-windows-symbolic', { sortGroup: SortGroup.TOP,
focusCallback: Lang.bind(this, this._focusWindows) });
'emblem-documents-symbolic', { sortGroup: SortGroup.TOP,
focusCallback: Lang.bind(this, this._focusWindows) });
},
addGroup: function(root, name, icon, params) {
@ -87,7 +87,7 @@ const CtrlAltTabManager = new Lang.Class({
if (Main.sessionMode.hasWindows && !Main.overview.visible) {
let screen = global.screen;
let display = screen.get_display();
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen.get_active_workspace ());
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
let windowTracker = Shell.WindowTracker.get_default();
let textureCache = St.TextureCache.get_default();
for (let i = 0; i < windows.length; i++) {
@ -100,7 +100,7 @@ const CtrlAltTabManager = new Lang.Class({
if (app)
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
else
icon = textureCache.bind_cairo_surface_property(windows[i], 'icon');
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
}
items.push({ name: windows[i].title,
@ -140,25 +140,31 @@ const CtrlAltTabPopup = new Lang.Class({
Name: 'CtrlAltTabPopup',
Extends: SwitcherPopup.SwitcherPopup,
_init: function(items) {
this.parent(items);
_createSwitcher: function() {
this._switcherList = new CtrlAltTabSwitcher(this._items);
return true;
},
_keyPressHandler: function(keysym, action) {
_initialSelection: function(backward, binding) {
if (binding == 'switch-panels') {
if (backward)
this._selectedIndex = this._items.length - 1;
} else if (binding == 'switch-panels-backward') {
if (!backward)
this._selectedIndex = this._items.length - 1;
}
this._select(this._selectedIndex);
},
_keyPressHandler: function(keysym, backwards, action) {
if (action == Meta.KeyBindingAction.SWITCH_PANELS)
this._select(this._next());
this._select(backwards ? this._previous() : this._next());
else if (action == Meta.KeyBindingAction.SWITCH_PANELS_BACKWARD)
this._select(this._previous());
this._select(backwards ? this._next() : this._previous());
else if (keysym == Clutter.Left)
this._select(this._previous());
else if (keysym == Clutter.Right)
this._select(this._next());
else
return Clutter.EVENT_PROPAGATE;
return Clutter.EVENT_STOP;
},
_finish : function(time) {

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Signals = imports.signals;
const Lang = imports.lang;
@ -259,7 +258,7 @@ const ShowAppsIcon = new Lang.Class({
},
_createIcon: function(size) {
this._iconActor = new St.Icon({ icon_name: 'view-app-grid-symbolic',
this._iconActor = new St.Icon({ icon_name: 'view-grid-symbolic',
icon_size: size,
style_class: 'show-apps-icon',
track_hover: true });
@ -270,9 +269,6 @@ const ShowAppsIcon = new Lang.Class({
if (app == null)
return false;
if (!global.settings.is_writable('favorite-apps'))
return false;
let id = app.get_id();
let isFavorite = AppFavorites.getAppFavorites().isFavorite(id);
return isFavorite;
@ -385,8 +381,6 @@ const DashActor = new Lang.Class({
}
});
const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
const Dash = new Lang.Class({
Name: 'Dash',
@ -517,13 +511,10 @@ const Dash = new Lang.Class({
this._syncLabel(item, appIcon);
}));
let id = Main.overview.connect('hiding', Lang.bind(this, function() {
Main.overview.connect('hiding', Lang.bind(this, function() {
this._labelShowing = false;
item.hideLabel();
}));
item.child.connect('destroy', function() {
Main.overview.disconnect(id);
});
if (appIcon) {
appIcon.connect('sync-tooltip', Lang.bind(this, function() {
@ -536,17 +527,14 @@ const Dash = new Lang.Class({
let appIcon = new AppDisplay.AppIcon(app,
{ setSizeManually: true,
showLabel: false });
if (appIcon._draggable) {
appIcon._draggable.connect('drag-begin',
Lang.bind(this, function() {
appIcon.actor.opacity = 50;
}));
appIcon._draggable.connect('drag-end',
Lang.bind(this, function() {
appIcon.actor.opacity = 255;
}));
}
appIcon._draggable.connect('drag-begin',
Lang.bind(this, function() {
appIcon.actor.opacity = 50;
}));
appIcon._draggable.connect('drag-end',
Lang.bind(this, function() {
appIcon.actor.opacity = 255;
}));
appIcon.connect('menu-state-changed',
Lang.bind(this, function(appIcon, opened) {
this._itemMenuStateChanged(item, opened);
@ -592,7 +580,6 @@ const Dash = new Lang.Class({
this._showLabelTimeoutId = 0;
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._showLabelTimeoutId, '[gnome-shell] item.showLabel');
if (this._resetHoverTimeoutId > 0) {
Mainloop.source_remove(this._resetHoverTimeoutId);
this._resetHoverTimeoutId = 0;
@ -610,7 +597,6 @@ const Dash = new Lang.Class({
this._resetHoverTimeoutId = 0;
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._resetHoverTimeoutId, '[gnome-shell] this._labelShowing');
}
}
},
@ -644,29 +630,27 @@ const Dash = new Lang.Class({
let firstIcon = firstButton._delegate.icon;
let minHeight, natHeight;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
// Enforce the current icon size during the size request
firstIcon.icon.ensure_style();
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
firstIcon.icon.set_size(this.iconSize * scaleFactor, this.iconSize * scaleFactor);
firstIcon.icon.set_size(this.iconSize, this.iconSize);
[minHeight, natHeight] = firstButton.get_preferred_height(-1);
firstIcon.icon.set_size(currentWidth, currentHeight);
// 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;
let availSize = availHeight / iconChildren.length;
let iconSizes = baseIconSizes.map(function(s) {
return s * scaleFactor;
});
let iconSizes = [ 16, 22, 24, 32, 48, 64 ];
let newIconSize = baseIconSizes[0];
let newIconSize = 16;
for (let i = 0; i < iconSizes.length; i++) {
if (iconSizes[i] < availSize)
newIconSize = baseIconSizes[i];
newIconSize = iconSizes[i];
}
if (newIconSize == this.iconSize)
@ -863,9 +847,6 @@ const Dash = new Lang.Class({
if (app == null || app.is_window_backed())
return DND.DragMotionResult.NO_DROP;
if (!global.settings.is_writable('favorite-apps'))
return DND.DragMotionResult.NO_DROP;
let favorites = AppFavorites.getAppFavorites().getFavorites();
let numFavorites = favorites.length;
@ -942,9 +923,6 @@ const Dash = new Lang.Class({
return false;
}
if (!global.settings.is_writable('favorite-apps'))
return false;
let id = app.get_id();
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();

View File

@ -3,9 +3,6 @@
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GnomeDesktop = imports.gi.GnomeDesktop;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const GWeather = imports.gi.GWeather;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Cairo = imports.cairo;
@ -21,292 +18,22 @@ const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Calendar = imports.ui.calendar;
function _isToday(date) {
let now = new Date();
return now.getYear() == date.getYear() &&
now.getMonth() == date.getMonth() &&
now.getDate() == date.getDate();
}
const TodayButton = new Lang.Class({
Name: 'TodayButton',
_init: function(calendar) {
// Having the ability to go to the current date if the user is already
// on the current date can be confusing. So don't make the button reactive
// until the selected date changes.
this.actor = new St.Button({ style_class: 'datemenu-today-button',
x_align: St.Align.START,
can_focus: true,
reactive: false
});
this.actor.connect('clicked', Lang.bind(this,
function() {
this._calendar.setDate(new Date(), false);
}));
let hbox = new St.BoxLayout({ vertical: true });
this.actor.add_actor(hbox);
this._dayLabel = new St.Label({ style_class: 'day-label',
x_align: Clutter.ActorAlign.START });
hbox.add_actor(this._dayLabel);
this._dateLabel = new St.Label({ style_class: 'date-label' });
hbox.add_actor(this._dateLabel);
this._calendar = calendar;
this._calendar.connect('selected-date-changed', Lang.bind(this,
function(calendar, date) {
// Make the button reactive only if the selected date is not the
// current date.
this.actor.reactive = !_isToday(date)
}));
},
setDate: function(date) {
this._dayLabel.set_text(date.toLocaleFormat('%A'));
/* Translators: This is the date format to use when the calendar popup is
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
*/
let dateFormat = Shell.util_translate_time_string (N_("%B %e %Y"));
this._dateLabel.set_text(date.toLocaleFormat(dateFormat));
/* Translators: This is the accessible name of the date button shown
* below the time in the shell; it should combine the weekday and the
* date, e.g. "Tuesday February 17 2015".
*/
let dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
}
});
const WorldClocksSection = new Lang.Class({
Name: 'WorldClocksSection',
_init: function() {
this._clock = new GnomeDesktop.WallClock();
this._settings = null;
this._clockNotifyId = 0;
this._changedId = 0;
this._locations = [];
this.actor = new St.Button({ style_class: 'world-clocks-button',
x_fill: true,
can_focus: true });
this.actor.connect('clicked', Lang.bind(this,
function() {
let app = this._getClockApp();
app.activate();
Main.overview.hide();
Main.panel.closeCalendar();
}));
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
this._grid = new St.Widget({ style_class: 'world-clocks-grid',
layout_manager: layout });
layout.hookup_style(this._grid);
this.actor.child = this._grid;
Shell.AppSystem.get_default().connect('installed-changed',
Lang.bind(this, this._sync));
this._sync();
},
_getClockApp: function() {
return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop');
},
_sync: function() {
this.actor.visible = (this._getClockApp() != null);
if (this.actor.visible) {
if (!this._settings) {
this._settings = new Gio.Settings({ schema_id: 'org.gnome.clocks' });
this._changedId =
this._settings.connect('changed::world-clocks',
Lang.bind(this, this._clocksChanged));
this._clocksChanged();
}
} else {
if (this._settings)
this._settings.disconnect(this._changedId);
this._settings = null;
this._changedId = 0;
}
},
_clocksChanged: function() {
this._grid.destroy_all_children();
this._locations = [];
let world = GWeather.Location.get_world();
let clocks = this._settings.get_value('world-clocks').deep_unpack();
for (let i = 0; i < clocks.length; i++) {
let l = world.deserialize(clocks[i].location);
this._locations.push({ location: l });
}
this._locations.sort(function(a, b) {
return a.location.get_timezone().get_offset() -
b.location.get_timezone().get_offset();
});
let layout = this._grid.layout_manager;
let title = (this._locations.length == 0) ? _("Add world clocks…")
: _("World Clocks");
let header = new St.Label({ style_class: 'world-clocks-header',
x_align: Clutter.ActorAlign.START,
text: title });
layout.attach(header, 0, 0, 2, 1);
this.actor.label_actor = header;
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i].location;
let label = new St.Label({ style_class: 'world-clocks-city',
text: l.get_city_name(),
x_align: Clutter.ActorAlign.START,
x_expand: true });
let time = new St.Label({ style_class: 'world-clocks-time',
x_align: Clutter.ActorAlign.END,
x_expand: true });
if (this._grid.text_direction == Clutter.TextDirection.RTL) {
layout.attach(time, 0, i + 1, 1, 1);
layout.attach(label, 1, i + 1, 1, 1);
} else {
layout.attach(label, 0, i + 1, 1, 1);
layout.attach(time, 1, i + 1, 1, 1);
}
this._locations[i].actor = time;
}
if (this._grid.get_n_children() > 1) {
if (!this._clockNotifyId)
this._clockNotifyId =
this._clock.connect('notify::clock', Lang.bind(this, this._updateLabels));
this._updateLabels();
} else {
if (this._clockNotifyId)
this._clock.disconnect(this._clockNotifyId);
this._clockNotifyId = 0;
}
},
_updateLabels: function() {
for (let i = 0; i < this._locations.length; i++) {
let l = this._locations[i];
let tz = GLib.TimeZone.new(l.location.get_timezone().get_tzid());
let now = GLib.DateTime.new_now(tz);
l.actor.text = Util.formatTime(now, { timeOnly: true });
}
}
});
const MessagesIndicator = new Lang.Class({
Name: 'MessagesIndicator',
_init: function() {
this.actor = new St.Label({ text: '⚫', visible: false, y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
this._sources = [];
Main.messageTray.connect('source-added', Lang.bind(this, this._onSourceAdded));
Main.messageTray.connect('source-removed', Lang.bind(this, this._onSourceRemoved));
Main.messageTray.connect('queue-changed', Lang.bind(this, this._updateCount));
let sources = Main.messageTray.getSources();
sources.forEach(Lang.bind(this, function(source) { this._onSourceAdded(null, source); }));
},
_onSourceAdded: function(tray, source) {
source.connect('count-updated', Lang.bind(this, this._updateCount));
this._sources.push(source);
this._updateCount();
},
_onSourceRemoved: function(tray, source) {
this._sources.splice(this._sources.indexOf(source), 1);
this._updateCount();
},
_updateCount: function() {
let count = 0;
this._sources.forEach(Lang.bind(this,
function(source) {
count += source.unseenCount;
}));
count -= Main.messageTray.queueCount;
this.actor.visible = (count > 0);
}
});
const IndicatorPad = new Lang.Class({
Name: 'IndicatorPad',
Extends: St.Widget,
_init: function(actor) {
this._source = actor;
this._source.connect('notify::visible',
Lang.bind(this, this.queue_relayout));
this.parent();
},
vfunc_get_preferred_width: function(container, forHeight) {
if (this._source.visible)
return this._source.get_preferred_width(forHeight);
return [0, 0];
},
vfunc_get_preferred_height: function(container, forWidth) {
if (this._source.visible)
return this._source.get_preferred_height(forWidth);
return [0, 0];
}
});
const FreezableBinLayout = new Lang.Class({
Name: 'FreezableBinLayout',
Extends: Clutter.BinLayout,
_init: function() {
this.parent();
this._frozen = false;
this._savedWidth = [NaN, NaN];
this._savedHeight = [NaN, NaN];
},
set frozen(v) {
if (this._frozen == v)
return;
this._frozen = v;
if (!this._frozen)
this.layout_changed();
},
vfunc_get_preferred_width: function(container, forHeight) {
if (!this._frozen || this._savedWidth.some(isNaN))
this._savedWidth = this.parent(container, forHeight);
return this._savedWidth;
},
vfunc_get_preferred_height: function(container, forWidth) {
if (!this._frozen || this._savedHeight.some(isNaN))
this._savedHeight = this.parent(container, forWidth);
return this._savedHeight;
}
});
function _onVertSepRepaint (area)
{
let cr = area.get_context();
let themeNode = area.get_theme_node();
let [width, height] = area.get_surface_size();
let stippleColor = themeNode.get_color('-stipple-color');
let stippleWidth = themeNode.get_length('-stipple-width');
let x = Math.floor(width/2) + 0.5;
cr.moveTo(x, 0);
cr.lineTo(x, height);
Clutter.cairo_set_source_color(cr, stippleColor);
cr.setDash([1, 3], 1); // Hard-code for now
cr.setLineWidth(stippleWidth);
cr.stroke();
cr.$dispose();
};
const DateMenuButton = new Lang.Class({
Name: 'DateMenuButton',
@ -317,87 +44,110 @@ const DateMenuButton = new Lang.Class({
let hbox;
let vbox;
let menuAlignment = 0.5;
let menuAlignment = 0.25;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
menuAlignment = 1.0 - menuAlignment;
this.parent(menuAlignment);
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
this._indicator = new MessagesIndicator();
let box = new St.BoxLayout();
box.add_actor(new IndicatorPad(this._indicator.actor));
box.add_actor(this._clockDisplay);
box.add_actor(this._indicator.actor);
this.actor.label_actor = this._clockDisplay;
this.actor.add_actor(box);
this.actor.add_actor(this._clockDisplay);
this.actor.add_style_class_name ('clock-display');
let layout = new FreezableBinLayout();
let bin = new St.Widget({ layout_manager: layout });
this.menu.box.add_child(bin);
hbox = new St.BoxLayout({ name: 'calendarArea' });
bin.add_actor(hbox);
this.menu.box.add_child(hbox);
// Fill up the first column
vbox = new St.BoxLayout({vertical: true});
hbox.add(vbox);
// Date
this._date = new St.Label({ style_class: 'datemenu-date-label',
can_focus: true });
vbox.add(this._date);
this._eventList = new Calendar.EventsList();
this._calendar = new Calendar.Calendar();
this._calendar.connect('selected-date-changed',
Lang.bind(this, function(calendar, date) {
layout.frozen = !_isToday(date);
this._messageList.setDate(date);
// we know this._eventList is defined here, because selected-data-changed
// only gets emitted when the user clicks a date in the calendar,
// and the calender makes those dates unclickable when instantiated with
// a null event source
this._eventList.setDate(date);
}));
vbox.add(this._calendar.actor);
let separator = new PopupMenu.PopupSeparatorMenuItem();
vbox.add(separator.actor, { y_align: St.Align.END, expand: true, y_fill: false });
this._openCalendarItem = new PopupMenu.PopupMenuItem(_("Open Calendar"));
this._openCalendarItem.connect('activate', Lang.bind(this, this._onOpenCalendarActivate));
vbox.add(this._openCalendarItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
this._openClocksItem = new PopupMenu.PopupMenuItem(_("Open Clocks"));
this._openClocksItem.connect('activate', Lang.bind(this, this._onOpenClocksActivate));
vbox.add(this._openClocksItem.actor, {y_align: St.Align.END, expand: true, y_fill: false});
Shell.AppSystem.get_default().connect('installed-changed',
Lang.bind(this, this._appInstalledChanged));
item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop');
if (item) {
item.actor.show_on_set_parent = false;
item.actor.reparent(vbox);
this._dateAndTimeSeparator = separator;
}
this._separator = new St.DrawingArea({ style_class: 'calendar-vertical-separator',
pseudo_class: 'highlighted' });
this._separator.connect('repaint', Lang.bind(this, _onVertSepRepaint));
hbox.add(this._separator);
// Fill up the second column
hbox.add(this._eventList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
// Whenever the menu is opened, select today
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
// Whenever the menu is opened, select today
if (isOpen) {
let now = new Date();
this._calendar.setDate(now);
this._date.setDate(now);
this._messageList.setDate(now);
}
}));
// Fill up the first column
this._messageList = new Calendar.CalendarMessageList();
hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
// Fill up the second column
vbox = new St.BoxLayout({ style_class: 'datemenu-calendar-column',
vertical: true });
hbox.add(vbox);
this._date = new TodayButton(this._calendar);
vbox.add_actor(this._date.actor);
vbox.add(this._calendar.actor);
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
x_expand: true, x_fill: true,
overlay_scrollbars: true });
this._displaysSection.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
vbox.add_actor(this._displaysSection);
let displaysBox = new St.BoxLayout({ vertical: true,
style_class: 'datemenu-displays-box' });
this._displaysSection.add_actor(displaysBox);
this._clocksItem = new WorldClocksSection();
displaysBox.add(this._clocksItem.actor, { x_fill: true });
// Done with hbox for calendar and event list
this._clock = new GnomeDesktop.WallClock();
this._clock.bind_property('clock', this._clockDisplay, 'text', GObject.BindingFlags.SYNC_CREATE);
this._clock.connect('notify::clock', Lang.bind(this, this._updateClockAndDate));
this._updateClockAndDate();
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
this._sessionUpdated();
},
_getEventSource: function() {
return new Calendar.DBusEventSource();
_appInstalledChanged: function() {
this._calendarApp = undefined;
this._updateEventsVisibility();
},
_updateEventsVisibility: function() {
let visible = this._eventSource.hasCalendars;
this._openCalendarItem.actor.visible = visible &&
(this._getCalendarApp() != null);
this._openClocksItem.actor.visible = visible &&
(this._getClockApp() != null);
this._separator.visible = visible;
this._eventList.actor.visible = visible;
if (visible) {
let alignment = 0.25;
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
alignment = 1.0 - alignment;
this.menu._arrowAlignment = alignment;
} else {
this.menu._arrowAlignment = 0.5;
}
},
_setEventSource: function(eventSource) {
@ -405,24 +155,68 @@ const DateMenuButton = new Lang.Class({
this._eventSource.destroy();
this._calendar.setEventSource(eventSource);
this._messageList.setEventSource(eventSource);
this._eventList.setEventSource(eventSource);
this._eventSource = eventSource;
this._eventSource.connect('notify::has-calendars', Lang.bind(this, function() {
this._updateEventsVisibility();
}));
},
_sessionUpdated: function() {
let eventSource;
let showEvents = Main.sessionMode.showCalendarEvents;
if (showEvents) {
eventSource = this._getEventSource();
eventSource = new Calendar.DBusEventSource();
} else {
eventSource = new Calendar.EmptyEventSource();
}
this._setEventSource(eventSource);
this._updateEventsVisibility();
// Displays are not actually expected to launch Settings when activated
// but the corresponding app (clocks, weather); however we can consider
// that display-specific settings, so re-use "allowSettings" here ...
this._displaysSection.visible = Main.sessionMode.allowSettings;
// This needs to be handled manually, as the code to
// autohide separators doesn't work across the vbox
this._dateAndTimeSeparator.actor.visible = Main.sessionMode.allowSettings;
},
_updateClockAndDate: function() {
this._clockDisplay.set_text(this._clock.clock);
/* Translators: This is the date format to use when the calendar popup is
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
*/
let dateFormat = _("%A %B %e, %Y");
let displayDate = new Date();
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
},
_getCalendarApp: function() {
if (this._calendarApp !== undefined)
return this._calendarApp;
let apps = Gio.AppInfo.get_recommended_for_type('text/calendar');
if (apps && (apps.length > 0))
this._calendarApp = apps[0];
else
this._calendarApp = null;
return this._calendarApp;
},
_getClockApp: function() {
return Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
},
_onOpenCalendarActivate: function() {
this.menu.close();
let app = this._getCalendarApp();
if (app.get_id() == 'evolution.desktop')
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
app.launch([], global.create_app_launch_context(0, -1));
},
_onOpenClocksActivate: function() {
this.menu.close();
let app = this._getClockApp();
app.activate();
}
});

View File

@ -46,7 +46,7 @@ let dragMonitors = [];
function _getEventHandlerActor() {
if (!eventHandlerActor) {
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
// when you've grabbed the pointer.
eventHandlerActor.connect('event',
@ -79,12 +79,9 @@ const _Draggable = new Lang.Class({
dragActorOpacity: undefined });
this.actor = actor;
if (!params.manualMode) {
if (!params.manualMode)
this.actor.connect('button-press-event',
Lang.bind(this, this._onButtonPress));
this.actor.connect('touch-event',
Lang.bind(this, this._onTouchEvent));
}
this.actor.connect('destroy', Lang.bind(this, function() {
this._actorDestroyed = true;
@ -124,50 +121,8 @@ const _Draggable = new Lang.Class({
return Clutter.EVENT_PROPAGATE;
},
_onTouchEvent: function (actor, event) {
if (event.type() != Clutter.EventType.TOUCH_BEGIN ||
!global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
return Clutter.EVENT_PROPAGATE;
if (Tweener.getTweenCount(actor))
return Clutter.EVENT_PROPAGATE;
this._touchSequence = event.get_event_sequence();
this._buttonDown = true;
this._grabActor();
let [stageX, stageY] = event.get_coords();
this._dragStartX = stageX;
this._dragStartY = stageY;
return Clutter.EVENT_PROPAGATE;
},
_grabDevice: function(actor) {
let manager = Clutter.DeviceManager.get_default();
let pointer = manager.get_core_device(Clutter.InputDeviceType.POINTER_DEVICE);
if (pointer && this._touchSequence)
pointer.sequence_grab(this._touchSequence, actor);
else if (pointer)
pointer.grab (actor);
this._grabbedDevice = pointer;
},
_ungrabDevice: function() {
if (this._touchSequence)
this._grabbedDevice.sequence_ungrab (this._touchSequence);
else
this._grabbedDevice.ungrab();
this._touchSequence = null;
this._grabbedDevice = null;
},
_grabActor: function() {
this._grabDevice(this.actor);
Clutter.grab_pointer(this.actor);
this._onEventId = this.actor.connect('event',
Lang.bind(this, this._onEvent));
},
@ -176,7 +131,7 @@ const _Draggable = new Lang.Class({
if (!this._onEventId)
return;
this._ungrabDevice();
Clutter.ungrab_pointer();
this.actor.disconnect(this._onEventId);
this._onEventId = null;
},
@ -185,13 +140,13 @@ const _Draggable = new Lang.Class({
if (!this._eventsGrabbed) {
this._eventsGrabbed = Main.pushModal(_getEventHandlerActor());
if (this._eventsGrabbed)
this._grabDevice(_getEventHandlerActor());
Clutter.grab_pointer(_getEventHandlerActor());
}
},
_ungrabEvents: function() {
if (this._eventsGrabbed) {
this._ungrabDevice();
Clutter.ungrab_pointer();
Main.popModal(_getEventHandlerActor());
this._eventsGrabbed = false;
}
@ -202,9 +157,7 @@ const _Draggable = new Lang.Class({
// didn't start the drag, to drop the draggable in case the drag was in progress, and
// to complete the drag and ensure that whatever happens to be under the pointer does
// not get triggered if the drag was cancelled with Esc.
if (event.type() == Clutter.EventType.BUTTON_RELEASE ||
(event.type() == Clutter.EventType.TOUCH_END &&
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
if (event.type() == Clutter.EventType.BUTTON_RELEASE) {
this._buttonDown = false;
if (this._dragInProgress) {
return this._dragActorDropped(event);
@ -219,9 +172,7 @@ const _Draggable = new Lang.Class({
}
// We intercept MOTION event to figure out if the drag has started and to draw
// this._dragActor under the pointer when dragging is in progress
} else if (event.type() == Clutter.EventType.MOTION ||
(event.type() == Clutter.EventType.TOUCH_UPDATE &&
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
} else if (event.type() == Clutter.EventType.MOTION) {
if (this._dragInProgress) {
return this._updateDragPosition(event);
} else if (this._dragActor == null) {
@ -263,7 +214,7 @@ const _Draggable = new Lang.Class({
* This function is useful to call if you've specified manualMode
* for the draggable.
*/
startDrag: function (stageX, stageY, time, sequence) {
startDrag: function (stageX, stageY, time) {
currentDraggable = this;
this._dragInProgress = true;
@ -277,8 +228,6 @@ const _Draggable = new Lang.Class({
this.emit('drag-begin', time);
if (this._onEventId)
this._ungrabActor();
this._touchSequence = sequence;
this._grabEvents();
global.screen.set_cursor(Meta.Cursor.DND_IN_DRAG);
@ -287,7 +236,7 @@ const _Draggable = new Lang.Class({
if (this.actor._delegate && 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();
Shell.util_set_hidden_from_pick(this._dragActor, true);
@ -327,7 +276,7 @@ const _Draggable = new Lang.Class({
this._dragOrigScale = this._dragActor.scale_x;
// 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();
this._dragActor.set_scale(scaledWidth / this.actor.width,
scaledHeight / this.actor.height);
@ -337,7 +286,7 @@ const _Draggable = new Lang.Class({
this._dragOffsetY = actorStageY - this._dragStartY;
this._dragOrigParent.remove_actor(this._dragActor);
Main.uiGroup.add_child(this._dragActor);
Main.layoutManager.sessionGroup.add_child(this._dragActor);
this._dragActor.raise_top();
Shell.util_set_hidden_from_pick(this._dragActor, true);
}
@ -389,8 +338,8 @@ const _Draggable = new Lang.Class({
let threshold = Gtk.Settings.get_default().gtk_dnd_drag_threshold;
if ((Math.abs(stageX - this._dragStartX) > threshold ||
Math.abs(stageY - this._dragStartY) > threshold)) {
this.startDrag(stageX, stageY, event.get_time(), this._touchSequence);
this._updateDragPosition(event);
this.startDrag(stageX, stageY, event.get_time());
this._updateDragPosition(event);
}
return true;
@ -446,7 +395,6 @@ const _Draggable = new Lang.Class({
this._updateHoverId = GLib.idle_add(GLib.PRIORITY_DEFAULT,
Lang.bind(this, this._updateDragHover));
GLib.Source.set_name_by_id(this._updateHoverId, '[gnome-shell] this._updateDragHover');
},
_updateDragPosition : function (event) {
@ -500,7 +448,7 @@ const _Draggable = new Lang.Class({
event.get_time())) {
// If it accepted the drop without taking the actor,
// handle it ourselves.
if (this._dragActor.get_parent() == Main.uiGroup) {
if (this._dragActor.get_parent() == Main.layoutManager.sessionGroup) {
if (this._restoreOnSuccess) {
this._restoreDragActor(event.get_time());
return true;
@ -571,13 +519,20 @@ const _Draggable = new Lang.Class({
return;
}
this._animateDragEnd(eventTime,
{ x: snapBackX,
y: snapBackY,
scale_x: snapBackScale,
scale_y: snapBackScale,
time: SNAP_BACK_ANIMATION_TIME,
});
this._animationInProgress = true;
// No target, so snap back
Tweener.addTween(this._dragActor,
{ x: snapBackX,
y: snapBackY,
scale_x: snapBackScale,
scale_y: snapBackScale,
opacity: this._dragOrigOpacity,
time: SNAP_BACK_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._onAnimationComplete,
onCompleteScope: this,
onCompleteParams: [this._dragActor, eventTime]
});
},
_restoreDragActor: function(eventTime) {
@ -589,55 +544,32 @@ const _Draggable = new Lang.Class({
this._dragActor.set_scale(restoreScale, restoreScale);
this._dragActor.opacity = 0;
this._animateDragEnd(eventTime,
{ time: REVERT_ANIMATION_TIME });
},
_animateDragEnd: function (eventTime, params) {
this._animationInProgress = true;
// finish animation if the actor gets destroyed
// during it
this._dragActorDestroyId =
this._dragActor.connect('destroy',
Lang.bind(this, this._finishAnimation));
params['opacity'] = this._dragOrigOpacity;
params['transition'] = 'easeOutQuad';
params['onComplete'] = this._onAnimationComplete;
params['onCompleteScope'] = this;
params['onCompleteParams'] = [this._dragActor, eventTime];
// start the animation
Tweener.addTween(this._dragActor, params)
},
_finishAnimation : function () {
if (!this._animationInProgress)
return
this._animationInProgress = false;
if (!this._buttonDown)
this._dragComplete();
global.screen.set_cursor(Meta.Cursor.DEFAULT);
Tweener.addTween(this._dragActor,
{ opacity: this._dragOrigOpacity,
time: REVERT_ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._onAnimationComplete,
onCompleteScope: this,
onCompleteParams: [this._dragActor, eventTime]
});
},
_onAnimationComplete : function (dragActor, eventTime) {
dragActor.disconnect(this._dragActorDestroyId);
this._dragActorDestroyId = 0;
if (this._dragOrigParent) {
Main.uiGroup.remove_child(this._dragActor);
Main.layoutManager.sessionGroup.remove_child(this._dragActor);
this._dragOrigParent.add_actor(this._dragActor);
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
dragActor.set_position(this._dragOrigX, this._dragOrigY);
} else {
dragActor.destroy();
}
global.screen.set_cursor(Meta.Cursor.DEFAULT);
this.emit('drag-end', eventTime, false);
this._finishAnimation();
this._animationInProgress = false;
if (!this._buttonDown)
this._dragComplete();
},
_dragComplete: function() {

View File

@ -1,84 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Signals = imports.signals;
const Meta = imports.gi.Meta;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Main = imports.ui.main;
const EDGE_THRESHOLD = 20;
const DRAG_DISTANCE = 80;
const EdgeDragAction = new Lang.Class({
Name: 'EdgeDragAction',
Extends: Clutter.GestureAction,
_init : function(side, allowedModes) {
this.parent();
this._side = side;
this._allowedModes = allowedModes;
this.set_n_touch_points(1);
global.display.connect('grab-op-begin', Lang.bind(this, function() {
this.cancel();
}));
},
_getMonitorRect : function (x, y) {
let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 });
let monitorIndex = global.screen.get_monitor_index_for_rect(rect);
return global.screen.get_monitor_geometry(monitorIndex);
},
vfunc_gesture_prepare : function(action, actor) {
if (this.get_n_current_points() == 0)
return false;
if (!(this._allowedModes & Main.actionMode))
return false;
let [x, y] = this.get_press_coords(0);
let monitorRect = this._getMonitorRect(x, y);
return ((this._side == St.Side.LEFT && x < monitorRect.x + EDGE_THRESHOLD) ||
(this._side == St.Side.RIGHT && x > monitorRect.x + monitorRect.width - EDGE_THRESHOLD) ||
(this._side == St.Side.TOP && y < monitorRect.y + EDGE_THRESHOLD) ||
(this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD));
},
vfunc_gesture_progress : function (action, actor) {
let [startX, startY] = this.get_press_coords(0);
let [x, y] = this.get_motion_coords(0);
let offsetX = Math.abs (x - startX);
let offsetY = Math.abs (y - startY);
if (offsetX < EDGE_THRESHOLD && offsetY < EDGE_THRESHOLD)
return true;
if ((offsetX > offsetY &&
(this._side == St.Side.TOP || this._side == St.Side.BOTTOM)) ||
(offsetY > offsetX &&
(this._side == St.Side.LEFT || this._side == St.Side.RIGHT))) {
this.cancel();
return false;
}
return true;
},
vfunc_gesture_end : function (action, actor) {
let [startX, startY] = this.get_press_coords(0);
let [x, y] = this.get_motion_coords(0);
let monitorRect = this._getMonitorRect(startX, startY);
if ((this._side == St.Side.TOP && y > monitorRect.y + DRAG_DISTANCE) ||
(this._side == St.Side.BOTTOM && y < monitorRect.y + monitorRect.height - DRAG_DISTANCE) ||
(this._side == St.Side.LEFT && x > monitorRect.x + DRAG_DISTANCE) ||
(this._side == St.Side.RIGHT && x < monitorRect.x + monitorRect.width - DRAG_DISTANCE))
this.emit('activated');
}
});
Signals.addSignalMethods(EdgeDragAction.prototype);

View File

@ -1,6 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/*
* Copyright 2010-2016 Red Hat, Inc
* Copyright 2010 Red Hat, Inc
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,11 +25,9 @@ const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Pango = imports.gi.Pango;
const Polkit = imports.gi.Polkit;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const CheckBox = imports.ui.checkBox;
const GnomeSession = imports.misc.gnomeSession;
const LoginManager = imports.misc.loginManager;
const ModalDialog = imports.ui.modalDialog;
@ -39,7 +37,7 @@ const UserWidget = imports.ui.userWidget;
let _endSessionDialog = null;
const _ITEM_ICON_SIZE = 48;
const _DIALOG_ICON_SIZE = 48;
const _DIALOG_ICON_SIZE = 32;
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
@ -73,7 +71,6 @@ const logoutDialogContent = {
"You will be logged out automatically in %d seconds.",
seconds).format(seconds);
},
showBatteryWarning: false,
confirmButtons: [{ signal: 'ConfirmedLogout',
label: C_("button", "Log Out") }],
iconStyleClass: 'end-session-dialog-logout-icon',
@ -82,14 +79,11 @@ const logoutDialogContent = {
const shutdownDialogContent = {
subject: C_("title", "Power Off"),
subjectWithUpdates: C_("title", "Install Updates & Power Off"),
description: function(seconds) {
return ngettext("The system will power off automatically in %d second.",
"The system will power off automatically in %d seconds.",
seconds).format(seconds);
},
checkBoxText: C_("checkbox", "Install pending software updates"),
showBatteryWarning: true,
confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart") },
{ signal: 'ConfirmedShutdown',
@ -106,7 +100,6 @@ const restartDialogContent = {
"The system will restart automatically in %d seconds.",
seconds).format(seconds);
},
showBatteryWarning: false,
confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart") }],
iconName: 'view-refresh-symbolic',
@ -114,7 +107,7 @@ const restartDialogContent = {
showOtherSessions: true,
};
const restartUpdateDialogContent = {
const restartInstallDialogContent = {
subject: C_("title", "Restart & Install Updates"),
description: function(seconds) {
@ -122,48 +115,18 @@ const restartUpdateDialogContent = {
"The system will automatically restart and install updates in %d seconds.",
seconds).format(seconds);
},
showBatteryWarning: true,
confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart &amp; Install") }],
unusedFutureButtonForTranslation: C_("button", "Install &amp; Power Off"),
unusedFutureCheckBoxForTranslation: C_("checkbox", "Power off after updates are installed"),
label: C_("button", "Restart & Install") }],
iconName: 'view-refresh-symbolic',
iconStyleClass: 'end-session-dialog-shutdown-icon',
showOtherSessions: true,
};
const restartUpgradeDialogContent = {
subject: C_("title", "Restart & Install Upgrade"),
upgradeDescription: function(distroName, distroVersion) {
/* Translators: This is the text displayed for system upgrades in the
shut down dialog. First %s gets replaced with the distro name and
second %s with the distro version to upgrade to */
return _("%s %s will be installed after restart. Upgrade installation can take a long time: ensure that you have backed up and that the computer is plugged in.").format(distroName, distroVersion);
},
disableTimer: true,
showBatteryWarning: false,
confirmButtons: [{ signal: 'ConfirmedReboot',
label: C_("button", "Restart &amp; Install") }],
iconName: 'view-refresh-symbolic',
iconStyleClass: 'end-session-dialog-shutdown-icon',
showOtherSessions: true,
};
const DialogType = {
LOGOUT: 0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */,
SHUTDOWN: 1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */,
RESTART: 2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */,
UPDATE_RESTART: 3,
UPGRADE_RESTART: 4
};
const DialogContent = {
0 /* DialogType.LOGOUT */: logoutDialogContent,
1 /* DialogType.SHUTDOWN */: shutdownDialogContent,
2 /* DialogType.RESTART */: restartDialogContent,
3 /* DialogType.UPDATE_RESTART */: restartUpdateDialogContent,
4 /* DialogType.UPGRADE_RESTART */: restartUpgradeDialogContent
0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */: logoutDialogContent,
1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */: shutdownDialogContent,
2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */: restartDialogContent,
3: restartInstallDialogContent
};
const MAX_USERS_IN_SESSION_DIALOG = 5;
@ -180,30 +143,6 @@ const LogindSessionIface = '<node> \
const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
const PkOfflineIface = '<node> \
<interface name="org.freedesktop.PackageKit.Offline"> \
<property name="UpdatePrepared" type="b" access="read"/> \
<property name="UpdateTriggered" type="b" access="read"/> \
<property name="UpgradePrepared" type="b" access="read"/> \
<property name="UpgradeTriggered" type="b" access="read"/> \
<property name="PreparedUpgrade" type="a{sv}" access="read"/> \
<method name="Trigger"> \
<arg type="s" name="action" direction="in"/> \
</method> \
<method name="Cancel"/> \
</interface> \
</node>';
const PkOfflineProxy = Gio.DBusProxy.makeProxyWrapper(PkOfflineIface);
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) {
let desktopFile;
try {
@ -256,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() {
// This always returns the same singleton object
// By instantiating it initially, we register the
@ -286,26 +213,7 @@ const EndSessionDialog = new Lang.Class({
this._loginManager = LoginManager.getLoginManager();
this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name());
this._pkOfflineProxy = new PkOfflineProxy(Gio.DBus.system,
'org.freedesktop.PackageKit',
'/org/freedesktop/PackageKit',
Lang.bind(this, function(proxy, error) {
if (error)
log(error.message);
}));
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._updatesFile = Gio.File.new_for_path('/system-update');
this._secondsLeft = 0;
this._totalSecondsToStayOpen = 0;
@ -332,8 +240,7 @@ const EndSessionDialog = new Lang.Class({
x_align: St.Align.END,
y_align: St.Align.START });
let messageLayout = new St.BoxLayout({ vertical: true,
style_class: 'end-session-dialog-layout' });
let messageLayout = new St.BoxLayout({ vertical: true });
mainContentLayout.add(messageLayout,
{ y_align: St.Align.START });
@ -353,16 +260,6 @@ const EndSessionDialog = new Lang.Class({
{ y_fill: true,
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.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.contentLayout.add(this._scrollView,
@ -388,12 +285,6 @@ const EndSessionDialog = new Lang.Class({
this._inhibitorSection.add_actor(this._sessionHeader);
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.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
},
@ -408,22 +299,13 @@ const EndSessionDialog = new Lang.Class({
if (!open)
return;
if (this._type == 2 && this._updatesFile.query_exists(null))
this._type = 3;
let dialogContent = DialogContent[this._type];
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 displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
this._secondsLeft,
@ -438,19 +320,11 @@ const EndSessionDialog = new Lang.Class({
if (dialogContent.descriptionWithUser)
description = dialogContent.descriptionWithUser(realName, displayTime);
else
description = dialogContent.description(displayTime);
}
}
// Use a different description when we are installing a system upgrade
if (dialogContent.upgradeDescription) {
let name = this._pkOfflineProxy.PreparedUpgrade['name'].deep_unpack();
let version = this._pkOfflineProxy.PreparedUpgrade['version'].deep_unpack();
if (name != null && version != null)
description = dialogContent.upgradeDescription(name, version);
}
// Fall back to regular description
if (!description)
description = dialogContent.description(displayTime);
@ -514,73 +388,15 @@ const EndSessionDialog = new Lang.Class({
},
_confirm: function(signal) {
let callback = Lang.bind(this, function() {
this._fadeOutDialog();
this._stopTimer();
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);
}
this._fadeOutDialog();
this._stopTimer();
this._dbusImpl.emit_signal(signal, null);
},
_onOpened: function() {
this._sync();
},
_triggerOfflineUpdateReboot: function(callback) {
this._pkOfflineProxy.TriggerRemote('reboot',
function (result, error) {
if (error)
log(error.message);
callback();
});
},
_triggerOfflineUpdateShutdown: function(callback) {
this._pkOfflineProxy.TriggerRemote('power-off',
function (result, error) {
if (error)
log(error.message);
callback();
});
},
_triggerOfflineUpdateCancel: function(callback) {
this._pkOfflineProxy.CancelRemote(function (result, error) {
if (error)
log(error.message);
callback();
});
},
_startTimer: function() {
let startTime = GLib.get_monotonic_time();
this._secondsLeft = this._totalSecondsToStayOpen;
@ -603,7 +419,6 @@ const EndSessionDialog = new Lang.Class({
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._timerId, '[gnome-shell] this._confirm');
},
_stopTimer: function() {
@ -729,13 +544,6 @@ const EndSessionDialog = new Lang.Class({
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
this._type = type;
if (this._type == DialogType.RESTART) {
if (this._pkOfflineProxy.UpdateTriggered)
this._type = DialogType.UPDATE_RESTART;
else if (this._pkOfflineProxy.UpgradeTriggered)
this._type = DialogType.UPGRADE_RESTART;
}
this._applications = [];
this._applicationList.destroy_all_children();
@ -748,8 +556,6 @@ const EndSessionDialog = new Lang.Class({
return;
}
let dialogContent = DialogContent[this._type];
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) {
this._onInhibitorLoaded(proxy);
@ -758,23 +564,9 @@ const EndSessionDialog = new Lang.Class({
this._applications.push(inhibitor);
}
if (dialogContent.showOtherSessions)
if (DialogContent[type].showOtherSessions)
this._loadSessions();
let updateTriggered = this._pkOfflineProxy.UpdateTriggered;
let updatePrepared = this._pkOfflineProxy.UpdatePrepared;
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText);
this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
this._checkBox.actor.checked = (updatePrepared && updateTriggered);
// 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 || updatePrepared && updateTriggered && !updatesAllowed));
this._updateButtons();
if (!this.open(timestamp)) {
@ -783,9 +575,7 @@ const EndSessionDialog = new Lang.Class({
return;
}
if (!dialogContent.disableTimer)
this._startTimer();
this._startTimer();
this._sync();
let signalId = this.connect('opened',

View File

@ -5,8 +5,6 @@ imports.gi.versions.Gio = '2.0';
imports.gi.versions.Gdk = '3.0';
imports.gi.versions.GdkPixbuf = '2.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 Gettext = imports.gettext;
@ -47,11 +45,8 @@ function _patchLayoutClass(layoutClass, styleProps) {
layoutClass.prototype.hookup_style = function(container) {
container.connect('style-changed', Lang.bind(this, function() {
let node = container.get_theme_node();
for (let prop in styleProps) {
let [found, length] = node.lookup_length(styleProps[prop], false);
if (found)
this[prop] = length;
}
for (let prop in styleProps)
this[prop] = node.get_length(styleProps[prop]);
}));
};
layoutClass.prototype.child_set = function(actor, props) {
@ -77,10 +72,10 @@ function init() {
window._ = Gettext.gettext;
window.C_ = Gettext.pgettext;
window.ngettext = Gettext.ngettext;
window.N_ = function(s) { return s; };
// Miscellaneous monkeypatching
_patchContainerClass(St.BoxLayout);
_patchContainerClass(St.Table);
_patchLayoutClass(Clutter.TableLayout, { row_spacing: 'spacing-rows',
column_spacing: 'spacing-columns' });

View File

@ -203,16 +203,14 @@ const InstallExtensionDialog = new Lang.Class({
let message = _("Download and install “%s” from extensions.gnome.org?").format(info.name);
let box = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
vertical: false });
let box = new St.BoxLayout();
this.contentLayout.add(box);
let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) })
let icon = new St.Icon({ gicon: gicon });
box.add(icon);
let label = new St.Label({ style_class: 'prompt-dialog-headline headline',
text: message });
let label = new St.Label({ text: message });
box.add(label);
},

View File

@ -38,7 +38,6 @@ const connect = Lang.bind(_signals, _signals.connect);
const disconnect = Lang.bind(_signals, _signals.disconnect);
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
var initted = false;
var enabled;
@ -74,7 +73,7 @@ function disableExtension(uuid) {
if (extension.stylesheet) {
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
theme.unload_stylesheet(extension.stylesheet);
theme.unload_stylesheet(extension.stylesheet.get_path());
}
try {
@ -118,7 +117,7 @@ function enableExtension(uuid) {
let stylesheetFile = extension.dir.get_child(stylesheetNames[i]);
if (stylesheetFile.query_exists(null)) {
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
theme.load_stylesheet(stylesheetFile);
theme.load_stylesheet(stylesheetFile.get_path());
extension.stylesheet = stylesheetFile;
break;
}
@ -157,9 +156,7 @@ function loadExtension(extension) {
// Default to error, we set success as the last step
extension.state = ExtensionState.ERROR;
let checkVersion = !global.settings.get_boolean(EXTENSION_DISABLE_VERSION_CHECK_KEY);
if (checkVersion && ExtensionUtils.isOutOfDate(extension)) {
if (ExtensionUtils.isOutOfDate(extension)) {
extension.state = ExtensionState.OUT_OF_DATE;
} else {
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
@ -270,26 +267,8 @@ function onEnabledExtensionsChanged() {
enabledExtensions = newEnabledExtensions;
}
function _onVersionValidationChanged() {
// we want to reload all extensions, but only enable
// extensions when allowed by the sessionMode, so
// temporarily disable them all
enabledExtensions = [];
for (let uuid in ExtensionUtils.extensions)
reloadExtension(ExtensionUtils.extensions[uuid]);
enabledExtensions = getEnabledExtensions();
if (Main.sessionMode.allowExtensions) {
enabledExtensions.forEach(function(uuid) {
enableExtension(uuid);
});
}
}
function _loadExtensions() {
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
global.settings.connect('changed::' + EXTENSION_DISABLE_VERSION_CHECK_KEY, _onVersionValidationChanged);
enabledExtensions = getEnabledExtensions();
let finder = new ExtensionUtils.ExtensionFinder();
@ -334,7 +313,7 @@ function _sessionUpdated() {
// from allowExtensions in the future
if (Main.sessionMode.allowExtensions) {
if (initted)
enabledExtensions = getEnabledExtensions();
onEnabledExtensionsChanged();
enableAllExtensions();
} else {
disableAllExtensions();

View File

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

View File

@ -56,7 +56,7 @@ const GrabHelper = new Lang.Class({
this._grabStack = [];
this._actors = [];
this._ignoreUntilRelease = false;
this._ignoreRelease = false;
this._modalCount = 0;
},
@ -215,7 +215,7 @@ const GrabHelper = new Lang.Class({
_popGrabHelper(this);
this._ignoreUntilRelease = false;
this._ignoreRelease = false;
Main.popModal(this._owner);
global.sync_pointer();
@ -228,7 +228,7 @@ const GrabHelper = new Lang.Class({
// like the ComboBoxMenu that go away on press, but need to eat
// the next release event.
ignoreRelease: function() {
this._ignoreUntilRelease = true;
this._ignoreRelease = true;
},
// ungrab:
@ -283,22 +283,12 @@ const GrabHelper = new Lang.Class({
return Clutter.EVENT_STOP;
}
let motion = type == Clutter.EventType.MOTION;
let press = type == Clutter.EventType.BUTTON_PRESS;
let release = type == Clutter.EventType.BUTTON_RELEASE;
let button = press || release;
let touchUpdate = type == Clutter.EventType.TOUCH_UPDATE;
let touchBegin = type == Clutter.EventType.TOUCH_BEGIN;
let touchEnd = type == Clutter.EventType.TOUCH_END;
let touch = touchUpdate || touchBegin || touchEnd;
if (touch && !global.display.is_pointer_emulating_sequence (event.get_event_sequence()))
return Clutter.EVENT_PROPAGATE;
if (this._ignoreUntilRelease && (motion || release || touch)) {
if (release || touchEnd)
this._ignoreUntilRelease = false;
if (release && this._ignoreRelease) {
this._ignoreRelease = false;
return Clutter.EVENT_STOP;
}
@ -308,12 +298,11 @@ const GrabHelper = new Lang.Class({
if (Main.keyboard.shouldTakeEvent(event))
return Clutter.EVENT_PROPAGATE;
if (button || touchBegin) {
// If we have a press event, ignore the next
// motion/release events.
if (press || touchBegin)
this._ignoreUntilRelease = true;
if (button) {
// If we have a press event, ignore the next event,
// which should be a release event.
if (press)
this._ignoreRelease = true;
let i = this._actorInGrabStack(event.get_source()) + 1;
this.ungrab({ actor: this._grabStack[i].actor, isUser: true });
return Clutter.EVENT_STOP;

View File

@ -11,9 +11,6 @@ const Main = imports.ui.main;
const MAX_CANDIDATES_PER_PAGE = 16;
const DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8',
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f' ];
const CandidateArea = new Lang.Class({
Name: 'CandidateArea',
@ -41,11 +38,11 @@ const CandidateArea = new Lang.Class({
this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' });
this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous' });
this._previousButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' });
this._buttonBox.add(this._previousButton, { expand: true });
this._nextButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-next button' });
this._nextButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-next' });
this._nextButton.child = new St.Icon({ style_class: 'candidate-page-button-icon' });
this._buttonBox.add(this._nextButton, { expand: true });
@ -92,7 +89,7 @@ const CandidateArea = new Lang.Class({
if (!visible)
continue;
box._indexLabel.text = ((indexes && indexes[i]) ? indexes[i] : DEFAULT_INDEX_LABELS[i]);
box._indexLabel.text = ((indexes && indexes[i]) ? indexes[i] : '%x'.format(i + 1));
box._candidateLabel.text = candidates[i];
}
@ -158,22 +155,10 @@ const CandidatePopup = new Lang.Class({
panelService.connect('set-cursor-location',
Lang.bind(this, function(ps, x, y, w, h) {
this._setDummyCursorGeometry(x, y, w, h);
Main.layoutManager.setDummyCursorPosition(x, y);
if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
}));
try {
panelService.connect('set-cursor-location-relative',
Lang.bind(this, function(ps, x, y, w, h) {
if (!global.display.focus_window)
return;
let window = global.display.focus_window.get_compositor_private();
this._setDummyCursorGeometry(window.x + x, window.y + y, w, h);
}));
} catch(e) {
// Only recent IBus versions have support for this signal
// which is used for wayland clients. In order to work
// with older IBus versions we can silently ignore the
// signal's absence.
}
panelService.connect('update-preedit-text',
Lang.bind(this, function(ps, text, cursorPosition, visible) {
this._preeditText.visible = visible;
@ -258,12 +243,6 @@ const CandidatePopup = new Lang.Class({
}));
},
_setDummyCursorGeometry: function(x, y, w, h) {
Main.layoutManager.setDummyCursorGeometry(x, y, w, h);
if (this._boxPointer.actor.visible)
this._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0);
},
_updateVisibility: function() {
let isVisible = (this._preeditText.visible ||
this._auxText.visible ||

View File

@ -10,30 +10,12 @@ const St = imports.gi.St;
const Lang = imports.lang;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const Main = imports.ui.main;
const ICON_SIZE = 96;
const MIN_ICON_SIZE = 16;
const EXTRA_SPACE_ANIMATION_TIME = 0.25;
const ANIMATION_TIME_IN = 0.350;
const ANIMATION_TIME_OUT = 1/2 * ANIMATION_TIME_IN;
const ANIMATION_MAX_DELAY_FOR_ITEM = 2/3 * ANIMATION_TIME_IN;
const ANIMATION_BASE_DELAY_FOR_ITEM = 1/4 * ANIMATION_MAX_DELAY_FOR_ITEM;
const ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 2/3 * ANIMATION_TIME_OUT;
const ANIMATION_FADE_IN_TIME_FOR_ITEM = 1/4 * ANIMATION_TIME_IN;
const ANIMATION_BOUNCE_ICON_SCALE = 1.1;
const AnimationDirection = {
IN: 0,
OUT: 1
};
const APPICON_ANIMATION_OUT_SCALE = 3;
const APPICON_ANIMATION_OUT_TIME = 0.25;
const BaseIcon = new Lang.Class({
Name: 'BaseIcon',
@ -161,6 +143,11 @@ const BaseIcon = new Lang.Class({
this.icon = this.createIcon(this.iconSize);
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() {
@ -191,55 +178,9 @@ const BaseIcon = new Lang.Class({
_onIconThemeChanged: function() {
this._createIconTexture(this.iconSize);
},
animateZoomOut: function() {
// Animate only the child instead of the entire actor, so the
// styles like hover and running are not applied while
// animating.
zoomOutActor(this.actor.child);
}
});
function clamp(value, min, max) {
return Math.max(Math.min(value, max), min);
};
function zoomOutActor(actor) {
let actorClone = new Clutter.Clone({ source: actor,
reactive: false });
let [width, height] = actor.get_transformed_size();
let [x, y] = actor.get_transformed_position();
actorClone.set_size(width, height);
actorClone.set_position(x, y);
actorClone.opacity = 255;
actorClone.set_pivot_point(0.5, 0.5);
Main.uiGroup.add_actor(actorClone);
// Avoid monitor edges to not zoom outside the current monitor
let monitor = Main.layoutManager.findMonitorForActor(actor);
let scaledWidth = width * APPICON_ANIMATION_OUT_SCALE;
let scaledHeight = height * APPICON_ANIMATION_OUT_SCALE;
let scaledX = x - (scaledWidth - width) / 2;
let scaledY = y - (scaledHeight - height) / 2;
let containedX = clamp(scaledX, monitor.x, monitor.x + monitor.width - scaledWidth);
let containedY = clamp(scaledY, monitor.y, monitor.y + monitor.height - scaledHeight);
Tweener.addTween(actorClone,
{ time: APPICON_ANIMATION_OUT_TIME,
scale_x: APPICON_ANIMATION_OUT_SCALE,
scale_y: APPICON_ANIMATION_OUT_SCALE,
translation_x: containedX - scaledX,
translation_y: containedY - scaledY,
opacity: 0,
transition: 'easeOutQuad',
onComplete: function() {
actorClone.destroy();
}
});
}
const IconGrid = new Lang.Class({
Name: 'IconGrid',
@ -278,20 +219,6 @@ const IconGrid = new Lang.Class({
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('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) {
@ -402,202 +329,15 @@ const IconGrid = new Lang.Class({
}
},
/**
* Intended to be override by subclasses if they need a different
* set of items to be animated.
*/
_getChildrenToAnimate: function() {
return this._getVisibleChildren();
},
_animationDone: function() {
this._animating = false;
this.emit('animation-done');
},
animatePulse: function(animationDirection) {
if (animationDirection != AnimationDirection.IN)
throw new Error("Pulse animation only implements 'in' animation direction");
if (this._animating)
return;
this._animating = true;
let actors = this._getChildrenToAnimate();
if (actors.length == 0) {
this._animationDone();
return;
}
// For few items the animation can be slow, so use a smaller
// delay when there are less than 4 items
// (ANIMATION_BASE_DELAY_FOR_ITEM = 1/4 *
// ANIMATION_MAX_DELAY_FOR_ITEM)
let maxDelay = Math.min(ANIMATION_BASE_DELAY_FOR_ITEM * actors.length,
ANIMATION_MAX_DELAY_FOR_ITEM);
for (let index = 0; index < actors.length; index++) {
let actor = actors[index];
actor.reactive = false;
actor.set_scale(0, 0);
actor.set_pivot_point(0.5, 0.5);
let delay = index / actors.length * maxDelay;
let bounceUpTime = ANIMATION_TIME_IN / 4;
let isLastItem = index == actors.length - 1;
Tweener.addTween(actor,
{ time: bounceUpTime,
transition: 'easeInOutQuad',
delay: delay,
scale_x: ANIMATION_BOUNCE_ICON_SCALE,
scale_y: ANIMATION_BOUNCE_ICON_SCALE,
onComplete: Lang.bind(this, function() {
Tweener.addTween(actor,
{ time: ANIMATION_TIME_IN - bounceUpTime,
transition: 'easeInOutQuad',
scale_x: 1,
scale_y: 1,
onComplete: Lang.bind(this, function() {
if (isLastItem)
this._animationDone();
actor.reactive = true;
})
});
})
});
}
},
animateSpring: function(animationDirection, sourceActor) {
if (this._animating)
return;
this._animating = true;
let actors = this._getChildrenToAnimate();
if (actors.length == 0) {
this._animationDone();
return;
}
let [sourceX, sourceY] = sourceActor.get_transformed_position();
let [sourceWidth, sourceHeight] = sourceActor.get_size();
// Get the center
let [sourceCenterX, sourceCenterY] = [sourceX + sourceWidth / 2, sourceY + sourceHeight / 2];
// Design decision, 1/2 of the source actor size.
let [sourceScaledWidth, sourceScaledHeight] = [sourceWidth / 2, sourceHeight / 2];
actors.forEach(function(actor) {
let [actorX, actorY] = actor._transformedPosition = actor.get_transformed_position();
let [x, y] = [actorX - sourceX, actorY - sourceY];
actor._distance = Math.sqrt(x * x + y * y);
});
let maxDist = actors.reduce(function(prev, cur) {
return Math.max(prev, cur._distance);
}, 0);
let minDist = actors.reduce(function(prev, cur) {
return Math.min(prev, cur._distance);
}, Infinity);
let normalization = maxDist - minDist;
for (let index = 0; index < actors.length; index++) {
let actor = actors[index];
actor.opacity = 0;
actor.reactive = false;
let actorClone = new Clutter.Clone({ source: actor });
Main.uiGroup.add_actor(actorClone);
let [width, height,,] = this._getAllocatedChildSizeAndSpacing(actor);
actorClone.set_size(width, height);
let scaleX = sourceScaledWidth / width;
let scaleY = sourceScaledHeight / height;
let [adjustedSourcePositionX, adjustedSourcePositionY] = [sourceCenterX - sourceScaledWidth / 2, sourceCenterY - sourceScaledHeight / 2];
let movementParams, fadeParams;
if (animationDirection == AnimationDirection.IN) {
let isLastItem = actor._distance == minDist;
actorClone.opacity = 0;
actorClone.set_scale(scaleX, scaleY);
actorClone.set_position(adjustedSourcePositionX, adjustedSourcePositionY);
let delay = (1 - (actor._distance - minDist) / normalization) * ANIMATION_MAX_DELAY_FOR_ITEM;
let [finalX, finalY] = actor._transformedPosition;
movementParams = { time: ANIMATION_TIME_IN,
transition: 'easeInOutQuad',
delay: delay,
x: finalX,
y: finalY,
scale_x: 1,
scale_y: 1,
onComplete: Lang.bind(this, function() {
if (isLastItem)
this._animationDone();
actor.opacity = 255;
actor.reactive = true;
actorClone.destroy();
})};
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
transition: 'easeInOutQuad',
delay: delay,
opacity: 255 };
} else {
let isLastItem = actor._distance == maxDist;
let [startX, startY] = actor._transformedPosition;
actorClone.set_position(startX, startY);
let delay = (actor._distance - minDist) / normalization * ANIMATION_MAX_DELAY_OUT_FOR_ITEM;
movementParams = { time: ANIMATION_TIME_OUT,
transition: 'easeInOutQuad',
delay: delay,
x: adjustedSourcePositionX,
y: adjustedSourcePositionY,
scale_x: scaleX,
scale_y: scaleY,
onComplete: Lang.bind(this, function() {
if (isLastItem) {
this._animationDone();
this._restoreItemsOpacity();
}
actor.reactive = true;
actorClone.destroy();
})};
fadeParams = { time: ANIMATION_FADE_IN_TIME_FOR_ITEM,
transition: 'easeInOutQuad',
delay: ANIMATION_TIME_OUT + delay - ANIMATION_FADE_IN_TIME_FOR_ITEM,
opacity: 0 };
}
Tweener.addTween(actorClone, movementParams);
Tweener.addTween(actorClone, fadeParams);
}
},
_restoreItemsOpacity: function() {
for (let index = 0; index < this._items.length; index++) {
this._items[index].actor.opacity = 255;
}
},
_getAllocatedChildSizeAndSpacing: function(child) {
let [,, natWidth, natHeight] = child.get_preferred_size();
let width = Math.min(this._getHItemSize(), natWidth);
let xSpacing = Math.max(0, width - natWidth) / 2;
let height = Math.min(this._getVItemSize(), natHeight);
let ySpacing = Math.max(0, height - natHeight) / 2;
return [width, height, xSpacing, ySpacing];
},
_calculateChildBox: function(child, x, y, box) {
let [childMinWidth, childMinHeight, childNaturalWidth, childNaturalHeight] =
child.get_preferred_size();
/* Center the item in its allocation horizontally */
let [width, height, childXSpacing, childYSpacing] =
this._getAllocatedChildSizeAndSpacing(child);
let width = Math.min(this._getHItemSize(), childNaturalWidth);
let childXSpacing = Math.max(0, width - childNaturalWidth) / 2;
let height = Math.min(this._getVItemSize(), childNaturalHeight);
let childYSpacing = Math.max(0, height - childNaturalHeight) / 2;
let childBox = new Clutter.ActorBox();
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
@ -773,22 +513,25 @@ const IconGrid = new Lang.Class({
this._fixedHItemSize = Math.max(this._hItemSize - neededSpacePerItem, MIN_ICON_SIZE);
this._fixedVItemSize = Math.max(this._vItemSize - neededSpacePerItem, MIN_ICON_SIZE);
if (this._fixedHItemSize < MIN_ICON_SIZE)
this._fixedHItemSize = MIN_ICON_SIZE;
if (this._fixedVItemSize < MIN_ICON_SIZE)
this._fixedVItemSize = MIN_ICON_SIZE;
this._updateSpacingForSize(availWidth, availHeight);
}
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
Lang.bind(this, this._updateIconSizes));
let scale = Math.min(this._fixedHItemSize, this._fixedVItemSize) / Math.max(this._hItemSize, this._vItemSize);
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._updateChildrenScale(scale); }));
},
// Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up
_updateIconSizes: function() {
let scale = Math.min(this._fixedHItemSize, this._fixedVItemSize) / Math.max(this._hItemSize, this._vItemSize);
let newIconSize = Math.floor(ICON_SIZE * scale);
_updateChildrenScale: function(scale) {
for (let i in this._items) {
let newIconSize = Math.floor(ICON_SIZE * scale);
this._items[i].icon.setIconSize(newIconSize);
}
}
});
Signals.addSignalMethods(IconGrid.prototype);
const PaginatedIconGrid = new Lang.Class({
Name: 'PaginatedIconGrid',
@ -797,7 +540,6 @@ const PaginatedIconGrid = new Lang.Class({
_init: function(params) {
this.parent(params);
this._nPages = 0;
this.currentPage = 0;
this._rowsPerPage = 0;
this._spaceBetweenPages = 0;
this._childrenPerPage = 0;
@ -861,15 +603,6 @@ const PaginatedIconGrid = new Lang.Class({
}
},
// Overriden from IconGrid
_getChildrenToAnimate: function() {
let children = this._getVisibleChildren();
let firstIndex = this._childrenPerPage * this.currentPage;
let lastIndex = firstIndex + this._childrenPerPage;
return children.slice(firstIndex, lastIndex);
},
_computePages: function (availWidthPerPage, availHeightPerPage) {
let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage);
let nRows;
@ -902,10 +635,6 @@ const PaginatedIconGrid = new Lang.Class({
return this._nPages;
},
getPageHeight: function() {
return this._availableHeightPerPageForItems();
},
getPageY: function(pageNumber) {
if (!this._nPages)
return 0;

View File

@ -6,11 +6,9 @@ const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const InputSourceManager = imports.ui.status.keyboard;
const BoxPointer = imports.ui.boxpointer;
const Layout = imports.ui.layout;
@ -25,9 +23,6 @@ const KEYBOARD_TYPE = 'keyboard-type';
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
const CARIBOU_BUS_NAME = 'org.gnome.Caribou.Daemon';
const CARIBOU_OBJECT_PATH = '/org/gnome/Caribou/Daemon';
const CaribouKeyboardIface = '<node> \
<interface name="org.gnome.Caribou.Keyboard"> \
<method name="Show"> \
@ -52,22 +47,13 @@ const CaribouKeyboardIface = '<node> \
</interface> \
</node>';
const CaribouDaemonIface = '<node> \
<interface name="org.gnome.Caribou.Daemon"> \
<method name="Run" /> \
<method name="Quit" /> \
</interface> \
</node>';
const CaribouDaemonProxy = Gio.DBusProxy.makeProxyWrapper(CaribouDaemonIface);
const Key = new Lang.Class({
Name: 'Key',
_init : function(key) {
this._key = key;
this.actor = this._makeKey(key, GLib.markup_escape_text(key.label, -1));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this.actor = this._makeKey();
this._extended_keys = this._key.get_extended_keys();
this._extended_keyboard = null;
@ -90,55 +76,20 @@ const Key = new Lang.Class({
}
},
_onDestroy: function() {
if (this._boxPointer) {
this._boxPointer.actor.destroy();
this._boxPointer = null;
}
},
_makeKey: function (key, label) {
_makeKey: function () {
let label = GLib.markup_escape_text(this._key.label, -1);
let button = new St.Button ({ label: label,
style_class: 'keyboard-key' });
button.key_width = this._key.width;
button.connect('button-press-event', Lang.bind(this,
function () {
key.press();
this._key.press();
return Clutter.EVENT_PROPAGATE;
}));
button.connect('button-release-event', Lang.bind(this,
function () {
key.release();
return Clutter.EVENT_PROPAGATE;
}));
button.connect('touch-event', Lang.bind(this,
function (actor, event) {
let device = event.get_device();
let sequence = event.get_event_sequence();
// We only handle touch events here on wayland. On X11
// we do get emulated pointer events, which already works
// for single-touch cases. Besides, the X11 passive touch grab
// set up by Mutter will make us see first the touch events
// and later the pointer events, so it will look like two
// unrelated series of events, we want to avoid double handling
// in these cases.
if (!Meta.is_wayland_compositor())
return Clutter.EVENT_PROPAGATE;
if (!this._touchPressed &&
event.type() == Clutter.EventType.TOUCH_BEGIN) {
device.sequence_grab(sequence, actor);
this._touchPressed = true;
key.press();
} else if (this._touchPressed &&
event.type() == Clutter.EventType.TOUCH_END &&
device.sequence_get_grabbed_actor(sequence) == actor) {
device.sequence_ungrab(sequence);
this._touchPressed = false;
key.release();
}
this._key.release();
return Clutter.EVENT_PROPAGATE;
}));
@ -161,9 +112,18 @@ const Key = new Lang.Class({
for (let i = 0; i < this._extended_keys.length; ++i) {
let extended_key = this._extended_keys[i];
let label = this._getUnichar(extended_key);
let key = this._makeKey(extended_key, label);
let key = new St.Button({ label: label, style_class: 'keyboard-key' });
key.extended_key = extended_key;
key.connect('button-press-event', Lang.bind(this,
function () {
extended_key.press();
return Clutter.EVENT_PROPAGATE;
}));
key.connect('button-release-event', Lang.bind(this,
function () {
extended_key.release();
return Clutter.EVENT_PROPAGATE;
}));
this._extended_keyboard.add(key);
}
this._boxPointer.bin.add_actor(this._extended_keyboard);
@ -201,28 +161,11 @@ const Keyboard = new Lang.Class({
this._timestamp = global.display.get_current_time_roundtrip();
this._keyboardSettings = new Gio.Settings({ schema_id: KEYBOARD_SCHEMA });
this._keyboardSettings.connect('changed', Lang.bind(this, this._sync));
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._sync));
this._daemonProxy = null;
this._lastDeviceId = null;
if (Meta.is_wayland_compositor() &&
Caribou.DisplayAdapter.set_default)
Caribou.DisplayAdapter.set_default(new ShellWaylandAdapter());
Meta.get_backend().connect('last-device-changed', Lang.bind(this,
function (backend, deviceId) {
let manager = Clutter.DeviceManager.get_default();
let device = manager.get_device(deviceId);
if (device.get_device_name().indexOf('XTEST') < 0) {
this._lastDeviceId = deviceId;
this._sync();
}
}));
this._sync();
this._keyboardSettings = new Gio.Settings({ schema: KEYBOARD_SCHEMA });
this._keyboardSettings.connect('changed', Lang.bind(this, this._settingsChanged));
this._a11yApplicationsSettings = new Gio.Settings({ schema: A11Y_APPLICATIONS_SCHEMA });
this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._settingsChanged));
this._settingsChanged();
this._showIdleId = 0;
this._subkeysBoxPointer = null;
@ -240,22 +183,8 @@ const Keyboard = new Lang.Class({
this._redraw();
},
_lastDeviceIsTouchscreen: function () {
if (!this._lastDeviceId)
return false;
let manager = Clutter.DeviceManager.get_default();
let device = manager.get_device(this._lastDeviceId);
if (!device)
return false;
return device.get_device_type() == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
},
_sync: function () {
this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD) ||
this._lastDeviceIsTouchscreen();
_settingsChanged: function (settings, key) {
this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
if (!this._enableKeyboard && !this._keyboard)
return;
if (this._enableKeyboard && this._keyboard &&
@ -285,35 +214,9 @@ const Keyboard = new Lang.Class({
this.actor = null;
this._destroySource();
if (this._daemonProxy) {
this._daemonProxy.QuitRemote(function (result, error) {
if (error) {
log(error.message);
return;
}
});
this._daemonProxy = null;
}
},
_setupKeyboard: function() {
if (!this._daemonProxy) {
this._daemonProxy = new CaribouDaemonProxy(Gio.DBus.session, CARIBOU_BUS_NAME,
CARIBOU_OBJECT_PATH,
Lang.bind(this, function(proxy, error) {
if (error) {
log(error.message);
return;
}
}));
}
this._daemonProxy.RunRemote(function (result, error) {
if (error) {
log(error.message);
return;
}
});
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
Main.layoutManager.keyboardBox.add_actor(this.actor);
Main.layoutManager.trackChrome(this.actor);
@ -363,14 +266,12 @@ const Keyboard = new Lang.Class({
return;
}
if (!this._showIdleId) {
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE,
Lang.bind(this, function() {
this.Show(time);
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.Show');
}
if (!this._showIdleId)
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE,
Lang.bind(this, function() {
this.Show(time);
return GLib.SOURCE_REMOVE;
}));
},
_createLayersForGroup: function (gname) {
@ -599,7 +500,6 @@ const Keyboard = new Lang.Class({
this._show(monitor);
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
},
_show: function(monitor) {
@ -626,7 +526,6 @@ const Keyboard = new Lang.Class({
this._hide();
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._keyboardRestingId, '[gnome-shell] this._clearKeyboardRestTimer');
},
_hide: function() {
@ -652,7 +551,7 @@ const Keyboard = new Lang.Class({
_moveTemporarily: function () {
let currentWindow = global.screen.get_display().focus_window;
let rect = currentWindow.get_frame_rect();
let rect = currentWindow.get_outer_rect();
let newX = rect.x;
let newY = 3 * this.actor.height / 2;
@ -753,53 +652,3 @@ const KeyboardSource = new Lang.Class({
this._keyboard.show(Main.layoutManager.bottomIndex);
}
});
const ShellWaylandAdapter = new Lang.Class({
Name: 'ShellWaylandAdapter',
Extends: Caribou.XAdapter,
_init: function () {
this.parent();
let deviceManager = Clutter.DeviceManager.get_default();
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
this._inputSourceManager = InputSourceManager.getInputSourceManager();
this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
Lang.bind(this, this._onSourceChanged));
this._sourcesModifiedId = this._inputSourceManager.connect ('sources-changed',
Lang.bind(this, this._onSourcesModified));
},
_onSourcesModified: function () {
this.emit('config-changed');
},
_onSourceChanged: function (inputSourceManager, oldSource) {
let source = inputSourceManager.currentSource;
this.emit('group-changed', source.index, source.id, '');
},
vfunc_get_groups: function () {
let inputSources = this._inputSourceManager.inputSources;
let groups = []
let variants = [];
for (let i in inputSources) {
let is = inputSources[i];
groups[is.index] = is.id;
variants[is.index] = '';
}
return [groups, groups.length, variants, variants.length];
},
vfunc_keyval_press: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.PRESSED);
},
vfunc_keyval_release: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.RELEASED);
},
});

View File

@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
@ -11,7 +12,6 @@ const St = imports.gi.St;
const Background = imports.ui.background;
const BackgroundMenu = imports.ui.backgroundMenu;
const LoginManager = imports.misc.loginManager;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
@ -21,6 +21,12 @@ const Tweener = imports.ui.tweener;
const STARTUP_ANIMATION_TIME = 0.5;
const KEYBOARD_ANIMATION_TIME = 0.15;
const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
// The message tray takes this much pressure
// in the pressure barrier at once to release it.
const MESSAGE_TRAY_PRESSURE_THRESHOLD = 250; // pixels
const MESSAGE_TRAY_PRESSURE_TIMEOUT = 1000; // ms
const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
@ -46,16 +52,11 @@ const MonitorConstraint = new Lang.Class({
'index': GObject.ParamSpec.int('index',
'Monitor index', 'Track specific monitor',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
-1, 64, -1),
'work-area': GObject.ParamSpec.boolean('work-area',
'Work-area', 'Track monitor\'s work-area',
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE,
false)},
-1, 64, -1)},
_init: function(props) {
this._primary = false;
this._index = -1;
this._workArea = false;
this.parent(props);
},
@ -85,19 +86,6 @@ const MonitorConstraint = new Lang.Class({
this.notify('index');
},
get work_area() {
return this._workArea;
},
set work_area(v) {
if (v == this._workArea)
return;
this._workArea = v;
if (this.actor)
this.actor.queue_relayout();
this.notify('work-area');
},
vfunc_set_actor: function(actor) {
if (actor) {
if (!this._monitorsChangedId) {
@ -105,21 +93,10 @@ const MonitorConstraint = new Lang.Class({
this.actor.queue_relayout();
}));
}
if (!this._workareasChangedId) {
this._workareasChangedId = global.screen.connect('workareas-changed', Lang.bind(this, function() {
if (this._workArea)
this.actor.queue_relayout();
}));
}
} else {
if (this._monitorsChangedId)
Main.layoutManager.disconnect(this._monitorsChangedId);
this._monitorsChangedId = 0;
if (this._workareasChangedId)
global.screen.disconnect(this._workareasChangedId);
this._workareasChangedId = 0;
}
this.parent(actor);
@ -129,21 +106,15 @@ const MonitorConstraint = new Lang.Class({
if (!this._primary && this._index < 0)
return;
let index;
if (this._primary)
index = Main.layoutManager.primaryIndex;
else
index = Math.min(this._index, Main.layoutManager.monitors.length - 1);
let rect;
if (this._workArea) {
let ws = global.screen.get_workspace_by_index(0);
rect = ws.get_work_area_for_monitor(index);
let monitor;
if (this._primary) {
monitor = Main.layoutManager.primaryMonitor;
} else {
rect = Main.layoutManager.monitors[index];
let index = Math.min(this._index, Main.layoutManager.monitors.length - 1);
monitor = Main.layoutManager.monitors[index];
}
actorBox.init_rect(rect.x, rect.y, rect.width, rect.height);
actorBox.init_rect(monitor.x, monitor.y, monitor.width, monitor.height);
}
});
@ -166,7 +137,6 @@ const Monitor = new Lang.Class({
const defaultParams = {
trackFullscreen: false,
affectsStruts: false,
affectsInputRegion: true
};
const LayoutManager = new Lang.Class({
@ -181,6 +151,7 @@ const LayoutManager = new Lang.Class({
this._keyboardIndex = -1;
this._rightPanelBarrier = null;
this._trayBarrier = null;
this._inOverview = false;
this._updateRegionIdle = 0;
@ -190,9 +161,9 @@ const LayoutManager = new Lang.Class({
this._isPopupWindowVisible = false;
this._startingUp = true;
// We don't want to paint the stage background color because either
// the SystemBackground we create or the MetaBackgroundActor inside
// global.window_group covers the entirety of the screen.
// Normally, the stage is always covered so Clutter doesn't need to clear
// it; however it becomes visible when using the magnifier.
global.stage.color = DEFAULT_BACKGROUND_COLOR;
global.stage.no_clear_hint = true;
// Set up stage hierarchy to group all UI actors under one container.
@ -213,34 +184,32 @@ const LayoutManager = new Lang.Class({
let height = global.stage.height;
[alloc.min_size, alloc.natural_size] = [height, height];
});
global.stage.remove_actor(global.window_group);
this.uiGroup.add_actor(global.window_group);
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);
this.sessionGroup.add_actor(global.window_group);
this.overviewGroup = new St.Widget({ name: 'overviewGroup',
visible: false,
reactive: true });
visible: false });
this.addChrome(this.overviewGroup);
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
visible: false,
clip_to_allocation: true,
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.modalDialogGroup = new St.Widget({ name: 'modalDialogGroup',
layout_manager: new Clutter.BinLayout() });
this.uiGroup.add_actor(this.modalDialogGroup);
this.trayBox = new St.Widget({ name: 'trayBox',
layout_manager: new Clutter.BinLayout() });
this.addChrome(this.trayBox);
this._setupTrayPressure();
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
reactive: true,
@ -248,17 +217,39 @@ const LayoutManager = new Lang.Class({
this.addChrome(this.keyboardBox);
this._keyboardHeightNotifyId = 0;
this.osdGroup = new St.Widget();
this.sessionGroup.add_child(this.osdGroup);
this.switcherPopupGroup = new St.Widget();
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 and size set in setDummyCursorGeometry.
this.dummyCursor = new St.Widget({ width: 0, height: 0, visible: false });
this.uiGroup.add_actor(this.dummyCursor);
// position set in setDummyCursorPosition.
this.dummyCursor = new St.Widget({ width: 0, height: 0 });
this.uiGroup.add_child(this.dummyCursor);
global.stage.remove_actor(global.top_window_group);
this.uiGroup.add_actor(global.top_window_group);
// 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));
let feedbackGroup = Meta.get_feedback_group_for_screen(global.screen);
global.stage.remove_actor(feedbackGroup);
this.uiGroup.add_actor(feedbackGroup);
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();
global.window_group.add_child(this._backgroundGroup);
@ -275,25 +266,12 @@ const LayoutManager = new Lang.Class({
global.screen.connect('in-fullscreen-changed',
Lang.bind(this, this._updateFullscreen));
this._monitorsChanged();
// NVIDIA drivers don't preserve FBO contents across
// suspend/resume, see
// https://bugzilla.gnome.org/show_bug.cgi?id=739178
if (Shell.util_need_background_refresh()) {
LoginManager.getLoginManager().connect('prepare-for-sleep',
function(lm, suspending) {
if (suspending)
return;
Meta.Background.refresh_all();
});
}
},
// This is called by Main after everything else is constructed
init: function() {
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
this._loadBackground();
this._prepareStartupAnimation();
},
showOverview: function() {
@ -301,6 +279,10 @@ const LayoutManager = new Lang.Class({
this._inOverview = true;
this._updateVisibility();
this._updateRegions();
global.window_group.hide();
global.top_window_group.hide();
},
hideOverview: function() {
@ -308,6 +290,10 @@ const LayoutManager = new Lang.Class({
this._inOverview = false;
this._updateVisibility();
this._queueUpdateRegions();
global.window_group.show();
global.top_window_group.show();
},
_sessionUpdated: function() {
@ -349,7 +335,7 @@ const LayoutManager = new Lang.Class({
});
this.hotCorners = [];
let size = this.panelBox.height;
let size = this.panelGroup.height;
// build new hot corners
for (let i = 0; i < this.monitors.length; i++) {
@ -401,7 +387,7 @@ const LayoutManager = new Lang.Class({
},
_addBackgroundMenu: function(bgManager) {
BackgroundMenu.addBackgroundMenu(bgManager.backgroundActor, this);
BackgroundMenu.addBackgroundMenu(bgManager.background.actor, this);
},
_createBackgroundManager: function(monitorIndex) {
@ -418,10 +404,10 @@ const LayoutManager = new Lang.Class({
_showSecondaryBackgrounds: function() {
for (let i = 0; i < this.monitors.length; i++) {
if (i != this.primaryIndex) {
let backgroundActor = this._bgManagers[i].backgroundActor;
backgroundActor.show();
backgroundActor.opacity = 0;
Tweener.addTween(backgroundActor,
let background = this._bgManagers[i].background;
background.actor.show();
background.actor.opacity = 0;
Tweener.addTween(background.actor,
{ opacity: 255,
time: BACKGROUND_FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
@ -444,30 +430,29 @@ const LayoutManager = new Lang.Class({
this._bgManagers.push(bgManager);
if (i != this.primaryIndex && this._startingUp)
bgManager.backgroundActor.hide();
bgManager.background.actor.hide();
}
},
_updateKeyboardBox: function() {
this.keyboardBox.set_position(this.keyboardMonitor.x,
this.keyboardMonitor.y + this.keyboardMonitor.height);
this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
},
_updateBoxes: function() {
this.screenShieldGroup.set_position(0, 0);
this.screenShieldGroup.set_size(global.screen_width, global.screen_height);
this.systemGroup.set_position(0, 0);
this.systemGroup.set_size(global.screen_width, global.screen_height);
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
this.panelBox.set_size(this.primaryMonitor.width, -1);
this.panelGroup.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
this.panelGroup.set_size(this.primaryMonitor.width, -1);
this.keyboardIndex = this.primaryIndex;
if (this.keyboardIndex < 0)
this.keyboardIndex = this.primaryIndex;
this.trayBox.set_position(this.bottomMonitor.x,
this.bottomMonitor.y + this.bottomMonitor.height);
this.trayBox.set_size(this.bottomMonitor.width, -1);
},
_panelBoxChanged: function() {
_panelGroupChanged: function() {
this._updatePanelBarrier();
let size = this.panelBox.height;
let size = this.panelGroup.height;
this.hotCorners.forEach(function(corner) {
if (corner)
corner.setBarrierSize(size);
@ -480,19 +465,60 @@ const LayoutManager = new Lang.Class({
this._rightPanelBarrier = null;
}
if (this.panelBox.height) {
if (this.panelGroup.height) {
let primary = this.primaryMonitor;
this._rightPanelBarrier = new Meta.Barrier({ display: global.display,
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 });
}
},
_setupTrayPressure: function() {
this._trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD,
MESSAGE_TRAY_PRESSURE_TIMEOUT,
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this._trayPressure.setEventFilter(this._trayBarrierEventFilter);
this._trayPressure.connect('trigger', function(barrier) {
if (Main.layoutManager.bottomMonitor.inFullscreen)
return;
Main.messageTray.openTray();
});
},
_updateTrayBarrier: function() {
let monitor = this.bottomMonitor;
if (this._trayBarrier) {
this._trayPressure.removeBarrier(this._trayBarrier);
this._trayBarrier.destroy();
this._trayBarrier = null;
}
this._trayBarrier = new Meta.Barrier({ display: global.display,
x1: monitor.x, x2: monitor.x + monitor.width,
y1: monitor.y + monitor.height, y2: monitor.y + monitor.height,
directions: Meta.BarrierDirection.NEGATIVE_Y });
this._trayPressure.addBarrier(this._trayBarrier);
},
_trayBarrierEventFilter: function(event) {
// Throw out all events where the pointer was grabbed by another
// client, as the client that grabbed the pointer expects to have
// complete control over it
if (event.grabbed && Main.modalCount == 0)
return true;
return false;
},
_monitorsChanged: function() {
this._updateMonitors();
this._updateBoxes();
this._updateTrayBarrier();
this._updateHotCorners();
this._updateBackgrounds();
this._updateFullscreen();
@ -541,32 +567,15 @@ const LayoutManager = new Lang.Class({
set keyboardIndex(v) {
this._keyboardIndex = v;
this._updateKeyboardBox();
this.keyboardBox.set_position(this.keyboardMonitor.x,
this.keyboardMonitor.y + this.keyboardMonitor.height);
this.keyboardBox.set_size(this.keyboardMonitor.width, -1);
},
get 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
//
// We have two different animations, depending on whether we're a greeter
@ -581,8 +590,14 @@ const LayoutManager = new Lang.Class({
//
// When starting a normal user session, we want to grow it out of the middle
// of the screen.
//
// Usually, we don't want to paint the stage background color because the
// MetaBackgroundActor inside global.window_group covers the entirety of the
// screen. So, we set no_clear_hint at the end of the animation.
_prepareStartupAnimation: function() {
global.stage.show();
// 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.
this._coverPane = new Clutter.Actor({ opacity: 0,
@ -591,30 +606,26 @@ const LayoutManager = new Lang.Class({
reactive: true });
this.addChrome(this._coverPane);
if (Meta.is_restart()) {
// On restart, we don't do an animation. Force an update of the
// regions immediately so that maximized windows restore to the
// right size taking struts into account.
this._updateRegions();
} else if (Main.sessionMode.isGreeter) {
this.panelBox.translation_y = -this.panelBox.height;
if (Main.sessionMode.isGreeter) {
this.panelGroup.translation_y = -this.panelGroup.height;
} else {
this._updateBackgrounds();
// We need to force an update of the regions now before we scale
// the UI group to get the correct allocation for the struts.
// the UI group to get the coorect allocation for the struts.
this._updateRegions();
this.trayBox.hide();
this.keyboardBox.hide();
let monitor = this.primaryMonitor;
let x = monitor.x + monitor.width / 2.0;
let y = monitor.y + monitor.height / 2.0;
this.uiGroup.set_pivot_point(x / global.screen_width,
y / global.screen_height);
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.75;
this.uiGroup.opacity = 0;
this.sessionGroup.set_pivot_point(x / global.screen_width,
y / global.screen_height);
this.sessionGroup.scale_x = this.sessionGroup.scale_y = 0.75;
this.sessionGroup.opacity = 0;
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
}
@ -626,24 +637,21 @@ const LayoutManager = new Lang.Class({
// until the event loop is uncontended and idle.
// This helps to prevent us from running the animation
// when the system is bogged down
let id = GLib.idle_add(GLib.PRIORITY_LOW, Lang.bind(this, function() {
GLib.idle_add(GLib.PRIORITY_LOW, Lang.bind(this, function() {
this._startupAnimation();
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(id, '[gnome-shell] this._startupAnimation');
},
_startupAnimation: function() {
if (Meta.is_restart())
this._startupAnimationComplete();
else if (Main.sessionMode.isGreeter)
if (Main.sessionMode.isGreeter)
this._startupAnimationGreeter();
else
this._startupAnimationSession();
},
_startupAnimationGreeter: function() {
Tweener.addTween(this.panelBox,
Tweener.addTween(this.panelGroup,
{ translation_y: 0,
time: STARTUP_ANIMATION_TIME,
transition: 'easeOutQuad',
@ -652,7 +660,7 @@ const LayoutManager = new Lang.Class({
},
_startupAnimationSession: function() {
Tweener.addTween(this.uiGroup,
Tweener.addTween(this.sessionGroup,
{ scale_x: 1,
scale_y: 1,
opacity: 255,
@ -666,11 +674,9 @@ const LayoutManager = new Lang.Class({
this._coverPane.destroy();
this._coverPane = null;
this._systemBackground.actor.destroy();
this._systemBackground = null;
this._startingUp = false;
this.trayBox.show();
this.keyboardBox.show();
if (!Main.sessionMode.isGreeter) {
@ -724,7 +730,7 @@ const LayoutManager = new Lang.Class({
this._updateRegions();
},
// setDummyCursorGeometry:
// setDummyCursorPosition:
//
// The cursor dummy is a standard widget commonly used for popup
// menus and box pointers to track, as the box pointer API only
@ -733,21 +739,19 @@ const LayoutManager = new Lang.Class({
// is what you should use. Given that the menu should not track
// 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
// position and has the right size.
setDummyCursorGeometry: function(x, y, w, h) {
// position.
setDummyCursorPosition: function(x, y) {
this.dummyCursor.set_position(Math.round(x), Math.round(y));
this.dummyCursor.set_size(Math.round(w), Math.round(h));
},
// addChrome:
// @actor: an actor to add to the chrome
// @params: (optional) additional params
//
// Adds @actor to the chrome, and (unless %affectsInputRegion in
// @params is %false) extends the input region to include it.
// Changes in @actor's size, position, and visibility will
// automatically result in appropriate changes to the input
// region.
// Adds @actor to the chrome, and extends the input region
// to include it. Changes in @actor's size, position, and
// visibility will automatically result in appropriate changes
// to the input region.
//
// If %affectsStruts in @params is %true (and @actor is along a
// screen edge), then @actor's size and position will also affect
@ -759,9 +763,9 @@ const LayoutManager = new Lang.Class({
// monitor (it will be hidden whenever a fullscreen window is visible,
// and shown otherwise)
addChrome: function(actor, params) {
this.uiGroup.add_actor(actor);
if (this.uiGroup.contains(global.top_window_group))
this.uiGroup.set_child_below_sibling(actor, global.top_window_group);
this.sessionGroup.add_actor(actor);
if (this.sessionGroup.contains(global.top_window_group))
this.sessionGroup.set_child_below_sibling(actor, global.top_window_group);
this._trackActor(actor, params);
},
@ -812,7 +816,7 @@ const LayoutManager = new Lang.Class({
//
// Removes @actor from the chrome
removeChrome: function(actor) {
this.uiGroup.remove_actor(actor);
this.sessionGroup.remove_actor(actor);
this._untrackActor(actor);
},
@ -835,13 +839,10 @@ const LayoutManager = new Lang.Class({
Lang.bind(this, this._queueUpdateRegions));
actorData.allocationId = actor.connect('notify::allocation',
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
// need to connect to 'destroy' too.
this._trackedActors.push(actorData);
this._updateActorVisibility(actorData);
this._queueUpdateRegions();
},
@ -855,28 +856,27 @@ const LayoutManager = new Lang.Class({
this._trackedActors.splice(i, 1);
actor.disconnect(actorData.visibleId);
actor.disconnect(actorData.allocationId);
actor.disconnect(actorData.destroyId);
actor.disconnect(actorData.parentSetId);
this._queueUpdateRegions();
},
_updateActorVisibility: function(actorData) {
if (!actorData.trackFullscreen)
return;
let monitor = this.findMonitorForActor(actorData.actor);
actorData.actor.visible = !(global.window_group.visible &&
monitor &&
monitor.inFullscreen);
},
_updateVisibility: function() {
let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
global.window_group.visible = windowsVisible;
global.top_window_group.visible = windowsVisible;
for (let i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i], visible;
if (!actorData.trackFullscreen)
continue;
this._trackedActors.forEach(Lang.bind(this, this._updateActorVisibility));
if (!windowsVisible)
visible = true;
else if (this.findMonitorForActor(actorData.actor).inFullscreen)
visible = false;
else
visible = true;
actorData.actor.visible = visible;
}
},
getWorkAreaForMonitor: function(monitorIndex) {
@ -900,12 +900,15 @@ const LayoutManager = new Lang.Class({
},
_queueUpdateRegions: function() {
if (Main.sessionMode.isGreeter)
return;
if (this._startingUp)
return;
if (!this._updateRegionIdle)
this._updateRegionIdle = Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
Lang.bind(this, this._updateRegions));
this._updateRegionIdle = Mainloop.idle_add(Lang.bind(this, this._updateRegions),
Meta.PRIORITY_BEFORE_REDRAW);
},
_getWindowActorsForWorkspace: function(workspace) {
@ -933,27 +936,19 @@ const LayoutManager = new Lang.Class({
},
_updateRegions: function() {
let rects = [], struts = [], i;
if (this._updateRegionIdle) {
Meta.later_remove(this._updateRegionIdle);
Mainloop.source_remove(this._updateRegionIdle);
delete this._updateRegionIdle;
}
// No need to update when we have a modal.
if (Main.modalCount > 0)
return GLib.SOURCE_REMOVE;
// Bug workaround - get_transformed_position()/get_transformed_size() don't work after
// a change in stage size until the first pick or paint.
// https://bugzilla.gnome.org/show_bug.cgi?id=761565
global.stage.get_actor_at_pos(Clutter.PickMode.ALL, 0, 0);
let rects = [], struts = [], i;
let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow);
let wantsInputRegion = !isPopupMenuVisible;
for (i = 0; i < this._trackedActors.length; i++) {
let actorData = this._trackedActors[i];
if (!(actorData.affectsInputRegion && wantsInputRegion) && !actorData.affectsStruts)
if (!wantsInputRegion && !actorData.affectsStruts)
continue;
let [x, y] = actorData.actor.get_transformed_position();
@ -963,7 +958,7 @@ const LayoutManager = new Lang.Class({
w = Math.round(w);
h = Math.round(h);
if (actorData.affectsInputRegion && wantsInputRegion && actorData.actor.get_paint_visibility())
if (wantsInputRegion && actorData.actor.get_paint_visibility())
rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h }));
if (actorData.affectsStruts) {
@ -973,43 +968,67 @@ const LayoutManager = new Lang.Class({
let y1 = Math.max(y, 0);
let y2 = Math.min(y + h, global.screen_height);
// Metacity wants to know what side of the monitor the
// strut is considered to be attached to. First, we find
// the monitor that contains the strut. If the actor is
// NetWM struts are not really powerful enought to handle
// a multi-monitor scenario, they only describe what happens
// around the outer sides of the full display region. However
// it can describe a partial region along each side, so
// we can support having the struts only affect the
// primary monitor. This should be enough as we only have
// chrome affecting the struts on the primary monitor so
// far.
//
// Metacity wants to know what side of the screen the
// strut is considered to be attached to. If the actor is
// only touching one edge, or is touching the entire
// border of that monitor, then it's obvious which side
// to call it. If it's in a corner, we pick a side
// arbitrarily. If it doesn't touch any edges, or it
// spans the width/height across the middle of the
// screen, then we don't create a strut for it at all.
let monitor = this.findMonitorForActor(actorData.actor);
// border of the primary monitor, then it's obvious which
// side to call it. If it's in a corner, we pick a side
// arbitrarily. If it doesn't touch any edges, or it spans
// the width/height across the middle of the screen, then
// we don't create a strut for it at all.
let side;
if (x1 <= monitor.x && x2 >= monitor.x + monitor.width) {
if (y1 <= monitor.y)
let primary = this.primaryMonitor;
if (x1 <= primary.x && x2 >= primary.x + primary.width) {
if (y1 <= primary.y)
side = Meta.Side.TOP;
else if (y2 >= monitor.y + monitor.height)
else if (y2 >= primary.y + primary.height)
side = Meta.Side.BOTTOM;
else
continue;
} else if (y1 <= monitor.y && y2 >= monitor.y + monitor.height) {
if (x1 <= monitor.x)
} else if (y1 <= primary.y && y2 >= primary.y + primary.height) {
if (x1 <= 0)
side = Meta.Side.LEFT;
else if (x2 >= monitor.x + monitor.width)
else if (x2 >= primary.x + primary.width)
side = Meta.Side.RIGHT;
else
continue;
} else if (x1 <= monitor.x)
} else if (x1 <= 0)
side = Meta.Side.LEFT;
else if (y1 <= monitor.y)
else if (y1 <= 0)
side = Meta.Side.TOP;
else if (x2 >= monitor.x + monitor.width)
else if (x2 >= global.screen_width)
side = Meta.Side.RIGHT;
else if (y2 >= monitor.y + monitor.height)
else if (y2 >= global.screen_height)
side = Meta.Side.BOTTOM;
else
continue;
// Ensure that the strut rects goes all the way to the screen edge,
// as this really what mutter expects.
switch (side) {
case Meta.Side.TOP:
y1 = 0;
break;
case Meta.Side.BOTTOM:
y2 = global.screen_height;
break;
case Meta.Side.LEFT:
x1 = 0;
break;
case Meta.Side.RIGHT:
x2 = global.screen_width;
break;
}
let strutRect = new Meta.Rectangle({ x: x1, y: y1, width: x2 - x1, height: y2 - y1});
let strut = new Meta.Strut({ rect: strutRect, side: side });
struts.push(strut);
@ -1026,13 +1045,7 @@ const LayoutManager = new Lang.Class({
}
return GLib.SOURCE_REMOVE;
},
modalEnded: function() {
// We don't update the stage input region while in a modal,
// so queue an update now.
this._queueUpdateRegions();
},
}
});
Signals.addSignalMethods(LayoutManager.prototype);
@ -1060,8 +1073,8 @@ const HotCorner = new Lang.Class({
this._pressureBarrier = new PressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD,
HOT_CORNER_PRESSURE_TIMEOUT,
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW);
Shell.KeyBindingMode.NORMAL |
Shell.KeyBindingMode.OVERVIEW);
this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview));
// Cache the three ripples instead of dynamically creating and destroying them.
@ -1069,9 +1082,9 @@ const HotCorner = new Lang.Class({
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 });
layoutManager.uiGroup.add_actor(this._ripple1);
layoutManager.uiGroup.add_actor(this._ripple2);
layoutManager.uiGroup.add_actor(this._ripple3);
layoutManager.sessionGroup.add_actor(this._ripple1);
layoutManager.sessionGroup.add_actor(this._ripple2);
layoutManager.sessionGroup.add_actor(this._ripple3);
},
setBarrierSize: function(size) {
@ -1238,10 +1251,10 @@ const HotCorner = new Lang.Class({
const PressureBarrier = new Lang.Class({
Name: 'PressureBarrier',
_init: function(threshold, timeout, actionMode) {
_init: function(threshold, timeout, keybindingMode) {
this._threshold = threshold;
this._timeout = timeout;
this._actionMode = actionMode;
this._keybindingMode = keybindingMode;
this._barriers = [];
this._eventFilter = null;
@ -1324,11 +1337,8 @@ const PressureBarrier = new Lang.Class({
},
_onBarrierLeft: function(barrier, event) {
barrier._isHit = false;
if (this._barriers.every(function(b) { return !b._isHit; })) {
this._reset();
this._isTriggered = false;
}
this._reset();
this._isTriggered = false;
},
_trigger: function() {
@ -1338,8 +1348,6 @@ const PressureBarrier = new Lang.Class({
},
_onBarrierHit: function(barrier, event) {
barrier._isHit = true;
// If we've triggered the barrier, wait until the pointer has the
// left the barrier hitbox until we trigger it again.
if (this._isTriggered)
@ -1349,7 +1357,7 @@ const PressureBarrier = new Lang.Class({
return;
// Throw out all events not in the proper keybinding mode
if (!(this._actionMode & Main.actionMode))
if (!(this._keybindingMode & Main.keybindingMode))
return;
let slide = this._getDistanceAlongBarrier(barrier, event);

View File

@ -1,272 +0,0 @@
const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const CtrlAltTab = imports.ui.ctrlAltTab;
const Lang = imports.lang;
const Layout = imports.ui.layout;
const Main = imports.ui.main;
const Overview = imports.ui.overview;
const OverviewControls = imports.ui.overviewControls;
const Tweener = imports.ui.tweener;
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'bluetooth-applet': 'bluetooth',
'gnome-volume-control-applet': 'volume', // renamed to gnome-sound-applet
// when moved to control center
'gnome-sound-applet': 'volume',
'nm-applet': 'network',
'gnome-power-manager': 'battery',
'keyboard': 'keyboard',
'a11y-keyboard': 'a11y',
'kbd-scrolllock': 'keyboard',
'kbd-numlock': 'keyboard',
'kbd-capslock': 'keyboard',
'ibus-ui-gtk': 'keyboard'
};
// Offset of the original position from the bottom-right corner
const CONCEALED_WIDTH = 3;
const REVEAL_ANIMATION_TIME = 0.2;
const TEMP_REVEAL_TIME = 2;
const BARRIER_THRESHOLD = 70;
const BARRIER_TIMEOUT = 1000;
const LegacyTray = new Lang.Class({
Name: 'LegacyTray',
_init: function() {
this.actor = new St.Widget({ clip_to_allocation: true,
layout_manager: new Clutter.BinLayout() });
let constraint = new Layout.MonitorConstraint({ primary: true,
work_area: true });
this.actor.add_constraint(constraint);
this._slideLayout = new OverviewControls.SlideLayout();
this._slideLayout.translationX = 0;
this._slideLayout.slideDirection = OverviewControls.SlideDirection.LEFT;
this._slider = new St.Widget({ x_expand: true, y_expand: true,
x_align: Clutter.ActorAlign.START,
y_align: Clutter.ActorAlign.END,
layout_manager: this._slideLayout });
this.actor.add_actor(this._slider);
this._slider.connect('notify::allocation', Lang.bind(this, this._syncBarrier));
this._box = new St.BoxLayout({ style_class: 'legacy-tray' });
this._slider.add_actor(this._box);
this._concealHandle = new St.Button({ style_class: 'legacy-tray-handle',
/* translators: 'Hide' is a verb */
accessible_name: _("Hide tray"),
can_focus: true });
this._concealHandle.child = new St.Icon({ icon_name: 'go-previous-symbolic' });
this._box.add_child(this._concealHandle);
this._iconBox = new St.BoxLayout({ style_class: 'legacy-tray-icon-box' });
this._box.add_actor(this._iconBox);
this._revealHandle = new St.Button({ style_class: 'legacy-tray-handle' });
this._revealHandle.child = new St.Icon({ icon_name: 'go-next-symbolic' });
this._box.add_child(this._revealHandle);
this._revealHandle.bind_property('visible',
this._concealHandle, 'visible',
GObject.BindingFlags.BIDIRECTIONAL |
GObject.BindingFlags.INVERT_BOOLEAN);
this._revealHandle.connect('notify::visible',
Lang.bind(this, this._sync));
this._revealHandle.connect('notify::hover',
Lang.bind(this ,this._sync));
this._revealHandle.connect('clicked', Lang.bind(this,
function() {
this._concealHandle.show();
}));
this._concealHandle.connect('clicked', Lang.bind(this,
function() {
this._revealHandle.show();
}));
this._horizontalBarrier = null;
this._pressureBarrier = new Layout.PressureBarrier(BARRIER_THRESHOLD,
BARRIER_TIMEOUT,
Shell.ActionMode.NORMAL);
this._pressureBarrier.connect('trigger', Lang.bind(this, function() {
this._concealHandle.show();
}));
Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
Main.layoutManager.trackChrome(this._slider, { affectsInputRegion: true });
Main.uiGroup.set_child_below_sibling(this.actor, Main.layoutManager.modalDialogGroup);
Main.ctrlAltTabManager.addGroup(this.actor,
_("Status Icons"), 'focus-legacy-systray-symbolic',
{ sortGroup: CtrlAltTab.SortGroup.BOTTOM });
this._trayManager = new Shell.TrayManager();
this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
this._trayIconRemovedId = this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
this._trayManager.manage_screen(global.screen, this.actor);
Main.overview.connect('showing', Lang.bind(this,
function() {
Tweener.removeTweens(this._slider);
Tweener.addTween(this._slider, { opacity: 0,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' });
}));
Main.overview.connect('shown', Lang.bind(this, this._sync));
Main.overview.connect('hiding', Lang.bind(this,
function() {
this._sync();
Tweener.removeTweens(this._slider);
Tweener.addTween(this._slider, { opacity: 255,
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad' });
}));
Main.layoutManager.connect('monitors-changed',
Lang.bind(this, this._sync));
global.screen.connect('in-fullscreen-changed',
Lang.bind(this, this._sync));
Main.sessionMode.connect('updated', Lang.bind(this, this._sync));
this._sync();
},
_onTrayIconAdded: function(tm, icon) {
let wmClass = icon.wm_class ? icon.wm_class.toLowerCase() : '';
if (STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass] !== undefined)
return;
let button = new St.Button({ child: icon,
style_class: 'legacy-tray-icon',
button_mask: St.ButtonMask.ONE |
St.ButtonMask.TWO |
St.ButtonMask.THREE,
can_focus: true,
x_fill: true, y_fill: true });
let app = Shell.WindowTracker.get_default().get_app_from_pid(icon.pid);
if (!app)
app = Shell.AppSystem.get_default().lookup_startup_wmclass(wmClass);
if (!app)
app = Shell.AppSystem.get_default().lookup_desktop_wmclass(wmClass);
if (app)
button.accessible_name = app.get_name();
else
button.accessible_name = icon.title;
button.connect('clicked',
function() {
icon.click(Clutter.get_current_event());
});
button.connect('key-press-event',
function() {
icon.click(Clutter.get_current_event());
return Clutter.EVENT_PROPAGATE;
});
button.connect('key-focus-in', Lang.bind(this,
function() {
this._concealHandle.show();
}));
this._iconBox.add_actor(button);
if (!this._concealHandle.visible) {
this._concealHandle.show();
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, TEMP_REVEAL_TIME,
Lang.bind(this, function() {
this._concealHandle.hide();
return GLib.SOURCE_REMOVE;
}));
}
},
_onTrayIconRemoved: function(tm, icon) {
if (!this.actor.contains(icon))
return;
icon.get_parent().destroy();
this._sync();
},
_syncBarrier: function() {
let rtl = (this._slider.get_text_direction() == Clutter.TextDirection.RTL);
let [x, y] = this._slider.get_transformed_position();
let [w, h] = this._slider.get_transformed_size();
let x1 = Math.round(x);
if (rtl)
x1 += Math.round(w);
let x2 = x1;
let y1 = Math.round(y);
let y2 = y1 + Math.round(h);
if (this._horizontalBarrier &&
this._horizontalBarrier.x1 == x1 &&
this._horizontalBarrier.y1 == y1 &&
this._horizontalBarrier.x2 == x2 &&
this._horizontalBarrier.y2 == y2)
return;
this._unsetBarrier();
let directions = (rtl ? Meta.BarrierDirection.NEGATIVE_X : Meta.BarrierDirection.POSITIVE_X);
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
x1: x1, x2: x2,
y1: y1, y2: y2,
directions: directions });
this._pressureBarrier.addBarrier(this._horizontalBarrier);
},
_unsetBarrier: function() {
if (this._horizontalBarrier == null)
return;
this._pressureBarrier.removeBarrier(this._horizontalBarrier);
this._horizontalBarrier.destroy();
this._horizontalBarrier = null;
},
_sync: function() {
// FIXME: we no longer treat tray icons as notifications
let allowed = Main.sessionMode.hasNotifications;
let hasIcons = this._iconBox.get_n_children() > 0;
let inOverview = Main.overview.visible && !Main.overview.animationInProgress;
let inFullscreen = Main.layoutManager.primaryMonitor.inFullscreen;
this.actor.visible = allowed && hasIcons && !inOverview && !inFullscreen;
if (!hasIcons)
this._concealHandle.hide();
let targetSlide;
if (this._concealHandle.visible) {
targetSlide = 1.0;
} else if (!hasIcons) {
targetSlide = 0.0;
} else {
let [, boxWidth] = this._box.get_preferred_width(-1);
let [, handleWidth] = this._revealHandle.get_preferred_width(-1);
if (this._revealHandle.hover)
targetSlide = handleWidth / boxWidth;
else
targetSlide = CONCEALED_WIDTH / boxWidth;
}
if (this.actor.visible) {
Tweener.addTween(this._slideLayout,
{ slideX: targetSlide,
time: REVEAL_ANIMATION_TIME,
transition: 'easeOutQuad' });
} else {
this._slideLayout.slideX = targetSlide;
this._unsetBarrier();
}
}
});

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