Compare commits

..

15 Commits

Author SHA1 Message Date
45797a977b app-system: Add back StartupWMClass matching
While unfortunate that we still have to scan all apps with get_all(),
support for this feature will be short-lived, so hopefully we can drop
it in the future as new apps adapt to the desktop file / app ID
recommendations.

For now, simply scan all desktop IDs.
2013-10-02 18:22:28 -04:00
884b94233e app-system: Put back support for the installed-changed signal
Use the new GAppInfoMonitor that Ryan added to glib to know when the
set of apps has changed.
2013-10-02 18:22:27 -04:00
74d3e3139f app-system: Lazily create ShellApps for apps we care about
Rather than create all ShellApps up-front, create them lazily. We really
had no reason to do this before as we were scanning GMenu to get all the
apps, but doing this can remove a need for get_all, which is slow and
memory-hungry.
2013-10-02 18:22:27 -04:00
77b5385cc3 appDisplay: Use the desktop file index for app searching
Rather than scanning all apps for searching, use Ryan's new desktop
file index and the glib support APIs for app searching instead of our
own system.
2013-10-02 18:22:27 -04:00
d749d646be appDisplay: Use a proper string key for the app search provider
We were always sort of cheating when we used objects as the search ID.
Since the new desktop file index will return us a list of desktop file
IDs, just use those as IDs instead.
2013-10-02 18:22:27 -04:00
fa8224d7b5 app-system: Remove use of gnome-menus internally
We want to transition to a system in the future where we have a desktop
file cache. As we no longer differentiate categories or similar, it no
longer makes sense to have app visibility based on categories. Thus,
we no longer need to use gnome-menus to list all apps. The potential
issue here is reloading all desktop files when new files are created,
but this can be dealt with individually.

The "All Applications" view still uses gnome-menus.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 18:22:27 -04:00
f687197ccc appDisplay: Ignore the NoDisplay flag for directories
This makes us match the native app search.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 18:22:15 -04:00
28a6aefb6c app-system: Remove visible_id_to_app
Since appDisplay.js makes its own GMenu tree, it's not necessary
anymore. This does mean that searches will show apps in NoDisplay
categories, but that's an obscure enough edge case not to matter.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 18:22:15 -04:00
96c2a90e11 app-system: Remove lookup_app_for_path
It's absurdly silly. Just modify the one place that uses it
to be better.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 18:22:15 -04:00
63cf46e49b app-system: Remove known_vendor_prefixes
This does remove support for legacy prefixed app infos with
subdirs, but since we want to remove support for the menu spec,
let's not even bother.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 18:22:15 -04:00
200a9ef1af app-system: Remove get_tree
Make clients construct their own gmenu tree if they need it.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 18:22:08 -04:00
6050ca6e0c app-system: Map wmclass to ID rather than apps
This makes the refcounting and memory management easier to understand.
2013-10-02 18:22:08 -04:00
8bd7db9227 app-system: Don't use gmenu_tree_entry_get_desktop_app_info
It's a broken method when it comes to giving us a useful GDesktopAppInfo,
and it's hard to fix libgmenu properly, so simply recreate the app info
using the desktop file ID that libgmenu has.
2013-10-02 18:22:07 -04:00
982feb85c1 app: Port to be based on GDesktopAppInfo
We weren't using the GMenuTreeEntry for anything special anymore,
so remove it.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 18:14:18 -04:00
f165cc23c0 app-system: Remove lookup_app_by_tree_entry
We want to move away from gnome-menus eventually, so the simple
utility method isn't really worth keeping around. Reimplement it
in the one place that uses it.

https://bugzilla.gnome.org/show_bug.cgi?id=698486
2013-10-02 17:39:36 -04:00
401 changed files with 84290 additions and 117742 deletions

18
.gitignore vendored
View File

@ -17,20 +17,17 @@ config.status
config
configure
data/50-gnome-shell-*.xml
data/org.gnome.Shell.desktop
data/org.gnome.Shell.desktop.in
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.evolution.calendar.gschema.xml
data/org.gnome.shell.evolution.calendar.gschema.valid
data/org.gnome.Shell.PortalHelper.desktop
data/org.gnome.Shell.PortalHelper.service
data/theme/.sass-cache
docs/reference/*/*.args
docs/reference/*/*.bak
docs/reference/*/*.hierarchy
@ -46,8 +43,6 @@ docs/reference/*/xml/
docs/reference/shell/doc-gen-*
gtk-doc.make
js/misc/config.js
js/js-resources.c
js/js-resources.h
intltool-extract.in
intltool-merge.in
intltool-update.in
@ -81,11 +76,12 @@ 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

41
COPYING
View File

@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@ -303,16 +303,17 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@ -335,5 +336,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,11 +1,7 @@
# Point to our macro directory and pick up user flags from the environment
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
SUBDIRS = data js src tests po docs
if BUILD_BROWSER_PLUGIN
SUBDIRS += browser-plugin
endif
SUBDIRS = data js src browser-plugin tests po docs
if ENABLE_MAN
SUBDIRS += man

1108
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

@ -13,7 +13,9 @@
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Authors:
* Jasper St. Pierre <jstpierre@mecheye.net>
@ -33,15 +35,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 +145,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 +330,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 +833,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 +852,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 +894,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 +912,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 +990,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 +1003,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,10 +1013,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 ();
*(NPObject**)value = instance->pdata;
*(NPObject**)value = funcs.createobject (instance, &plugin_class);
break;
case NPPVpluginNeedsXEmbed:
*(bool *)value = TRUE;
break;
default:
@ -1047,11 +1037,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.21.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AX_IS_RELEASE([git-directory])
AC_INIT([gnome-shell],[3.10.0.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@ -17,7 +16,6 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
# Initialize libtool
LT_PREREQ([2.2.6])
@ -38,7 +36,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
@ -52,36 +50,21 @@ 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
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
AC_ARG_ENABLE([systemd],
AS_HELP_STRING([--enable-systemd], [Use systemd]),
[enable_systemd=$enableval],
[enable_systemd=auto])
AS_IF([test x$enable_systemd != xno], [
AC_MSG_CHECKING([for libsystemd])
PKG_CHECK_EXISTS([libsystemd],
[have_systemd=yes
AC_DEFINE([HAVE_SYSTEMD], [1], [Define if we have systemd])],
[have_systemd=no])
AC_MSG_RESULT($have_systemd)
])
AC_MSG_RESULT($enable_systemd)
CLUTTER_MIN_VERSION=1.21.5
GOBJECT_INTROSPECTION_MIN_VERSION=1.45.4
GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.21.4
GTK_MIN_VERSION=3.15.0
GIO_MIN_VERSION=2.45.3
CLUTTER_MIN_VERSION=1.13.4
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.35.4
MUTTER_MIN_VERSION=3.10.0
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
@ -98,43 +81,51 @@ 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"
if test x$have_systemd = xyes; then
SHARED_PCS="${SHARED_PCS} libsystemd"
fi
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
libsecret-unstable gcr-base-3 >= $GCR_MIN_VERSION"
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(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
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],
[Enable browser plugin [default=yes]])],,
enable_browser_plugin=yes)
AS_IF([test x$enable_browser_plugin = xyes], [
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
])
AM_CONDITIONAL(BUILD_BROWSER_PLUGIN, test x$enable_browser_plugin = xyes)
PKG_CHECK_MODULES(BLUETOOTH, gnome-bluetooth-1.0 >= 3.9.0,
[AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
AC_SUBST([HAVE_BLUETOOTH],[1])],
AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.9.0],
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=applet_libdir gnome-bluetooth-1.0`
BLUETOOTH_LIBS=`$PKG_CONFIG --variable=applet_libs gnome-bluetooth-1.0`
AC_SUBST([BLUETOOTH_LIBS],["$BLUETOOTH_LIBS"])
AC_SUBST([BLUETOOTH_DIR],["$BLUETOOTH_DIR"])
AC_DEFINE_UNQUOTED([BLUETOOTH_DIR],["$BLUETOOTH_DIR"],[Path to installed GnomeBluetooth typelib and library])
AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
AC_SUBST([HAVE_BLUETOOTH],[1])
AC_MSG_RESULT([yes])],
[AC_DEFINE([HAVE_BLUETOOTH],[0])
AC_SUBST([HAVE_BLUETOOTH],[0])])
AC_SUBST([HAVE_BLUETOOTH],[0])
AC_MSG_RESULT([no])])
PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedataserver-1.2 >= $LIBEDATASERVER_MIN_VERSION gio-2.0)
AC_SUBST(CALENDAR_SERVER_CFLAGS)
@ -154,9 +145,6 @@ AC_SUBST(MUTTER_TYPELIB_DIR)
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
AC_SUBST(GJS_CONSOLE)
GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0`
AC_SUBST(GLIB_COMPILE_RESOURCES)
AC_CHECK_FUNCS(fdwalk)
AC_CHECK_FUNCS(mallinfo)
AC_CHECK_HEADERS([sys/resource.h])
@ -172,38 +160,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()
@ -221,29 +177,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
@ -263,15 +201,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

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

View File

@ -1,28 +1,12 @@
CLEANFILES =
NULL =
wandadir = $(pkgdatadir)
dist_wanda_DATA = wanda.png
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 \
$(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
@ -38,49 +22,46 @@ 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_in_files = 50-gnome-shell-system.xml.in
@ -107,31 +88,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_in_files) \
$(dist_theme_files) \
perf-background.xml.in \
org.gnome.Shell.PortalHelper.desktop.in \
org.gnome.Shell.PortalHelper.service.in \
org.gnome.shell.gschema.xml.in.in \
gnome-shell-theme.gresource.xml \
$(resource_files) \
$(NULL)
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 \
org.gnome.shell.gschema.xml.in \
gnome-shell-theme.gresource \
$(NULL)
org.gnome.shell.gschema.xml.in

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

@ -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,9 +0,0 @@
[Desktop Entry]
_Name=Network Login
Type=Application
Exec=gapplication launch org.gnome.Shell.PortalHelper
DBusActivatable=true
NoDisplay=true
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

@ -13,36 +13,28 @@
</key>
<key name="enabled-extensions" type="as">
<default>[]</default>
<_summary>UUIDs of extensions to enable</_summary>
<_summary>Uuids of extensions to enable</_summary>
<_description>
GNOME Shell extensions have a UUID property; this key lists extensions
GNOME Shell extensions have a uuid property; this key lists extensions
which should be loaded. Any extension that wants to be loaded needs
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>false</default>
<_summary>Disables the validation of extension version compatibility</_summary>
<_description>
GNOME Shell will only load extensions that claim to support the current
running version. Enabling this option will disable this check and try to
load all extensions regardless of the versions they claim to support.
EnableExtension and DisableExtension DBus methods on org.gnome.Shell.
</_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>
<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>
</key>
<key name="app-picker-view" type="u">
<default>0</default>
<_summary>App Picker View</_summary>
<key name="app-folder-categories" type="as">
<default>[ 'Utilities', 'Sundry' ]</default>
<_summary>List of categories that should be displayed as folders</_summary>
<_description>
Index of the currently selected view in the application picker.
Each category name in this list will be represented as folder in the
application view, rather than being displayed inline in the main view.
</_description>
</key>
<key name="command-history" type="as">
@ -51,15 +43,14 @@
</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>
</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>
<_summary>Always show the 'Log out' menuitem in the user menu.</_summary>
<_description>
This key overrides the automatic hiding of the 'Log out'
menu item in single-user, single-session situations.
menuitem in single-user, single-session situations.
</_description>
</key>
<key name="remember-mount-password" type="b">
@ -72,20 +63,22 @@
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>
</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">
@ -111,10 +104,10 @@
</_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>
<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 notification list.
Keybinding to toggle the visibility of the message tray.
</_description>
</key>
<key name="focus-active-notification" type="as">
@ -124,11 +117,6 @@
Keybinding to focus the active notification.
</_description>
</key>
<key name="pause-resume-tweens" type="as">
<default>[]</default>
<_summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</_summary>
<_description></_description>
</key>
</schema>
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"
@ -147,11 +135,11 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key type="b" name="current-workspace-only">
<default>false</default>
<_summary>Limit switcher to current workspace.</_summary>
<_description>
<summary>Limit switcher to current workspace.</summary>
<description>
If true, only applications that have windows on the current workspace are shown in the switcher.
Otherwise, all applications are included.
</_description>
</description>
</key>
</schema>
@ -174,11 +162,11 @@
</key>
<key type="b" name="current-workspace-only">
<default>true</default>
<_summary>Limit switcher to current workspace.</_summary>
<_description>
<summary>Limit switcher to current workspace.</summary>
<description>
If true, only windows from the current workspace are shown in the switcher.
Otherwise, all windows are included.
</_description>
</description>
</key>
</schema>
@ -193,6 +181,15 @@
</_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>

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

BIN
data/wanda.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 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) $(BLUETOOTH_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

@ -1,38 +1,124 @@
NULL =
BUILT_SOURCES =
EXTRA_DIST = misc/config.js.in
CLEANFILES = misc/config.js
misc/config.js: misc/config.js.in Makefile
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
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-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
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate --c-name shell_js_resources $<
jsdir = $(pkgdatadir)/js
js_built_sources = js-resources.c js-resources.h
BUILT_SOURCES += $(js_built_sources)
all-local: $(js_built_sources)
js_resource_dist_files = $(filter-out misc/config.js, $(js_resource_files))
EXTRA_DIST = \
$(js_resource_dist_files) \
js-resources.gresource.xml \
misc/config.js.in \
$(NULL)
CLEANFILES = \
$(js_built_sources) \
nobase_dist_js_DATA = \
gdm/authPrompt.js \
gdm/batch.js \
gdm/fingerprint.js \
gdm/loginDialog.js \
gdm/realmd.js \
gdm/util.js \
extensionPrefs/main.js \
misc/config.js \
misc/extensionUtils.js \
misc/fileUtils.js \
misc/gnomeSession.js \
misc/hash.js \
misc/history.js \
misc/jsParse.js \
misc/loginManager.js \
misc/modemManager.js \
misc/objectManager.js \
misc/params.js \
misc/smartcardManager.js \
misc/util.js \
perf/core.js \
ui/altTab.js \
ui/animation.js \
ui/appDisplay.js \
ui/appFavorites.js \
ui/backgroundMenu.js \
ui/background.js \
ui/boxpointer.js \
ui/calendar.js \
ui/checkBox.js \
ui/ctrlAltTab.js \
ui/dash.js \
ui/dateMenu.js \
ui/dnd.js \
ui/endSessionDialog.js \
ui/extensionSystem.js \
ui/extensionDownloader.js \
ui/environment.js \
ui/focusCaretTracker.js\
ui/ibusCandidatePopup.js\
ui/grabHelper.js \
ui/iconGrid.js \
ui/keyboard.js \
ui/layout.js \
ui/lightbox.js \
ui/lookingGlass.js \
ui/magnifier.js \
ui/magnifierDBus.js \
ui/main.js \
ui/messageTray.js \
ui/modalDialog.js \
ui/separator.js \
ui/sessionMode.js \
ui/shellEntry.js \
ui/shellMountOperation.js \
ui/slider.js \
ui/notificationDaemon.js \
ui/osdWindow.js \
ui/overview.js \
ui/overviewControls.js \
ui/panel.js \
ui/panelMenu.js \
ui/pointerWatcher.js \
ui/popupMenu.js \
ui/remoteSearch.js \
ui/remoteMenu.js \
ui/runDialog.js \
ui/screencast.js \
ui/screenshot.js \
ui/screenShield.js \
ui/scripting.js \
ui/search.js \
ui/searchDisplay.js \
ui/shellDBus.js \
ui/status/accessibility.js \
ui/status/brightness.js \
ui/status/keyboard.js \
ui/status/network.js \
ui/status/power.js \
ui/status/rfkill.js \
ui/status/volume.js \
ui/status/bluetooth.js \
ui/status/screencast.js \
ui/status/system.js \
ui/switcherPopup.js \
ui/tweener.js \
ui/unlockDialog.js \
ui/userWidget.js \
ui/viewSelector.js \
ui/wanda.js \
ui/windowAttentionHandler.js \
ui/windowManager.js \
ui/workspace.js \
ui/workspaceThumbnail.js \
ui/workspacesView.js \
ui/workspaceSwitcherPopup.js \
ui/xdndHandler.js \
ui/components/__init__.js \
ui/components/autorunManager.js \
ui/components/automountManager.js \
ui/components/networkAgent.js \
ui/components/polkitAgent.js \
ui/components/telepathyClient.js \
ui/components/keyring.js \
$(NULL)

View File

@ -13,15 +13,13 @@ const _ = Gettext.gettext;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
const GnomeShellIface = '<node> \
<interface name="org.gnome.Shell.Extensions"> \
<signal name="ExtensionStatusChanged"> \
<arg type="s" name="uuid"/> \
<arg type="i" name="state"/> \
<arg type="s" name="error"/> \
</signal> \
</interface> \
</node>';
const GnomeShellIface = <interface name="org.gnome.Shell.Extensions">
<signal name="ExtensionStatusChanged">
<arg type="s" name="uuid"/>
<arg type="i" name="state"/>
<arg type="s" name="error"/>
</signal>
</interface>;
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
@ -46,9 +44,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 +59,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 +102,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,26 +149,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,
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]) {
@ -171,46 +201,23 @@ 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));
finder.connect('extensions-loaded', Lang.bind(this, this._extensionsLoaded));
finder.scanExtensions();
this._extensionsLoaded();
},
_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);
_extensionFound: function(signals, extension) {
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() {
@ -218,6 +225,7 @@ const Application = new Lang.Class({
},
_onStartup: function(app) {
this._buildModel();
this._buildUI(app);
this._scanExtensions();
},
@ -225,129 +233,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;
@ -60,7 +59,6 @@ const AuthPrompt = new Lang.Class({
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged));
this._userVerifier.connect('ovirt-user-authenticated', Lang.bind(this, this._onOVirtUserAuthenticated));
this.smartcardDetected = this._userVerifier.smartcardDetected;
this.connect('next', Lang.bind(this, function() {
@ -81,7 +79,6 @@ const AuthPrompt = new Lang.Class({
if (event.get_key_symbol() == Clutter.KEY_Escape) {
this.cancel();
}
return Clutter.EVENT_PROPAGATE;
}));
this._userWell = new St.Bin({ x_fill: true,
@ -95,7 +92,7 @@ const AuthPrompt = new Lang.Class({
this.actor.add(this._label,
{ expand: true,
x_fill: false,
x_fill: true,
y_fill: true,
x_align: St.Align.START });
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
@ -113,7 +110,7 @@ const AuthPrompt = new Lang.Class({
this._message = new St.Label({ opacity: 0,
styleClass: 'login-dialog-message' });
this._message.clutter_text.line_wrap = true;
this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
this.actor.add(this._message, { x_fill: true, y_align: St.Align.START });
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
vertical: false });
@ -127,7 +124,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 +132,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 +160,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 +187,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);
@ -220,11 +219,6 @@ const AuthPrompt = new Lang.Class({
this.emit('prompted');
},
_onOVirtUserAuthenticated: function() {
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
this.reset();
},
_onSmartcardStatusChanged: function() {
this.smartcardDetected = this._userVerifier.smartcardDetected;
@ -259,14 +253,14 @@ const AuthPrompt = new Lang.Class({
},
_onVerificationComplete: function() {
this.setActorInDefaultButtonWell(null);
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
this.cancelButton.reactive = false;
},
_onReset: function() {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.reset();
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) {
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
this.reset();
}
},
addActorToDefaultButtonWell: function(actor) {
@ -283,12 +277,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 +286,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 +294,7 @@ const AuthPrompt = new Lang.Class({
transition: 'linear',
onCompleteScope: this,
onComplete: function() {
if (wasSpinner) {
if (isSpinner) {
if (this._spinner)
this._spinner.stop();
}
@ -414,7 +397,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 +414,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;
@ -465,10 +444,10 @@ const AuthPrompt = new Lang.Class({
// The user is constant at the unlock screen, so it will immediately
// respond to the request with the username
beginRequestType = BeginRequestType.PROVIDE_USERNAME;
} else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) ||
} else if (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
// with a smartcard.
beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME;
} else {
// In all other cases, we should get the username up front.
@ -502,7 +481,6 @@ const AuthPrompt = new Lang.Class({
finish: function(onComplete) {
if (!this._userVerifier.hasPendingMessages) {
this._userVerifier.clear();
onComplete();
return;
}
@ -510,15 +488,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

@ -13,35 +13,9 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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.
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
const Lang = imports.lang;

View File

@ -5,13 +5,11 @@ const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const FprintManagerIface = '<node> \
<interface name="net.reactivated.Fprint.Manager"> \
<method name="GetDefaultDevice"> \
<arg type="o" direction="out" /> \
</method> \
</interface> \
</node>';
const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
<method name='GetDefaultDevice'>
<arg type='o' direction='out' />
</method>
</interface>;
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface);

View File

@ -13,7 +13,9 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
const AccountsService = imports.gi.AccountsService;
@ -22,12 +24,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 +38,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 +48,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',
@ -59,7 +59,7 @@ const UserListItem = new Lang.Class({
this._userChangedId = this.user.connect('changed',
Lang.bind(this, this._onUserChanged));
let layout = new St.BoxLayout({ vertical: true });
let layout = new St.BoxLayout({ vertical: false });
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
can_focus: true,
@ -67,24 +67,40 @@ 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._userAvatar = new UserWidget.Avatar(this.user,
{ styleClass: 'login-dialog-user-list-item-icon' });
layout.add(this._userAvatar.actor);
let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box',
vertical: true });
layout.add(textLayout, { expand: true });
this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
GObject.BindingFlags.SYNC_CREATE);
this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' });
this.actor.label_actor = this._nameLabel;
textLayout.add(this._nameLabel,
{ y_fill: false,
y_align: St.Align.MIDDLE,
expand: true });
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
scale_x: 0 });
layout.add(this._timedLoginIndicator);
textLayout.add(this._timedLoginIndicator,
{ x_fill: true,
x_align: St.Align.MIDDLE,
y_fill: false,
y_align: St.Align.END });
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
this._onUserChanged();
},
_onUserChanged: function() {
this._nameLabel.set_text(this.user.get_real_name());
this._userAvatar.update();
this._updateLoggedIn();
},
syncStyleClasses: function() {
this._updateLoggedIn();
},
@ -95,10 +111,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');
},
@ -177,6 +189,7 @@ const UserList = new Lang.Class({
for (let userName in this._items) {
let item = this._items[userName];
item.actor.sync_hover();
item.syncStyleClasses();
}
},
@ -212,10 +225,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,16 +297,7 @@ 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);
this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.TOP);
Main.uiGroup.add_actor(this._menu.actor);
this._menu.actor.hide();
@ -383,19 +383,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 +419,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,28 +470,26 @@ 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();
if (!this._userManager.is_loaded)
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
Lang.bind(this, function() {
if (this._userManager.is_loaded) {
this._loadUserList();
this._userManager.disconnect(this._userManagerLoadedId);
this._userManagerLoadedId = 0;
}
}));
else
this._loadUserList();
this._userList.connect('activate',
Lang.bind(this, function(userList, item) {
this._onUserListActivated(item);
@ -488,221 +505,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) {
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
Lang.bind(this, function() {
if (this._userManager.is_loaded) {
this._loadUserList();
this._userManager.disconnect(this._userManagerLoadedId);
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');
}
},
},
_updateDisableUserList: function() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
@ -740,38 +543,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,24 +568,7 @@ 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;
@ -838,7 +607,6 @@ const LoginDialog = new Lang.Class({
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
this._fadeInBannerView();
},
_showRealmLoginHint: function(realmManager, hint) {
@ -858,61 +626,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,
@ -928,7 +664,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 false;
}));
},
onCompleteScope: this });
},
@ -982,9 +721,7 @@ const LoginDialog = new Lang.Class({
function() {
this._timedLoginAnimationTime -= _TIMED_LOGIN_IDLE_THRESHOLD;
hold.release();
return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginAnimationTime');
return hold;
},
@ -1048,7 +785,7 @@ const LoginDialog = new Lang.Class({
global.stage.connect('captured-event',
Lang.bind(this, function(actor, event) {
if (this._timedLoginDelay == undefined)
return Clutter.EVENT_PROPAGATE;
return false;
if (event.type() == Clutter.EventType.KEY_PRESS ||
event.type() == Clutter.EventType.BUTTON_PRESS) {
@ -1061,7 +798,7 @@ const LoginDialog = new Lang.Class({
this._resetTimedLogin();
}
return Clutter.EVENT_PROPAGATE;
return false;
}));
},
@ -1087,9 +824,7 @@ const LoginDialog = new Lang.Class({
},
_showUserList: function() {
this._ensureUserListLoaded();
this._authPrompt.hide();
this._hideBannerView();
this._sessionMenuButton.close();
this._setUserListExpanded(true);
this._notListedButton.show();
@ -1108,11 +843,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();
},
@ -1122,73 +864,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() {
@ -1200,8 +895,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,
@ -1211,12 +904,7 @@ const LoginDialog = new Lang.Class({
},
close: function() {
Main.popModal(this.actor);
Main.ctrlAltTabManager.removeGroup(this.actor);
},
cancel: function() {
this._authPrompt.cancel();
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
},
addCharacter: function(unichar) {

View File

@ -1,64 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const OVirtCredentialsIface = '<node> \
<interface name="org.ovirt.vdsm.Credentials"> \
<signal name="UserAuthenticated"> \
<arg type="s" name="token"/> \
</signal> \
</interface> \
</node>';
const OVirtCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(OVirtCredentialsIface);
let _oVirtCredentialsManager = null;
function OVirtCredentials() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
g_interface_name: OVirtCredentialsInfo.name,
g_interface_info: OVirtCredentialsInfo,
g_name: 'org.ovirt.vdsm.Credentials',
g_object_path: '/org/ovirt/vdsm/Credentials',
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
self.init(null);
return self;
}
const OVirtCredentialsManager = new Lang.Class({
Name: 'OVirtCredentialsManager',
_init: function() {
this._token = null;
this._credentials = new OVirtCredentials();
this._credentials.connectSignal('UserAuthenticated',
Lang.bind(this, this._onUserAuthenticated));
},
_onUserAuthenticated: function(proxy, sender, [token]) {
this._token = token;
this.emit('user-authenticated', token);
},
hasToken: function() {
return this._token != null;
},
getToken: function() {
return this._token;
},
resetToken: function() {
this._token = null;
}
});
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
function getOVirtCredentialsManager() {
if (!_oVirtCredentialsManager)
_oVirtCredentialsManager = new OVirtCredentialsManager();
return _oVirtCredentialsManager;
}

View File

@ -5,58 +5,52 @@ const Lang = imports.lang;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const ProviderIface = '<node> \
<interface name="org.freedesktop.realmd.Provider"> \
<property name="Name" type="s" access="read"/> \
<property name="Version" type="s" access="read"/> \
<property name="Realms" type="ao" access="read"/> \
<method name="Discover"> \
<arg name="string" type="s" direction="in"/> \
<arg name="options" type="a{sv}" direction="in"/> \
<arg name="relevance" type="i" direction="out"/> \
<arg name="realm" type="ao" direction="out"/> \
</method> \
</interface> \
</node>';
const ProviderIface = <interface name='org.freedesktop.realmd.Provider'>
<property name="Name" type="s" access="read"/>
<property name="Version" type="s" access="read"/>
<property name="Realms" type="ao" access="read"/>
<method name="Discover">
<arg name="string" type="s" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
<arg name="relevance" type="i" direction="out"/>
<arg name="realm" type="ao" direction="out"/>
</method>
</interface>;
const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface);
const ServiceIface = '<node> \
<interface name="org.freedesktop.realmd.Service"> \
<method name="Cancel"> \
<arg name="operation" type="s" direction="in"/> \
</method> \
<method name="Release" /> \
<method name="SetLocale"> \
<arg name="locale" type="s" direction="in"/> \
</method> \
<signal name="Diagnostics"> \
<arg name="data" type="s"/> \
<arg name="operation" type="s"/> \
</signal> \
</interface> \
</node>';
const ServiceIface = <interface name="org.freedesktop.realmd.Service">
<method name="Cancel">
<arg name="operation" type="s" direction="in"/>
</method>
<method name="Release" />
<method name="SetLocale">
<arg name="locale" type="s" direction="in"/>
</method>
<signal name="Diagnostics">
<arg name="data" type="s"/>
<arg name="operation" type="s"/>
</signal>
</interface>;
const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
const RealmIface = '<node> \
<interface name="org.freedesktop.realmd.Realm"> \
<property name="Name" type="s" access="read"/> \
<property name="Configured" type="s" access="read"/> \
<property name="Details" type="a(ss)" access="read"/> \
<property name="LoginFormats" type="as" access="read"/> \
<property name="LoginPolicy" type="s" access="read"/> \
<property name="PermittedLogins" type="as" access="read"/> \
<property name="SupportedInterfaces" type="as" access="read"/> \
<method name="ChangeLoginPolicy"> \
<arg name="login_policy" type="s" direction="in"/> \
<arg name="permitted_add" type="as" direction="in"/> \
<arg name="permitted_remove" type="as" direction="in"/> \
<arg name="options" type="a{sv}" direction="in"/> \
</method> \
<method name="Deconfigure"> \
<arg name="options" type="a{sv}" direction="in"/> \
</method> \
</interface> \
</node>';
const RealmIface = <interface name="org.freedesktop.realmd.Realm">
<property name="Name" type="s" access="read"/>
<property name="Configured" type="s" access="read"/>
<property name="Details" type="a(ss)" access="read"/>
<property name="LoginFormats" type="as" access="read"/>
<property name="LoginPolicy" type="s" access="read"/>
<property name="PermittedLogins" type="as" access="read"/>
<property name="SupportedInterfaces" type="as" access="read"/>
<method name="ChangeLoginPolicy">
<arg name="login_policy" type="s" direction="in"/>
<arg name="permitted_add" type="as" direction="in"/>
<arg name="permitted_remove" type="as" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
</method>
<method name="Deconfigure">
<arg name="options" type="a{sv}" direction="in"/>
</method>
</interface>;
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
const Manager = new Lang.Class({

View File

@ -10,7 +10,6 @@ const St = imports.gi.St;
const Batch = imports.gdm.batch;
const Fprint = imports.gdm.fingerprint;
const OVirt = imports.gdm.oVirt;
const Main = imports.ui.main;
const Params = imports.misc.params;
const ShellEntry = imports.ui.shellEntry;
@ -20,7 +19,6 @@ const Tweener = imports.ui.tweener;
const PASSWORD_SERVICE_NAME = 'gdm-password';
const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
const SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
const OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
const FADE_ANIMATION_TIME = 0.16;
const CLONE_FADE_ANIMATION_TIME = 0.25;
@ -35,8 +33,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 +126,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 +140,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;
@ -153,14 +151,6 @@ const ShellUserVerifier = new Lang.Class({
this.reauthenticating = false;
this._failCounter = 0;
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
if (this._oVirtCredentialsManager.hasToken())
this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken());
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
Lang.bind(this, this._oVirtUserAuthenticated));
},
begin: function(userName, hold) {
@ -191,37 +181,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);
@ -267,9 +240,7 @@ const ShellUserVerifier = new Lang.Class({
Lang.bind(this, function() {
this._messageQueueTimeoutId = 0;
this._queueMessageTimeout();
return GLib.SOURCE_REMOVE;
}));
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
},
_queueMessage: function(message, messageType) {
@ -300,24 +271,18 @@ 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();
}
}));
},
_oVirtUserAuthenticated: function(token) {
this._preemptingService = OVIRT_SERVICE_NAME;
this.emit('ovirt-user-authenticated');
},
_checkForSmartcard: function() {
let smartcardDetected;
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 +309,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 +332,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 +373,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;
@ -492,12 +455,6 @@ const ShellUserVerifier = new Lang.Class({
if (!this.serviceIsForeground(serviceName))
return;
if (serviceName == OVIRT_SERVICE_NAME) {
// The only question asked by this service is "Token?"
this.answerQuery(serviceName, this._oVirtCredentialsManager.getToken());
return;
}
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
},
@ -558,16 +515,6 @@ const ShellUserVerifier = new Lang.Class({
},
_onConversationStopped: function(client, serviceName) {
// If the login failed with the preauthenticated oVirt credentials
// then discard the credentials and revert to default authentication
// mechanism.
if (this.serviceIsForeground(OVIRT_SERVICE_NAME)) {
this._oVirtCredentialsManager.resetToken();
this._preemptingService = null;
this._verificationFailed(false);
return;
}
// if the password service fails, then cancel everything.
// But if, e.g., fingerprint fails, still give
// password authentication a chance to succeed

View File

@ -1,127 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell">
<file>gdm/authPrompt.js</file>
<file>gdm/batch.js</file>
<file>gdm/fingerprint.js</file>
<file>gdm/loginDialog.js</file>
<file>gdm/oVirt.js</file>
<file>gdm/realmd.js</file>
<file>gdm/util.js</file>
<file>extensionPrefs/main.js</file>
<file>misc/config.js</file>
<file>misc/extensionUtils.js</file>
<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>
<file>misc/params.js</file>
<file>misc/smartcardManager.js</file>
<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>
<file>ui/calendar.js</file>
<file>ui/checkBox.js</file>
<file>ui/ctrlAltTab.js</file>
<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>
<file>ui/extensionSystem.js</file>
<file>ui/focusCaretTracker.js</file>
<file>ui/grabHelper.js</file>
<file>ui/ibusCandidatePopup.js</file>
<file>ui/iconGrid.js</file>
<file>ui/keyboard.js</file>
<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>
<file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file>
<file>ui/popupMenu.js</file>
<file>ui/remoteMenu.js</file>
<file>ui/remoteSearch.js</file>
<file>ui/runDialog.js</file>
<file>ui/screenShield.js</file>
<file>ui/screencast.js</file>
<file>ui/screenshot.js</file>
<file>ui/scripting.js</file>
<file>ui/search.js</file>
<file>ui/separator.js</file>
<file>ui/sessionMode.js</file>
<file>ui/shellDBus.js</file>
<file>ui/shellEntry.js</file>
<file>ui/shellMountOperation.js</file>
<file>ui/slider.js</file>
<file>ui/switcherPopup.js</file>
<file>ui/tweener.js</file>
<file>ui/unlockDialog.js</file>
<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>
<file>ui/workspaceThumbnail.js</file>
<file>ui/workspacesView.js</file>
<file>ui/xdndHandler.js</file>
<file>ui/components/__init__.js</file>
<file>ui/components/autorunManager.js</file>
<file>ui/components/automountManager.js</file>
<file>ui/components/networkAgent.js</file>
<file>ui/components/polkitAgent.js</file>
<file>ui/components/telepathyClient.js</file>
<file>ui/components/keyring.js</file>
<file>ui/status/accessibility.js</file>
<file>ui/status/brightness.js</file>
<file>ui/status/location.js</file>
<file>ui/status/keyboard.js</file>
<file>ui/status/network.js</file>
<file>ui/status/power.js</file>
<file>ui/status/rfkill.js</file>
<file>ui/status/volume.js</file>
<file>ui/status/bluetooth.js</file>
<file>ui/status/screencast.js</file>
<file>ui/status/system.js</file>
</gresource>
</gresources>

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()];
@ -174,9 +174,17 @@ const ExtensionFinder = new Lang.Class({
this.emit('extension-found', extension);
},
_extensionsLoaded: function() {
this.emit('extensions-loaded');
},
scanExtensions: function() {
let perUserDir = Gio.File.new_for_path(global.userdatadir);
FileUtils.collectFromDatadirs('extensions', true, Lang.bind(this, this._loadExtension, perUserDir));
FileUtils.collectFromDatadirsAsync('extensions',
{ processFile: Lang.bind(this, this._loadExtension),
loadedCallback: Lang.bind(this, this._extensionsLoaded),
includeUserDir: true,
data: perUserDir });
}
});
Signals.addSignalMethods(ExtensionFinder.prototype);

View File

@ -5,27 +5,80 @@ const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Params = imports.misc.params;
function collectFromDatadirs(subdir, includeUserDir, processFile) {
function listDirAsync(file, callback) {
let allFiles = [];
file.enumerate_children_async('standard::name,standard::type',
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_LOW, null, function (obj, res) {
let enumerator = obj.enumerate_children_finish(res);
function onNextFileComplete(obj, res) {
let files = obj.next_files_finish(res);
if (files.length) {
allFiles = allFiles.concat(files);
enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, onNextFileComplete);
} else {
enumerator.close(null);
callback(allFiles);
}
}
enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, onNextFileComplete);
});
}
function _collectFromDirectoryAsync(dir, loadState) {
function done() {
loadState.numLoading--;
if (loadState.loadedCallback &&
loadState.numLoading == 0)
loadState.loadedCallback(loadState.data);
}
dir.query_info_async('standard::type', Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT, null, function(object, res) {
try {
object.query_info_finish(res);
} catch (e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
log(e.message);
done();
return;
}
listDirAsync(dir, Lang.bind(this, function(infos) {
for (let i = 0; i < infos.length; i++)
loadState.processFile(dir.get_child(infos[i].get_name()),
infos[i], loadState.data);
done();
}));
});
}
function collectFromDatadirsAsync(subdir, params) {
params = Params.parse(params, { includeUserDir: false,
processFile: null,
loadedCallback: null,
data: null });
let loadState = { data: params.data,
numLoading: 0,
loadedCallback: params.loadedCallback,
processFile: params.processFile };
if (params.processFile == null) {
if (params.loadedCallback)
params.loadedCallback(params.data);
return;
}
let dataDirs = GLib.get_system_data_dirs();
if (includeUserDir)
if (params.includeUserDir)
dataDirs.unshift(GLib.get_user_data_dir());
loadState.numLoading = dataDirs.length;
for (let i = 0; i < dataDirs.length; i++) {
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', subdir]);
let dir = Gio.File.new_for_path(path);
let fileEnum;
try {
fileEnum = dir.enumerate_children('standard::name,standard::type',
Gio.FileQueryInfoFlags.NONE, null);
} catch (e) {
fileEnum = null;
}
if (fileEnum != null) {
let info;
while ((info = fileEnum.next_file(null)))
processFile(fileEnum.get_child(info), info);
}
_collectFromDirectoryAsync(dir, loadState);
}
}

View File

@ -4,17 +4,15 @@ const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Signals = imports.signals;
const PresenceIface = '<node> \
<interface name="org.gnome.SessionManager.Presence"> \
<method name="SetStatus"> \
<arg type="u" direction="in"/> \
</method> \
<property name="status" type="u" access="readwrite"/> \
<signal name="StatusChanged"> \
<arg type="u" direction="out"/> \
</signal> \
</interface> \
</node>';
const PresenceIface = <interface name="org.gnome.SessionManager.Presence">
<method name="SetStatus">
<arg type="u" direction="in"/>
</method>
<property name="status" type="u" access="readwrite"/>
<signal name="StatusChanged">
<arg type="u" direction="out"/>
</signal>
</interface>;
const PresenceStatus = {
AVAILABLE: 0,
@ -32,16 +30,14 @@ function Presence(initCallback, cancellable) {
// Note inhibitors are immutable objects, so they don't
// change at runtime (changes always come in the form
// of new inhibitors)
const InhibitorIface = '<node> \
<interface name="org.gnome.SessionManager.Inhibitor"> \
<method name="GetAppId"> \
<arg type="s" direction="out" /> \
</method> \
<method name="GetReason"> \
<arg type="s" direction="out" /> \
</method> \
</interface> \
</node>';
const InhibitorIface = <interface name="org.gnome.SessionManager.Inhibitor">
<method name="GetAppId">
<arg type="s" direction="out" />
</method>
<method name="GetReason">
<arg type="s" direction="out" />
</method>
</interface>;
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface);
function Inhibitor(objectPath, initCallback, cancellable) {
@ -49,29 +45,27 @@ function Inhibitor(objectPath, initCallback, cancellable) {
}
// Not the full interface, only the methods we use
const SessionManagerIface = '<node> \
<interface name="org.gnome.SessionManager"> \
<method name="Logout"> \
<arg type="u" direction="in" /> \
</method> \
<method name="Shutdown" /> \
<method name="Reboot" /> \
<method name="CanShutdown"> \
<arg type="b" direction="out" /> \
</method> \
<method name="IsInhibited"> \
<arg type="u" direction="in" /> \
<arg type="b" direction="out" /> \
</method> \
<property name="SessionIsActive" type="b" access="read"/> \
<signal name="InhibitorAdded"> \
<arg type="o" direction="out"/> \
</signal> \
<signal name="InhibitorRemoved"> \
<arg type="o" direction="out"/> \
</signal> \
</interface> \
</node>';
const SessionManagerIface = <interface name="org.gnome.SessionManager">
<method name="Logout">
<arg type="u" direction="in" />
</method>
<method name="Shutdown" />
<method name="Reboot" />
<method name="CanShutdown">
<arg type="b" direction="out" />
</method>
<method name="IsInhibited">
<arg type="u" direction="in" />
<arg type="b" direction="out" />
</method>
<property name="SessionIsActive" type="b" access="read"/>
<signal name="InhibitorAdded">
<arg type="o" direction="out"/>
</signal>
<signal name="InhibitorRemoved">
<arg type="o" direction="out"/>
</signal>
</interface>;
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
function SessionManager(initCallback, cancellable) {

144
js/misc/hash.js Normal file
View File

@ -0,0 +1,144 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const System = imports.system;
const Params = imports.misc.params;
// This is an implementation of EcmaScript SameValue algorithm,
// which returns true if two values are not observably distinguishable.
// It was taken from http://wiki.ecmascript.org/doku.php?id=harmony:egal
//
// In the future, we may want to use the 'is' operator instead.
function _sameValue(x, y) {
if (x === y) {
// 0 === -0, but they are not identical
return x !== 0 || 1 / x === 1 / y;
}
// NaN !== NaN, but they are identical.
// NaNs are the only non-reflexive value, i.e., if x !== x,
// then x is a NaN.
// isNaN is broken: it converts its argument to number, so
// isNaN("foo") => true
return x !== x && y !== y;
}
const _hashers = {
object: function(o) { return o ? System.addressOf(o) : 'null'; },
function: function(f) { return System.addressOf(f); },
string: function(s) { return s; },
number: function(n) { return String(n); },
undefined: function() { return 'undefined'; },
};
/* Map is meant to be similar in usage to ES6 Map, which is
described at http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets,
without requiring more than ES5 + Gjs extensions.
Known differences from other implementations:
Polyfills around the web usually implement HashMaps for
primitive values and reversed WeakMaps for object keys,
but we want real maps with real O(1) semantics in all cases,
and the easiest way is to have different hashers for different
types.
Known differences from the ES6 specification:
- Map is a Lang.Class, not a ES6 class, so inheritance,
prototype, sealing, etc. work differently.
- items(), keys() and values() don't return iterators,
they return actual arrays, so they incur a full copy everytime
they're called, and they don't see changes if you mutate
the table while iterating
(admittedly, the ES6 spec is a bit unclear on this, and
the reference code would just blow up)
*/
const Map = new Lang.Class({
Name: 'Map',
_init: function(iterable) {
this._pool = { };
this._size = 0;
if (iterable) {
for (let i = 0; i < iterable.length; i++) {
let [key, value] = iterable[i];
this.set(key, value);
}
}
},
_hashKey: function(key) {
let type = typeof(key);
return type + ':' + _hashers[type](key);
},
_internalGet: function(key) {
let hash = this._hashKey(key);
let node = this._pool[hash];
if (node && _sameValue(node.key, key))
return [true, node.value];
else
return [false, null];
},
get: function(key) {
return this._internalGet(key)[1];
},
has: function(key) {
return this._internalGet(key)[0];
},
set: function(key, value) {
let hash = this._hashKey(key);
let node = this._pool[hash];
if (node) {
node.key = key;
node.value = value;
} else {
this._pool[hash] = { key: key, value: value };
this._size++;
}
},
delete: function(key) {
let hash = this._hashKey(key);
let node = this._pool[hash];
if (node && _sameValue(node.key, key)) {
delete this._pool[hash];
this._size--;
return [node.key, node.value];
} else {
return [null, null];
}
},
keys: function() {
let pool = this._pool;
return Object.getOwnPropertyNames(pool).map(function(hash) {
return pool[hash].key;
});
},
values: function() {
let pool = this._pool;
return Object.getOwnPropertyNames(pool).map(function(hash) {
return pool[hash].value;
});
},
items: function() {
let pool = this._pool;
return Object.getOwnPropertyNames(pool).map(function(hash) {
return [pool[hash].key, pool[hash].value];
});
},
size: function() {
return this._size;
},
});

View File

@ -89,7 +89,7 @@ const HistoryManager = new Lang.Class({
} else if (symbol == Clutter.KEY_Down) {
return this._setNextItem(entry.get_text());
}
return Clutter.EVENT_PROPAGATE;
return false;
},
_indexChanged: function() {

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

@ -7,48 +7,62 @@ const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const SystemdLoginManagerIface = '<node> \
<interface name="org.freedesktop.login1.Manager"> \
<method name="Suspend"> \
<arg type="b" direction="in"/> \
</method> \
<method name="CanSuspend"> \
<arg type="s" direction="out"/> \
</method> \
<method name="Inhibit"> \
<arg type="s" direction="in"/> \
<arg type="s" direction="in"/> \
<arg type="s" direction="in"/> \
<arg type="s" direction="in"/> \
<arg type="h" direction="out"/> \
</method> \
<method name="GetSession"> \
<arg type="s" direction="in"/> \
<arg type="o" direction="out"/> \
</method> \
<method name="ListSessions"> \
<arg name="sessions" type="a(susso)" direction="out"/> \
</method> \
<signal name="PrepareForSleep"> \
<arg type="b" direction="out"/> \
</signal> \
</interface> \
</node>';
const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager'>
<method name='Suspend'>
<arg type='b' direction='in'/>
</method>
<method name='CanSuspend'>
<arg type='s' direction='out'/>
</method>
<method name='Inhibit'>
<arg type='s' direction='in'/>
<arg type='s' direction='in'/>
<arg type='s' direction='in'/>
<arg type='s' direction='in'/>
<arg type='h' direction='out'/>
</method>
<method name='GetSession'>
<arg type='s' direction='in'/>
<arg type='o' direction='out'/>
</method>
<method name='ListSessions'>
<arg name='sessions' type='a(susso)' direction='out'/>
</method>
<signal name='PrepareForSleep'>
<arg type='b' direction='out'/>
</signal>
</interface>;
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 SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session'>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
const ConsoleKitManagerIface = <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>;
const ConsoleKitSessionIface = <interface name='org.freedesktop.ConsoleKit.Session'>
<signal name='Lock' />
<signal name='Unlock' />
</interface>;
const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
function haveSystemd() {
return GLib.access("/run/systemd/seats", 0) >= 0;
}
@ -78,7 +92,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 +110,7 @@ function getLoginManager() {
if (haveSystemd())
_loginManager = new LoginManagerSystemd();
else
_loginManager = new LoginManagerDummy();
_loginManager = new LoginManagerConsoleKit();
}
return _loginManager;
@ -113,6 +127,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 +151,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 +182,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 +197,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 +245,4 @@ const LoginManagerDummy = new Lang.Class({
callback(null);
}
});
Signals.addSignalMethods(LoginManagerDummy.prototype);
Signals.addSignalMethods(LoginManagerConsoleKit.prototype);

View File

@ -92,41 +92,37 @@ function _findProviderForSid(sid) {
// The following are not the complete interfaces, just the methods we need
// (or may need in the future)
const ModemGsmNetworkInterface = '<node> \
<interface name="org.freedesktop.ModemManager.Modem.Gsm.Network"> \
<method name="GetRegistrationInfo"> \
<arg type="(uss)" direction="out" /> \
</method> \
<method name="GetSignalQuality"> \
<arg type="u" direction="out" /> \
</method> \
<property name="AccessTechnology" type="u" access="read" /> \
<signal name="SignalQuality"> \
<arg type="u" direction="out" /> \
</signal> \
<signal name="RegistrationInfo"> \
<arg type="u" direction="out" /> \
<arg type="s" direction="out" /> \
<arg type="s" direction="out" /> \
</signal> \
</interface> \
</node>';
const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network">
<method name="GetRegistrationInfo">
<arg type="(uss)" direction="out" />
</method>
<method name="GetSignalQuality">
<arg type="u" direction="out" />
</method>
<property name="AccessTechnology" type="u" access="read" />
<signal name="SignalQuality">
<arg type="u" direction="out" />
</signal>
<signal name="RegistrationInfo">
<arg type="u" direction="out" />
<arg type="s" direction="out" />
<arg type="s" direction="out" />
</signal>
</interface>;
const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface);
const ModemCdmaInterface = '<node> \
<interface name="org.freedesktop.ModemManager.Modem.Cdma"> \
<method name="GetSignalQuality"> \
<arg type="u" direction="out" /> \
</method> \
<method name="GetServingSystem"> \
<arg type="(usu)" direction="out" /> \
</method> \
<signal name="SignalQuality"> \
<arg type="u" direction="out" /> \
</signal> \
</interface> \
</node>';
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
<method name="GetSignalQuality">
<arg type="u" direction="out" />
</method>
<method name="GetServingSystem">
<arg type="(usu)" direction="out" />
</method>
<signal name="SignalQuality">
<arg type="u" direction="out" />
</signal>
</interface>;
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
@ -222,26 +218,20 @@ Signals.addSignalMethods(ModemCdma.prototype);
// Support for the new ModemManager1 interface (MM >= 0.7)
//------------------------------------------------------------------------------
const BroadbandModemInterface = '<node> \
<interface name="org.freedesktop.ModemManager1.Modem"> \
<property name="SignalQuality" type="(ub)" access="read" /> \
</interface> \
</node>';
const BroadbandModemInterface = <interface name="org.freedesktop.ModemManager1.Modem">
<property name="SignalQuality" type="(ub)" access="read" />
</interface>;
const BroadbandModemProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemInterface);
const BroadbandModem3gppInterface = '<node> \
<interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp"> \
<property name="OperatorCode" type="s" access="read" /> \
<property name="OperatorName" type="s" access="read" /> \
</interface> \
</node>';
const BroadbandModem3gppInterface = <interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp">
<property name="OperatorCode" type="s" access="read" />
<property name="OperatorName" type="s" access="read" />
</interface>;
const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gppInterface);
const BroadbandModemCdmaInterface = '<node> \
<interface name="org.freedesktop.ModemManager1.Modem.ModemCdma"> \
<property name="Sid" type="u" access="read" /> \
</interface> \
</node>';
const BroadbandModemCdmaInterface = <interface name="org.freedesktop.ModemManager1.Modem.ModemCdma">
<property name="Sid" type="u" access="read" />
</interface>;
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
const BroadbandModem = new Lang.Class({

View File

@ -8,21 +8,19 @@ const Signals = imports.signals;
// Specified in the D-Bus specification here:
// http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
const ObjectManagerIface = '<node> \
<interface name="org.freedesktop.DBus.ObjectManager"> \
<method name="GetManagedObjects"> \
<arg name="objects" type="a{oa{sa{sv}}}" direction="out"/> \
</method> \
<signal name="InterfacesAdded"> \
<arg name="objectPath" type="o"/> \
<arg name="interfaces" type="a{sa{sv}}" /> \
</signal> \
<signal name="InterfacesRemoved"> \
<arg name="objectPath" type="o"/> \
<arg name="interfaces" type="as" /> \
</signal> \
</interface> \
</node>';
const ObjectManagerIface = <interface name="org.freedesktop.DBus.ObjectManager">
<method name="GetManagedObjects">
<arg name="objects" type="a{oa{sa{sv}}}" direction="out"/>
</method>
<signal name="InterfacesAdded">
<arg name="objectPath" type="o"/>
<arg name="interfaces" type="a{sa{sv}}" />
</signal>
<signal name="InterfacesRemoved">
<arg name="objectPath" type="o"/>
<arg name="interfaces" type="as" />
</signal>
</interface>;
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);

View File

@ -7,14 +7,12 @@ const Signals = imports.signals;
const ObjectManager = imports.misc.objectManager;
const SmartcardTokenIface = '<node> \
<interface name="org.gnome.SettingsDaemon.Smartcard.Token"> \
<property name="Name" type="s" access="read"/> \
<property name="Driver" type="o" access="read"/> \
<property name="IsInserted" type="b" access="read"/> \
<property name="UsedToLogin" type="b" access="read"/> \
</interface> \
</node>';
const SmartcardTokenIface = <interface name="org.gnome.SettingsDaemon.Smartcard.Token">
<property name="Name" type="s" access="read"/>
<property name="Driver" type="o" access="read"/>
<property name="IsInserted" type="b" access="read"/>
<property name="UsedToLogin" type="b" access="read"/>
</interface>;
let _smartcardManager = null;

View File

@ -1,15 +1,12 @@
// -*- 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 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 +37,6 @@ const _urlRegexp = new RegExp(
')' +
')', 'gi');
let _desktopSettings = null;
// findUrls:
// @str: string to find URLs in
//
@ -84,22 +79,6 @@ function spawnCommandLine(command_line) {
}
}
// spawnApp:
// @argv: an argv array
//
// Runs @argv as if it was an application, handling startup notification
function spawnApp(argv) {
try {
let app = Gio.AppInfo.create_from_commandline(argv.join(' '), null,
Gio.AppInfoCreateFlags.SUPPORTS_STARTUP_NOTIFICATION);
let context = global.create_app_launch_context(0, -1);
app.launch([], context);
} catch(err) {
_handleSpawnError(argv[0], err);
}
}
// trySpawn:
// @argv: an argv array
//
@ -133,7 +112,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:
@ -157,109 +136,10 @@ function trySpawnCommandLine(command_line) {
}
function _handleSpawnError(command, err) {
let title = _("Execution of %s failed:").format(command);
let title = _("Execution of '%s' failed:").format(command);
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://www.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() == 'www.gnome.org' && this._everSeenRedirect) {
// Yay, we got to gnome!
decision.ignore();
this._doneCallback(PortalHelperResult.COMPLETED);
return true;
} else if (uri.get_host() != 'www.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

@ -2,7 +2,6 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
@ -24,7 +23,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,
@ -58,14 +57,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) {
@ -81,6 +72,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;
@ -106,6 +98,18 @@ 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;
return true;
},
_initialSelection: function(backward, binding) {
if (binding == 'switch-group') {
if (backward) {
@ -144,13 +148,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) {
@ -160,8 +164,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());
@ -169,11 +171,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) {
@ -304,7 +302,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');
}
},
@ -313,7 +310,7 @@ const AppSwitcherPopup = new Lang.Class({
this._createThumbnails();
this._thumbnailTimeoutId = 0;
this._thumbnailsFocused = false;
return GLib.SOURCE_REMOVE;
return false;
},
_destroyThumbnails : function() {
@ -354,85 +351,45 @@ const AppSwitcherPopup = new Lang.Class({
}
});
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;
// 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) {
Main.activateWindow(this._items[index]);
},
_finish: function() {
this._highlightItem(this._selectedIndex);
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 global.display.get_tab_list(Meta.TabList.NORMAL, 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;
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 {
@ -440,11 +397,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() {
@ -454,32 +407,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 global.display.get_tab_list(Meta.TabList.NORMAL, 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',
@ -497,6 +424,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;
}
});
@ -512,10 +440,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++) {
@ -525,8 +454,9 @@ const AppSwitcher = new Lang.Class({
appIcon.cachedWindows = allWindows.filter(function(w) {
return windowTracker.get_window_app (w) == appIcon.app;
});
if (appIcon.cachedWindows.length > 0)
if (workspace == null || appIcon.cachedWindows.length > 0) {
this._addIcon(appIcon);
}
}
this._curApp = -1;
@ -542,13 +472,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);
@ -559,22 +488,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++) {
@ -582,11 +508,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) {
@ -618,9 +542,8 @@ const AppSwitcher = new Lang.Class({
Lang.bind(this, function () {
this._enterItem(index);
this._mouseTimeOutId = 0;
return GLib.SOURCE_REMOVE;
return false;
}));
GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
} else
this._itemEntered(index);
},
@ -720,19 +643,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);
@ -764,17 +685,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,
@ -786,7 +705,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

@ -1,18 +1,17 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
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 +20,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 +30,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;
@ -63,7 +59,7 @@ const Animation = new Lang.Class({
_update: function() {
this._showFrame(this._frame + 1);
return GLib.SOURCE_CONTINUE;
return true;
},
_animationsLoaded: function() {
@ -82,7 +78,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,38 +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',
'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',
@ -56,21 +24,6 @@ const AppFavorites = new Lang.Class({
reload: function() {
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
// 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) {
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 appSys = Shell.AppSystem.get_default();
let apps = ids.map(function (id) {
return appSys.lookup_app(id);

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

@ -13,61 +13,56 @@ const BackgroundMenu = new Lang.Class({
Name: 'BackgroundMenu',
Extends: PopupMenu.PopupMenu,
_init: function(layoutManager) {
this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
_init: function(source) {
this.parent(source, 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);
Main.uiGroup.add_actor(this.actor);
this.actor.hide();
}
});
function addBackgroundMenu(actor, layoutManager) {
function addBackgroundMenu(actor) {
let cursor = new St.Bin({ opacity: 0 });
Main.uiGroup.add_actor(cursor);
actor.reactive = true;
actor._backgroundMenu = new BackgroundMenu(layoutManager);
actor._backgroundMenu = new BackgroundMenu(cursor);
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();
cursor.set_position(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);
});
actor._backgroundMenu.destroy();
actor._backgroundMenu = null;
actor._backgroundManager = null;
cursor.destroy();
});
}

View File

@ -69,7 +69,7 @@ const BoxPointer = new Lang.Class({
_muteInput: function() {
if (this._capturedEventId == 0)
this._capturedEventId = this.actor.connect('captured-event',
function() { return Clutter.EVENT_STOP; });
function() { return true; });
},
_unmuteInput: function() {
@ -121,9 +121,6 @@ const BoxPointer = new Lang.Class({
},
hide: function(animate, onComplete) {
if (!this.actor.visible)
return;
let xOffset = 0;
let yOffset = 0;
let themeNode = this.actor.get_theme_node();
@ -188,9 +185,7 @@ const BoxPointer = new Lang.Class({
},
_getPreferredHeight: function(actor, forWidth, alloc) {
let themeNode = this.actor.get_theme_node();
let borderWidth = themeNode.get_length('-arrow-border-width');
let [minSize, naturalSize] = this.bin.get_preferred_height(forWidth - 2 * borderWidth);
let [minSize, naturalSize] = this.bin.get_preferred_height(forWidth);
alloc.min_size = minSize;
alloc.natural_size = naturalSize;
this._adjustAllocationForArrow(false, alloc);
@ -287,40 +282,38 @@ const BoxPointer = new Lang.Class({
let skipBottomLeft = false;
let skipBottomRight = false;
if (rise) {
switch (this._arrowSide) {
case St.Side.TOP:
if (this._arrowOrigin == x1)
skipTopLeft = true;
else if (this._arrowOrigin == x2)
skipTopRight = true;
break;
switch (this._arrowSide) {
case St.Side.TOP:
if (this._arrowOrigin == x1)
skipTopLeft = true;
else if (this._arrowOrigin == x2)
skipTopRight = true;
break;
case St.Side.RIGHT:
if (this._arrowOrigin == y1)
skipTopRight = true;
else if (this._arrowOrigin == y2)
skipBottomRight = true;
break;
case St.Side.RIGHT:
if (this._arrowOrigin == y1)
skipTopRight = true;
else if (this._arrowOrigin == y2)
skipBottomRight = true;
break;
case St.Side.BOTTOM:
if (this._arrowOrigin == x1)
skipBottomLeft = true;
else if (this._arrowOrigin == x2)
skipBottomRight = true;
break;
case St.Side.BOTTOM:
if (this._arrowOrigin == x1)
skipBottomLeft = true;
else if (this._arrowOrigin == x2)
skipBottomRight = true;
break;
case St.Side.LEFT:
if (this._arrowOrigin == y1)
skipTopLeft = true;
else if (this._arrowOrigin == y2)
skipBottomLeft = true;
break;
}
case St.Side.LEFT:
if (this._arrowOrigin == y1)
skipTopLeft = true;
else if (this._arrowOrigin == y2)
skipBottomLeft = true;
break;
}
cr.moveTo(x1 + borderRadius, y1);
if (this._arrowSide == St.Side.TOP && rise) {
if (this._arrowSide == St.Side.TOP) {
if (skipTopLeft) {
cr.moveTo(x1, y2 - borderRadius);
cr.lineTo(x1, y1 - rise);
@ -342,7 +335,7 @@ const BoxPointer = new Lang.Class({
3*Math.PI/2, Math.PI*2);
}
if (this._arrowSide == St.Side.RIGHT && rise) {
if (this._arrowSide == St.Side.RIGHT) {
if (skipTopRight) {
cr.lineTo(x2 + rise, y1);
cr.lineTo(x2 + rise, y1 + halfBase);
@ -363,7 +356,7 @@ const BoxPointer = new Lang.Class({
0, Math.PI/2);
}
if (this._arrowSide == St.Side.BOTTOM && rise) {
if (this._arrowSide == St.Side.BOTTOM) {
if (skipBottomLeft) {
cr.lineTo(x1 + halfBase, y2);
cr.lineTo(x1, y2 + rise);
@ -384,7 +377,7 @@ const BoxPointer = new Lang.Class({
Math.PI/2, Math.PI);
}
if (this._arrowSide == St.Side.LEFT && rise) {
if (this._arrowSide == St.Side.LEFT) {
if (skipTopLeft) {
cr.lineTo(x1, y1 + halfBase);
cr.lineTo(x1 - rise, y1);

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() {
@ -78,7 +77,7 @@ const AutomountManager = new Lang.Class({
}));
this._mountAllId = 0;
return GLib.SOURCE_REMOVE;
return false;
},
_onDriveConnected: 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;
return false;
});
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))
@ -64,7 +64,7 @@ function startAppForMount(app, mount) {
try {
retval = app.launch(files,
global.create_app_launch_context(0, -1))
global.create_app_launch_context())
} catch (e) {
log('Unable to launch the application ' + app.get_name()
+ ': ' + e.toString());
@ -75,14 +75,12 @@ function startAppForMount(app, mount) {
/******************************************/
const HotplugSnifferIface = '<node> \
<interface name="org.gnome.Shell.HotplugSniffer"> \
<method name="SniffURI"> \
<arg type="s" direction="in" /> \
<arg type="as" direction="out" /> \
</method> \
</interface> \
</node>';
const HotplugSnifferIface = <interface name="org.gnome.Shell.HotplugSniffer">
<method name="SniffURI">
<arg type="s" direction="in" />
<arg type="as" direction="out" />
</method>
</interface>;
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface);
function HotplugSniffer() {
@ -96,7 +94,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 +165,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 +480,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 +489,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 +529,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 +540,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 +549,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 +598,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 +609,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,11 @@ 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;
let prompter = null;
const KeyringDialog = new Lang.Class({
Name: 'KeyringDialog',
@ -47,13 +43,11 @@ 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,
{ x_fill: false,
y_fill: false,
x_align: St.Align.START,
{ y_fill: false,
y_align: St.Align.START });
let description = new St.Label({ style_class: 'prompt-dialog-description' });
@ -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,14 @@ 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);
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 +163,7 @@ const KeyringDialog = new Lang.Class({
this._continueButton.can_focus = sensitive;
this._continueButton.reactive = sensitive;
this._setWorking(!sensitive);
this.setWorking(!sensitive);
},
_ensureOpen: function() {
@ -296,13 +248,11 @@ const KeyringPrompter = new Lang.Class({
function() {
let dialog = this._enabled ? new KeyringDialog()
: new KeyringDummyDialog();
this._currentPrompt = dialog.prompt;
return this._currentPrompt;
return dialog.prompt;
}));
this._dbusId = null;
this._registered = false;
this._enabled = false;
this._currentPrompt = null;
},
enable: function() {
@ -317,10 +267,6 @@ const KeyringPrompter = new Lang.Class({
disable: function() {
this._enabled = false;
if (this._prompter.prompting)
this._currentPrompt.cancel();
this._currentPrompt = null;
}
});

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)
@ -147,8 +138,6 @@ const NetworkSecretDialog = new Lang.Class({
key: Clutter.KEY_Escape,
},
this._okButton]);
this._updateOkButton();
},
_updateOkButton: function() {
@ -264,7 +253,6 @@ const NetworkSecretDialog = new Lang.Class({
case 'leap':
case 'ttls':
case 'peap':
case 'fast':
// TTLS and PEAP are actually much more complicated, but this complication
// is not visible here since we only care about phase2 authentication
// (and don't even care of which one)
@ -318,7 +306,7 @@ const NetworkSecretDialog = new Lang.Class({
wirelessSetting = this._connection.get_setting_wireless();
ssid = NetworkManager.utils_ssid_to_utf8(wirelessSetting.get_ssid());
content.title = _("Authentication required by wireless network");
content.message = _("Passwords or encryption keys are required to access the wireless network %s.").format(ssid);
content.message = _("Passwords or encryption keys are required to access the wireless network '%s'.").format(ssid);
this._getWirelessSecrets(content.secrets, wirelessSetting);
break;
case '802-3-ethernet':
@ -340,13 +328,12 @@ 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':
case 'bluetooth':
content.title = _("Mobile broadband network password");
content.message = _("A password is required to connect to %s.").format(connectionSetting.get_id());
content.message = _("A password is required to connect to '%s'.").format(connectionSetting.get_id());
this._getMobileSecrets(content.secrets, connectionType);
break;
default:
@ -383,12 +370,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;
@ -451,7 +432,6 @@ const VPNRequestHandler = new Lang.Class({
},
_vpnChildFinished: function(pid, status, requestObj) {
this._childWatch = 0;
if (this._newStylePlugin) {
// For new style plugin, all work is done in the async reading functions
// Just reap the process here
@ -526,12 +506,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 +542,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,13 +582,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._native.connect('new-request', Lang.bind(this, this._newRequest));
this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest));
@ -636,92 +608,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];
}));
@ -781,33 +682,18 @@ const NetworkAgent = new Lang.Class({
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, dir.get_child(name).get_path()));

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,13 +50,11 @@ 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,
{ x_fill: false,
y_fill: false,
x_align: St.Align.START,
{ y_fill: false,
y_align: St.Align.START });
this._descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
@ -71,9 +63,7 @@ const AuthenticationDialog = new Lang.Class({
this._descriptionLabel.clutter_text.line_wrap = true;
messageBox.add(this._descriptionLabel,
{ x_fill: false,
y_fill: true,
x_align: St.Align.START,
{ y_fill: true,
y_align: St.Align.START });
if (userNames.length > 1) {
@ -105,8 +95,7 @@ const AuthenticationDialog = new Lang.Class({
if (userIsRoot) {
let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-root-label',
text: userRealName }));
messageBox.add(userLabel, { x_fill: false,
x_align: St.Align.START });
messageBox.add(userLabel);
} else {
let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
vertical: false });
@ -142,20 +131,13 @@ 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();
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label' });
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
this._errorMessageLabel.clutter_text.line_wrap = true;
messageBox.add(this._errorMessageLabel, { x_fill: false, x_align: St.Align.START });
messageBox.add(this._errorMessageLabel);
this._errorMessageLabel.hide();
this._infoMessageLabel = new St.Label({ style_class: 'prompt-dialog-info-label' });
@ -178,10 +160,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 +178,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 +224,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,8 +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;
const Meta = imports.gi.Meta;
@ -259,7 +257,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 +268,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 +380,6 @@ const DashActor = new Lang.Class({
}
});
const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
const Dash = new Lang.Class({
Name: 'Dash',
@ -517,13 +510,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 +526,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);
@ -589,10 +576,8 @@ const Dash = new Lang.Class({
Lang.bind(this, function() {
this._labelShowing = true;
item.showLabel();
this._showLabelTimeoutId = 0;
return GLib.SOURCE_REMOVE;
return false;
}));
GLib.Source.set_name_by_id(this._showLabelTimeoutId, '[gnome-shell] item.showLabel');
if (this._resetHoverTimeoutId > 0) {
Mainloop.source_remove(this._resetHoverTimeoutId);
this._resetHoverTimeoutId = 0;
@ -607,10 +592,8 @@ const Dash = new Lang.Class({
this._resetHoverTimeoutId = Mainloop.timeout_add(DASH_ITEM_HOVER_TIMEOUT,
Lang.bind(this, function() {
this._labelShowing = false;
this._resetHoverTimeoutId = 0;
return GLib.SOURCE_REMOVE;
return false;
}));
GLib.Source.set_name_by_id(this._resetHoverTimeoutId, '[gnome-shell] this._labelShowing');
}
}
},
@ -644,29 +627,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 +844,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 +920,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,125 @@ 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._calendar = new Calendar.Calendar();
this._calendar.connect('selected-date-changed',
Lang.bind(this, function(calendar, date) {
layout.frozen = !_isToday(date);
this._messageList.setDate(date);
}));
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);
}
}));
this.menu.box.add_child(hbox);
// 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 });
vbox = new St.BoxLayout({vertical: true});
hbox.add(vbox);
this._date = new TodayButton(this._calendar);
vbox.add_actor(this._date.actor);
// 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) {
// 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);
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 separator = new PopupMenu.PopupSeparatorMenuItem();
vbox.add(separator.actor, { y_align: St.Align.END, expand: true, y_fill: false });
let displaysBox = new St.BoxLayout({ vertical: true,
style_class: 'datemenu-displays-box' });
this._displaysSection.add_actor(displaysBox);
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._clocksItem = new WorldClocksSection();
displaysBox.add(this._clocksItem.actor, { x_fill: true });
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) {
if (isOpen) {
let now = new Date();
/* Passing true to setDate() forces events to be reloaded. We
* want this behavior, because
*
* o It will cause activation of the calendar server which is
* useful if it has crashed
*
* o It will cause the calendar server to reload events which
* is useful if dynamic updates are not supported or not
* properly working
*
* Since this only happens when the menu is opened, the cost
* isn't very big.
*/
this._calendar.setDate(now, true);
// No need to update this._eventList as ::selected-date-changed
// signal will fire
}
}));
// 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 +170,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());
},
_onOpenClocksActivate: function() {
this.menu.close();
let app = this._getClockApp();
app.activate();
}
});

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