Compare commits
7 Commits
3.5.3
...
wip/input-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4802861ed | ||
|
|
a8fa0b8146 | ||
|
|
cf0bb62f40 | ||
|
|
de8106967d | ||
|
|
1a24f061cf | ||
|
|
e038845458 | ||
|
|
b03273c765 |
114
NEWS
114
NEWS
@@ -1,117 +1,3 @@
|
|||||||
3.5.3
|
|
||||||
=====
|
|
||||||
* calendar: Adapt to Evolution-Data-Server API changes [Matthew; #677402]
|
|
||||||
* messageTray: Don't show non urgent notifications while in fullscreen
|
|
||||||
[Adel; #677590]
|
|
||||||
* modalDialog: show dialogs on monitor with the mouse pointer [Tim; #642591]
|
|
||||||
* extensionSystem: Prepare for extension updating system [Jasper; #677586]
|
|
||||||
* appDisplay: Don't show apps in NoDisplay categories in the All view
|
|
||||||
[Jasper; #658176]
|
|
||||||
* st: Trigger theme updates on resolution changes [Florian; #677975]
|
|
||||||
* Always enable a11y [Bastien; #678095]
|
|
||||||
* telepathyClient: ignore invalidated channels [Guillaume; #677457]
|
|
||||||
* shell-app: Update app menu if necessary [Florian; #676238]
|
|
||||||
* Enable the Screen Reader menu item [Matthias; #663256]
|
|
||||||
* Disable unredirection when a modal operation is active [Giovanni]
|
|
||||||
* Make folks optional [Colin]
|
|
||||||
* Improve mount-operation support [Cosimo]
|
|
||||||
- Fix exception when showing password entry [#678428]
|
|
||||||
- Close the password entry on operation abort [#673787]
|
|
||||||
- autorun: Don't allow autorun for things we mount on startup [#660595]
|
|
||||||
- Turn passphrase prompt into a dialog [#674962]
|
|
||||||
- Implement org.Gtk.MountOperationHandler [#678516]
|
|
||||||
* Network menu improvements
|
|
||||||
- Sort Wifi networks by strength [Giovanni; #658946]
|
|
||||||
- Prefer wifi/3g over VPN in the panel [Cosimo; #672591]
|
|
||||||
* clock: Switch to using GnomeWallClock [Colin; #657074]
|
|
||||||
* remoteSearch: Allow to reference .desktop file for Title/Icon
|
|
||||||
[Florian; #678816]
|
|
||||||
* Fix memory leaks [Jasper, Pavel; #678079, #678406, #678737]
|
|
||||||
* Misc fixes [Florian, Giovanni, Guillaume, Jasper, Kjartan, Piotr, Rui;
|
|
||||||
#658955, #677497, #678396, #678502]
|
|
||||||
* Misc cleanups [Bastien, Florian, Jasper; #677426, #677515, #678096, #678416]
|
|
||||||
|
|
||||||
Contributors:
|
|
||||||
Matthew Barnes, Giovanni Campagna, Cosimo Cecchi, Matthias Clasen,
|
|
||||||
Guillaume Desmottes, Piotr Drąg, Adel Gadllah, Tim L, Kjartan Maraas,
|
|
||||||
Rui Matos, Florian Müllner, Bastien Nocera, Jasper St. Pierre, Colin Walters
|
|
||||||
|
|
||||||
Translations:
|
|
||||||
Matej Urbančič [sl], Yuri Kozlov [ru], Tom Tryfonidis [el],
|
|
||||||
Kjartan Maraas [nb], Žygimantas Beručka [lt], Luca Ferretti [it],
|
|
||||||
Khaled Hosny [ar], Daniel Mustieles [es], Fran Diéguez [gl], A S Alam [pa]
|
|
||||||
|
|
||||||
3.5.2
|
|
||||||
=====
|
|
||||||
* main: Move 'toggle-recording' binding into the shell [Florian; #674377]
|
|
||||||
* popupMenu: make sure to break the grab when the slider is not visible
|
|
||||||
[Stefano; #672713]
|
|
||||||
* st-theme-node-drawing: Don't use GL types [Neil; #672711]
|
|
||||||
* Mirror Evolution calendar settings into our own schema [Owen; #674424]
|
|
||||||
* shell-network-agent: don't crash if a request isn't found [Dan; #674961]
|
|
||||||
* notificationDaemon: Match app based on WM_CLASS [Jasper; #673761]
|
|
||||||
* NetworkMenu: use network-offline while loading [Giovanni; #674426]
|
|
||||||
* lookingGlass: Remove the Errors tab [Jasper; #675104]
|
|
||||||
* searchDisplay: Reset keyboard focus after displaying async results
|
|
||||||
[Rui; #675078]
|
|
||||||
* gdm: don't fail if fprintd is unavailable [Ray; #675006]
|
|
||||||
* messageTray: Fix scrolling up [Jasper; #661615]
|
|
||||||
* main: Close the recorder instead of pausing it [Rui; #675128]
|
|
||||||
* Accessibility [Alejandro]
|
|
||||||
- Use the proper label_actor for date menu on top panel [#675307]
|
|
||||||
- Set the proper role/label_actor for SearchResult.content [#672242]
|
|
||||||
- do not expose a label text if 'hidden' style class is used [#675341]
|
|
||||||
* Magnifier: Add brightness and contrast functionality [Joseph; #639851]
|
|
||||||
* theme: use a smaller border-radius for top bar [Jakub; #672430]
|
|
||||||
* placeDisplay: use new bookmark file location [Matthias; #675443]
|
|
||||||
* port all synchronous search providers to the async API [Jasper, Rui; #675328]
|
|
||||||
* NetworkAgent: disallow multiple requests for the same connection/setting
|
|
||||||
[Giovanni; #674961]
|
|
||||||
* userMenu: Update to latest mockups [Florian; #675802]
|
|
||||||
* util: Don't double-fork when spawning from Alt-F2 [Colin; #675789]
|
|
||||||
* messageTray: Make Source usable without subclassing [Jasper; #661236]
|
|
||||||
* panel: Check for appMenu button's reactivity before opening [Florian; #676316]
|
|
||||||
* Fix formatting of bluetooth passkey [Florian; #651251]
|
|
||||||
* notificationDaemon: Filter out file-transfer notifications [Jasper; #676175]
|
|
||||||
* Don't use global.log() [Jasper; #675790]
|
|
||||||
* Fix broken extension loading in some distributions [Owen, Alexandre; #670477]
|
|
||||||
* shell-app: Raise windows in reverse order to preserve the stacking
|
|
||||||
[Rui; #676371]
|
|
||||||
* Generalize gdm-mode [Florian; #676156]
|
|
||||||
* Switch string formatting to the one inside gjs [Jasper; #675479]
|
|
||||||
* extensionUtils: Support subdirectories in getCurrentExtension
|
|
||||||
[Jasper; #677001]
|
|
||||||
* panel: Refuse to add (legacy) status icons not part of the session mode
|
|
||||||
[Florian; #677058]
|
|
||||||
* Add an initial-setup mode [Matthias; #676697]
|
|
||||||
* status/keyboard: Port to the new input sources settings [Rui; #641531]
|
|
||||||
* NetworkMenu: show notifications for failed VPN connections [Giovanni; #676330]
|
|
||||||
* userMenu: Indicate progress on status changes [Florian; #659067]
|
|
||||||
* recorder: Honor "disable-save-to-disk" lockdown key [Rūdolfs; #673630]
|
|
||||||
* searchDisplay: Use the rowLimit we pass to the IconGrid [Christian; #675527]
|
|
||||||
* endSessionDialog: Factor out _updateDescription from _updateContent
|
|
||||||
[Alejandro; #674210]
|
|
||||||
* Fix empathy's appMenu freezing the shell [Alban; #676447]
|
|
||||||
* Code cleanups [Florian, Giovanni, Jasper; #672807, #672413, #676837, #676850,
|
|
||||||
#672272]
|
|
||||||
* Misc bug fixes [Alban, Florian, Giovanni, Guillaume, Jasper, Piotr, Rico,
|
|
||||||
Ron, Rui, Stefano; #659968, #672192, #673177, #673198, #674323, #675301,
|
|
||||||
#675370, #676347, #676806, #677097]
|
|
||||||
|
|
||||||
Contributors:
|
|
||||||
Alban Browaeys, Giovanni Campagna, Matthias Clasen, Guillaume Desmottes,
|
|
||||||
Piotr Drąg, Stefano Facchini, Rui Matos, Rūdolfs Mazurs, Florian Müllner,
|
|
||||||
Alejandro Piñeiro, Neil Roberts, Alexandre Rostovtsev, Joseph Scheuhammer,
|
|
||||||
Jakub Steiner, Jasper St. Pierre, Ray Strode, Owen Taylor, Rico Tzschichholz,
|
|
||||||
Colin Walters, Dan Winship, Ron Yorston
|
|
||||||
|
|
||||||
Translations:
|
|
||||||
OKANO Takayoshi [ja], Daniel Mustieles [es], Changwoo Ryu [ko],
|
|
||||||
Yaron Shahrabani [he], Fran Diéguez [gl], Jonh Wendell [pt_BR],
|
|
||||||
Kjartan Maraas [nb], Luca Ferretti [it], Tom Tryfonidis [el],
|
|
||||||
Sandeep Sheshrao Shedmake [mr], Takanori MATSUURA [ja], Dirgita [id],
|
|
||||||
Mantas Kriaučiūnas [lt], Matej Urbančič [sl], Jiro Matsuzawa [ja]
|
|
||||||
|
|
||||||
3.4.1
|
3.4.1
|
||||||
=====
|
=====
|
||||||
* Fix crash that occurred when an icon theme change caused unexpected
|
* Fix crash that occurred when an icon theme change caused unexpected
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
"It can be used only by extensions.gnome.org"
|
"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 4
|
#define PLUGIN_API_VERSION 3
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
@@ -163,7 +163,6 @@ NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
|
|||||||
plugin->newp = NPP_New;
|
plugin->newp = NPP_New;
|
||||||
plugin->destroy = NPP_Destroy;
|
plugin->destroy = NPP_Destroy;
|
||||||
plugin->getvalue = NPP_GetValue;
|
plugin->getvalue = NPP_GetValue;
|
||||||
plugin->setwindow = NPP_SetWindow;
|
|
||||||
|
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -268,7 +267,6 @@ typedef struct {
|
|||||||
NPObject parent;
|
NPObject parent;
|
||||||
NPP instance;
|
NPP instance;
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
GSettings *settings;
|
|
||||||
NPObject *listener;
|
NPObject *listener;
|
||||||
NPObject *restart_listener;
|
NPObject *restart_listener;
|
||||||
gint signal_id;
|
gint signal_id;
|
||||||
@@ -325,9 +323,6 @@ on_shell_appeared (GDBusConnection *connection,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHELL_SCHEMA "org.gnome.shell"
|
|
||||||
#define ENABLED_EXTENSIONS_KEY "enabled-extensions"
|
|
||||||
|
|
||||||
static NPObject *
|
static NPObject *
|
||||||
plugin_object_allocate (NPP instance,
|
plugin_object_allocate (NPP instance,
|
||||||
NPClass *klass)
|
NPClass *klass)
|
||||||
@@ -337,7 +332,6 @@ plugin_object_allocate (NPP instance,
|
|||||||
|
|
||||||
obj->instance = instance;
|
obj->instance = instance;
|
||||||
obj->proxy = g_object_ref (data->proxy);
|
obj->proxy = g_object_ref (data->proxy);
|
||||||
obj->settings = g_settings_new (SHELL_SCHEMA);
|
|
||||||
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
|
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
|
||||||
G_CALLBACK (on_shell_signal), obj);
|
G_CALLBACK (on_shell_signal), obj);
|
||||||
|
|
||||||
@@ -498,61 +492,7 @@ plugin_enable_extension (PluginObject *obj,
|
|||||||
NPString uuid,
|
NPString uuid,
|
||||||
gboolean enabled)
|
gboolean enabled)
|
||||||
{
|
{
|
||||||
gboolean ret;
|
|
||||||
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
||||||
gsize length;
|
|
||||||
gchar **uuids;
|
|
||||||
const gchar **new_uuids;
|
|
||||||
|
|
||||||
if (!uuid_is_valid (uuid_str))
|
|
||||||
{
|
|
||||||
g_free (uuid_str);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uuids = g_settings_get_strv (obj->settings, ENABLED_EXTENSIONS_KEY);
|
|
||||||
length = g_strv_length (uuids);
|
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
new_uuids = g_new (const gchar *, length + 2); /* New key, NULL */
|
|
||||||
memcpy (new_uuids, uuids, length * sizeof (*new_uuids));
|
|
||||||
new_uuids[length] = uuid_str;
|
|
||||||
new_uuids[length + 1] = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gsize i = 0, j = 0;
|
|
||||||
new_uuids = g_new (const gchar *, length);
|
|
||||||
for (i = 0; i < length; i ++)
|
|
||||||
{
|
|
||||||
if (g_str_equal (uuids[i], uuid_str))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
new_uuids[j] = uuids[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_uuids[j] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = g_settings_set_strv (obj->settings,
|
|
||||||
ENABLED_EXTENSIONS_KEY,
|
|
||||||
new_uuids);
|
|
||||||
|
|
||||||
g_strfreev (uuids);
|
|
||||||
g_free (new_uuids);
|
|
||||||
g_free (uuid_str);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
plugin_install_extension (PluginObject *obj,
|
|
||||||
NPString uuid)
|
|
||||||
{
|
|
||||||
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
|
||||||
|
|
||||||
if (!uuid_is_valid (uuid_str))
|
if (!uuid_is_valid (uuid_str))
|
||||||
{
|
{
|
||||||
g_free (uuid_str);
|
g_free (uuid_str);
|
||||||
@@ -560,7 +500,7 @@ plugin_install_extension (PluginObject *obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_dbus_proxy_call (obj->proxy,
|
g_dbus_proxy_call (obj->proxy,
|
||||||
"InstallRemoteExtension",
|
(enabled ? "EnableExtension" : "DisableExtension"),
|
||||||
g_variant_new ("(s)", uuid_str),
|
g_variant_new ("(s)", uuid_str),
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1, /* timeout */
|
-1, /* timeout */
|
||||||
@@ -573,6 +513,40 @@ plugin_install_extension (PluginObject *obj,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_install_extension (PluginObject *obj,
|
||||||
|
NPString uuid,
|
||||||
|
NPString version_tag)
|
||||||
|
{
|
||||||
|
gchar *uuid_str = g_strndup (uuid.UTF8Characters, uuid.UTF8Length);
|
||||||
|
gchar *version_tag_str;
|
||||||
|
|
||||||
|
if (!uuid_is_valid (uuid_str))
|
||||||
|
{
|
||||||
|
g_free (uuid_str);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
version_tag_str = g_strndup (version_tag.UTF8Characters,
|
||||||
|
version_tag.UTF8Length);
|
||||||
|
|
||||||
|
g_dbus_proxy_call (obj->proxy,
|
||||||
|
"InstallRemoteExtension",
|
||||||
|
g_variant_new ("(ss)",
|
||||||
|
uuid_str,
|
||||||
|
version_tag_str),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* timeout */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
NULL, /* callback */
|
||||||
|
NULL /* user_data */);
|
||||||
|
|
||||||
|
g_free (uuid_str);
|
||||||
|
g_free (version_tag_str);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
plugin_uninstall_extension (PluginObject *obj,
|
plugin_uninstall_extension (PluginObject *obj,
|
||||||
NPString uuid,
|
NPString uuid,
|
||||||
@@ -797,9 +771,11 @@ plugin_object_invoke (NPObject *npobj,
|
|||||||
else if (name == install_extension_id)
|
else if (name == install_extension_id)
|
||||||
{
|
{
|
||||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||||
|
if (!NPVARIANT_IS_STRING(args[1])) return FALSE;
|
||||||
|
|
||||||
return plugin_install_extension (obj,
|
return plugin_install_extension (obj,
|
||||||
NPVARIANT_TO_STRING(args[0]));
|
NPVARIANT_TO_STRING(args[0]),
|
||||||
|
NPVARIANT_TO_STRING(args[1]));
|
||||||
}
|
}
|
||||||
else if (name == uninstall_extension_id)
|
else if (name == uninstall_extension_id)
|
||||||
{
|
{
|
||||||
@@ -970,12 +946,3 @@ NPP_GetValue(NPP instance,
|
|||||||
|
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opera tries to call NPP_SetWindow without checking the
|
|
||||||
* NULL pointer beforehand. */
|
|
||||||
NPError
|
|
||||||
NPP_SetWindow(NPP instance,
|
|
||||||
NPWindow *window)
|
|
||||||
{
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|||||||
69
configure.ac
69
configure.ac
@@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.5.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.4.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
@@ -62,47 +62,28 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
|||||||
|
|
||||||
CLUTTER_MIN_VERSION=1.9.16
|
CLUTTER_MIN_VERSION=1.9.16
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=1.33.2
|
GJS_MIN_VERSION=1.29.18
|
||||||
MUTTER_MIN_VERSION=3.5.3
|
MUTTER_MIN_VERSION=3.4.1
|
||||||
FOLKS_MIN_VERSION=0.5.2
|
FOLKS_MIN_VERSION=0.5.2
|
||||||
GTK_MIN_VERSION=3.3.9
|
GTK_MIN_VERSION=3.3.9
|
||||||
GIO_MIN_VERSION=2.31.6
|
GIO_MIN_VERSION=2.31.6
|
||||||
LIBECAL_MIN_VERSION=3.5.3
|
LIBECAL_MIN_VERSION=2.32.0
|
||||||
LIBEDATASERVER_MIN_VERSION=3.5.3
|
LIBEDATASERVER_MIN_VERSION=1.2.0
|
||||||
LIBEDATASERVERUI_MIN_VERSION=3.5.3
|
LIBEDATASERVERUI_MIN_VERSION=2.91.6
|
||||||
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
||||||
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
|
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
|
||||||
POLKIT_MIN_VERSION=0.100
|
POLKIT_MIN_VERSION=0.100
|
||||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||||
GCR_MIN_VERSION=3.3.90
|
GCR_MIN_VERSION=3.3.90
|
||||||
GNOME_DESKTOP_REQUIRED_VERSION=3.5.1
|
|
||||||
GNOME_MENUS_REQUIRED_VERSION=3.5.3
|
|
||||||
|
|
||||||
AC_ARG_WITH(folks,
|
|
||||||
AS_HELP_STRING([--with-folks],
|
|
||||||
[Enable folks support]),
|
|
||||||
[with_folks=$withval], [with_folks=yes])
|
|
||||||
|
|
||||||
if test x${with_folks} = xyes; then
|
|
||||||
FOLKS_REQUIREMENT="folks >= $FOLKS_MIN_VERSION"
|
|
||||||
AC_DEFINE([HAVE_FOLKS], [1], [folks support])
|
|
||||||
AC_SUBST([HAVE_FOLKS],[1])
|
|
||||||
else
|
|
||||||
FOLKS_REQUIREMENT=
|
|
||||||
AC_SUBST([HAVE_FOLKS],[0])
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(BUILD_WITH_FOLKS, test x${with_folks} = xyes)
|
|
||||||
|
|
||||||
# Collect more than 20 libraries for a prize!
|
# Collect more than 20 libraries for a prize!
|
||||||
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||||
libxml-2.0
|
libxml-2.0
|
||||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||||
atk-bridge-2.0
|
folks >= $FOLKS_MIN_VERSION
|
||||||
$FOLKS_REQUIREMENT
|
|
||||||
libmutter >= $MUTTER_MIN_VERSION
|
libmutter >= $MUTTER_MIN_VERSION
|
||||||
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
||||||
libgnome-menu-3.0 >= $GNOME_MENUS_REQUIRED_VERSION
|
libgnome-menu-3.0 $recorder_modules
|
||||||
$recorder_modules
|
|
||||||
gdk-x11-3.0 libsoup-2.4
|
gdk-x11-3.0 libsoup-2.4
|
||||||
gl
|
gl
|
||||||
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
@@ -114,8 +95,7 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
|||||||
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
||||||
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
||||||
libnm-glib libnm-util gnome-keyring-1
|
libnm-glib libnm-util gnome-keyring-1
|
||||||
gcr-3 >= $GCR_MIN_VERSION
|
gcr-3 >= $GCR_MIN_VERSION)
|
||||||
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION)
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||||
|
|
||||||
@@ -123,6 +103,10 @@ PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
|||||||
|
|
||||||
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
||||||
|
|
||||||
|
GJS_VERSION=`$PKG_CONFIG --modversion gjs-internals-1.0`
|
||||||
|
AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're linking to])
|
||||||
|
AC_SUBST([GJS_VERSION], ["$GJS_VERSION"])
|
||||||
|
|
||||||
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
||||||
|
|
||||||
saved_CFLAGS=$CFLAGS
|
saved_CFLAGS=$CFLAGS
|
||||||
@@ -137,7 +121,7 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
|
|||||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 x11)
|
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 x11)
|
||||||
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
||||||
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
|
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
|
||||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.1)
|
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 0.1.7)
|
||||||
|
|
||||||
AC_MSG_CHECKING([for bluetooth support])
|
AC_MSG_CHECKING([for bluetooth support])
|
||||||
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
||||||
@@ -253,6 +237,31 @@ AC_ARG_ENABLE(jhbuild-wrapper-script,
|
|||||||
AS_HELP_STRING([--enable-jhbuild-wrapper-script],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
|
AS_HELP_STRING([--enable-jhbuild-wrapper-script],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
|
||||||
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
|
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([location of system Certificate Authority list])
|
||||||
|
AC_ARG_WITH(ca-certificates,
|
||||||
|
[AC_HELP_STRING([--with-ca-certificates=@<:@path@:>@],
|
||||||
|
[path to system Certificate Authority list])])
|
||||||
|
|
||||||
|
if test "$with_ca_certificates" = "no"; then
|
||||||
|
AC_MSG_RESULT([disabled])
|
||||||
|
else
|
||||||
|
if test -z "$with_ca_certificates"; then
|
||||||
|
for f in /etc/pki/tls/certs/ca-bundle.crt \
|
||||||
|
/etc/ssl/certs/ca-certificates.crt; do
|
||||||
|
if test -f "$f"; then
|
||||||
|
with_ca_certificates="$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test -z "$with_ca_certificates"; then
|
||||||
|
AC_MSG_ERROR([could not find. Use --with-ca-certificates=path to set, or --without-ca-certificates to disable])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT($with_ca_certificates)
|
||||||
|
AC_DEFINE_UNQUOTED(SHELL_SYSTEM_CA_FILE, ["$with_ca_certificates"], [The system TLS CA list])
|
||||||
|
fi
|
||||||
|
AC_SUBST(SHELL_SYSTEM_CA_FILE,["$with_ca_certificates"])
|
||||||
|
|
||||||
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
|
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
|
||||||
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
|
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
|
||||||
|
|
||||||
|
|||||||
@@ -53,14 +53,9 @@ dist_theme_DATA = \
|
|||||||
theme/ws-switch-arrow-up.svg \
|
theme/ws-switch-arrow-up.svg \
|
||||||
theme/ws-switch-arrow-down.svg
|
theme/ws-switch-arrow-down.svg
|
||||||
|
|
||||||
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
|
gsettings_SCHEMAS = org.gnome.shell.gschema.xml org.gnome.shell.evolution.calendar.gschema.xml
|
||||||
|
|
||||||
@INTLTOOL_XML_NOMERGE_RULE@
|
@INTLTOOL_XML_NOMERGE_RULE@
|
||||||
|
|
||||||
%.gschema.xml.in: %.gschema.xml.in.in Makefile
|
|
||||||
$(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \
|
|
||||||
$< > $@ || rm $@
|
|
||||||
|
|
||||||
@GSETTINGS_RULES@
|
@GSETTINGS_RULES@
|
||||||
|
|
||||||
# We need to compile schemas at make time
|
# We need to compile schemas at make time
|
||||||
@@ -85,13 +80,13 @@ EXTRA_DIST = \
|
|||||||
$(menu_DATA) \
|
$(menu_DATA) \
|
||||||
$(shaders_DATA) \
|
$(shaders_DATA) \
|
||||||
$(convert_DATA) \
|
$(convert_DATA) \
|
||||||
org.gnome.shell.gschema.xml.in.in
|
org.gnome.shell.evolution.calendar.gschema.xml.in \
|
||||||
|
org.gnome.shell.gschema.xml.in
|
||||||
|
|
||||||
CLEANFILES = \
|
CLEANFILES = \
|
||||||
gnome-shell.desktop.in \
|
gnome-shell.desktop.in \
|
||||||
gnome-shell-extension-prefs.in \
|
gnome-shell-extension-prefs.in \
|
||||||
$(desktop_DATA) \
|
$(desktop_DATA) \
|
||||||
$(gsettings_SCHEMAS) \
|
$(gsettings_SCHEMAS) \
|
||||||
gschemas.compiled \
|
gschemas.compiled
|
||||||
org.gnome.shell.gschema.valid \
|
|
||||||
org.gnome.shell.gschema.xml.in
|
|
||||||
|
|||||||
21
data/org.gnome.shell.evolution.calendar.gschema.xml.in
Normal file
21
data/org.gnome.shell.evolution.calendar.gschema.xml.in
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- NOTE: This schema is a GNOME 3.4 workaround - it uses the same path
|
||||||
|
as org.gnome.evolution.calendar, but avoids us requiring Evolution
|
||||||
|
be installed. In GNOME 3.6 the selected state will become a flag
|
||||||
|
on the calendar. Because the translations are in Evolution,
|
||||||
|
this is untranslated and in POTFILES.skip.
|
||||||
|
-->
|
||||||
|
<schemalist>
|
||||||
|
<schema path="/org/gnome/evolution/calendar/" id="org.gnome.shell.evolution.calendar" gettext-domain="evolution">
|
||||||
|
<key type="as" name="selected-calendars">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>List of selected calendars</summary>
|
||||||
|
<description>List of calendars to load</description>
|
||||||
|
</key>
|
||||||
|
<key type="as" name="selected-tasks">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>List of selected task lists</summary>
|
||||||
|
<description>List of task lists to load</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
||||||
@@ -61,6 +61,7 @@ value here is from the TpConnectionPresenceType enumeration.</_summary>
|
|||||||
<_summary>Internally used to store the last session presence status for the user. The
|
<_summary>Internally used to store the last session presence status for the user. The
|
||||||
value here is from the GsmPresenceStatus enumeration.</_summary>
|
value here is from the GsmPresenceStatus enumeration.</_summary>
|
||||||
</key>
|
</key>
|
||||||
|
<child name="clock" schema="org.gnome.shell.clock"/>
|
||||||
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
||||||
<child name="recorder" schema="org.gnome.shell.recorder"/>
|
<child name="recorder" schema="org.gnome.shell.recorder"/>
|
||||||
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
||||||
@@ -107,6 +108,24 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
|
|||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.clock" path="/org/gnome/shell/clock/"
|
||||||
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
|
<key name="show-seconds" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<_summary>Show time with seconds</_summary>
|
||||||
|
<_description>
|
||||||
|
If true, display seconds in time.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="show-date" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<_summary>Show date in clock</_summary>
|
||||||
|
<_description>
|
||||||
|
If true, display date in the clock, in addition to time.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
<schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
|
<schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
<key name="framerate" type="i">
|
<key name="framerate" type="i">
|
||||||
@@ -328,11 +328,6 @@ StScrollBar StButton#vhandle:hover
|
|||||||
background-gradient-end: rgba(255, 255, 255, 0.2);
|
background-gradient-end: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification-icon-button:insensitive,
|
|
||||||
.notification-button:insensitive {
|
|
||||||
color: #9f9f9f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Panel */
|
/* Panel */
|
||||||
|
|
||||||
#panel {
|
#panel {
|
||||||
@@ -362,7 +357,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
}
|
}
|
||||||
|
|
||||||
.panel-corner {
|
.panel-corner {
|
||||||
-panel-corner-radius: 6px;
|
-panel-corner-radius: 10px;
|
||||||
-panel-corner-background-color: black;
|
-panel-corner-background-color: black;
|
||||||
-panel-corner-border-width: 2px;
|
-panel-corner-border-width: 2px;
|
||||||
-panel-corner-border-color: transparent;
|
-panel-corner-border-color: transparent;
|
||||||
@@ -414,7 +409,7 @@ StScrollBar StButton#vhandle:hover
|
|||||||
.panel-button:active,
|
.panel-button:active,
|
||||||
.panel-button:overview,
|
.panel-button:overview,
|
||||||
.panel-button:focus {
|
.panel-button:focus {
|
||||||
border-image: url("panel-button-border.svg") 6 10 0 2;
|
border-image: url("panel-button-border.svg") 10 10 0 2;
|
||||||
background-image: url("panel-button-highlight-wide.svg");
|
background-image: url("panel-button-highlight-wide.svg");
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: black 0px 2px 2px;
|
text-shadow: black 0px 2px 2px;
|
||||||
@@ -436,10 +431,6 @@ StScrollBar StButton#vhandle:hover
|
|||||||
-boxpointer-gap: 4px
|
-boxpointer-gap: 4px
|
||||||
}
|
}
|
||||||
|
|
||||||
#networkMenu {
|
|
||||||
spacing: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* User Menu */
|
/* User Menu */
|
||||||
|
|
||||||
#panelUserMenu {
|
#panelUserMenu {
|
||||||
@@ -1952,12 +1943,10 @@ StScrollBar StButton#vhandle:hover
|
|||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
/* intentionally left transparent to avoid dialog changing size */
|
||||||
color: rgba(0,0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.prompt-dialog-null-label {
|
.prompt-dialog-null-label {
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
|
color: rgba(0,0,0,0);
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2051,3 +2040,30 @@ StScrollBar StButton#vhandle:hover
|
|||||||
-arrow-rise: 10px;
|
-arrow-rise: 10px;
|
||||||
-boxpointer-gap: 5px;
|
-boxpointer-gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Candidate Window */
|
||||||
|
.candidate-panel {
|
||||||
|
min-width: 100px;
|
||||||
|
padding: .5em;
|
||||||
|
spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candidate-area {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candidate-label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candidate-hlabel-content {
|
||||||
|
padding: 0em .5em 0em 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candidate-htext-content {
|
||||||
|
padding: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.candidate-vcontent {
|
||||||
|
padding: 0em .5em 0em 0em;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="17"
|
width="21"
|
||||||
height="10"
|
height="10"
|
||||||
id="svg2"
|
id="svg2"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
@@ -66,9 +66,9 @@
|
|||||||
<rect
|
<rect
|
||||||
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
id="rect3796"
|
id="rect3796"
|
||||||
width="7"
|
width="3"
|
||||||
height="2"
|
height="2"
|
||||||
x="5"
|
x="9"
|
||||||
y="8" />
|
y="8" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -6,8 +6,9 @@ misc/config.js: misc/config.js.in Makefile
|
|||||||
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
|
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
|
||||||
sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \
|
sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \
|
||||||
-e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \
|
-e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \
|
||||||
-e "s|[@]HAVE_FOLKS@|$(HAVE_FOLKS)|g" \
|
-e "s|[@]GJS_VERSION@|$(GJS_VERSION)|g" \
|
||||||
-e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \
|
-e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \
|
||||||
|
-e "s|[@]SHELL_SYSTEM_CA_FILE@|$(SHELL_SYSTEM_CA_FILE)|g" \
|
||||||
-e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
|
-e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \
|
||||||
-e "s|[@]datadir@|$(datadir)|g" \
|
-e "s|[@]datadir@|$(datadir)|g" \
|
||||||
-e "s|[@]libexecdir@|$(libexecdir)|g" \
|
-e "s|[@]libexecdir@|$(libexecdir)|g" \
|
||||||
@@ -27,6 +28,7 @@ nobase_dist_js_DATA = \
|
|||||||
misc/config.js \
|
misc/config.js \
|
||||||
misc/extensionUtils.js \
|
misc/extensionUtils.js \
|
||||||
misc/fileUtils.js \
|
misc/fileUtils.js \
|
||||||
|
misc/format.js \
|
||||||
misc/gnomeSession.js \
|
misc/gnomeSession.js \
|
||||||
misc/history.js \
|
misc/history.js \
|
||||||
misc/jsParse.js \
|
misc/jsParse.js \
|
||||||
@@ -51,7 +53,6 @@ nobase_dist_js_DATA = \
|
|||||||
ui/endSessionDialog.js \
|
ui/endSessionDialog.js \
|
||||||
ui/environment.js \
|
ui/environment.js \
|
||||||
ui/extensionSystem.js \
|
ui/extensionSystem.js \
|
||||||
ui/extensionDownloader.js \
|
|
||||||
ui/flashspot.js \
|
ui/flashspot.js \
|
||||||
ui/iconGrid.js \
|
ui/iconGrid.js \
|
||||||
ui/keyboard.js \
|
ui/keyboard.js \
|
||||||
@@ -66,7 +67,6 @@ nobase_dist_js_DATA = \
|
|||||||
ui/messageTray.js \
|
ui/messageTray.js \
|
||||||
ui/modalDialog.js \
|
ui/modalDialog.js \
|
||||||
ui/networkAgent.js \
|
ui/networkAgent.js \
|
||||||
ui/sessionMode.js \
|
|
||||||
ui/shellEntry.js \
|
ui/shellEntry.js \
|
||||||
ui/shellMountOperation.js \
|
ui/shellMountOperation.js \
|
||||||
ui/notificationDaemon.js \
|
ui/notificationDaemon.js \
|
||||||
@@ -84,6 +84,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/shellDBus.js \
|
ui/shellDBus.js \
|
||||||
ui/statusIconDispatcher.js \
|
ui/statusIconDispatcher.js \
|
||||||
ui/status/accessibility.js \
|
ui/status/accessibility.js \
|
||||||
|
ui/status/candidatePanel.js \
|
||||||
ui/status/keyboard.js \
|
ui/status/keyboard.js \
|
||||||
ui/status/network.js \
|
ui/status/network.js \
|
||||||
ui/status/power.js \
|
ui/status/power.js \
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ const GObject = imports.gi.GObject;
|
|||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const Format = imports.format;
|
|
||||||
|
|
||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
|
const Format = imports.misc.format;
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
|
|
||||||
|
|
||||||
@@ -202,17 +202,23 @@ const Application = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_scanExtensions: function() {
|
_scanExtensions: function() {
|
||||||
let finder = new ExtensionUtils.ExtensionFinder();
|
ExtensionUtils.scanExtensions(Lang.bind(this, function(uuid, dir, type) {
|
||||||
finder.connect('extension-found', Lang.bind(this, this._extensionFound));
|
if (ExtensionUtils.extensions[uuid] !== undefined)
|
||||||
finder.scanExtensions();
|
return;
|
||||||
},
|
|
||||||
|
|
||||||
_extensionFound: function(signals, extension) {
|
let extension;
|
||||||
let iter = this._model.append();
|
try {
|
||||||
this._model.set(iter, [0, 1], [extension.uuid, extension.metadata.name]);
|
extension = ExtensionUtils.createExtensionObject(uuid, dir, type);
|
||||||
this._extensionIters[uuid] = iter;
|
} catch(e) {
|
||||||
},
|
global.logError('' + e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let iter = this._model.append();
|
||||||
|
this._model.set(iter, [0, 1], [uuid, extension.metadata.name]);
|
||||||
|
this._extensionIters[uuid] = iter;
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
_onActivate: function() {
|
_onActivate: function() {
|
||||||
this._window.present();
|
this._window.present();
|
||||||
@@ -251,7 +257,7 @@ function initEnvironment() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
logError: function(s) {
|
logError: function(s) {
|
||||||
log('ERROR: ' + s);
|
global.log('ERROR: ' + s);
|
||||||
},
|
},
|
||||||
|
|
||||||
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell'])
|
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell'])
|
||||||
@@ -262,6 +268,7 @@ function initEnvironment() {
|
|||||||
|
|
||||||
function main(argv) {
|
function main(argv) {
|
||||||
initEnvironment();
|
initEnvironment();
|
||||||
|
ExtensionUtils.init();
|
||||||
|
|
||||||
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
||||||
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
||||||
/* The version of this package */
|
/* The version of this package */
|
||||||
const PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
const PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
||||||
|
/* The version of GJS we're linking to */
|
||||||
|
const GJS_VERSION = '@GJS_VERSION@';
|
||||||
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
||||||
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
||||||
/* 1 if folks is available, 0 otherwise */
|
/* The system TLS CA list */
|
||||||
const HAVE_FOLKS = @HAVE_FOLKS@;
|
const SHELL_SYSTEM_CA_FILE = '@SHELL_SYSTEM_CA_FILE@';
|
||||||
/* gettext package */
|
/* gettext package */
|
||||||
const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
|
const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
|
||||||
/* locale dir */
|
/* locale dir */
|
||||||
|
|||||||
@@ -3,9 +3,6 @@
|
|||||||
// Common utils for the extension system and the extension
|
// Common utils for the extension system and the extension
|
||||||
// preferences tool
|
// preferences tool
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Signals = imports.signals;
|
|
||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const ShellJS = imports.gi.ShellJS;
|
const ShellJS = imports.gi.ShellJS;
|
||||||
@@ -17,6 +14,9 @@ const ExtensionType = {
|
|||||||
PER_USER: 2
|
PER_USER: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// GFile for user extensions
|
||||||
|
var userExtensionsDir = null;
|
||||||
|
|
||||||
// Maps uuid -> metadata object
|
// Maps uuid -> metadata object
|
||||||
const extensions = {};
|
const extensions = {};
|
||||||
|
|
||||||
@@ -40,18 +40,13 @@ function getCurrentExtension() {
|
|||||||
throw new Error('Could not find current extension');
|
throw new Error('Could not find current extension');
|
||||||
|
|
||||||
let path = match[1];
|
let path = match[1];
|
||||||
let file = Gio.File.new_for_path(path);
|
let uuid = GLib.path_get_basename(GLib.path_get_dirname(path));
|
||||||
|
|
||||||
// Walk up the directory tree, looking for an extesion with
|
let extension = extensions[uuid];
|
||||||
// the same UUID as a directory name.
|
if (extension === undefined)
|
||||||
while (file != null) {
|
throw new Error('Could not find current extension');
|
||||||
let extension = extensions[file.get_basename()];
|
|
||||||
if (extension !== undefined)
|
|
||||||
return extension;
|
|
||||||
file = file.get_parent();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error('Could not find current extension');
|
return extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,6 +83,9 @@ function isOutOfDate(extension) {
|
|||||||
if (!versionCheck(extension.metadata['shell-version'], Config.PACKAGE_VERSION))
|
if (!versionCheck(extension.metadata['shell-version'], Config.PACKAGE_VERSION))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (extension.metadata['js-version'] && !versionCheck(extension.metadata['js-version'], Config.GJS_VERSION))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +120,7 @@ function createExtensionObject(uuid, dir, type) {
|
|||||||
|
|
||||||
// Encourage people to add this
|
// Encourage people to add this
|
||||||
if (!meta.url) {
|
if (!meta.url) {
|
||||||
log('Warning: Missing "url" property in %s/metadata.json'.format(uuid));
|
global.log('Warning: Missing "url" property in metadata.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uuid != meta.uuid) {
|
if (uuid != meta.uuid) {
|
||||||
@@ -152,48 +150,45 @@ function installImporter(extension) {
|
|||||||
_extension = null;
|
_extension = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExtensionFinder = new Lang.Class({
|
function init() {
|
||||||
Name: 'ExtensionFinder',
|
let userExtensionsPath = GLib.build_filenamev([global.userdatadir, 'extensions']);
|
||||||
|
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
|
||||||
_scanExtensionsInDirectory: function(dir, type) {
|
try {
|
||||||
let fileEnum;
|
if (!userExtensionsDir.query_exists(null))
|
||||||
let file, info;
|
userExtensionsDir.make_directory_with_parents(null);
|
||||||
try {
|
} catch (e) {
|
||||||
fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
|
global.logError('' + e);
|
||||||
} catch(e) {
|
|
||||||
logError(e, 'Could not enumerate extensions directory');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((info = fileEnum.next_file(null)) != null) {
|
|
||||||
let fileType = info.get_file_type();
|
|
||||||
if (fileType != Gio.FileType.DIRECTORY)
|
|
||||||
continue;
|
|
||||||
let uuid = info.get_name();
|
|
||||||
let extensionDir = dir.get_child(uuid);
|
|
||||||
|
|
||||||
let existing = extensions[uuid];
|
|
||||||
if (existing) {
|
|
||||||
log('Extension %s already installed in %s. %s will not be loaded'.format(uuid, existing.path, extensionDir.get_path()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let extension = createExtensionObject(uuid, extensionDir, type);
|
|
||||||
this.emit('extension-found', extension);
|
|
||||||
}
|
|
||||||
fileEnum.close(null);
|
|
||||||
},
|
|
||||||
|
|
||||||
scanExtensions: function() {
|
|
||||||
let userExtensionsDir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions']));
|
|
||||||
this._scanExtensionsInDirectory(userExtensionsDir, ExtensionType.PER_USER);
|
|
||||||
|
|
||||||
let systemDataDirs = GLib.get_system_data_dirs();
|
|
||||||
for (let i = 0; i < systemDataDirs.length; i++) {
|
|
||||||
let dirPath = GLib.build_filenamev([systemDataDirs[i], 'gnome-shell', 'extensions']);
|
|
||||||
let dir = Gio.file_new_for_path(dirPath);
|
|
||||||
if (dir.query_exists(null))
|
|
||||||
this._scanExtensionsInDirectory(dir, ExtensionType.SYSTEM);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
Signals.addSignalMethods(ExtensionFinder.prototype);
|
|
||||||
|
function scanExtensionsInDirectory(callback, dir, type) {
|
||||||
|
let fileEnum;
|
||||||
|
let file, info;
|
||||||
|
try {
|
||||||
|
fileEnum = dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null);
|
||||||
|
} catch(e) {
|
||||||
|
global.logError('' + e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((info = fileEnum.next_file(null)) != null) {
|
||||||
|
let fileType = info.get_file_type();
|
||||||
|
if (fileType != Gio.FileType.DIRECTORY)
|
||||||
|
continue;
|
||||||
|
let uuid = info.get_name();
|
||||||
|
let extensionDir = dir.get_child(uuid);
|
||||||
|
callback(uuid, extensionDir, type);
|
||||||
|
}
|
||||||
|
fileEnum.close(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function scanExtensions(callback) {
|
||||||
|
let systemDataDirs = GLib.get_system_data_dirs();
|
||||||
|
scanExtensionsInDirectory(callback, userExtensionsDir, ExtensionType.PER_USER);
|
||||||
|
for (let i = 0; i < systemDataDirs.length; i++) {
|
||||||
|
let dirPath = GLib.build_filenamev([systemDataDirs[i], 'gnome-shell', 'extensions']);
|
||||||
|
let dir = Gio.file_new_for_path(dirPath);
|
||||||
|
if (dir.query_exists(null))
|
||||||
|
scanExtensionsInDirectory(callback, dir, ExtensionType.SYSTEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
71
js/misc/format.js
Normal file
71
js/misc/format.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const ShellJS = imports.gi.ShellJS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended to extend the String object and provide
|
||||||
|
* an String.format API for string formatting.
|
||||||
|
* It has to be set up using String.prototype.format = Format.format;
|
||||||
|
* Usage:
|
||||||
|
* "somestring %s %d".format('hello', 5);
|
||||||
|
* It supports %s, %d, %x and %f, for %f it also support precisions like
|
||||||
|
* "%.2f".format(1.526). All specifiers can be prefixed with a minimum
|
||||||
|
* field width, e.g. "%5s".format("foo"). Unless the width is prefixed
|
||||||
|
* with '0', the formatted string will be padded with spaces.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function format() {
|
||||||
|
let str = this;
|
||||||
|
let i = 0;
|
||||||
|
let args = arguments;
|
||||||
|
|
||||||
|
return str.replace(/%(I+)?([0-9]+)?(?:\.([0-9]+))?(.)/g, function (str, flagsGroup, widthGroup, precisionGroup, genericGroup) {
|
||||||
|
|
||||||
|
if (precisionGroup != '' && genericGroup != 'f')
|
||||||
|
throw new Error("Precision can only be specified for 'f'");
|
||||||
|
|
||||||
|
let hasAlternativeIntFlag = (flagsGroup.indexOf('I') != -1);
|
||||||
|
|
||||||
|
if (hasAlternativeIntFlag && genericGroup != 'd')
|
||||||
|
throw new Error("Alternative output digits can only be specfied for 'd'");
|
||||||
|
|
||||||
|
let fillChar = (widthGroup[0] == '0') ? '0' : ' ';
|
||||||
|
let width = parseInt(widthGroup, 10) || 0;
|
||||||
|
|
||||||
|
function fillWidth(s, c, w) {
|
||||||
|
let fill = '';
|
||||||
|
for (let i = 0; i < w; i++)
|
||||||
|
fill += c;
|
||||||
|
return fill.substr(s.length) + s;
|
||||||
|
}
|
||||||
|
|
||||||
|
let s = '';
|
||||||
|
switch (genericGroup) {
|
||||||
|
case '%':
|
||||||
|
return '%';
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
s = args[i++].toString();
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
let intV = parseInt(args[i++]);
|
||||||
|
if (hasAlternativeIntFlag)
|
||||||
|
s = ShellJS.format_int_alternative_output(intV);
|
||||||
|
else
|
||||||
|
s = intV.toString();
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
s = parseInt(args[i++]).toString(16);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
if (precisionGroup == '')
|
||||||
|
s = parseFloat(args[i++]).toString();
|
||||||
|
else
|
||||||
|
s = parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported conversion character %' + genericGroup);
|
||||||
|
}
|
||||||
|
return fillWidth(s, fillChar, width);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -83,33 +83,24 @@ function spawnCommandLine(command_line) {
|
|||||||
// this will throw an error.
|
// this will throw an error.
|
||||||
function trySpawn(argv)
|
function trySpawn(argv)
|
||||||
{
|
{
|
||||||
var success, pid;
|
|
||||||
try {
|
try {
|
||||||
[success, pid] = GLib.spawn_async(null, argv, null,
|
GLib.spawn_async(null, argv, null,
|
||||||
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
GLib.SpawnFlags.SEARCH_PATH,
|
||||||
null, null);
|
null, null);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
/* Rewrite the error in case of ENOENT */
|
if (err.code == GLib.SpawnError.G_SPAWN_ERROR_NOENT) {
|
||||||
if (err.matches(GLib.SpawnError, GLib.SpawnError.NOENT)) {
|
err.message = _("Command not found");
|
||||||
throw new GLib.SpawnError({ code: GLib.SpawnError.NOENT,
|
} else {
|
||||||
message: _("Command not found") });
|
|
||||||
} else if (err instanceof GLib.Error) {
|
|
||||||
// The exception from gjs contains an error string like:
|
// The exception from gjs contains an error string like:
|
||||||
// Error invoking GLib.spawn_command_line_async: Failed to
|
// Error invoking GLib.spawn_command_line_async: Failed to
|
||||||
// execute child process "foo" (No such file or directory)
|
// execute child process "foo" (No such file or directory)
|
||||||
// We are only interested in the part in the parentheses. (And
|
// We are only interested in the part in the parentheses. (And
|
||||||
// we can't pattern match the text, since it gets localized.)
|
// we can't pattern match the text, since it gets localized.)
|
||||||
let message = err.message.replace(/.*\((.+)\)/, '$1');
|
err.message = err.message.replace(/.*\((.+)\)/, '$1');
|
||||||
throw new (err.constructor)({ code: err.code,
|
|
||||||
message: message });
|
|
||||||
} else {
|
|
||||||
throw err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
// 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 () {}, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// trySpawnCommandLine:
|
// trySpawnCommandLine:
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ const Search = imports.ui.search;
|
|||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const Workspace = imports.ui.workspace;
|
const Workspace = imports.ui.workspace;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const Util = imports.misc.util;
|
|
||||||
|
|
||||||
const MAX_APPLICATION_WORK_MILLIS = 75;
|
const MAX_APPLICATION_WORK_MILLIS = 75;
|
||||||
const MENU_POPUP_TIMEOUT = 600;
|
const MENU_POPUP_TIMEOUT = 600;
|
||||||
@@ -37,7 +36,6 @@ const AlphabeticalView = new Lang.Class({
|
|||||||
|
|
||||||
this._pendingAppLaterId = 0;
|
this._pendingAppLaterId = 0;
|
||||||
this._appIcons = {}; // desktop file id
|
this._appIcons = {}; // desktop file id
|
||||||
this._allApps = [];
|
|
||||||
|
|
||||||
let box = new St.BoxLayout({ vertical: true });
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
|
box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
|
||||||
@@ -62,22 +60,16 @@ const AlphabeticalView = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
removeAll: function() {
|
_removeAll: function() {
|
||||||
this._grid.removeAll();
|
this._grid.removeAll();
|
||||||
this._appIcons = {};
|
this._appIcons = {};
|
||||||
this._allApps = [];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addApp: function(app) {
|
_addApp: function(app) {
|
||||||
var id = app.get_id();
|
var id = app.get_id();
|
||||||
if (this._appIcons[id] !== undefined)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let appIcon = new AppWellIcon(app);
|
let appIcon = new AppWellIcon(app);
|
||||||
let pos = Util.insertSorted(this._allApps, app, function(a, b) {
|
|
||||||
return a.compare_by_name(b);
|
this._grid.addItem(appIcon.actor);
|
||||||
});
|
|
||||||
this._grid.addItem(appIcon.actor, pos);
|
|
||||||
appIcon.actor.connect('key-focus-in', Lang.bind(this, this._ensureIconVisible));
|
appIcon.actor.connect('key-focus-in', Lang.bind(this, this._ensureIconVisible));
|
||||||
|
|
||||||
this._appIcons[id] = appIcon;
|
this._appIcons[id] = appIcon;
|
||||||
@@ -128,6 +120,14 @@ const AlphabeticalView = new Lang.Class({
|
|||||||
icon.actor.visible = true;
|
icon.actor.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setAppList: function(apps) {
|
||||||
|
this._removeAll();
|
||||||
|
for (var i = 0; i < apps.length; i++) {
|
||||||
|
var app = apps[i];
|
||||||
|
this._addApp(app);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -147,6 +147,7 @@ const ViewByCategories = new Lang.Class({
|
|||||||
// (used only before the actor is mapped the first time)
|
// (used only before the actor is mapped the first time)
|
||||||
this._currentCategory = -2;
|
this._currentCategory = -2;
|
||||||
this._categories = [];
|
this._categories = [];
|
||||||
|
this._apps = null;
|
||||||
|
|
||||||
this._categoryBox = new St.BoxLayout({ vertical: true,
|
this._categoryBox = new St.BoxLayout({ vertical: true,
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@@ -203,19 +204,16 @@ const ViewByCategories = new Lang.Class({
|
|||||||
if (nextType == GMenu.TreeItemType.ENTRY) {
|
if (nextType == GMenu.TreeItemType.ENTRY) {
|
||||||
var entry = iter.get_entry();
|
var entry = iter.get_entry();
|
||||||
var app = this._appSystem.lookup_app_by_tree_entry(entry);
|
var app = this._appSystem.lookup_app_by_tree_entry(entry);
|
||||||
if (!entry.get_app_info().get_nodisplay()) {
|
if (!entry.get_app_info().get_nodisplay())
|
||||||
this._view.addApp(app);
|
|
||||||
appList.push(app);
|
appList.push(app);
|
||||||
}
|
|
||||||
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||||
var itemDir = iter.get_directory();
|
if (!dir.get_is_nodisplay())
|
||||||
if (!itemDir.get_is_nodisplay())
|
this._loadCategory(iter.get_directory(), appList);
|
||||||
this._loadCategory(itemDir, appList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_addCategory: function(name, index, dir) {
|
_addCategory: function(name, index, dir, allApps) {
|
||||||
let button = new St.Button({ label: GLib.markup_escape_text (name, -1),
|
let button = new St.Button({ label: GLib.markup_escape_text (name, -1),
|
||||||
style_class: 'app-filter',
|
style_class: 'app-filter',
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
@@ -227,6 +225,7 @@ const ViewByCategories = new Lang.Class({
|
|||||||
|
|
||||||
var apps;
|
var apps;
|
||||||
if (dir == null) {
|
if (dir == null) {
|
||||||
|
apps = allApps;
|
||||||
this._allCategoryButton = button;
|
this._allCategoryButton = button;
|
||||||
} else {
|
} else {
|
||||||
apps = [];
|
apps = [];
|
||||||
@@ -240,7 +239,6 @@ const ViewByCategories = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_removeAll: function() {
|
_removeAll: function() {
|
||||||
this._view.removeAll();
|
|
||||||
this._categories = [];
|
this._categories = [];
|
||||||
this._categoryBox.destroy_all_children();
|
this._categoryBox.destroy_all_children();
|
||||||
},
|
},
|
||||||
@@ -248,8 +246,13 @@ const ViewByCategories = new Lang.Class({
|
|||||||
refresh: function() {
|
refresh: function() {
|
||||||
this._removeAll();
|
this._removeAll();
|
||||||
|
|
||||||
|
var allApps = Shell.AppSystem.get_default().get_all();
|
||||||
|
allApps.sort(function(a, b) {
|
||||||
|
return a.compare_by_name(b);
|
||||||
|
});
|
||||||
|
|
||||||
/* Translators: Filter to display all applications */
|
/* Translators: Filter to display all applications */
|
||||||
this._addCategory(_("All"), -1, null);
|
this._addCategory(_("All"), -1, null, allApps);
|
||||||
|
|
||||||
var tree = this._appSystem.get_tree();
|
var tree = this._appSystem.get_tree();
|
||||||
var root = tree.get_root_directory();
|
var root = tree.get_root_directory();
|
||||||
@@ -267,6 +270,7 @@ const ViewByCategories = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._view.setAppList(allApps);
|
||||||
this._selectCategory(-1);
|
this._selectCategory(-1);
|
||||||
|
|
||||||
if (this._focusDummy) {
|
if (this._focusDummy) {
|
||||||
@@ -308,10 +312,11 @@ const AppSearchProvider = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("APPLICATIONS"));
|
this.parent(_("APPLICATIONS"));
|
||||||
|
|
||||||
this._appSys = Shell.AppSystem.get_default();
|
this._appSys = Shell.AppSystem.get_default();
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(apps, callback) {
|
getResultMetas: function(apps) {
|
||||||
let metas = [];
|
let metas = [];
|
||||||
for (let i = 0; i < apps.length; i++) {
|
for (let i = 0; i < apps.length; i++) {
|
||||||
let app = apps[i];
|
let app = apps[i];
|
||||||
@@ -322,15 +327,15 @@ const AppSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback(metas);
|
return metas;
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
this.searchSystem.pushResults(this, this._appSys.initial_search(terms));
|
return this._appSys.initial_search(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
this.searchSystem.pushResults(this, this._appSys.subsearch(previousResults, terms));
|
return this._appSys.subsearch(previousResults, terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(app, params) {
|
activateResult: function(app, params) {
|
||||||
@@ -373,7 +378,7 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
|
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(prefs, callback) {
|
getResultMetas: function(prefs) {
|
||||||
let metas = [];
|
let metas = [];
|
||||||
for (let i = 0; i < prefs.length; i++) {
|
for (let i = 0; i < prefs.length; i++) {
|
||||||
let pref = prefs[i];
|
let pref = prefs[i];
|
||||||
@@ -384,15 +389,15 @@ const SettingsSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback(metas);
|
return metas;
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
|
return this._appSys.search_settings(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
|
return this._appSys.search_settings(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(pref, params) {
|
activateResult: function(pref, params) {
|
||||||
|
|||||||
@@ -123,8 +123,7 @@ const AutomountManager = new Lang.Class({
|
|||||||
let volumes = this._volumeMonitor.get_volumes();
|
let volumes = this._volumeMonitor.get_volumes();
|
||||||
volumes.forEach(Lang.bind(this, function(volume) {
|
volumes.forEach(Lang.bind(this, function(volume) {
|
||||||
this._checkAndMountVolume(volume, { checkSession: false,
|
this._checkAndMountVolume(volume, { checkSession: false,
|
||||||
useMountOp: false,
|
useMountOp: false });
|
||||||
allowAutorun: false });
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -202,8 +201,7 @@ const AutomountManager = new Lang.Class({
|
|||||||
|
|
||||||
_checkAndMountVolume: function(volume, params) {
|
_checkAndMountVolume: function(volume, params) {
|
||||||
params = Params.parse(params, { checkSession: true,
|
params = Params.parse(params, { checkSession: true,
|
||||||
useMountOp: true,
|
useMountOp: true });
|
||||||
allowAutorun: true });
|
|
||||||
|
|
||||||
if (params.checkSession) {
|
if (params.checkSession) {
|
||||||
// if we're not in the current ConsoleKit session,
|
// if we're not in the current ConsoleKit session,
|
||||||
@@ -238,20 +236,15 @@ const AutomountManager = new Lang.Class({
|
|||||||
|
|
||||||
if (params.useMountOp) {
|
if (params.useMountOp) {
|
||||||
let operation = new ShellMountOperation.ShellMountOperation(volume);
|
let operation = new ShellMountOperation.ShellMountOperation(volume);
|
||||||
this._mountVolume(volume, operation, params.allowAutorun);
|
this._mountVolume(volume, operation.mountOp);
|
||||||
} else {
|
} else {
|
||||||
this._mountVolume(volume, null, params.allowAutorun);
|
this._mountVolume(volume, null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_mountVolume: function(volume, operation, allowAutorun) {
|
_mountVolume: function(volume, operation) {
|
||||||
if (allowAutorun)
|
this._allowAutorun(volume);
|
||||||
this._allowAutorun(volume);
|
volume.mount(0, operation, null,
|
||||||
|
|
||||||
let mountOp = operation ? operation.mountOp : null;
|
|
||||||
volume._operation = operation;
|
|
||||||
|
|
||||||
volume.mount(0, mountOp, null,
|
|
||||||
Lang.bind(this, this._onVolumeMounted));
|
Lang.bind(this, this._onVolumeMounted));
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -260,19 +253,15 @@ const AutomountManager = new Lang.Class({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
volume.mount_finish(res);
|
volume.mount_finish(res);
|
||||||
this._closeOperation(volume);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// FIXME: we will always get G_IO_ERROR_FAILED from the gvfs udisks
|
let string = e.toString();
|
||||||
// backend in this case, see
|
|
||||||
// https://bugs.freedesktop.org/show_bug.cgi?id=51271
|
|
||||||
if (e.message.indexOf('No key available with this passphrase') != -1) {
|
|
||||||
this._reaskPassword(volume);
|
|
||||||
} else {
|
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
|
||||||
log('Unable to mount volume ' + volume.get_name() + ': ' + e.toString());
|
|
||||||
|
|
||||||
this._closeOperation(volume);
|
// FIXME: needs proper error code handling instead of this
|
||||||
}
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
if (string.indexOf('No key available with this passphrase') != -1)
|
||||||
|
this._reaskPassword(volume);
|
||||||
|
else
|
||||||
|
log('Unable to mount volume ' + volume.get_name() + ': ' + string);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -284,16 +273,8 @@ const AutomountManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_reaskPassword: function(volume) {
|
_reaskPassword: function(volume) {
|
||||||
let existingDialog = volume._operation ? volume._operation.borrowDialog() : null;
|
let operation = new ShellMountOperation.ShellMountOperation(volume, { reaskPassword: true });
|
||||||
let operation =
|
this._mountVolume(volume, operation.mountOp);
|
||||||
new ShellMountOperation.ShellMountOperation(volume,
|
|
||||||
{ existingDialog: existingDialog });
|
|
||||||
this._mountVolume(volume, operation);
|
|
||||||
},
|
|
||||||
|
|
||||||
_closeOperation: function(volume) {
|
|
||||||
if (volume._operation)
|
|
||||||
volume._operation.close();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_allowAutorun: function(volume) {
|
_allowAutorun: function(volume) {
|
||||||
|
|||||||
@@ -23,14 +23,12 @@ const AutorunSetting = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// misc utils
|
// misc utils
|
||||||
function shouldAutorunMount(mount, forTransient) {
|
function ignoreAutorunForMount(mount) {
|
||||||
let root = mount.get_root();
|
let root = mount.get_root();
|
||||||
let volume = mount.get_volume();
|
let volume = mount.get_volume();
|
||||||
|
|
||||||
if (!volume || (!volume.allowAutorun && forTransient))
|
if ((root.is_native() && !isMountRootHidden(root)) ||
|
||||||
return false;
|
(volume && volume.allowAutorun && volume.should_automount()))
|
||||||
|
|
||||||
if (!root.is_native() || isMountRootHidden(root))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -226,9 +224,11 @@ const AutorunManager = new Lang.Class({
|
|||||||
try {
|
try {
|
||||||
mount.unmount_with_operation_finish(res);
|
mount.unmount_with_operation_finish(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
||||||
log('Unable to eject the mount ' + mount.get_name()
|
// but we can't access the error code from JS.
|
||||||
+ ': ' + e.toString());
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
log('Unable to eject the mount ' + mount.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -236,9 +236,11 @@ const AutorunManager = new Lang.Class({
|
|||||||
try {
|
try {
|
||||||
source.eject_with_operation_finish(res);
|
source.eject_with_operation_finish(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
||||||
log('Unable to eject the drive ' + source.get_name()
|
// but we can't access the error code from JS.
|
||||||
+ ': ' + e.toString());
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
log('Unable to eject the drive ' + source.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -246,9 +248,11 @@ const AutorunManager = new Lang.Class({
|
|||||||
try {
|
try {
|
||||||
drive.stop_finish(res);
|
drive.stop_finish(res);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED_HANDLED))
|
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
||||||
log('Unable to stop the drive ' + drive.get_name()
|
// but we can't access the error code from JS.
|
||||||
+ ': ' + e.toString());
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
log('Unable to stop the drive ' + drive.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -258,15 +262,16 @@ const AutorunResidentSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("Removable Devices"), 'media-removable', St.IconType.FULLCOLOR);
|
this.parent(_("Removable Devices"));
|
||||||
|
|
||||||
this._mounts = [];
|
this._mounts = [];
|
||||||
|
|
||||||
this._notification = new AutorunResidentNotification(this);
|
this._notification = new AutorunResidentNotification(this);
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
},
|
},
|
||||||
|
|
||||||
addMount: function(mount, apps) {
|
addMount: function(mount, apps) {
|
||||||
if (!shouldAutorunMount(mount, false))
|
if (ignoreAutorunForMount(mount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let filtered = this._mounts.filter(function (element) {
|
let filtered = this._mounts.filter(function (element) {
|
||||||
@@ -305,6 +310,12 @@ const AutorunResidentSource = new Lang.Class({
|
|||||||
Main.messageTray.add(this);
|
Main.messageTray.add(this);
|
||||||
this.pushNotification(this._notification);
|
this.pushNotification(this._notification);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
return new St.Icon ({ icon_name: 'media-removable',
|
||||||
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -444,7 +455,7 @@ const AutorunTransientDispatcher = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// if the mount doesn't want to be autorun, return
|
// if the mount doesn't want to be autorun, return
|
||||||
if (!shouldAutorunMount(mount, true))
|
if (ignoreAutorunForMount(mount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let setting = this._getAutorunSettingForType(contentTypes[0]);
|
let setting = this._getAutorunSettingForType(contentTypes[0]);
|
||||||
@@ -489,11 +500,11 @@ const AutorunTransientSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(mount, apps) {
|
_init: function(mount, apps) {
|
||||||
|
this.parent(mount.get_name());
|
||||||
|
|
||||||
this.mount = mount;
|
this.mount = mount;
|
||||||
this.apps = apps;
|
this.apps = apps;
|
||||||
|
|
||||||
this.parent(mount.get_name());
|
|
||||||
|
|
||||||
this._notification = new AutorunTransientNotification(this);
|
this._notification = new AutorunTransientNotification(this);
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ const Calendar = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All the children after this are days, and get removed when we update the calendar
|
// All the children after this are days, and get removed when we update the calendar
|
||||||
this._firstDayIndex = this.actor.get_n_children();
|
this._firstDayIndex = this.actor.get_children().length;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStyleChange: function(actor, event) {
|
_onStyleChange: function(actor, event) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ const Contact = new Lang.Class({
|
|||||||
this.individual.full_name ||
|
this.individual.full_name ||
|
||||||
this.individual.nickname ||
|
this.individual.nickname ||
|
||||||
email ||
|
email ||
|
||||||
C_("contact", "Unknown");
|
_("Unknown");
|
||||||
let aliasLabel = new St.Label({ text: aliasText,
|
let aliasLabel = new St.Label({ text: aliasText,
|
||||||
style_class: 'contact-details-alias' });
|
style_class: 'contact-details-alias' });
|
||||||
details.add(aliasLabel, { x_fill: true,
|
details.add(aliasLabel, { x_fill: true,
|
||||||
@@ -154,7 +154,7 @@ const ContactSearchProvider = new Lang.Class({
|
|||||||
this._contactSys = Shell.ContactSystem.get_default();
|
this._contactSys = Shell.ContactSystem.get_default();
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(ids, callback) {
|
getResultMetas: function(ids) {
|
||||||
let metas = [];
|
let metas = [];
|
||||||
for (let i = 0; i < ids.length; i++) {
|
for (let i = 0; i < ids.length; i++) {
|
||||||
let contact = new Contact(ids[i]);
|
let contact = new Contact(ids[i]);
|
||||||
@@ -165,15 +165,15 @@ const ContactSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback(metas);
|
return metas;
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
this.searchSystem.pushResults(this, this._contactSys.initial_search(terms));
|
return this._contactSys.initial_search(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
this.searchSystem.pushResults(this, this._contactSys.subsearch(previousResults, terms));
|
return this._contactSys.subsearch(previousResults, terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
createResultActor: function(resultMeta, terms) {
|
createResultActor: function(resultMeta, terms) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Cairo = imports.cairo;
|
const Cairo = imports.cairo;
|
||||||
@@ -17,6 +16,14 @@ const Main = imports.ui.main;
|
|||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const Calendar = imports.ui.calendar;
|
const Calendar = imports.ui.calendar;
|
||||||
|
const UPowerGlib = imports.gi.UPowerGlib;
|
||||||
|
|
||||||
|
// in org.gnome.desktop.interface
|
||||||
|
const CLOCK_FORMAT_KEY = 'clock-format';
|
||||||
|
|
||||||
|
// in org.gnome.shell.clock
|
||||||
|
const CLOCK_SHOW_DATE_KEY = 'show-date';
|
||||||
|
const CLOCK_SHOW_SECONDS_KEY = 'show-seconds';
|
||||||
|
|
||||||
function _onVertSepRepaint (area)
|
function _onVertSepRepaint (area)
|
||||||
{
|
{
|
||||||
@@ -38,7 +45,9 @@ const DateMenuButton = new Lang.Class({
|
|||||||
Name: 'DateMenuButton',
|
Name: 'DateMenuButton',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.Button,
|
||||||
|
|
||||||
_init: function() {
|
_init: function(params) {
|
||||||
|
params = Params.parse(params, { showEvents: true });
|
||||||
|
|
||||||
let item;
|
let item;
|
||||||
let hbox;
|
let hbox;
|
||||||
let vbox;
|
let vbox;
|
||||||
@@ -53,8 +62,8 @@ const DateMenuButton = new Lang.Class({
|
|||||||
// role ATK_ROLE_MENU like other elements of the panel.
|
// role ATK_ROLE_MENU like other elements of the panel.
|
||||||
this.actor.accessible_role = Atk.Role.LABEL;
|
this.actor.accessible_role = Atk.Role.LABEL;
|
||||||
|
|
||||||
this._clockDisplay = new St.Label();
|
this._clock = new St.Label();
|
||||||
this.actor.add_actor(this._clockDisplay);
|
this.actor.add_actor(this._clock);
|
||||||
|
|
||||||
hbox = new St.BoxLayout({name: 'calendarArea' });
|
hbox = new St.BoxLayout({name: 'calendarArea' });
|
||||||
this.menu.addActor(hbox);
|
this.menu.addActor(hbox);
|
||||||
@@ -66,11 +75,11 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
// Date
|
// Date
|
||||||
this._date = new St.Label();
|
this._date = new St.Label();
|
||||||
this.actor.label_actor = this._clockDisplay;
|
this.actor.label_actor = this._date;
|
||||||
this._date.style_class = 'datemenu-date-label';
|
this._date.style_class = 'datemenu-date-label';
|
||||||
vbox.add(this._date);
|
vbox.add(this._date);
|
||||||
|
|
||||||
if (Main.sessionMode.showCalendarEvents) {
|
if (params.showEvents) {
|
||||||
this._eventSource = new Calendar.DBusEventSource();
|
this._eventSource = new Calendar.DBusEventSource();
|
||||||
this._eventList = new Calendar.EventsList(this._eventSource);
|
this._eventList = new Calendar.EventsList(this._eventSource);
|
||||||
} else {
|
} else {
|
||||||
@@ -101,7 +110,7 @@ const DateMenuButton = new Lang.Class({
|
|||||||
item.actor.reparent(vbox);
|
item.actor.reparent(vbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Main.sessionMode.showCalendarEvents) {
|
if (params.showEvents) {
|
||||||
// Add vertical separator
|
// Add vertical separator
|
||||||
|
|
||||||
item = new St.DrawingArea({ style_class: 'calendar-vertical-separator',
|
item = new St.DrawingArea({ style_class: 'calendar-vertical-separator',
|
||||||
@@ -148,13 +157,68 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
// Done with hbox for calendar and event list
|
// Done with hbox for calendar and event list
|
||||||
|
|
||||||
this._clock = new GnomeDesktop.WallClock();
|
// Track changes to clock settings
|
||||||
this._clock.connect('notify::clock', Lang.bind(this, this._updateClockAndDate));
|
this._desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
||||||
|
this._clockSettings = new Gio.Settings({ schema: 'org.gnome.shell.clock' });
|
||||||
|
this._desktopSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
||||||
|
this._clockSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
||||||
|
|
||||||
|
// https://bugzilla.gnome.org/show_bug.cgi?id=655129
|
||||||
|
this._upClient = new UPowerGlib.Client();
|
||||||
|
this._upClient.connect('notify-resume', Lang.bind(this, this._updateClockAndDate));
|
||||||
|
|
||||||
|
// Start the clock
|
||||||
this._updateClockAndDate();
|
this._updateClockAndDate();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateClockAndDate: function() {
|
_updateClockAndDate: function() {
|
||||||
this._clockDisplay.set_text(this._clock.clock);
|
let format = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
|
||||||
|
let showDate = this._clockSettings.get_boolean(CLOCK_SHOW_DATE_KEY);
|
||||||
|
let showSeconds = this._clockSettings.get_boolean(CLOCK_SHOW_SECONDS_KEY);
|
||||||
|
|
||||||
|
let clockFormat;
|
||||||
|
let dateFormat;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case '24h':
|
||||||
|
if (showDate)
|
||||||
|
/* Translators: This is the time format with date used
|
||||||
|
in 24-hour mode. */
|
||||||
|
clockFormat = showSeconds ? _("%a %b %e, %R:%S")
|
||||||
|
: _("%a %b %e, %R");
|
||||||
|
else
|
||||||
|
/* Translators: This is the time format without date used
|
||||||
|
in 24-hour mode. */
|
||||||
|
clockFormat = showSeconds ? _("%a %R:%S")
|
||||||
|
: _("%a %R");
|
||||||
|
break;
|
||||||
|
case '12h':
|
||||||
|
default:
|
||||||
|
if (showDate)
|
||||||
|
/* Translators: This is a time format with date used
|
||||||
|
for AM/PM. */
|
||||||
|
clockFormat = showSeconds ? _("%a %b %e, %l:%M:%S %p")
|
||||||
|
: _("%a %b %e, %l:%M %p");
|
||||||
|
else
|
||||||
|
/* Translators: This is a time format without date used
|
||||||
|
for AM/PM. */
|
||||||
|
clockFormat = showSeconds ? _("%a %l:%M:%S %p")
|
||||||
|
: _("%a %l:%M %p");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let displayDate = new Date();
|
||||||
|
|
||||||
|
this._clock.set_text(displayDate.toLocaleFormat(clockFormat));
|
||||||
|
|
||||||
|
/* 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").
|
||||||
|
*/
|
||||||
|
dateFormat = _("%A %B %e, %Y");
|
||||||
|
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
|
||||||
|
|
||||||
|
Mainloop.timeout_add_seconds(1, Lang.bind(this, this._updateClockAndDate));
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpenCalendarActivate: function() {
|
_onOpenCalendarActivate: function() {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ const St = imports.gi.St;
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const GnomeSession = imports.misc.gnomeSession;
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
@@ -287,13 +288,13 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._applicationList.connect('actor-added',
|
this._applicationList.connect('actor-added',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_n_children() == 1)
|
if (this._applicationList.get_children().length == 1)
|
||||||
scrollView.show();
|
scrollView.show();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._applicationList.connect('actor-removed',
|
this._applicationList.connect('actor-removed',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_n_children() == 0)
|
if (this._applicationList.get_children().length == 0)
|
||||||
scrollView.hide();
|
scrollView.hide();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -341,7 +342,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateDescription: function() {
|
_updateContent: function() {
|
||||||
if (this.state != ModalDialog.State.OPENING &&
|
if (this.state != ModalDialog.State.OPENING &&
|
||||||
this.state != ModalDialog.State.OPENED)
|
this.state != ModalDialog.State.OPENED)
|
||||||
return;
|
return;
|
||||||
@@ -351,6 +352,17 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
let subject = dialogContent.subject;
|
let subject = dialogContent.subject;
|
||||||
let description;
|
let description;
|
||||||
|
|
||||||
|
if (this._user.is_loaded && !dialogContent.iconName) {
|
||||||
|
let iconFile = this._user.get_icon_file();
|
||||||
|
if (GLib.file_test(iconFile, GLib.FileTest.EXISTS))
|
||||||
|
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
|
||||||
|
else
|
||||||
|
this._setIconFromName('avatar-default', dialogContent.iconStyleClass);
|
||||||
|
} else if (dialogContent.iconName) {
|
||||||
|
this._setIconFromName(dialogContent.iconName,
|
||||||
|
dialogContent.iconStyleClass);
|
||||||
|
}
|
||||||
|
|
||||||
if (this._inhibitors.length > 0) {
|
if (this._inhibitors.length > 0) {
|
||||||
this._stopTimer();
|
this._stopTimer();
|
||||||
description = dialogContent.inhibitedDescription;
|
description = dialogContent.inhibitedDescription;
|
||||||
@@ -383,27 +395,6 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
_setLabelText(this._descriptionLabel, description);
|
_setLabelText(this._descriptionLabel, description);
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateContent: function() {
|
|
||||||
if (this.state != ModalDialog.State.OPENING &&
|
|
||||||
this.state != ModalDialog.State.OPENED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let dialogContent = DialogContent[this._type];
|
|
||||||
|
|
||||||
if (this._user.is_loaded && !dialogContent.iconName) {
|
|
||||||
let iconFile = this._user.get_icon_file();
|
|
||||||
if (GLib.file_test(iconFile, GLib.FileTest.EXISTS))
|
|
||||||
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
|
|
||||||
else
|
|
||||||
this._setIconFromName('avatar-default', dialogContent.iconStyleClass);
|
|
||||||
} else if (dialogContent.iconName) {
|
|
||||||
this._setIconFromName(dialogContent.iconName,
|
|
||||||
dialogContent.iconStyleClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._updateDescription();
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateButtons: function() {
|
_updateButtons: function() {
|
||||||
let dialogContent = DialogContent[this._type];
|
let dialogContent = DialogContent[this._type];
|
||||||
let buttons = [{ action: Lang.bind(this, this.cancel),
|
let buttons = [{ action: Lang.bind(this, this.cancel),
|
||||||
@@ -450,7 +441,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
{ _secondsLeft: 0,
|
{ _secondsLeft: 0,
|
||||||
time: this._secondsLeft,
|
time: this._secondsLeft,
|
||||||
transition: 'linear',
|
transition: 'linear',
|
||||||
onUpdate: Lang.bind(this, this._updateDescription),
|
onUpdate: Lang.bind(this, this._updateContent),
|
||||||
onComplete: Lang.bind(this, function() {
|
onComplete: Lang.bind(this, function() {
|
||||||
let dialogContent = DialogContent[this._type];
|
let dialogContent = DialogContent[this._type];
|
||||||
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
|
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ function init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OK, now things are initialized enough that we can import shell JS
|
// OK, now things are initialized enough that we can import shell JS
|
||||||
const Format = imports.format;
|
const Format = imports.misc.format;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
Tweener.init();
|
Tweener.init();
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Gio = imports.gi.Gio;
|
|
||||||
const Soup = imports.gi.Soup;
|
|
||||||
const St = imports.gi.St;
|
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
|
||||||
const FileUtils = imports.misc.fileUtils;
|
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
|
||||||
|
|
||||||
const _signals = ExtensionSystem._signals;
|
|
||||||
|
|
||||||
const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
|
|
||||||
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
|
|
||||||
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
|
|
||||||
|
|
||||||
let _httpSession;
|
|
||||||
|
|
||||||
function installExtensionFromUUID(uuid) {
|
|
||||||
let params = { uuid: uuid,
|
|
||||||
shell_version: Config.PACKAGE_VERSION };
|
|
||||||
|
|
||||||
let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
|
|
||||||
|
|
||||||
_httpSession.queue_message(message,
|
|
||||||
function(session, message) {
|
|
||||||
let info = JSON.parse(message.response_body.data);
|
|
||||||
let dialog = new InstallExtensionDialog(uuid, info);
|
|
||||||
dialog.open(global.get_current_time());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstallExtensionFromUUID(uuid) {
|
|
||||||
let extension = ExtensionUtils.extensions[uuid];
|
|
||||||
if (!extension)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Don't try to uninstall system extensions
|
|
||||||
if (extension.type != ExtensionUtils.ExtensionType.PER_USER)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ExtensionSystem.unloadExtension(uuid))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
FileUtils.recursivelyDeleteDir(extension.dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotExtensionZipFile(session, message, uuid) {
|
|
||||||
if (message.status_code != Soup.KnownStatusCode.OK) {
|
|
||||||
logExtensionError(uuid, 'downloading extension: ' + message.status_code);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let dir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions', uuid]));
|
|
||||||
try {
|
|
||||||
if (!dir.query_exists(null))
|
|
||||||
dir.make_directory_with_parents(null);
|
|
||||||
} catch (e) {
|
|
||||||
logExtensionError('Could not create extension directory');
|
|
||||||
}
|
|
||||||
|
|
||||||
let [file, stream] = Gio.File.new_tmp('XXXXXX.shell-extension.zip');
|
|
||||||
let contents = message.response_body.flatten().as_bytes();
|
|
||||||
stream.output_stream.write_bytes(contents, null);
|
|
||||||
stream.close(null);
|
|
||||||
let [success, pid] = GLib.spawn_async(null,
|
|
||||||
['unzip', '-uod', dir.get_path(), '--', file.get_path()],
|
|
||||||
null,
|
|
||||||
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
|
||||||
null);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
logExtensionError(uuid, 'extract: could not extract');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
|
|
||||||
GLib.spawn_close_pid(pid);
|
|
||||||
|
|
||||||
// Add extension to 'enabled-extensions' for the user, always...
|
|
||||||
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
|
|
||||||
if (enabledExtensions.indexOf(uuid) == -1) {
|
|
||||||
enabledExtensions.push(uuid);
|
|
||||||
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExtensionSystem.loadExtension(dir, ExtensionUtils.ExtensionType.PER_USER, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const InstallExtensionDialog = new Lang.Class({
|
|
||||||
Name: 'InstallExtensionDialog',
|
|
||||||
Extends: ModalDialog.ModalDialog,
|
|
||||||
|
|
||||||
_init: function(uuid, info) {
|
|
||||||
this.parent({ styleClass: 'extension-dialog' });
|
|
||||||
|
|
||||||
this._uuid = uuid;
|
|
||||||
this._info = info;
|
|
||||||
|
|
||||||
this.setButtons([{ label: _("Cancel"),
|
|
||||||
action: Lang.bind(this, this._onCancelButtonPressed),
|
|
||||||
key: Clutter.Escape
|
|
||||||
},
|
|
||||||
{ label: _("Install"),
|
|
||||||
action: Lang.bind(this, this._onInstallButtonPressed)
|
|
||||||
}]);
|
|
||||||
|
|
||||||
let message = _("Download and install '%s' from extensions.gnome.org?").format(info.name);
|
|
||||||
|
|
||||||
let box = new St.BoxLayout();
|
|
||||||
this.contentLayout.add(box);
|
|
||||||
|
|
||||||
let gicon = new Gio.FileIcon({ file: Gio.File.new_for_uri(REPOSITORY_URL_BASE + info.icon) })
|
|
||||||
let icon = new St.Icon({ gicon: gicon });
|
|
||||||
box.add(icon);
|
|
||||||
|
|
||||||
let label = new St.Label({ text: message });
|
|
||||||
box.add(label);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onCancelButtonPressed: function(button, event) {
|
|
||||||
this.close(global.get_current_time());
|
|
||||||
|
|
||||||
// Even though the extension is already "uninstalled", send through
|
|
||||||
// a state-changed signal for any users who want to know if the install
|
|
||||||
// went through correctly -- using proper async DBus would block more
|
|
||||||
// traditional clients like the plugin
|
|
||||||
let meta = { uuid: this._uuid,
|
|
||||||
state: ExtensionSystem.ExtensionState.UNINSTALLED,
|
|
||||||
error: '' };
|
|
||||||
|
|
||||||
_signals.emit('extension-state-changed', meta);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onInstallButtonPressed: function(button, event) {
|
|
||||||
let state = { uuid: this._uuid,
|
|
||||||
state: ExtensionSystem.ExtensionState.DOWNLOADING,
|
|
||||||
error: '' };
|
|
||||||
|
|
||||||
_signals.emit('extension-state-changed', state);
|
|
||||||
|
|
||||||
let params = { shell_version: Config.PACKAGE_VERSION };
|
|
||||||
|
|
||||||
let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
|
|
||||||
let message = Soup.form_request_new_from_hash('GET', url, params);
|
|
||||||
|
|
||||||
_httpSession.queue_message(message,
|
|
||||||
Lang.bind(this, function(session, message) {
|
|
||||||
gotExtensionZipFile(session, message, this._uuid);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.close(global.get_current_time());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
_httpSession = new Soup.SessionAsync({ ssl_use_system_ca_file: true });
|
|
||||||
|
|
||||||
// See: https://bugzilla.gnome.org/show_bug.cgi?id=655189 for context.
|
|
||||||
// _httpSession.add_feature(new Soup.ProxyResolverDefault());
|
|
||||||
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
|
|
||||||
}
|
|
||||||
@@ -3,11 +3,19 @@
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const Soup = imports.gi.Soup;
|
||||||
|
|
||||||
|
const Config = imports.misc.config;
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
|
const FileUtils = imports.misc.fileUtils;
|
||||||
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
|
|
||||||
|
const API_VERSION = 1;
|
||||||
|
|
||||||
const ExtensionState = {
|
const ExtensionState = {
|
||||||
ENABLED: 1,
|
ENABLED: 1,
|
||||||
@@ -22,6 +30,29 @@ const ExtensionState = {
|
|||||||
UNINSTALLED: 99
|
UNINSTALLED: 99
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
|
||||||
|
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
|
||||||
|
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
|
||||||
|
|
||||||
|
const _httpSession = new Soup.SessionAsync();
|
||||||
|
|
||||||
|
// The unfortunate state of gjs, gobject-introspection and libsoup
|
||||||
|
// means that I have to do a hack to add a feature.
|
||||||
|
// See: https://bugzilla.gnome.org/show_bug.cgi?id=655189 for context.
|
||||||
|
|
||||||
|
if (Soup.Session.prototype.add_feature != null)
|
||||||
|
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
|
||||||
|
|
||||||
|
function _getCertFile() {
|
||||||
|
let localCert = GLib.build_filenamev([global.userdatadir, 'extensions.gnome.org.crt']);
|
||||||
|
if (GLib.file_test(localCert, GLib.FileTest.EXISTS))
|
||||||
|
return localCert;
|
||||||
|
else
|
||||||
|
return Config.SHELL_SYSTEM_CA_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_httpSession.ssl_ca_file = _getCertFile();
|
||||||
|
|
||||||
// Arrays of uuids
|
// Arrays of uuids
|
||||||
var enabledExtensions;
|
var enabledExtensions;
|
||||||
// Contains the order that extensions were enabled in.
|
// Contains the order that extensions were enabled in.
|
||||||
@@ -38,6 +69,90 @@ const disconnect = Lang.bind(_signals, _signals.disconnect);
|
|||||||
|
|
||||||
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
|
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
|
||||||
|
|
||||||
|
function installExtensionFromUUID(uuid, version_tag) {
|
||||||
|
let params = { uuid: uuid,
|
||||||
|
version_tag: version_tag,
|
||||||
|
shell_version: Config.PACKAGE_VERSION,
|
||||||
|
api_version: API_VERSION.toString() };
|
||||||
|
|
||||||
|
let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
|
||||||
|
|
||||||
|
_httpSession.queue_message(message,
|
||||||
|
function(session, message) {
|
||||||
|
let info = JSON.parse(message.response_body.data);
|
||||||
|
let dialog = new InstallExtensionDialog(uuid, version_tag, info.name);
|
||||||
|
dialog.open(global.get_current_time());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstallExtensionFromUUID(uuid) {
|
||||||
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
|
if (!extension)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Try to disable it -- if it's ERROR'd, we can't guarantee that,
|
||||||
|
// but it will be removed on next reboot, and hopefully nothing
|
||||||
|
// broke too much.
|
||||||
|
disableExtension(uuid);
|
||||||
|
|
||||||
|
// Don't try to uninstall system extensions
|
||||||
|
if (extension.type != ExtensionUtils.ExtensionType.PER_USER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
extension.state = ExtensionState.UNINSTALLED;
|
||||||
|
_signals.emit('extension-state-changed', extension);
|
||||||
|
|
||||||
|
delete ExtensionUtils.extensions[uuid];
|
||||||
|
|
||||||
|
FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(extension.path));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotExtensionZipFile(session, message, uuid) {
|
||||||
|
if (message.status_code != Soup.KnownStatusCode.OK) {
|
||||||
|
logExtensionError(uuid, 'downloading extension: ' + message.status_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: use a GFile mkstemp-type method once one exists
|
||||||
|
let fd, tmpzip;
|
||||||
|
try {
|
||||||
|
[fd, tmpzip] = GLib.file_open_tmp('XXXXXX.shell-extension.zip');
|
||||||
|
} catch (e) {
|
||||||
|
logExtensionError(uuid, 'tempfile: ' + e.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let stream = new Gio.UnixOutputStream({ fd: fd });
|
||||||
|
let dir = ExtensionUtils.userExtensionsDir.get_child(uuid);
|
||||||
|
Shell.write_soup_message_to_stream(stream, message);
|
||||||
|
stream.close(null);
|
||||||
|
let [success, pid] = GLib.spawn_async(null,
|
||||||
|
['unzip', '-uod', dir.get_path(), '--', tmpzip],
|
||||||
|
null,
|
||||||
|
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
||||||
|
null);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
logExtensionError(uuid, 'extract: could not extract');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
|
||||||
|
GLib.spawn_close_pid(pid);
|
||||||
|
|
||||||
|
// Add extension to 'enabled-extensions' for the user, always...
|
||||||
|
let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
||||||
|
if (enabledExtensions.indexOf(uuid) == -1) {
|
||||||
|
enabledExtensions.push(uuid);
|
||||||
|
global.settings.set_strv(ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadExtension(dir, ExtensionUtils.ExtensionType.PER_USER, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function disableExtension(uuid) {
|
function disableExtension(uuid) {
|
||||||
let extension = ExtensionUtils.extensions[uuid];
|
let extension = ExtensionUtils.extensions[uuid];
|
||||||
if (!extension)
|
if (!extension)
|
||||||
@@ -67,11 +182,6 @@ function disableExtension(uuid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extension.stylesheet) {
|
|
||||||
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
|
||||||
theme.unload_stylesheet(extension.stylesheet.get_path());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
extension.stateObj.disable();
|
extension.stateObj.disable();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@@ -114,17 +224,6 @@ function enableExtension(uuid) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stylesheetFile = extension.dir.get_child('stylesheet.css');
|
|
||||||
if (stylesheetFile.query_exists(null)) {
|
|
||||||
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
|
|
||||||
try {
|
|
||||||
theme.load_stylesheet(stylesheetFile.get_path());
|
|
||||||
extension.stylesheet = stylesheetFile;
|
|
||||||
} catch (e) {
|
|
||||||
logExtensionError(uuid, 'Stylesheet parse error: ' + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension.state = ExtensionState.ENABLED;
|
extension.state = ExtensionState.ENABLED;
|
||||||
_signals.emit('extension-state-changed', extension);
|
_signals.emit('extension-state-changed', extension);
|
||||||
}
|
}
|
||||||
@@ -138,50 +237,48 @@ function logExtensionError(uuid, message, state) {
|
|||||||
extension.errors = [];
|
extension.errors = [];
|
||||||
|
|
||||||
extension.errors.push(message);
|
extension.errors.push(message);
|
||||||
log('Extension "%s" had error: %s'.format(uuid, message));
|
global.logError('Extension "%s" had error: %s'.format(uuid, message));
|
||||||
state = state || ExtensionState.ERROR;
|
state = state || ExtensionState.ERROR;
|
||||||
_signals.emit('extension-state-changed', { uuid: uuid,
|
_signals.emit('extension-state-changed', { uuid: uuid,
|
||||||
error: message,
|
error: message,
|
||||||
state: state });
|
state: state });
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadExtension(extension) {
|
function loadExtension(dir, type, enabled) {
|
||||||
|
let uuid = dir.get_basename();
|
||||||
|
let extension;
|
||||||
|
|
||||||
|
if (ExtensionUtils.extensions[uuid] != undefined) {
|
||||||
|
global.logError('Extension "%s" is already loaded'.format(uuid));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
extension = ExtensionUtils.createExtensionObject(uuid, dir, type);
|
||||||
|
} catch(e) {
|
||||||
|
logExtensionError(uuid, e.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Default to error, we set success as the last step
|
// Default to error, we set success as the last step
|
||||||
extension.state = ExtensionState.ERROR;
|
extension.state = ExtensionState.ERROR;
|
||||||
|
|
||||||
if (ExtensionUtils.isOutOfDate(extension)) {
|
if (ExtensionUtils.isOutOfDate(extension)) {
|
||||||
logExtensionError(extension.uuid, 'extension is not compatible with current GNOME Shell and/or GJS version', ExtensionState.OUT_OF_DATE);
|
logExtensionError(uuid, 'extension is not compatible with current GNOME Shell and/or GJS version', ExtensionState.OUT_OF_DATE);
|
||||||
extension.state = ExtensionState.OUT_OF_DATE;
|
extension.state = ExtensionState.OUT_OF_DATE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
initExtension(extension.uuid);
|
initExtension(uuid);
|
||||||
if (extension.state == ExtensionState.DISABLED)
|
if (extension.state == ExtensionState.DISABLED)
|
||||||
enableExtension(extension.uuid);
|
enableExtension(uuid);
|
||||||
} else {
|
} else {
|
||||||
extension.state = ExtensionState.INITIALIZED;
|
extension.state = ExtensionState.INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
_signals.emit('extension-state-changed', extension);
|
_signals.emit('extension-state-changed', extension);
|
||||||
}
|
global.log('Loaded extension ' + uuid);
|
||||||
|
|
||||||
function unloadExtension(uuid) {
|
|
||||||
let extension = ExtensionUtils.extensions[uuid];
|
|
||||||
if (!extension)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Try to disable it -- if it's ERROR'd, we can't guarantee that,
|
|
||||||
// but it will be removed on next reboot, and hopefully nothing
|
|
||||||
// broke too much.
|
|
||||||
disableExtension(uuid);
|
|
||||||
|
|
||||||
extension.state = ExtensionState.UNINSTALLED;
|
|
||||||
_signals.emit('extension-state-changed', extension);
|
|
||||||
|
|
||||||
delete ExtensionUtils.extensions[uuid];
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initExtension(uuid) {
|
function initExtension(uuid) {
|
||||||
@@ -196,6 +293,18 @@ function initExtension(uuid) {
|
|||||||
logExtensionError(uuid, 'Missing extension.js');
|
logExtensionError(uuid, 'Missing extension.js');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let stylesheetPath = null;
|
||||||
|
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||||
|
let theme = themeContext.get_theme();
|
||||||
|
let stylesheetFile = dir.get_child('stylesheet.css');
|
||||||
|
if (stylesheetFile.query_exists(null)) {
|
||||||
|
try {
|
||||||
|
theme.load_stylesheet(stylesheetFile.get_path());
|
||||||
|
} catch (e) {
|
||||||
|
logExtensionError(uuid, 'Stylesheet parse error: ' + e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let extensionModule;
|
let extensionModule;
|
||||||
let extensionState = null;
|
let extensionState = null;
|
||||||
@@ -203,17 +312,24 @@ function initExtension(uuid) {
|
|||||||
ExtensionUtils.installImporter(extension);
|
ExtensionUtils.installImporter(extension);
|
||||||
extensionModule = extension.imports.extension;
|
extensionModule = extension.imports.extension;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (stylesheetPath != null)
|
||||||
|
theme.unload_stylesheet(stylesheetPath);
|
||||||
logExtensionError(uuid, '' + e);
|
logExtensionError(uuid, '' + e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extensionModule.init) {
|
if (!extensionModule.init) {
|
||||||
try {
|
logExtensionError(uuid, 'missing \'init\' function');
|
||||||
extensionState = extensionModule.init(extension);
|
return;
|
||||||
} catch (e) {
|
}
|
||||||
logExtensionError(uuid, 'Failed to evaluate init function:' + e);
|
|
||||||
return;
|
try {
|
||||||
}
|
extensionState = extensionModule.init(extension);
|
||||||
|
} catch (e) {
|
||||||
|
if (stylesheetPath != null)
|
||||||
|
theme.unload_stylesheet(stylesheetPath);
|
||||||
|
logExtensionError(uuid, 'Failed to evaluate init function:' + e);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extensionState)
|
if (!extensionState)
|
||||||
@@ -256,13 +372,81 @@ function onEnabledExtensionsChanged() {
|
|||||||
enabledExtensions = newEnabledExtensions;
|
enabledExtensions = newEnabledExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadExtensions() {
|
function init() {
|
||||||
|
ExtensionUtils.init();
|
||||||
|
|
||||||
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||||
enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
||||||
|
|
||||||
let finder = new ExtensionUtils.ExtensionFinder();
|
|
||||||
finder.connect('extension-found', function(signals, extension) {
|
|
||||||
loadExtension(extension);
|
|
||||||
});
|
|
||||||
finder.scanExtensions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadExtensions() {
|
||||||
|
ExtensionUtils.scanExtensions(function(uuid, dir, type) {
|
||||||
|
let enabled = enabledExtensions.indexOf(uuid) != -1;
|
||||||
|
loadExtension(dir, type, enabled);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const InstallExtensionDialog = new Lang.Class({
|
||||||
|
Name: 'InstallExtensionDialog',
|
||||||
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
|
_init: function(uuid, version_tag, name) {
|
||||||
|
this.parent({ styleClass: 'extension-dialog' });
|
||||||
|
|
||||||
|
this._uuid = uuid;
|
||||||
|
this._version_tag = version_tag;
|
||||||
|
this._name = name;
|
||||||
|
|
||||||
|
this.setButtons([{ label: _("Cancel"),
|
||||||
|
action: Lang.bind(this, this._onCancelButtonPressed),
|
||||||
|
key: Clutter.Escape
|
||||||
|
},
|
||||||
|
{ label: _("Install"),
|
||||||
|
action: Lang.bind(this, this._onInstallButtonPressed)
|
||||||
|
}]);
|
||||||
|
|
||||||
|
let message = _("Download and install '%s' from extensions.gnome.org?").format(name);
|
||||||
|
|
||||||
|
this._descriptionLabel = new St.Label({ text: message });
|
||||||
|
|
||||||
|
this.contentLayout.add(this._descriptionLabel,
|
||||||
|
{ y_fill: true,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
},
|
||||||
|
|
||||||
|
_onCancelButtonPressed: function(button, event) {
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
|
||||||
|
// Even though the extension is already "uninstalled", send through
|
||||||
|
// a state-changed signal for any users who want to know if the install
|
||||||
|
// went through correctly -- using proper async DBus would block more
|
||||||
|
// traditional clients like the plugin
|
||||||
|
let meta = { uuid: this._uuid,
|
||||||
|
state: ExtensionState.UNINSTALLED,
|
||||||
|
error: '' };
|
||||||
|
|
||||||
|
_signals.emit('extension-state-changed', meta);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInstallButtonPressed: function(button, event) {
|
||||||
|
let state = { uuid: this._uuid,
|
||||||
|
state: ExtensionState.DOWNLOADING,
|
||||||
|
error: '' };
|
||||||
|
|
||||||
|
_signals.emit('extension-state-changed', state);
|
||||||
|
|
||||||
|
let params = { version_tag: this._version_tag,
|
||||||
|
shell_version: Config.PACKAGE_VERSION,
|
||||||
|
api_version: API_VERSION.toString() };
|
||||||
|
|
||||||
|
let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
|
||||||
|
let message = Soup.form_request_new_from_hash('GET', url, params);
|
||||||
|
|
||||||
|
_httpSession.queue_message(message,
|
||||||
|
Lang.bind(this, function(session, message) {
|
||||||
|
gotExtensionZipFile(session, message, this._uuid);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -282,10 +282,6 @@ const IconGrid = new Lang.Class({
|
|||||||
return this._computeLayout(rowWidth)[0];
|
return this._computeLayout(rowWidth)[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
getRowLimit: function() {
|
|
||||||
return this._rowLimit;
|
|
||||||
},
|
|
||||||
|
|
||||||
_computeLayout: function (forWidth) {
|
_computeLayout: function (forWidth) {
|
||||||
let nColumns = 0;
|
let nColumns = 0;
|
||||||
let usedWidth = 0;
|
let usedWidth = 0;
|
||||||
@@ -309,22 +305,21 @@ const IconGrid = new Lang.Class({
|
|||||||
this._grid.queue_relayout();
|
this._grid.queue_relayout();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeAll: function() {
|
removeAll: function () {
|
||||||
this._grid.destroy_all_children();
|
this._grid.get_children().forEach(Lang.bind(this, function (child) {
|
||||||
|
child.destroy();
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
addItem: function(actor, index) {
|
addItem: function(actor) {
|
||||||
if (index !== undefined)
|
this._grid.add_actor(actor);
|
||||||
this._grid.insert_child_at_index(actor, index);
|
|
||||||
else
|
|
||||||
this._grid.add_actor(actor);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getItemAtIndex: function(index) {
|
getItemAtIndex: function(index) {
|
||||||
return this._grid.get_child_at_index(index);
|
return this._grid.get_children()[index];
|
||||||
},
|
},
|
||||||
|
|
||||||
visibleItemsCount: function() {
|
visibleItemsCount: function() {
|
||||||
return this._grid.get_n_children() - this._grid.get_n_skip_paint();
|
return this._grid.get_children().length - this._grid.get_n_skip_paint();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -541,8 +541,16 @@ const KeyboardSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(keyboard) {
|
_init: function(keyboard) {
|
||||||
|
this.parent(_("Keyboard"));
|
||||||
this._keyboard = keyboard;
|
this._keyboard = keyboard;
|
||||||
this.parent(_("Keyboard"), 'input-keyboard', St.IconType.SYMBOLIC);
|
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
return new St.Icon({ icon_name: 'input-keyboard',
|
||||||
|
icon_type: St.IconType.SYMBOLIC,
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSummaryClick: function() {
|
handleSummaryClick: function() {
|
||||||
|
|||||||
@@ -53,10 +53,6 @@ const LayoutManager = new Lang.Class({
|
|||||||
global.screen.connect('monitors-changed',
|
global.screen.connect('monitors-changed',
|
||||||
Lang.bind(this, this._monitorsChanged));
|
Lang.bind(this, this._monitorsChanged));
|
||||||
this._monitorsChanged();
|
this._monitorsChanged();
|
||||||
|
|
||||||
this._chrome.connect('primary-fullscreen-changed', Lang.bind(this, function(chrome, state) {
|
|
||||||
this.emit('primary-fullscreen-changed', state);
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is called by Main after everything else is constructed;
|
// This is called by Main after everything else is constructed;
|
||||||
@@ -228,9 +224,26 @@ const LayoutManager = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
get currentMonitor() {
|
get focusIndex() {
|
||||||
let index = global.screen.get_current_monitor();
|
let focusWindow = global.display.focus_window;
|
||||||
return Main.layoutManager.monitors[index];
|
|
||||||
|
if (focusWindow) {
|
||||||
|
let wrect = focusWindow.get_outer_rect();
|
||||||
|
for (let i = 0; i < this.monitors.length; i++) {
|
||||||
|
let monitor = this.monitors[i];
|
||||||
|
|
||||||
|
if (monitor.x <= wrect.x && monitor.y <= wrect.y &&
|
||||||
|
monitor.x + monitor.width > wrect.x &&
|
||||||
|
monitor.y + monitor.height > wrect.y)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.primaryIndex;
|
||||||
|
},
|
||||||
|
|
||||||
|
get focusMonitor() {
|
||||||
|
return this.monitors[this.focusIndex];
|
||||||
},
|
},
|
||||||
|
|
||||||
_startupAnimation: function() {
|
_startupAnimation: function() {
|
||||||
@@ -839,8 +852,6 @@ const Chrome = new Lang.Class({
|
|||||||
for (let i = 0; i < this._monitors.length; i++)
|
for (let i = 0; i < this._monitors.length; i++)
|
||||||
wasInFullscreen[i] = this._monitors[i].inFullscreen;
|
wasInFullscreen[i] = this._monitors[i].inFullscreen;
|
||||||
|
|
||||||
let primaryWasInFullscreen = this._primaryMonitor.inFullscreen;
|
|
||||||
|
|
||||||
this._updateFullscreen();
|
this._updateFullscreen();
|
||||||
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
@@ -850,15 +861,10 @@ const Chrome = new Lang.Class({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primaryWasInFullscreen != this._primaryMonitor.inFullscreen) {
|
|
||||||
this.emit('primary-fullscreen-changed', this._primaryMonitor.inFullscreen);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateRegions: function() {
|
updateRegions: function() {
|
||||||
@@ -973,5 +979,3 @@ const Chrome = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Signals.addSignalMethods(Chrome.prototype);
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
|||||||
'const stage = global.stage; ' +
|
'const stage = global.stage; ' +
|
||||||
'const color = function(pixel) { let c= new Clutter.Color(); c.from_pixel(pixel); return c; }; ' +
|
'const color = function(pixel) { let c= new Clutter.Color(); c.from_pixel(pixel); return c; }; ' +
|
||||||
/* Special lookingGlass functions */
|
/* Special lookingGlass functions */
|
||||||
'const it = Main.lookingGlass.getIt(); ' +
|
'const it = Main.lookingGlass.getIt(); ' +
|
||||||
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
||||||
|
|
||||||
const HISTORY_KEY = 'looking-glass-history';
|
const HISTORY_KEY = 'looking-glass-history';
|
||||||
@@ -320,7 +320,7 @@ const WindowList = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateWindowList: function() {
|
_updateWindowList: function() {
|
||||||
this.actor.destroy_all_children();
|
this.actor.get_children().forEach(function (actor) { actor.destroy(); });
|
||||||
let windows = global.get_window_actors();
|
let windows = global.get_window_actors();
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
@@ -378,7 +378,7 @@ const ObjInspector = new Lang.Class({
|
|||||||
this._previousObj = null;
|
this._previousObj = null;
|
||||||
this._obj = obj;
|
this._obj = obj;
|
||||||
|
|
||||||
this._container.destroy_all_children();
|
this._container.get_children().forEach(function (child) { child.destroy(); });
|
||||||
|
|
||||||
let hbox = new St.BoxLayout({ style_class: 'lg-obj-inspector-title' });
|
let hbox = new St.BoxLayout({ style_class: 'lg-obj-inspector-title' });
|
||||||
this._container.add_actor(hbox);
|
this._container.add_actor(hbox);
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ const Params = imports.misc.params;
|
|||||||
|
|
||||||
const MOUSE_POLL_FREQUENCY = 50;
|
const MOUSE_POLL_FREQUENCY = 50;
|
||||||
const CROSSHAIRS_CLIP_SIZE = [100, 100];
|
const CROSSHAIRS_CLIP_SIZE = [100, 100];
|
||||||
const NO_CHANGE = 0.0;
|
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
const APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
|
const APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
|
||||||
@@ -25,13 +24,6 @@ const SHOW_KEY = 'screen-magnifier-enabled';
|
|||||||
const MAGNIFIER_SCHEMA = 'org.gnome.desktop.a11y.magnifier';
|
const MAGNIFIER_SCHEMA = 'org.gnome.desktop.a11y.magnifier';
|
||||||
const SCREEN_POSITION_KEY = 'screen-position';
|
const SCREEN_POSITION_KEY = 'screen-position';
|
||||||
const MAG_FACTOR_KEY = 'mag-factor';
|
const MAG_FACTOR_KEY = 'mag-factor';
|
||||||
const INVERT_LIGHTNESS_KEY = 'invert-lightness';
|
|
||||||
const BRIGHT_RED_KEY = 'brightness-red';
|
|
||||||
const BRIGHT_GREEN_KEY = 'brightness-green';
|
|
||||||
const BRIGHT_BLUE_KEY = 'brightness-blue';
|
|
||||||
const CONTRAST_RED_KEY = 'contrast-red';
|
|
||||||
const CONTRAST_GREEN_KEY = 'contrast-green';
|
|
||||||
const CONTRAST_BLUE_KEY = 'contrast-blue';
|
|
||||||
const LENS_MODE_KEY = 'lens-mode';
|
const LENS_MODE_KEY = 'lens-mode';
|
||||||
const CLAMP_MODE_KEY = 'scroll-at-edges';
|
const CLAMP_MODE_KEY = 'scroll-at-edges';
|
||||||
const MOUSE_TRACKING_KEY = 'mouse-tracking';
|
const MOUSE_TRACKING_KEY = 'mouse-tracking';
|
||||||
@@ -451,21 +443,6 @@ const Magnifier = new Lang.Class({
|
|||||||
aPref = this._settings.get_enum(MOUSE_TRACKING_KEY);
|
aPref = this._settings.get_enum(MOUSE_TRACKING_KEY);
|
||||||
if (aPref)
|
if (aPref)
|
||||||
zoomRegion.setMouseTrackingMode(aPref);
|
zoomRegion.setMouseTrackingMode(aPref);
|
||||||
|
|
||||||
aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY);
|
|
||||||
if (aPref)
|
|
||||||
zoomRegion.setInvertLightness(aPref);
|
|
||||||
|
|
||||||
let bc = {};
|
|
||||||
bc.r = this._settings.get_double(BRIGHT_RED_KEY);
|
|
||||||
bc.g = this._settings.get_double(BRIGHT_GREEN_KEY);
|
|
||||||
bc.b = this._settings.get_double(BRIGHT_BLUE_KEY);
|
|
||||||
zoomRegion.setBrightness(bc);
|
|
||||||
|
|
||||||
bc.r = this._settings.get_double(CONTRAST_RED_KEY);
|
|
||||||
bc.g = this._settings.get_double(CONTRAST_GREEN_KEY);
|
|
||||||
bc.b = this._settings.get_double(CONTRAST_BLUE_KEY);
|
|
||||||
zoomRegion.setContrast(bc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY);
|
let showCrosshairs = this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY);
|
||||||
@@ -488,23 +465,6 @@ const Magnifier = new Lang.Class({
|
|||||||
this._settings.connect('changed::' + MOUSE_TRACKING_KEY,
|
this._settings.connect('changed::' + MOUSE_TRACKING_KEY,
|
||||||
Lang.bind(this, this._updateMouseTrackingMode));
|
Lang.bind(this, this._updateMouseTrackingMode));
|
||||||
|
|
||||||
this._settings.connect('changed::' + INVERT_LIGHTNESS_KEY,
|
|
||||||
Lang.bind(this, this._updateInvertLightness));
|
|
||||||
|
|
||||||
this._settings.connect('changed::' + BRIGHT_RED_KEY,
|
|
||||||
Lang.bind(this, this._updateBrightness));
|
|
||||||
this._settings.connect('changed::' + BRIGHT_GREEN_KEY,
|
|
||||||
Lang.bind(this, this._updateBrightness));
|
|
||||||
this._settings.connect('changed::' + BRIGHT_BLUE_KEY,
|
|
||||||
Lang.bind(this, this._updateBrightness));
|
|
||||||
|
|
||||||
this._settings.connect('changed::' + CONTRAST_RED_KEY,
|
|
||||||
Lang.bind(this, this._updateContrast));
|
|
||||||
this._settings.connect('changed::' + CONTRAST_GREEN_KEY,
|
|
||||||
Lang.bind(this, this._updateContrast));
|
|
||||||
this._settings.connect('changed::' + CONTRAST_BLUE_KEY,
|
|
||||||
Lang.bind(this, this._updateContrast));
|
|
||||||
|
|
||||||
this._settings.connect('changed::' + SHOW_CROSS_HAIRS_KEY,
|
this._settings.connect('changed::' + SHOW_CROSS_HAIRS_KEY,
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this.setCrosshairsVisible(this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY));
|
this.setCrosshairsVisible(this._settings.get_boolean(SHOW_CROSS_HAIRS_KEY));
|
||||||
@@ -580,38 +540,7 @@ const Magnifier = new Lang.Class({
|
|||||||
this._settings.get_enum(MOUSE_TRACKING_KEY)
|
this._settings.get_enum(MOUSE_TRACKING_KEY)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_updateInvertLightness: function() {
|
|
||||||
// Applies only to the first zoom region.
|
|
||||||
if (this._zoomRegions.length) {
|
|
||||||
this._zoomRegions[0].setInvertLightness(
|
|
||||||
this._settings.get_boolean(INVERT_LIGHTNESS_KEY)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateBrightness: function() {
|
|
||||||
// Applies only to the first zoom region.
|
|
||||||
if (this._zoomRegions.length) {
|
|
||||||
let brightness = {};
|
|
||||||
brightness.r = this._settings.get_double(BRIGHT_RED_KEY);
|
|
||||||
brightness.g = this._settings.get_double(BRIGHT_GREEN_KEY);
|
|
||||||
brightness.b = this._settings.get_double(BRIGHT_BLUE_KEY);
|
|
||||||
this._zoomRegions[0].setBrightness(brightness);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateContrast: function() {
|
|
||||||
// Applies only to the first zoom region.
|
|
||||||
if (this._zoomRegions.length) {
|
|
||||||
let contrast = {};
|
|
||||||
contrast.r = this._settings.get_double(CONTRAST_RED_KEY);
|
|
||||||
contrast.g = this._settings.get_double(CONTRAST_GREEN_KEY);
|
|
||||||
contrast.b = this._settings.get_double(CONTRAST_BLUE_KEY);
|
|
||||||
this._zoomRegions[0].setContrast(contrast);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(Magnifier.prototype);
|
Signals.addSignalMethods(Magnifier.prototype);
|
||||||
|
|
||||||
@@ -625,9 +554,6 @@ const ZoomRegion = new Lang.Class({
|
|||||||
this._clampScrollingAtEdges = false;
|
this._clampScrollingAtEdges = false;
|
||||||
this._lensMode = false;
|
this._lensMode = false;
|
||||||
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
|
this._screenPosition = GDesktopEnums.MagnifierScreenPosition.FULL_SCREEN;
|
||||||
this._invertLightness = false;
|
|
||||||
this._brightness = { r: NO_CHANGE, g: NO_CHANGE, b: NO_CHANGE };
|
|
||||||
this._contrast = { r: NO_CHANGE, g: NO_CHANGE, b: NO_CHANGE };
|
|
||||||
|
|
||||||
this._magView = null;
|
this._magView = null;
|
||||||
this._background = null;
|
this._background = null;
|
||||||
@@ -953,86 +879,6 @@ const ZoomRegion = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* setInvertLightness:
|
|
||||||
* Set whether to invert the lightness of the magnified view.
|
|
||||||
* @flag Boolean to either invert brightness (true), or not (false).
|
|
||||||
*/
|
|
||||||
setInvertLightness: function(flag) {
|
|
||||||
this._invertLightness = flag;
|
|
||||||
if (this._magShaderEffects)
|
|
||||||
this._magShaderEffects.setInvertLightness(this._invertLightness);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getInvertLightness:
|
|
||||||
* Retrieve whether the lightness is inverted.
|
|
||||||
* @return Boolean indicating inversion (true), or not (false).
|
|
||||||
*/
|
|
||||||
getInvertLightness: function() {
|
|
||||||
return this._invertLightness;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* setBrightness:
|
|
||||||
* Alter the brightness of the magnified view.
|
|
||||||
* @brightness Object containing the contrast for the red, green,
|
|
||||||
* and blue channels. Values of 0.0 represent "standard"
|
|
||||||
* brightness (no change), whereas values less or greater than
|
|
||||||
* 0.0 indicate decreased or incresaed brightness, respectively.
|
|
||||||
*/
|
|
||||||
setBrightness: function(brightness) {
|
|
||||||
this._brightness.r = brightness.r;
|
|
||||||
this._brightness.g = brightness.g;
|
|
||||||
this._brightness.b = brightness.b;
|
|
||||||
if (this._magShaderEffects)
|
|
||||||
this._magShaderEffects.setBrightness(this._brightness);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getBrightness:
|
|
||||||
* Retrive the current brightness of the Zoom Region.
|
|
||||||
* @return Object containing the brightness change for the red, green,
|
|
||||||
* and blue channels.
|
|
||||||
*/
|
|
||||||
getBrightness: function() {
|
|
||||||
let brightness = {};
|
|
||||||
brightness.r = this._brightness.r;
|
|
||||||
brightness.g = this._brightness.g;
|
|
||||||
brightness.b = this._brightness.b;
|
|
||||||
return brightness;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* setContrast:
|
|
||||||
* Alter the contrast of the magnified view.
|
|
||||||
* @contrast Object containing the contrast for the red, green,
|
|
||||||
* and blue channels. Values of 0.0 represent "standard"
|
|
||||||
* contrast (no change), whereas values less or greater than
|
|
||||||
* 0.0 indicate decreased or incresaed contrast, respectively.
|
|
||||||
*/
|
|
||||||
setContrast: function(contrast) {
|
|
||||||
this._contrast.r = contrast.r;
|
|
||||||
this._contrast.g = contrast.g;
|
|
||||||
this._contrast.b = contrast.b;
|
|
||||||
if (this._magShaderEffects)
|
|
||||||
this._magShaderEffects.setContrast(this._contrast);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getContrast:
|
|
||||||
* Retreive the contrast of the magnified view.
|
|
||||||
* @return Object containing the contrast for the red, green,
|
|
||||||
* and blue channels.
|
|
||||||
*/
|
|
||||||
getContrast: function() {
|
|
||||||
let contrast = {};
|
|
||||||
contrast.r = this._contrast.r;
|
|
||||||
contrast.g = this._contrast.g;
|
|
||||||
contrast.b = this._contrast.b;
|
|
||||||
return contrast;
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Private methods ////
|
//// Private methods ////
|
||||||
|
|
||||||
_createActors: function() {
|
_createActors: function() {
|
||||||
@@ -1071,12 +917,6 @@ const ZoomRegion = new Lang.Class({
|
|||||||
this._crossHairsActor = this._crossHairs.addToZoomRegion(this, this._mouseActor);
|
this._crossHairsActor = this._crossHairs.addToZoomRegion(this, this._mouseActor);
|
||||||
else
|
else
|
||||||
this._crossHairsActor = null;
|
this._crossHairsActor = null;
|
||||||
|
|
||||||
// Contrast and brightness effects.
|
|
||||||
this._magShaderEffects = new MagShaderEffects(this._uiGroupClone);
|
|
||||||
this._magShaderEffects.setInvertLightness(this._invertLightness);
|
|
||||||
this._magShaderEffects.setBrightness(this._brightness);
|
|
||||||
this._magShaderEffects.setContrast(this._contrast);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_destroyActors: function() {
|
_destroyActors: function() {
|
||||||
@@ -1085,8 +925,6 @@ const ZoomRegion = new Lang.Class({
|
|||||||
if (this._crossHairs)
|
if (this._crossHairs)
|
||||||
this._crossHairs.removeFromParent(this._crossHairsActor);
|
this._crossHairs.removeFromParent(this._crossHairsActor);
|
||||||
|
|
||||||
this._magShaderEffects.destroyEffects();
|
|
||||||
this._magShaderEffects = null;
|
|
||||||
this._magView.destroy();
|
this._magView.destroy();
|
||||||
this._magView = null;
|
this._magView = null;
|
||||||
this._background = null;
|
this._background = null;
|
||||||
@@ -1595,133 +1433,3 @@ const Crosshairs = new Lang.Class({
|
|||||||
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
|
this._vertBottomHair.set_position((groupWidth - thickness) / 2, bottom);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const MagShaderEffects = new Lang.Class({
|
|
||||||
Name: 'MagShaderEffects',
|
|
||||||
|
|
||||||
_init: function(uiGroupClone) {
|
|
||||||
this._inverse = new Shell.InvertLightnessEffect();
|
|
||||||
this._brightnessContrast = new Clutter.BrightnessContrastEffect();
|
|
||||||
this._inverse.set_enabled(false);
|
|
||||||
this._brightnessContrast.set_enabled(false);
|
|
||||||
|
|
||||||
this._magView = uiGroupClone;
|
|
||||||
this._magView.add_effect(this._inverse);
|
|
||||||
this._magView.add_effect(this._brightnessContrast);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* destroyEffects:
|
|
||||||
* Remove contrast and brightness effects from the magnified view, and
|
|
||||||
* lose the reference to the actor they were applied to. Don't use this
|
|
||||||
* object after calling this.
|
|
||||||
*/
|
|
||||||
destroyEffects: function() {
|
|
||||||
this._magView.clear_effects();
|
|
||||||
this._brightnessContrast = null;
|
|
||||||
this._inverse = null;
|
|
||||||
this._magView = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* setInvertLightness:
|
|
||||||
* Enable/disable invert lightness effect.
|
|
||||||
* @invertFlag: Enabled flag.
|
|
||||||
*/
|
|
||||||
setInvertLightness: function(invertFlag) {
|
|
||||||
this._inverse.set_enabled(invertFlag);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getInvertLightness:
|
|
||||||
* Report whether the inversion effect is enabled.
|
|
||||||
* @return: Boolean.
|
|
||||||
*/
|
|
||||||
getInvertLightness: function() {
|
|
||||||
return this._inverse.get_enabled();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* setBrightness:
|
|
||||||
* Set the brightness of the magnified view.
|
|
||||||
* @brightness: Object containing the brightness for the red, green,
|
|
||||||
* and blue channels. Values of 0.0 represent "standard"
|
|
||||||
* brightness (no change), whereas values less or greater than
|
|
||||||
* 0.0 indicate decreased or incresaed brightness,
|
|
||||||
* respectively.
|
|
||||||
*/
|
|
||||||
setBrightness: function(brightness) {
|
|
||||||
let bRed = brightness.r;
|
|
||||||
let bGreen = brightness.g;
|
|
||||||
let bBlue = brightness.b;
|
|
||||||
this._brightnessContrast.set_brightness_full(bRed, bGreen, bBlue);
|
|
||||||
|
|
||||||
// Enable the effect if the brightness OR contrast change are such that
|
|
||||||
// it modifies the brightness and/or contrast.
|
|
||||||
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
|
|
||||||
this._brightnessContrast.set_enabled(
|
|
||||||
(bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE ||
|
|
||||||
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getBrightness:
|
|
||||||
* Retrieve current brightness of the magnified view.
|
|
||||||
* @return: Object containing the brightness for the red, green,
|
|
||||||
* and blue channels. Values of 0.0 represent "standard"
|
|
||||||
* brightness (no change), whereas values less or greater than
|
|
||||||
* 0.0 indicate decreased or incresaed brightness, respectively.
|
|
||||||
*/
|
|
||||||
getBrightness: function() {
|
|
||||||
let result = {};
|
|
||||||
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
|
|
||||||
result.r = bRed;
|
|
||||||
result.g = bGreen;
|
|
||||||
result.b = bBlue;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the contrast of the magnified view.
|
|
||||||
* @contrast: Object containing the contrast for the red, green,
|
|
||||||
* and blue channels. Values of 0.0 represent "standard"
|
|
||||||
* contrast (no change), whereas values less or greater than
|
|
||||||
* 0.0 indicate decreased or incresaed contrast, respectively.
|
|
||||||
*/
|
|
||||||
setContrast: function(contrast) {
|
|
||||||
let cRed = contrast.r;
|
|
||||||
let cGreen = contrast.g;
|
|
||||||
let cBlue = contrast.b;
|
|
||||||
|
|
||||||
this._brightnessContrast.set_contrast_full(cRed, cGreen, cBlue);
|
|
||||||
|
|
||||||
// Enable the effect if the contrast OR brightness change are such that
|
|
||||||
// it modifies the brightness and/or contrast.
|
|
||||||
// should be able to use Clutter.color_equal(), but that complains of
|
|
||||||
// a null first argument.
|
|
||||||
let [bRed, bGreen, bBlue] = this._brightnessContrast.get_brightness();
|
|
||||||
this._brightnessContrast.set_enabled(
|
|
||||||
cRed != NO_CHANGE || cGreen != NO_CHANGE || cBlue != NO_CHANGE ||
|
|
||||||
bRed != NO_CHANGE || bGreen != NO_CHANGE || bBlue != NO_CHANGE
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve current contrast of the magnified view.
|
|
||||||
* @return: Object containing the contrast for the red, green,
|
|
||||||
* and blue channels. Values of 0.0 represent "standard"
|
|
||||||
* contrast (no change), whereas values less or greater than
|
|
||||||
* 0.0 indicate decreased or incresaed contrast, respectively.
|
|
||||||
*/
|
|
||||||
getContrast: function() {
|
|
||||||
let resutl = {};
|
|
||||||
let [cRed, cGreen, cBlue] = this._brightnessContrast.get_contrast();
|
|
||||||
result.r = cRed;
|
|
||||||
result.g = cGreen;
|
|
||||||
result.b = cBlue;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|||||||
116
js/ui/main.js
116
js/ui/main.js
@@ -18,7 +18,6 @@ const PolkitAuthenticationAgent = imports.ui.polkitAuthenticationAgent;
|
|||||||
const KeyringPrompt = imports.ui.keyringPrompt;
|
const KeyringPrompt = imports.ui.keyringPrompt;
|
||||||
const Environment = imports.ui.environment;
|
const Environment = imports.ui.environment;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
|
||||||
const Keyboard = imports.ui.keyboard;
|
const Keyboard = imports.ui.keyboard;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
@@ -31,9 +30,7 @@ const NetworkAgent = imports.ui.networkAgent;
|
|||||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||||
const Scripting = imports.ui.scripting;
|
const Scripting = imports.ui.scripting;
|
||||||
const SessionMode = imports.ui.sessionMode;
|
|
||||||
const ShellDBus = imports.ui.shellDBus;
|
const ShellDBus = imports.ui.shellDBus;
|
||||||
const ShellMountOperation = imports.ui.shellMountOperation;
|
|
||||||
const TelepathyClient = imports.ui.telepathyClient;
|
const TelepathyClient = imports.ui.telepathyClient;
|
||||||
const WindowManager = imports.ui.windowManager;
|
const WindowManager = imports.ui.windowManager;
|
||||||
const Magnifier = imports.ui.magnifier;
|
const Magnifier = imports.ui.magnifier;
|
||||||
@@ -49,6 +46,7 @@ let automountManager = null;
|
|||||||
let autorunManager = null;
|
let autorunManager = null;
|
||||||
let panel = null;
|
let panel = null;
|
||||||
let hotCorners = [];
|
let hotCorners = [];
|
||||||
|
let placesManager = null;
|
||||||
let overview = null;
|
let overview = null;
|
||||||
let runDialog = null;
|
let runDialog = null;
|
||||||
let lookingGlass = null;
|
let lookingGlass = null;
|
||||||
@@ -59,9 +57,7 @@ let windowAttentionHandler = null;
|
|||||||
let telepathyClient = null;
|
let telepathyClient = null;
|
||||||
let ctrlAltTabManager = null;
|
let ctrlAltTabManager = null;
|
||||||
let recorder = null;
|
let recorder = null;
|
||||||
let sessionMode = null;
|
|
||||||
let shellDBusService = null;
|
let shellDBusService = null;
|
||||||
let shellMountOpDBusService = null;
|
|
||||||
let modalCount = 0;
|
let modalCount = 0;
|
||||||
let modalActorFocusStack = [];
|
let modalActorFocusStack = [];
|
||||||
let uiGroup = null;
|
let uiGroup = null;
|
||||||
@@ -74,24 +70,24 @@ let networkAgent = null;
|
|||||||
let _startDate;
|
let _startDate;
|
||||||
let _defaultCssStylesheet = null;
|
let _defaultCssStylesheet = null;
|
||||||
let _cssStylesheet = null;
|
let _cssStylesheet = null;
|
||||||
|
let _gdmCssStylesheet = null;
|
||||||
let _overridesSettings = null;
|
let _overridesSettings = null;
|
||||||
|
|
||||||
let background = null;
|
let background = null;
|
||||||
|
|
||||||
function createUserSession() {
|
function _createUserSession() {
|
||||||
// Load the calendar server. Note that we are careful about
|
// Load the calendar server. Note that we are careful about
|
||||||
// not loading any events until the user presses the clock
|
// not loading any events until the user presses the clock
|
||||||
global.launch_calendar_server();
|
global.launch_calendar_server();
|
||||||
|
|
||||||
|
placesManager = new PlaceDisplay.PlacesManager();
|
||||||
telepathyClient = new TelepathyClient.Client();
|
telepathyClient = new TelepathyClient.Client();
|
||||||
automountManager = new AutomountManager.AutomountManager();
|
automountManager = new AutomountManager.AutomountManager();
|
||||||
autorunManager = new AutorunManager.AutorunManager();
|
autorunManager = new AutorunManager.AutorunManager();
|
||||||
networkAgent = new NetworkAgent.NetworkAgent();
|
networkAgent = new NetworkAgent.NetworkAgent();
|
||||||
|
|
||||||
_initRecorder();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createGDMSession() {
|
function _createGDMSession() {
|
||||||
// We do this this here instead of at the top to prevent GDM
|
// We do this this here instead of at the top to prevent GDM
|
||||||
// related code from getting loaded in normal user sessions
|
// related code from getting loaded in normal user sessions
|
||||||
const LoginDialog = imports.gdm.loginDialog;
|
const LoginDialog = imports.gdm.loginDialog;
|
||||||
@@ -102,13 +98,8 @@ function createGDMSession() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createInitialSetupSession() {
|
|
||||||
networkAgent = new NetworkAgent.NetworkAgent();
|
|
||||||
}
|
|
||||||
|
|
||||||
function _initRecorder() {
|
function _initRecorder() {
|
||||||
let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
|
let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
|
||||||
let desktopLockdownSettings = new Gio.Settings({ schema: 'org.gnome.desktop.lockdown' });
|
|
||||||
let bindingSettings = new Gio.Settings({ schema: 'org.gnome.shell.keybindings' });
|
let bindingSettings = new Gio.Settings({ schema: 'org.gnome.shell.keybindings' });
|
||||||
|
|
||||||
global.display.add_keybinding('toggle-recording',
|
global.display.add_keybinding('toggle-recording',
|
||||||
@@ -121,7 +112,7 @@ function _initRecorder() {
|
|||||||
if (recorder.is_recording()) {
|
if (recorder.is_recording()) {
|
||||||
recorder.close();
|
recorder.close();
|
||||||
Meta.enable_unredirect_for_screen(global.screen);
|
Meta.enable_unredirect_for_screen(global.screen);
|
||||||
} else if (!desktopLockdownSettings.get_boolean('disable-save-to-disk')) {
|
} else {
|
||||||
// read the parameters from GSettings always in case they have changed
|
// read the parameters from GSettings always in case they have changed
|
||||||
recorder.set_framerate(recorderSettings.get_int('framerate'));
|
recorder.set_framerate(recorderSettings.get_int('framerate'));
|
||||||
/* Translators: this is a filename used for screencast recording */
|
/* Translators: this is a filename used for screencast recording */
|
||||||
@@ -140,6 +131,26 @@ function _initRecorder() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _initUserSession() {
|
||||||
|
_initRecorder();
|
||||||
|
|
||||||
|
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1);
|
||||||
|
|
||||||
|
ExtensionSystem.init();
|
||||||
|
ExtensionSystem.loadExtensions();
|
||||||
|
|
||||||
|
Meta.keybindings_set_custom_handler('panel-run-dialog', function() {
|
||||||
|
getRunDialog().open();
|
||||||
|
});
|
||||||
|
|
||||||
|
Meta.keybindings_set_custom_handler('panel-main-menu', function () {
|
||||||
|
overview.toggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
// These are here so we don't break compatibility.
|
// These are here so we don't break compatibility.
|
||||||
global.logError = window.log;
|
global.logError = window.log;
|
||||||
@@ -150,9 +161,7 @@ function start() {
|
|||||||
|
|
||||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||||
|
|
||||||
sessionMode = new SessionMode.SessionMode();
|
|
||||||
shellDBusService = new ShellDBus.GnomeShell();
|
shellDBusService = new ShellDBus.GnomeShell();
|
||||||
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
|
|
||||||
|
|
||||||
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
||||||
// also initialize ShellAppSystem first. ShellAppSystem
|
// also initialize ShellAppSystem first. ShellAppSystem
|
||||||
@@ -174,6 +183,7 @@ function start() {
|
|||||||
global.stage.no_clear_hint = true;
|
global.stage.no_clear_hint = true;
|
||||||
|
|
||||||
_defaultCssStylesheet = global.datadir + '/theme/gnome-shell.css';
|
_defaultCssStylesheet = global.datadir + '/theme/gnome-shell.css';
|
||||||
|
_gdmCssStylesheet = global.datadir + '/theme/gdm.css';
|
||||||
loadTheme();
|
loadTheme();
|
||||||
|
|
||||||
// Set up stage hierarchy to group all UI actors under one container.
|
// Set up stage hierarchy to group all UI actors under one container.
|
||||||
@@ -201,7 +211,8 @@ function start() {
|
|||||||
layoutManager = new Layout.LayoutManager();
|
layoutManager = new Layout.LayoutManager();
|
||||||
xdndHandler = new XdndHandler.XdndHandler();
|
xdndHandler = new XdndHandler.XdndHandler();
|
||||||
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
||||||
overview = new Overview.Overview();
|
// This overview object is just a stub for non-user sessions
|
||||||
|
overview = new Overview.Overview({ isDummy: global.session_type != Shell.SessionType.USER });
|
||||||
magnifier = new Magnifier.Magnifier();
|
magnifier = new Magnifier.Magnifier();
|
||||||
statusIconDispatcher = new StatusIconDispatcher.StatusIconDispatcher();
|
statusIconDispatcher = new StatusIconDispatcher.StatusIconDispatcher();
|
||||||
panel = new Panel.Panel();
|
panel = new Panel.Panel();
|
||||||
@@ -211,7 +222,10 @@ function start() {
|
|||||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||||
|
|
||||||
sessionMode.createSession();
|
if (global.session_type == Shell.SessionType.USER)
|
||||||
|
_createUserSession();
|
||||||
|
else if (global.session_type == Shell.SessionType.GDM)
|
||||||
|
_createGDMSession();
|
||||||
|
|
||||||
panel.startStatusArea();
|
panel.startStatusArea();
|
||||||
|
|
||||||
@@ -219,30 +233,8 @@ function start() {
|
|||||||
keyboard.init();
|
keyboard.init();
|
||||||
overview.init();
|
overview.init();
|
||||||
|
|
||||||
if (sessionMode.hasWorkspaces)
|
if (global.session_type == Shell.SessionType.USER)
|
||||||
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
|
_initUserSession();
|
||||||
false, -1, 1);
|
|
||||||
|
|
||||||
if (sessionMode.allowExtensions) {
|
|
||||||
ExtensionDownloader.init();
|
|
||||||
ExtensionSystem.loadExtensions();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sessionMode.hasRunDialog) {
|
|
||||||
Meta.keybindings_set_custom_handler('panel-run-dialog', function() {
|
|
||||||
getRunDialog().open();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sessionMode.hasOverview) {
|
|
||||||
Meta.keybindings_set_custom_handler('panel-main-menu', function () {
|
|
||||||
overview.toggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
global.display.connect('overlay-key',
|
|
||||||
Lang.bind(overview, overview.toggle));
|
|
||||||
}
|
|
||||||
|
|
||||||
statusIconDispatcher.start(messageTray.actor);
|
statusIconDispatcher.start(messageTray.actor);
|
||||||
|
|
||||||
// Provide the bus object for gnome-session to
|
// Provide the bus object for gnome-session to
|
||||||
@@ -501,8 +493,8 @@ function loadTheme() {
|
|||||||
|
|
||||||
let theme = new St.Theme ({ application_stylesheet: cssStylesheet });
|
let theme = new St.Theme ({ application_stylesheet: cssStylesheet });
|
||||||
|
|
||||||
if (sessionMode.extraStylesheet)
|
if (global.session_type == Shell.SessionType.GDM)
|
||||||
theme.load_stylesheet(sessionMode.extraStylesheet);
|
theme.load_stylesheet(_gdmCssStylesheet);
|
||||||
|
|
||||||
if (previousTheme) {
|
if (previousTheme) {
|
||||||
let customStylesheets = previousTheme.get_custom_stylesheets();
|
let customStylesheets = previousTheme.get_custom_stylesheets();
|
||||||
@@ -566,11 +558,6 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
if (event.type() != Clutter.EventType.KEY_PRESS)
|
if (event.type() != Clutter.EventType.KEY_PRESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!sessionMode.allowKeybindingsWhenModal) {
|
|
||||||
if (modalCount > (overview.visible ? 1 : 0))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
let keyCode = event.get_key_code();
|
let keyCode = event.get_key_code();
|
||||||
let ignoredModifiers = global.display.get_ignored_modifier_mask();
|
let ignoredModifiers = global.display.get_ignored_modifier_mask();
|
||||||
@@ -579,6 +566,11 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
|
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
|
||||||
let action = global.display.get_keybinding_action(keyCode, modifierState);
|
let action = global.display.get_keybinding_action(keyCode, modifierState);
|
||||||
|
|
||||||
|
// Other bindings are only available to the user session when the overview is up and
|
||||||
|
// no modal dialog is present.
|
||||||
|
if (global.session_type == Shell.SessionType.USER && (!overview.visible || modalCount > 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
// This isn't a Meta.KeyBindingAction yet
|
// This isn't a Meta.KeyBindingAction yet
|
||||||
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
|
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
|
||||||
overview.hide();
|
overview.hide();
|
||||||
@@ -591,39 +583,28 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// None of the other bindings are relevant outside of the user's session
|
||||||
|
if (global.session_type != Shell.SessionType.USER)
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
// left/right would effectively act as synonyms for up/down if we enabled them;
|
// left/right would effectively act as synonyms for up/down if we enabled them;
|
||||||
// but that could be considered confusing; we also disable them in the main view.
|
// but that could be considered confusing; we also disable them in the main view.
|
||||||
//
|
//
|
||||||
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
|
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
|
||||||
// if (!sessionMode.hasWorkspaces)
|
|
||||||
// return false;
|
|
||||||
//
|
|
||||||
// wm.actionMoveWorkspaceLeft();
|
// wm.actionMoveWorkspaceLeft();
|
||||||
// return true;
|
// return true;
|
||||||
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
|
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
|
||||||
// if (!sessionMode.hasWorkspaces)
|
|
||||||
// return false;
|
|
||||||
//
|
|
||||||
// wm.actionMoveWorkspaceRight();
|
// wm.actionMoveWorkspaceRight();
|
||||||
// return true;
|
// return true;
|
||||||
case Meta.KeyBindingAction.WORKSPACE_UP:
|
case Meta.KeyBindingAction.WORKSPACE_UP:
|
||||||
if (!sessionMode.hasWorkspaces)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
wm.actionMoveWorkspaceUp();
|
wm.actionMoveWorkspaceUp();
|
||||||
return true;
|
return true;
|
||||||
case Meta.KeyBindingAction.WORKSPACE_DOWN:
|
case Meta.KeyBindingAction.WORKSPACE_DOWN:
|
||||||
if (!sessionMode.hasWorkspaces)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
wm.actionMoveWorkspaceDown();
|
wm.actionMoveWorkspaceDown();
|
||||||
return true;
|
return true;
|
||||||
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
|
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
|
||||||
case Meta.KeyBindingAction.COMMAND_2:
|
case Meta.KeyBindingAction.COMMAND_2:
|
||||||
if (!sessionMode.hasRunDialog)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
getRunDialog().open();
|
getRunDialog().open();
|
||||||
return true;
|
return true;
|
||||||
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
|
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
|
||||||
@@ -674,7 +655,6 @@ function pushModal(actor, timestamp, options) {
|
|||||||
log('pushModal: invocation of begin_modal failed');
|
log('pushModal: invocation of begin_modal failed');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Meta.disable_unredirect_for_screen(global.screen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
||||||
@@ -755,7 +735,6 @@ function popModal(actor, timestamp) {
|
|||||||
|
|
||||||
global.end_modal(timestamp);
|
global.end_modal(timestamp);
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
||||||
Meta.enable_unredirect_for_screen(global.screen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLookingGlass() {
|
function createLookingGlass() {
|
||||||
@@ -898,8 +877,7 @@ function initializeDeferredWork(actor, callback, props) {
|
|||||||
function queueDeferredWork(workId) {
|
function queueDeferredWork(workId) {
|
||||||
let data = _deferredWorkData[workId];
|
let data = _deferredWorkData[workId];
|
||||||
if (!data) {
|
if (!data) {
|
||||||
let message = 'Invalid work id %d'.format(workId);
|
global.logError('invalid work id ', workId);
|
||||||
logError(new Error(message), message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_deferredWorkQueue.indexOf(workId) < 0)
|
if (_deferredWorkQueue.indexOf(workId) < 0)
|
||||||
|
|||||||
@@ -746,7 +746,6 @@ const Notification = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let button = new St.Button({ can_focus: true });
|
let button = new St.Button({ can_focus: true });
|
||||||
button._actionId = id;
|
|
||||||
|
|
||||||
if (this._useActionIcons && Gtk.IconTheme.get_default().has_icon(id)) {
|
if (this._useActionIcons && Gtk.IconTheme.get_default().has_icon(id)) {
|
||||||
button.add_style_class_name('notification-icon-button');
|
button.add_style_class_name('notification-icon-button');
|
||||||
@@ -756,7 +755,7 @@ const Notification = new Lang.Class({
|
|||||||
button.label = label;
|
button.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._buttonBox.get_n_children() > 0)
|
if (this._buttonBox.get_children().length > 0)
|
||||||
this._buttonFocusManager.remove_group(this._buttonBox);
|
this._buttonFocusManager.remove_group(this._buttonBox);
|
||||||
|
|
||||||
this._buttonBox.add(button);
|
this._buttonBox.add(button);
|
||||||
@@ -766,31 +765,6 @@ const Notification = new Lang.Class({
|
|||||||
this.updated();
|
this.updated();
|
||||||
},
|
},
|
||||||
|
|
||||||
// setButtonSensitive:
|
|
||||||
// @id: the action ID
|
|
||||||
// @sensitive: whether the button should be sensitive
|
|
||||||
//
|
|
||||||
// If the notification contains a button with action ID @id,
|
|
||||||
// its sensitivity will be set to @sensitive. Insensitive
|
|
||||||
// buttons cannot be clicked.
|
|
||||||
setButtonSensitive: function(id, sensitive) {
|
|
||||||
if (!this._buttonBox)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let button = this._buttonBox.get_children().filter(function(b) {
|
|
||||||
return b._actionId == id;
|
|
||||||
})[0];
|
|
||||||
|
|
||||||
if (!button || button.reactive == sensitive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
button.reactive = sensitive;
|
|
||||||
if (sensitive)
|
|
||||||
button.remove_style_pseudo_class('insensitive');
|
|
||||||
else
|
|
||||||
button.add_style_pseudo_class('insensitive');
|
|
||||||
},
|
|
||||||
|
|
||||||
setUrgency: function(urgency) {
|
setUrgency: function(urgency) {
|
||||||
this.urgency = urgency;
|
this.urgency = urgency;
|
||||||
},
|
},
|
||||||
@@ -986,10 +960,8 @@ const Source = new Lang.Class({
|
|||||||
|
|
||||||
ICON_SIZE: 24,
|
ICON_SIZE: 24,
|
||||||
|
|
||||||
_init: function(title, iconName, iconType) {
|
_init: function(title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.iconName = iconName;
|
|
||||||
this.iconType = iconType;
|
|
||||||
|
|
||||||
this.actor = new Shell.GenericContainer();
|
this.actor = new Shell.GenericContainer();
|
||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
@@ -1019,8 +991,6 @@ const Source = new Lang.Class({
|
|||||||
this.isMuted = false;
|
this.isMuted = false;
|
||||||
|
|
||||||
this.notifications = [];
|
this.notifications = [];
|
||||||
|
|
||||||
this._setSummaryIcon(this.createNotificationIcon());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredWidth: function (actor, forHeight, alloc) {
|
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||||
@@ -1091,12 +1061,10 @@ const Source = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Called to create a new icon actor (of size this.ICON_SIZE).
|
// Called to create a new icon actor (of size this.ICON_SIZE).
|
||||||
// Provides a sane default implementation, override if you need
|
// Must be overridden by the subclass if you do not pass icons
|
||||||
// something more fancy.
|
// explicitly to the Notification() constructor.
|
||||||
createNotificationIcon: function() {
|
createNotificationIcon: function() {
|
||||||
return new St.Icon({ icon_name: this.iconName,
|
throw new Error('no implementation of createNotificationIcon in ' + this);
|
||||||
icon_type: this.iconType,
|
|
||||||
icon_size: this.ICON_SIZE });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Unlike createNotificationIcon, this always returns the same actor;
|
// Unlike createNotificationIcon, this always returns the same actor;
|
||||||
@@ -1147,14 +1115,16 @@ const Source = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
//// Protected methods ////
|
//// Protected methods ////
|
||||||
|
|
||||||
|
// The subclass must call this at least once to set the summary icon.
|
||||||
_setSummaryIcon: function(icon) {
|
_setSummaryIcon: function(icon) {
|
||||||
if (this._iconBin.child)
|
if (this._iconBin.child)
|
||||||
this._iconBin.child.destroy();
|
this._iconBin.child.destroy();
|
||||||
this._iconBin.child = icon;
|
this._iconBin.child = icon;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Default implementation is to do nothing, but subclasses can override
|
||||||
open: function(notification) {
|
open: function(notification) {
|
||||||
this.emit('opened', notification);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyNonResidentNotifications: function() {
|
destroyNonResidentNotifications: function() {
|
||||||
@@ -1284,7 +1254,7 @@ const SummaryItem = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
prepareNotificationStackForShowing: function() {
|
prepareNotificationStackForShowing: function() {
|
||||||
if (this.notificationStack.get_n_children() > 0)
|
if (this.notificationStack.get_children().length > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (let i = 0; i < this.source.notifications.length; i++) {
|
for (let i = 0; i < this.source.notifications.length; i++) {
|
||||||
@@ -1293,6 +1263,7 @@ const SummaryItem = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
doneShowingNotificationStack: function() {
|
doneShowingNotificationStack: function() {
|
||||||
|
let notificationActors = this.notificationStack.get_children();
|
||||||
for (let i = 0; i < this._stackedNotifications.length; i++) {
|
for (let i = 0; i < this._stackedNotifications.length; i++) {
|
||||||
let stackedNotification = this._stackedNotifications[i];
|
let stackedNotification = this._stackedNotifications[i];
|
||||||
let notification = stackedNotification.notification;
|
let notification = stackedNotification.notification;
|
||||||
@@ -1322,7 +1293,7 @@ const SummaryItem = new Lang.Class({
|
|||||||
this._stackedNotifications.push(stackedNotification);
|
this._stackedNotifications.push(stackedNotification);
|
||||||
if (!this.source.isChat)
|
if (!this.source.isChat)
|
||||||
notification.enableScrolling(false);
|
notification.enableScrolling(false);
|
||||||
if (this.notificationStack.get_n_children() > 0)
|
if (this.notificationStack.get_children().length > 0)
|
||||||
notification.setIconVisible(false);
|
notification.setIconVisible(false);
|
||||||
this.notificationStack.add(notification.actor);
|
this.notificationStack.add(notification.actor);
|
||||||
notification.expand(false);
|
notification.expand(false);
|
||||||
@@ -1468,7 +1439,6 @@ const MessageTray = new Lang.Class({
|
|||||||
this._overviewVisible = Main.overview.visible;
|
this._overviewVisible = Main.overview.visible;
|
||||||
this._notificationRemoved = false;
|
this._notificationRemoved = false;
|
||||||
this._reNotifyAfterHideNotification = null;
|
this._reNotifyAfterHideNotification = null;
|
||||||
this._inFullscreen = false;
|
|
||||||
|
|
||||||
this._corner = new Clutter.Rectangle({ width: 1,
|
this._corner = new Clutter.Rectangle({ width: 1,
|
||||||
height: 1,
|
height: 1,
|
||||||
@@ -1484,7 +1454,6 @@ const MessageTray = new Lang.Class({
|
|||||||
Main.layoutManager.trackChrome(this._notificationBin);
|
Main.layoutManager.trackChrome(this._notificationBin);
|
||||||
|
|
||||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
|
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
|
||||||
Main.layoutManager.connect('primary-fullscreen-changed', Lang.bind(this, this._onFullscreenChanged));
|
|
||||||
|
|
||||||
this._setSizePosition();
|
this._setSizePosition();
|
||||||
|
|
||||||
@@ -1958,11 +1927,6 @@ const MessageTray = new Lang.Class({
|
|||||||
this._updateState();
|
this._updateState();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onFullscreenChanged: function(obj, state) {
|
|
||||||
this._inFullscreen = state;
|
|
||||||
this._updateState();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onStatusChanged: function(status) {
|
_onStatusChanged: function(status) {
|
||||||
if (status == GnomeSession.PresenceStatus.BUSY) {
|
if (status == GnomeSession.PresenceStatus.BUSY) {
|
||||||
// remove notification and allow the summary to be closed now
|
// remove notification and allow the summary to be closed now
|
||||||
@@ -2020,7 +1984,7 @@ const MessageTray = new Lang.Class({
|
|||||||
_updateState: function() {
|
_updateState: function() {
|
||||||
// Notifications
|
// Notifications
|
||||||
let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
|
let notificationUrgent = this._notificationQueue.length > 0 && this._notificationQueue[0].urgency == Urgency.CRITICAL;
|
||||||
let notificationsPending = this._notificationQueue.length > 0 && ((!this._busy && !this._inFullscreen) || notificationUrgent);
|
let notificationsPending = this._notificationQueue.length > 0 && (!this._busy || notificationUrgent);
|
||||||
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
||||||
let notificationExpanded = this._notificationBin.y < 0;
|
let notificationExpanded = this._notificationBin.y < 0;
|
||||||
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked && !(this._pointerInKeyboard && notificationExpanded)) || this._notificationRemoved;
|
let notificationExpired = (this._notificationTimeoutId == 0 && !(this._notification && this._notification.urgency == Urgency.CRITICAL) && !this._pointerInTray && !this._locked && !(this._pointerInKeyboard && notificationExpanded)) || this._notificationRemoved;
|
||||||
@@ -2056,7 +2020,7 @@ const MessageTray = new Lang.Class({
|
|||||||
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
|
if (this._summaryState == State.HIDDEN && !mustHideSummary) {
|
||||||
if (summarySummoned) {
|
if (summarySummoned) {
|
||||||
this._showSummary(0);
|
this._showSummary(0);
|
||||||
} else if (notificationsDone && !this._busy && !this._inFullscreen) {
|
} else if (notificationsDone && !this._busy) {
|
||||||
if (this._backFromAway && this._unseenNotifications.length > 0)
|
if (this._backFromAway && this._unseenNotifications.length > 0)
|
||||||
this._showSummary(LONGER_SUMMARY_TIMEOUT);
|
this._showSummary(LONGER_SUMMARY_TIMEOUT);
|
||||||
else if (this._newSummaryItems.length > 0)
|
else if (this._newSummaryItems.length > 0)
|
||||||
@@ -2435,7 +2399,7 @@ const MessageTray = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onSummaryBoxPointerContentUpdated: function() {
|
_onSummaryBoxPointerContentUpdated: function() {
|
||||||
if (this._summaryBoxPointerItem.notificationStack.get_n_children() == 0)
|
if (this._summaryBoxPointerItem.notificationStack.get_children().length == 0)
|
||||||
this._hideSummaryBoxPointer();
|
this._hideSummaryBoxPointer();
|
||||||
this._adjustSummaryBoxPointerPosition();
|
this._adjustSummaryBoxPointerPosition();
|
||||||
|
|
||||||
@@ -2469,7 +2433,7 @@ const MessageTray = new Lang.Class({
|
|||||||
// We should be sure to hide the box pointer if all notifications in it are destroyed while
|
// We should be sure to hide the box pointer if all notifications in it are destroyed while
|
||||||
// it is hiding, so that we don't show an an animation of an empty blob being hidden.
|
// it is hiding, so that we don't show an an animation of an empty blob being hidden.
|
||||||
if (this._summaryBoxPointerState == State.HIDING &&
|
if (this._summaryBoxPointerState == State.HIDING &&
|
||||||
this._summaryBoxPointerItem.notificationStack.get_n_children() == 0) {
|
this._summaryBoxPointerItem.notificationStack.get_children().length == 0) {
|
||||||
this._summaryBoxPointer.actor.hide();
|
this._summaryBoxPointer.actor.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2525,7 +2489,15 @@ const SystemNotificationSource = new Lang.Class({
|
|||||||
Extends: Source,
|
Extends: Source,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("System Information"), 'dialog-information', St.IconType.SYMBOLIC);
|
this.parent(_("System Information"));
|
||||||
|
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
return new St.Icon({ icon_name: 'dialog-information',
|
||||||
|
icon_type: St.IconType.SYMBOLIC,
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function() {
|
open: function() {
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ const ModalDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_fadeOpen: function() {
|
_fadeOpen: function() {
|
||||||
let monitor = Main.layoutManager.currentMonitor;
|
let monitor = Main.layoutManager.focusMonitor;
|
||||||
|
|
||||||
this._backgroundBin.set_position(monitor.x, monitor.y);
|
this._backgroundBin.set_position(monitor.x, monitor.y);
|
||||||
this._backgroundBin.set_size(monitor.width, monitor.height);
|
this._backgroundBin.set_size(monitor.width, monitor.height);
|
||||||
|
|||||||
@@ -221,19 +221,12 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
|
let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
|
||||||
let id;
|
let id;
|
||||||
|
|
||||||
for (let hint in hints) {
|
|
||||||
// unpack the variants
|
|
||||||
hints[hint] = hints[hint].deep_unpack();
|
|
||||||
}
|
|
||||||
|
|
||||||
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
|
||||||
|
|
||||||
// Filter out chat, presence, calls and invitation notifications from
|
// Filter out chat, presence, calls and invitation notifications from
|
||||||
// Empathy, since we handle that information from telepathyClient.js
|
// Empathy, since we handle that information from telepathyClient.js
|
||||||
if (appName == 'Empathy' && (hints['category'] == 'im.received' ||
|
if (appName == 'Empathy' && (hints['category'] == 'im.received' ||
|
||||||
hints['category'] == 'x-empathy.im.room-invitation' ||
|
hints['category'] == 'x-empathy.im.room-invitation' ||
|
||||||
hints['category'] == 'x-empathy.call.incoming' ||
|
hints['category'] == 'x-empathy.call.incoming' ||
|
||||||
hints['category'] == 'x-empathy.transfer.incoming' ||
|
hints['category'] == 'x-empathy.call.incoming"' ||
|
||||||
hints['category'] == 'x-empathy.im.subscription-request' ||
|
hints['category'] == 'x-empathy.im.subscription-request' ||
|
||||||
hints['category'] == 'presence.online' ||
|
hints['category'] == 'presence.online' ||
|
||||||
hints['category'] == 'presence.offline')) {
|
hints['category'] == 'presence.offline')) {
|
||||||
@@ -256,6 +249,13 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let hint in hints) {
|
||||||
|
// unpack the variants
|
||||||
|
hints[hint] = hints[hint].deep_unpack();
|
||||||
|
}
|
||||||
|
|
||||||
|
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
||||||
|
|
||||||
// Be compatible with the various hints for image data and image path
|
// Be compatible with the various hints for image data and image path
|
||||||
// 'image-data' and 'image-path' are the latest name of these hints, introduced in 1.2
|
// 'image-data' and 'image-path' are the latest name of these hints, introduced in 1.2
|
||||||
|
|
||||||
@@ -483,7 +483,7 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconAdded: function(o, icon) {
|
_onTrayIconAdded: function(o, icon) {
|
||||||
let source = this._getSource(icon.title || icon.wm_class || C_("program", "Unknown"), icon.pid, null, null, icon);
|
let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null, null, icon);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconRemoved: function(o, icon) {
|
_onTrayIconRemoved: function(o, icon) {
|
||||||
@@ -638,10 +638,5 @@ const Source = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
},
|
|
||||||
|
|
||||||
createNotificationIcon: function() {
|
|
||||||
// We set the summary icon ourselves.
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Config = imports.misc.config;
|
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
@@ -12,9 +11,10 @@ const Shell = imports.gi.Shell;
|
|||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
|
|
||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const ContactDisplay = Config.HAVE_FOLKS ? imports.ui.contactDisplay : null;
|
const ContactDisplay = imports.ui.contactDisplay;
|
||||||
const Dash = imports.ui.dash;
|
const Dash = imports.ui.dash;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
@@ -99,8 +99,10 @@ const ShellInfo = new Lang.Class({
|
|||||||
const Overview = new Lang.Class({
|
const Overview = new Lang.Class({
|
||||||
Name: 'Overview',
|
Name: 'Overview',
|
||||||
|
|
||||||
_init : function() {
|
_init : function(params) {
|
||||||
this.isDummy = !Main.sessionMode.hasOverview;
|
params = Params.parse(params, { isDummy: false });
|
||||||
|
|
||||||
|
this.isDummy = params.isDummy;
|
||||||
|
|
||||||
// We only have an overview in user sessions, so
|
// We only have an overview in user sessions, so
|
||||||
// create a dummy overview in other cases
|
// create a dummy overview in other cases
|
||||||
@@ -208,8 +210,7 @@ const Overview = new Lang.Class({
|
|||||||
this.addSearchProvider(new AppDisplay.AppSearchProvider());
|
this.addSearchProvider(new AppDisplay.AppSearchProvider());
|
||||||
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
|
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
|
||||||
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
|
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
|
||||||
if (ContactDisplay != null)
|
this.addSearchProvider(new ContactDisplay.ContactSearchProvider());
|
||||||
this.addSearchProvider(new ContactDisplay.ContactSearchProvider());
|
|
||||||
|
|
||||||
// Load remote search providers provided by applications
|
// Load remote search providers provided by applications
|
||||||
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
|
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const St = imports.gi.St;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Atk = imports.gi.Atk;
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
|
const Config = imports.misc.config;
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
@@ -31,6 +32,33 @@ const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
|
|||||||
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
|
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
|
||||||
const SPINNER_ANIMATION_TIME = 0.2;
|
const SPINNER_ANIMATION_TIME = 0.2;
|
||||||
|
|
||||||
|
const STANDARD_STATUS_AREA_ORDER = ['a11y', 'keyboard', 'volume', 'bluetooth', 'network', 'battery', 'userMenu'];
|
||||||
|
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
||||||
|
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||||
|
'volume': imports.ui.status.volume.Indicator,
|
||||||
|
'battery': imports.ui.status.power.Indicator,
|
||||||
|
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||||
|
'userMenu': imports.ui.userMenu.UserMenuButton
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Config.HAVE_BLUETOOTH)
|
||||||
|
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
|
||||||
|
|
||||||
|
try {
|
||||||
|
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
|
||||||
|
} catch(e) {
|
||||||
|
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
||||||
|
}
|
||||||
|
|
||||||
|
const GDM_STATUS_AREA_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery', 'powerMenu'];
|
||||||
|
const GDM_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
||||||
|
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||||
|
'volume': imports.ui.status.volume.Indicator,
|
||||||
|
'battery': imports.ui.status.power.Indicator,
|
||||||
|
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||||
|
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
|
||||||
|
};
|
||||||
|
|
||||||
// To make sure the panel corners blend nicely with the panel,
|
// To make sure the panel corners blend nicely with the panel,
|
||||||
// we draw background and borders the same way, e.g. drawing
|
// we draw background and borders the same way, e.g. drawing
|
||||||
// them as filled shapes from the outside inwards instead of
|
// them as filled shapes from the outside inwards instead of
|
||||||
@@ -934,7 +962,7 @@ const Panel = new Lang.Class({
|
|||||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
|
|
||||||
/* Button on the left side of the panel. */
|
/* Button on the left side of the panel. */
|
||||||
if (Main.sessionMode.hasOverview) {
|
if (global.session_type == Shell.SessionType.USER) {
|
||||||
this._activitiesButton = new ActivitiesButton();
|
this._activitiesButton = new ActivitiesButton();
|
||||||
this._activities = this._activitiesButton.actor;
|
this._activities = this._activitiesButton.actor;
|
||||||
this._leftBox.add(this._activities);
|
this._leftBox.add(this._activities);
|
||||||
@@ -942,19 +970,28 @@ const Panel = new Lang.Class({
|
|||||||
// The activities button has a pretend menu, so as to integrate
|
// The activities button has a pretend menu, so as to integrate
|
||||||
// more cleanly with the rest of the panel
|
// more cleanly with the rest of the panel
|
||||||
this._menus.addMenu(this._activitiesButton.menu);
|
this._menus.addMenu(this._activitiesButton.menu);
|
||||||
}
|
|
||||||
|
|
||||||
if (Main.sessionMode.hasAppMenu) {
|
|
||||||
this._appMenu = new AppMenuButton(this._menus);
|
this._appMenu = new AppMenuButton(this._menus);
|
||||||
this._leftBox.add(this._appMenu.actor);
|
this._leftBox.add(this._appMenu.actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* center */
|
/* center */
|
||||||
this._dateMenu = new DateMenu.DateMenuButton();
|
if (global.session_type == Shell.SessionType.USER)
|
||||||
|
this._dateMenu = new DateMenu.DateMenuButton({ showEvents: true });
|
||||||
|
else
|
||||||
|
this._dateMenu = new DateMenu.DateMenuButton({ showEvents: false });
|
||||||
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
|
this._centerBox.add(this._dateMenu.actor, { y_fill: true });
|
||||||
this._menus.addMenu(this._dateMenu.menu);
|
this._menus.addMenu(this._dateMenu.menu);
|
||||||
|
|
||||||
/* right */
|
/* right */
|
||||||
|
if (global.session_type == Shell.SessionType.GDM) {
|
||||||
|
this._status_area_order = GDM_STATUS_AREA_ORDER;
|
||||||
|
this._status_area_shell_implementation = GDM_STATUS_AREA_SHELL_IMPLEMENTATION;
|
||||||
|
} else {
|
||||||
|
this._status_area_order = STANDARD_STATUS_AREA_ORDER;
|
||||||
|
this._status_area_shell_implementation = STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION;
|
||||||
|
}
|
||||||
|
|
||||||
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
||||||
Main.statusIconDispatcher.connect('status-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
|
Main.statusIconDispatcher.connect('status-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
|
||||||
|
|
||||||
@@ -1078,17 +1115,17 @@ const Panel = new Lang.Class({
|
|||||||
|
|
||||||
openAppMenu: function() {
|
openAppMenu: function() {
|
||||||
let menu = this._appMenu.menu;
|
let menu = this._appMenu.menu;
|
||||||
if (!this._appMenu.actor.reactive || menu.isOpen)
|
if (Main.overview.visible || menu.isOpen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
menu.open();
|
menu.open();
|
||||||
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
startStatusArea: function() {
|
startStatusArea: function() {
|
||||||
for (let i = 0; i < Main.sessionMode.statusArea.order.length; i++) {
|
for (let i = 0; i < this._status_area_order.length; i++) {
|
||||||
let role = Main.sessionMode.statusArea.order[i];
|
let role = this._status_area_order[i];
|
||||||
let constructor = Main.sessionMode.statusArea.implementation[role];
|
let constructor = this._status_area_shell_implementation[role];
|
||||||
if (!constructor) {
|
if (!constructor) {
|
||||||
// This icon is not implemented (this is a bug)
|
// This icon is not implemented (this is a bug)
|
||||||
continue;
|
continue;
|
||||||
@@ -1138,21 +1175,18 @@ const Panel = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconAdded: function(o, icon, role) {
|
_onTrayIconAdded: function(o, icon, role) {
|
||||||
if (Main.sessionMode.statusArea.implementation[role]) {
|
if (this._status_area_shell_implementation[role]) {
|
||||||
// This icon is legacy, and replaced by a Shell version
|
// This icon is legacy, and replaced by a Shell version
|
||||||
// Hide it
|
// Hide it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Main.sessionMode.statusArea.order.indexOf(role) == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
icon.height = PANEL_ICON_SIZE;
|
icon.height = PANEL_ICON_SIZE;
|
||||||
let buttonBox = new PanelMenu.ButtonBox();
|
let buttonBox = new PanelMenu.ButtonBox();
|
||||||
let box = buttonBox.actor;
|
let box = buttonBox.actor;
|
||||||
box.add_actor(icon);
|
box.add_actor(icon);
|
||||||
|
|
||||||
this._insertStatusItem(box, Main.sessionMode.statusArea.order.indexOf(role));
|
this._insertStatusItem(box, this._status_area_order.indexOf(role));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTrayIconRemoved: function(o, icon) {
|
_onTrayIconRemoved: function(o, icon) {
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ const PlacesManager = new Lang.Class({
|
|||||||
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
||||||
this._updateDevices();
|
this._updateDevices();
|
||||||
|
|
||||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_user_config_dir(), 'gtk-3.0', 'bookmarks']);
|
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), '.gtk-bookmarks']);
|
||||||
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
||||||
this._monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
this._monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
||||||
this._bookmarkTimeoutId = 0;
|
this._bookmarkTimeoutId = 0;
|
||||||
@@ -365,13 +365,12 @@ const PlaceSearchProvider = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(_("PLACES & DEVICES"));
|
this.parent(_("PLACES & DEVICES"));
|
||||||
this.placesManager = new PlacesManager();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(resultIds, callback) {
|
getResultMetas: function(resultIds) {
|
||||||
let metas = [];
|
let metas = [];
|
||||||
for (let i = 0; i < resultIds.length; i++) {
|
for (let i = 0; i < resultIds.length; i++) {
|
||||||
let placeInfo = this.placesManager.lookupPlaceById(resultIds[i]);
|
let placeInfo = Main.placesManager.lookupPlaceById(resultIds[i]);
|
||||||
if (!placeInfo)
|
if (!placeInfo)
|
||||||
metas.push(null);
|
metas.push(null);
|
||||||
else
|
else
|
||||||
@@ -382,22 +381,24 @@ const PlaceSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback(metas);
|
return metas;
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(id, params) {
|
activateResult: function(id, params) {
|
||||||
let placeInfo = this.placesManager.lookupPlaceById(id);
|
let placeInfo = Main.placesManager.lookupPlaceById(id);
|
||||||
placeInfo.launch(params);
|
placeInfo.launch(params);
|
||||||
},
|
},
|
||||||
|
|
||||||
_compareResultMeta: function (idA, idB) {
|
_compareResultMeta: function (idA, idB) {
|
||||||
let infoA = this.placesManager.lookupPlaceById(idA);
|
let infoA = Main.placesManager.lookupPlaceById(idA);
|
||||||
let infoB = this.placesManager.lookupPlaceById(idB);
|
let infoB = Main.placesManager.lookupPlaceById(idB);
|
||||||
return infoA.name.localeCompare(infoB.name);
|
return infoA.name.localeCompare(infoB.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
_searchPlaces: function(places, terms) {
|
_searchPlaces: function(places, terms) {
|
||||||
|
let multiplePrefixResults = [];
|
||||||
let prefixResults = [];
|
let prefixResults = [];
|
||||||
|
let multipleSubstringResults = [];
|
||||||
let substringResults = [];
|
let substringResults = [];
|
||||||
|
|
||||||
terms = terms.map(String.toLowerCase);
|
terms = terms.map(String.toLowerCase);
|
||||||
@@ -405,26 +406,29 @@ const PlaceSearchProvider = new Lang.Class({
|
|||||||
for (let i = 0; i < places.length; i++) {
|
for (let i = 0; i < places.length; i++) {
|
||||||
let place = places[i];
|
let place = places[i];
|
||||||
let mtype = place.matchTerms(terms);
|
let mtype = place.matchTerms(terms);
|
||||||
if (mtype == Search.MatchType.PREFIX)
|
if (mtype == Search.MatchType.MULTIPLE_PREFIX)
|
||||||
|
multiplePrefixResults.push(place.id);
|
||||||
|
else if (mtype == Search.MatchType.PREFIX)
|
||||||
prefixResults.push(place.id);
|
prefixResults.push(place.id);
|
||||||
|
else if (mtype == Search.MatchType.MULTIPLE_SUBSTRING)
|
||||||
|
multipleSubstringResults.push(place.id);
|
||||||
else if (mtype == Search.MatchType.SUBSTRING)
|
else if (mtype == Search.MatchType.SUBSTRING)
|
||||||
substringResults.push(place.id);
|
substringResults.push(place.id);
|
||||||
}
|
}
|
||||||
prefixResults.sort(Lang.bind(this, this._compareResultMeta));
|
multiplePrefixResults.sort(this._compareResultMeta);
|
||||||
substringResults.sort(Lang.bind(this, this._compareResultMeta));
|
prefixResults.sort(this._compareResultMeta);
|
||||||
|
multipleSubstringResults.sort(this._compareResultMeta);
|
||||||
this.searchSystem.pushResults(this, prefixResults.concat(substringResults));
|
substringResults.sort(this._compareResultMeta);
|
||||||
|
return multiplePrefixResults.concat(prefixResults.concat(multipleSubstringResults.concat(substringResults)));
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
let places = this.placesManager.getAllPlaces();
|
let places = Main.placesManager.getAllPlaces();
|
||||||
this._searchPlaces(places, terms);
|
return this._searchPlaces(places, terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
let places = previousResults.map(Lang.bind(this, function(id) {
|
let places = previousResults.map(function (id) { return Main.placesManager.lookupPlaceById(id); });
|
||||||
return this.placesManager.lookupPlaceById(id);
|
return this._searchPlaces(places, terms);
|
||||||
}));
|
|
||||||
this._searchPlaces(places, terms);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -167,7 +167,6 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
*/
|
*/
|
||||||
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
|
this._nullMessageLabel = new St.Label({ style_class: 'prompt-dialog-null-label',
|
||||||
text: 'abc'});
|
text: 'abc'});
|
||||||
this._nullMessageLabel.add_style_class_name('hidden');
|
|
||||||
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
this._nullMessageLabel.clutter_text.line_wrap = true;
|
this._nullMessageLabel.clutter_text.line_wrap = true;
|
||||||
messageBox.add(this._nullMessageLabel);
|
messageBox.add(this._nullMessageLabel);
|
||||||
|
|||||||
@@ -888,7 +888,8 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addSettingsAction: function(title, desktopFile) {
|
addSettingsAction: function(title, desktopFile) {
|
||||||
if (!Main.sessionMode.allowSettings)
|
// Don't allow user settings to get edited unless we're in a user session
|
||||||
|
if (global.session_type != Shell.SessionType.USER)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
let menuItem = this.addAction(title, function() {
|
let menuItem = this.addAction(title, function() {
|
||||||
@@ -906,7 +907,7 @@ const PopupMenuBase = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
isEmpty: function() {
|
isEmpty: function() {
|
||||||
return this.box.get_n_children() == 0;
|
return this.box.get_children().length == 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
isChildMenu: function(menu) {
|
isChildMenu: function(menu) {
|
||||||
@@ -1920,7 +1921,7 @@ const RemoteMenu = new Lang.Class({
|
|||||||
while (k0 < currentItems.length && currentItems[k0]._ignored)
|
while (k0 < currentItems.length && currentItems[k0]._ignored)
|
||||||
k0++;
|
k0++;
|
||||||
// find the right menu item matching the model item
|
// find the right menu item matching the model item
|
||||||
for (j0 = 0; k0 < currentItems.length && j0 < position; j0++, k0++) {
|
for (j0 = 0; j0 < position; j0++, k0++) {
|
||||||
if (currentItems[k0]._ignored)
|
if (currentItems[k0]._ignored)
|
||||||
k0++;
|
k0++;
|
||||||
}
|
}
|
||||||
@@ -1930,7 +1931,7 @@ const RemoteMenu = new Lang.Class({
|
|||||||
for (k = k0; k < currentItems.length; k++)
|
for (k = k0; k < currentItems.length; k++)
|
||||||
currentItems[k].destroy();
|
currentItems[k].destroy();
|
||||||
} else {
|
} else {
|
||||||
for (j = j0, k = k0; k < currentItems.length && j < j0 + removed; j++, k++) {
|
for (j = j0, k = k0; j < j0 + removed; j++, k++) {
|
||||||
currentItems[k].destroy();
|
currentItems[k].destroy();
|
||||||
|
|
||||||
if (currentItems[k]._ignored)
|
if (currentItems[k]._ignored)
|
||||||
@@ -1961,9 +1962,8 @@ const RemoteMenu = new Lang.Class({
|
|||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
} else if (changeSignal) {
|
} else if (changeSignal) {
|
||||||
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function(actionGroup, actionName) {
|
let signalId = this.actionGroup.connect(changeSignal, Lang.bind(this, function() {
|
||||||
actionGroup.disconnect(signalId);
|
this.actionGroup.disconnect(signalId);
|
||||||
if (this._actions[actionName]) return;
|
|
||||||
|
|
||||||
// force a full update
|
// force a full update
|
||||||
this._modelChanged(model, 0, -1, model.get_n_items(), target);
|
this._modelChanged(model, 0, -1, model.get_n_items(), target);
|
||||||
|
|||||||
@@ -62,25 +62,10 @@ function loadRemoteSearchProvidersFromDir(dir, addProviderCallback) {
|
|||||||
let remoteProvider, title;
|
let remoteProvider, title;
|
||||||
try {
|
try {
|
||||||
let group = KEY_FILE_GROUP;
|
let group = KEY_FILE_GROUP;
|
||||||
|
let icon = keyfile.get_string(group, 'Icon');
|
||||||
let busName = keyfile.get_string(group, 'BusName');
|
let busName = keyfile.get_string(group, 'BusName');
|
||||||
let objectPath = keyfile.get_string(group, 'ObjectPath');
|
let objectPath = keyfile.get_string(group, 'ObjectPath');
|
||||||
|
title = keyfile.get_locale_string(group, 'Title', null);
|
||||||
let appInfo = null;
|
|
||||||
try {
|
|
||||||
let desktopId = keyfile.get_string(group, 'DesktopId');
|
|
||||||
appInfo = Gio.DesktopAppInfo.new(desktopId);
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
let icon;
|
|
||||||
if (appInfo) {
|
|
||||||
icon = appInfo.get_icon();
|
|
||||||
title = appInfo.get_name();
|
|
||||||
} else {
|
|
||||||
let iconName = keyfile.get_string(group, 'Icon');
|
|
||||||
icon = new Gio.ThemedIcon({ name: iconName });
|
|
||||||
title = keyfile.get_locale_string(group, 'Title', null);
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteProvider = new RemoteSearchProvider(title,
|
remoteProvider = new RemoteSearchProvider(title,
|
||||||
icon,
|
icon,
|
||||||
@@ -106,6 +91,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
dbusName, dbusPath);
|
dbusName, dbusPath);
|
||||||
|
|
||||||
this.parent(title.toUpperCase());
|
this.parent(title.toUpperCase());
|
||||||
|
this.async = true;
|
||||||
this._cancellable = new Gio.Cancellable();
|
this._cancellable = new Gio.Cancellable();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -134,7 +120,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
this.searchSystem.pushResults(this, results[0]);
|
this.searchSystem.pushResults(this, results[0]);
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSetAsync: function(terms) {
|
||||||
this._cancellable.cancel();
|
this._cancellable.cancel();
|
||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
@@ -147,7 +133,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
getSubsearchResultSetAsync: function(previousResults, newTerms) {
|
||||||
this._cancellable.cancel();
|
this._cancellable.cancel();
|
||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
@@ -178,7 +164,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
callback(resultMetas);
|
callback(resultMetas);
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(ids, callback) {
|
getResultMetasAsync: function(ids, callback) {
|
||||||
this._cancellable.cancel();
|
this._cancellable.cancel();
|
||||||
this._cancellable.reset();
|
this._cancellable.reset();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ const DISABLED_OPEN_SEARCH_PROVIDERS_KEY = 'disabled-open-search-providers';
|
|||||||
const MatchType = {
|
const MatchType = {
|
||||||
NONE: 0,
|
NONE: 0,
|
||||||
SUBSTRING: 1,
|
SUBSTRING: 1,
|
||||||
PREFIX: 2
|
MULTIPLE_SUBSTRING: 2,
|
||||||
|
PREFIX: 3,
|
||||||
|
MULTIPLE_PREFIX: 4
|
||||||
};
|
};
|
||||||
|
|
||||||
const SearchResultDisplay = new Lang.Class({
|
const SearchResultDisplay = new Lang.Class({
|
||||||
@@ -51,7 +53,7 @@ const SearchResultDisplay = new Lang.Class({
|
|||||||
* Remove all results from this display.
|
* Remove all results from this display.
|
||||||
*/
|
*/
|
||||||
clear: function() {
|
clear: function() {
|
||||||
this.actor.destroy_all_children();
|
this.actor.get_children().forEach(function (actor) { actor.destroy(); });
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,8 +72,11 @@ const SearchResultDisplay = new Lang.Class({
|
|||||||
* Subclass this object to add a new result type
|
* Subclass this object to add a new result type
|
||||||
* to the search system, then call registerProvider()
|
* to the search system, then call registerProvider()
|
||||||
* in SearchSystem with an instance.
|
* in SearchSystem with an instance.
|
||||||
* Search is asynchronous and uses the
|
* By default, search is synchronous and uses the
|
||||||
* getInitialResultSet()/getSubsearchResultSet() methods.
|
* getInitialResultSet()/getSubsearchResultSet() methods.
|
||||||
|
* For asynchronous search, set the async property to true
|
||||||
|
* and implement getInitialResultSetAsync()/getSubsearchResultSetAsync()
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
const SearchProvider = new Lang.Class({
|
const SearchProvider = new Lang.Class({
|
||||||
Name: 'SearchProvider',
|
Name: 'SearchProvider',
|
||||||
@@ -79,6 +84,7 @@ const SearchProvider = new Lang.Class({
|
|||||||
_init: function(title) {
|
_init: function(title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.searchSystem = null;
|
this.searchSystem = null;
|
||||||
|
this.async = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +95,7 @@ const SearchProvider = new Lang.Class({
|
|||||||
* therefore a single term of length one or two), or when
|
* therefore a single term of length one or two), or when
|
||||||
* a new term is added.
|
* a new term is added.
|
||||||
*
|
*
|
||||||
* Should "return" an array of result identifier strings representing
|
* Should return an array of result identifier strings representing
|
||||||
* items which match the given search terms. This
|
* items which match the given search terms. This
|
||||||
* is expected to be a substring match on the metadata for a given
|
* is expected to be a substring match on the metadata for a given
|
||||||
* item. Ordering of returned results is up to the discretion of the provider,
|
* item. Ordering of returned results is up to the discretion of the provider,
|
||||||
@@ -99,9 +105,6 @@ const SearchProvider = new Lang.Class({
|
|||||||
* description) before single matches
|
* description) before single matches
|
||||||
* * Put items which match on a prefix before non-prefix substring matches
|
* * Put items which match on a prefix before non-prefix substring matches
|
||||||
*
|
*
|
||||||
* We say "return" above, but in order to make the query asynchronous, use
|
|
||||||
* this.searchSystem.pushResults();. The return value should be ignored.
|
|
||||||
*
|
|
||||||
* This function should be fast; do not perform unindexed full-text searches
|
* This function should be fast; do not perform unindexed full-text searches
|
||||||
* or network queries.
|
* or network queries.
|
||||||
*/
|
*/
|
||||||
@@ -109,6 +112,18 @@ const SearchProvider = new Lang.Class({
|
|||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getInitialResultSetAsync:
|
||||||
|
* @terms: Array of search terms, treated as logical AND
|
||||||
|
*
|
||||||
|
* Like getInitialResultSet(), but the method should return immediately
|
||||||
|
* without a return value - use SearchSystem.pushResults() when the
|
||||||
|
* corresponding results are ready.
|
||||||
|
*/
|
||||||
|
getInitialResultSetAsync: function(terms) {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getSubsearchResultSet:
|
* getSubsearchResultSet:
|
||||||
* @previousResults: Array of item identifiers
|
* @previousResults: Array of item identifiers
|
||||||
@@ -121,23 +136,46 @@ const SearchProvider = new Lang.Class({
|
|||||||
*
|
*
|
||||||
* This allows search providers to only search through the previous
|
* This allows search providers to only search through the previous
|
||||||
* result set, rather than possibly performing a full re-query.
|
* result set, rather than possibly performing a full re-query.
|
||||||
*
|
|
||||||
* Similar to getInitialResultSet, the return value for this will
|
|
||||||
* be ignored; use this.searchSystem.pushResults();.
|
|
||||||
*/
|
*/
|
||||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
getSubsearchResultSet: function(previousResults, newTerms) {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubsearchResultSetAsync:
|
||||||
|
* @previousResults: Array of item identifiers
|
||||||
|
* @newTerms: Updated search terms
|
||||||
|
*
|
||||||
|
* Like getSubsearchResultSet(), but the method should return immediately
|
||||||
|
* without a return value - use SearchSystem.pushResults() when the
|
||||||
|
* corresponding results are ready.
|
||||||
|
*/
|
||||||
|
getSubsearchResultSetAsync: function(previousResults, newTerms) {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getResultMetas:
|
* getResultMetas:
|
||||||
* @ids: Result identifier strings
|
* @ids: Result identifier strings
|
||||||
*
|
*
|
||||||
* Call callback with array of objects with 'id', 'name', (both strings) and
|
* Return an array of objects with 'id', 'name', (both strings) and
|
||||||
* 'createIcon' (function(size) returning a Clutter.Texture) properties
|
* 'createIcon' (function(size) returning a Clutter.Texture) properties
|
||||||
* with the same number of members as @ids
|
* with the same number of members as @ids
|
||||||
*/
|
*/
|
||||||
getResultMetas: function(ids, callback) {
|
getResultMetas: function(ids) {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getResultMetasAsync:
|
||||||
|
* @ids: Result identifier strings
|
||||||
|
* @callback: callback to pass the results to when ready
|
||||||
|
*
|
||||||
|
* Like getResultMetas(), but the method should return immediately
|
||||||
|
* without a return value - pass the results to the provided @callback
|
||||||
|
* when ready.
|
||||||
|
*/
|
||||||
|
getResultMetasAsync: function(ids, callback) {
|
||||||
throw new Error('Not implemented');
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -341,33 +379,42 @@ const SearchSystem = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let previousResultsArr = this._previousResults;
|
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
this._previousTerms = terms;
|
|
||||||
this._previousResults = results;
|
|
||||||
|
|
||||||
if (isSubSearch) {
|
if (isSubSearch) {
|
||||||
for (let i = 0; i < this._providers.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
let [provider, previousResults] = previousResultsArr[i];
|
let [provider, previousResults] = this._previousResults[i];
|
||||||
try {
|
try {
|
||||||
results.push([provider, []]);
|
if (provider.async) {
|
||||||
provider.getSubsearchResultSet(previousResults, terms);
|
provider.getSubsearchResultSetAsync(previousResults, terms);
|
||||||
|
results.push([provider, []]);
|
||||||
|
} else {
|
||||||
|
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
|
||||||
|
results.push([provider, providerResults]);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < this._providers.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
let provider = this._providers[i];
|
let provider = this._providers[i];
|
||||||
try {
|
try {
|
||||||
results.push([provider, []]);
|
if (provider.async) {
|
||||||
provider.getInitialResultSet(terms);
|
provider.getInitialResultSetAsync(terms);
|
||||||
|
results.push([provider, []]);
|
||||||
|
} else {
|
||||||
|
let providerResults = provider.getInitialResultSet(terms);
|
||||||
|
results.push([provider, providerResults]);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._previousTerms = terms;
|
||||||
|
this._previousResults = results;
|
||||||
|
this.emit('search-completed', results);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(SearchSystem.prototype);
|
Signals.addSignalMethods(SearchSystem.prototype);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ const Lang = imports.lang;
|
|||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Atk = imports.gi.Atk;
|
|
||||||
|
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
@@ -34,13 +33,12 @@ const SearchResult = new Lang.Class({
|
|||||||
content = new St.Bin({ style_class: 'search-result-content',
|
content = new St.Bin({ style_class: 'search-result-content',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
track_hover: true,
|
track_hover: true });
|
||||||
accessible_role: Atk.Role.PUSH_BUTTON });
|
|
||||||
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
||||||
{ createIcon: this.metaInfo['createIcon'] });
|
{ createIcon: this.metaInfo['createIcon'] });
|
||||||
content.set_child(icon.actor);
|
content.set_child(icon.actor);
|
||||||
this._dragActorSource = icon.icon;
|
this._dragActorSource = icon.icon;
|
||||||
content.label_actor = icon.label;
|
this.actor.label_actor = icon.label;
|
||||||
} else {
|
} else {
|
||||||
if (content._delegate && content._delegate.getDragActorSource)
|
if (content._delegate && content._delegate.getDragActorSource)
|
||||||
this._dragActorSource = content._delegate.getDragActorSource();
|
this._dragActorSource = content._delegate.getDragActorSource();
|
||||||
@@ -121,7 +119,13 @@ const GridSearchResults = new Lang.Class({
|
|||||||
if (results.length == 0)
|
if (results.length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
provider.getResultMetas(results, Lang.bind(this, this.renderResults));
|
if (provider.async) {
|
||||||
|
provider.getResultMetasAsync(results,
|
||||||
|
Lang.bind(this, this.renderResults));
|
||||||
|
} else {
|
||||||
|
let metas = provider.getResultMetas(results);
|
||||||
|
this.renderResults(metas);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
this._notDisplayedResult = [];
|
this._notDisplayedResult = [];
|
||||||
@@ -131,7 +135,7 @@ const GridSearchResults = new Lang.Class({
|
|||||||
|
|
||||||
getResultsForDisplay: function() {
|
getResultsForDisplay: function() {
|
||||||
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
let alreadyVisible = this._pendingClear ? 0 : this._grid.visibleItemsCount();
|
||||||
let canDisplay = this._grid.childrenInRow(this._width) * this._grid.getRowLimit()
|
let canDisplay = this._grid.childrenInRow(this._width) * MAX_SEARCH_RESULTS_ROWS
|
||||||
- alreadyVisible;
|
- alreadyVisible;
|
||||||
|
|
||||||
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
|
let numResults = Math.min(this._notDisplayedResult.length, canDisplay);
|
||||||
@@ -175,7 +179,8 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
_init: function(searchSystem, openSearchSystem) {
|
_init: function(searchSystem, openSearchSystem) {
|
||||||
this._searchSystem = searchSystem;
|
this._searchSystem = searchSystem;
|
||||||
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
|
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateCurrentResults));
|
||||||
|
this._searchSystem.connect('search-completed', Lang.bind(this, this._updateResults));
|
||||||
this._openSearchSystem = openSearchSystem;
|
this._openSearchSystem = openSearchSystem;
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ name: 'searchResults',
|
this.actor = new St.BoxLayout({ name: 'searchResults',
|
||||||
@@ -209,8 +214,10 @@ const SearchResults = new Lang.Class({
|
|||||||
this._content.add(this._statusText);
|
this._content.add(this._statusText);
|
||||||
this._providers = this._searchSystem.getProviders();
|
this._providers = this._searchSystem.getProviders();
|
||||||
this._providerMeta = [];
|
this._providerMeta = [];
|
||||||
|
this._providerMetaResults = {};
|
||||||
for (let i = 0; i < this._providers.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
this.createProviderMeta(this._providers[i]);
|
this.createProviderMeta(this._providers[i]);
|
||||||
|
this._providerMetaResults[this.providers[i].title] = [];
|
||||||
}
|
}
|
||||||
this._searchProvidersBox = new St.BoxLayout({ style_class: 'search-providers-box' });
|
this._searchProvidersBox = new St.BoxLayout({ style_class: 'search-providers-box' });
|
||||||
this.actor.add(this._searchProvidersBox);
|
this.actor.add(this._searchProvidersBox);
|
||||||
@@ -283,7 +290,8 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
this._providerMeta.push({ provider: provider,
|
this._providerMeta.push({ provider: provider,
|
||||||
actor: providerBox,
|
actor: providerBox,
|
||||||
resultDisplay: resultDisplay });
|
resultDisplay: resultDisplay,
|
||||||
|
hasPendingResults: false });
|
||||||
this._content.add(providerBox);
|
this._content.add(providerBox);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -299,6 +307,7 @@ const SearchResults = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_clearDisplay: function() {
|
_clearDisplay: function() {
|
||||||
|
this._visibleResultsCount = 0;
|
||||||
for (let i = 0; i < this._providerMeta.length; i++) {
|
for (let i = 0; i < this._providerMeta.length; i++) {
|
||||||
let meta = this._providerMeta[i];
|
let meta = this._providerMeta[i];
|
||||||
meta.resultDisplay.clear();
|
meta.resultDisplay.clear();
|
||||||
@@ -326,8 +335,6 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
doSearch: function (searchString) {
|
doSearch: function (searchString) {
|
||||||
this._searchSystem.updateSearch(searchString);
|
this._searchSystem.updateSearch(searchString);
|
||||||
let terms = this._searchSystem.getTerms();
|
|
||||||
this._openSearchSystem.setSearchTerms(terms);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_metaForProvider: function(provider) {
|
_metaForProvider: function(provider) {
|
||||||
@@ -339,6 +346,8 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
for (let i = 0; i < this._providerMeta.length; i++) {
|
for (let i = 0; i < this._providerMeta.length; i++) {
|
||||||
let meta = this._providerMeta[i];
|
let meta = this._providerMeta[i];
|
||||||
|
if (meta.hasPendingResults)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!meta.actor.visible)
|
if (!meta.actor.visible)
|
||||||
continue;
|
continue;
|
||||||
@@ -363,57 +372,78 @@ const SearchResults = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateStatusText: function () {
|
_updateCurrentResults: function(searchSystem, results) {
|
||||||
let haveResults = false;
|
let terms = searchSystem.getTerms();
|
||||||
|
let [provider, providerResults] = results;
|
||||||
|
let meta = this._metaForProvider(provider);
|
||||||
|
meta.hasPendingResults = false;
|
||||||
|
this._updateProviderResults(provider, providerResults, terms);
|
||||||
|
},
|
||||||
|
|
||||||
for (let i = 0; i < this._providerMeta.length; ++i)
|
_updateProviderResults: function(provider, providerResults, terms) {
|
||||||
if (this._providerMeta[i].resultDisplay.getFirstResult()) {
|
let meta = this._metaForProvider(provider);
|
||||||
haveResults = true;
|
if (providerResults.length == 0) {
|
||||||
break;
|
this._clearDisplayForProvider(provider);
|
||||||
|
meta.resultDisplay.setResults([], []);
|
||||||
|
} else {
|
||||||
|
this._providerMetaResults[provider.title] = providerResults;
|
||||||
|
meta.resultDisplay.setResults(providerResults, terms);
|
||||||
|
let results = meta.resultDisplay.getResultsForDisplay();
|
||||||
|
|
||||||
|
if (provider.async) {
|
||||||
|
provider.getResultMetasAsync(results, Lang.bind(this,
|
||||||
|
function(metas) {
|
||||||
|
this._clearDisplayForProvider(provider);
|
||||||
|
meta.actor.show();
|
||||||
|
|
||||||
|
// Hinding drops the key focus if we have it
|
||||||
|
let focus = global.stage.get_key_focus();
|
||||||
|
this._content.hide();
|
||||||
|
|
||||||
|
meta.resultDisplay.renderResults(metas);
|
||||||
|
this._maybeSetInitialSelection();
|
||||||
|
|
||||||
|
this._content.show();
|
||||||
|
if (this._content.contains(focus))
|
||||||
|
global.stage.set_key_focus(focus);
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
let metas = provider.getResultMetas(results);
|
||||||
|
this._clearDisplayForProvider(provider);
|
||||||
|
meta.actor.show();
|
||||||
|
meta.resultDisplay.renderResults(metas);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
this._maybeSetInitialSelection();
|
||||||
|
},
|
||||||
|
|
||||||
if (!haveResults) {
|
_updateResults: function(searchSystem, results) {
|
||||||
|
if (results.length == 0) {
|
||||||
this._statusText.set_text(_("No matching results."));
|
this._statusText.set_text(_("No matching results."));
|
||||||
this._statusText.show();
|
this._statusText.show();
|
||||||
} else {
|
} else {
|
||||||
this._statusText.hide();
|
this._statusText.hide();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
_updateResults: function(searchSystem, results) {
|
|
||||||
let terms = searchSystem.getTerms();
|
let terms = searchSystem.getTerms();
|
||||||
let [provider, providerResults] = results;
|
this._openSearchSystem.setSearchTerms(terms);
|
||||||
let meta = this._metaForProvider(provider);
|
|
||||||
|
|
||||||
if (providerResults.length == 0) {
|
// To avoid CSS transitions causing flickering when the first search
|
||||||
this._clearDisplayForProvider(provider);
|
// result stays the same, we hide the content while filling in the
|
||||||
meta.resultDisplay.setResults([], []);
|
// results.
|
||||||
this._maybeSetInitialSelection();
|
this._content.hide();
|
||||||
this._updateStatusText();
|
|
||||||
} else {
|
|
||||||
meta.resultDisplay.setResults(providerResults, terms);
|
|
||||||
let results = meta.resultDisplay.getResultsForDisplay();
|
|
||||||
|
|
||||||
provider.getResultMetas(results, Lang.bind(this, function(metas) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
this._clearDisplayForProvider(provider);
|
let [provider, providerResults] = results[i];
|
||||||
meta.actor.show();
|
let meta = this._metaForProvider(provider);
|
||||||
|
meta.hasPendingResults = provider.async;
|
||||||
// Hiding drops the key focus if we have it
|
if (!meta.hasPendingResults)
|
||||||
let focus = global.stage.get_key_focus();
|
this._updateProviderResults(provider, providerResults, terms);
|
||||||
// To avoid CSS transitions causing flickering when
|
|
||||||
// the first search result stays the same, we hide the
|
|
||||||
// content while filling in the results.
|
|
||||||
this._content.hide();
|
|
||||||
|
|
||||||
meta.resultDisplay.renderResults(metas);
|
|
||||||
this._maybeSetInitialSelection();
|
|
||||||
this._updateStatusText();
|
|
||||||
|
|
||||||
this._content.show();
|
|
||||||
if (this._content.contains(focus))
|
|
||||||
global.stage.set_key_focus(focus);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._content.show();
|
||||||
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
activateDefault: function() {
|
activateDefault: function() {
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
const Params = imports.misc.params;
|
|
||||||
|
|
||||||
|
|
||||||
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator,
|
|
||||||
'battery': imports.ui.status.power.Indicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
|
||||||
'userMenu': imports.ui.userMenu.UserMenuButton
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Config.HAVE_BLUETOOTH)
|
|
||||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] =
|
|
||||||
imports.ui.status.bluetooth.Indicator;
|
|
||||||
|
|
||||||
try {
|
|
||||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] =
|
|
||||||
imports.ui.status.network.NMApplet;
|
|
||||||
} catch(e) {
|
|
||||||
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const DEFAULT_MODE = 'user';
|
|
||||||
|
|
||||||
const _modes = {
|
|
||||||
'gdm': { hasOverview: false,
|
|
||||||
hasAppMenu: false,
|
|
||||||
showCalendarEvents: false,
|
|
||||||
allowSettings: false,
|
|
||||||
allowExtensions: false,
|
|
||||||
allowKeybindingsWhenModal: true,
|
|
||||||
hasRunDialog: false,
|
|
||||||
hasWorkspaces: false,
|
|
||||||
createSession: Main.createGDMSession,
|
|
||||||
extraStylesheet: global.datadir + '/theme/gdm.css',
|
|
||||||
statusArea: {
|
|
||||||
order: [
|
|
||||||
'a11y', 'display', 'keyboard',
|
|
||||||
'volume', 'battery', 'powerMenu'
|
|
||||||
],
|
|
||||||
implementation: {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator,
|
|
||||||
'battery': imports.ui.status.power.Indicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
|
||||||
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'initial-setup': { hasOverview: false,
|
|
||||||
hasAppMenu: false,
|
|
||||||
showCalendarEvents: false,
|
|
||||||
allowSettings: false,
|
|
||||||
allowExtensions: false,
|
|
||||||
allowKeybindingsWhenModal: false,
|
|
||||||
hasRunDialog: false,
|
|
||||||
hasWorkspaces: false,
|
|
||||||
createSession: Main.createInitialSetupSession,
|
|
||||||
extraStylesheet: null,
|
|
||||||
statusArea: {
|
|
||||||
order: [
|
|
||||||
'a11y', 'keyboard', 'volume'
|
|
||||||
],
|
|
||||||
implementation: {
|
|
||||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
|
||||||
'keyboard': imports.ui.status.keyboard.XKBIndicator,
|
|
||||||
'volume': imports.ui.status.volume.Indicator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'user': { hasOverview: true,
|
|
||||||
hasAppMenu: true,
|
|
||||||
showCalendarEvents: true,
|
|
||||||
allowSettings: true,
|
|
||||||
allowExtensions: true,
|
|
||||||
allowKeybindingsWhenModal: false,
|
|
||||||
hasRunDialog: true,
|
|
||||||
hasWorkspaces: true,
|
|
||||||
createSession: Main.createUserSession,
|
|
||||||
extraStylesheet: null,
|
|
||||||
statusArea: {
|
|
||||||
order: [
|
|
||||||
'input-method', 'a11y', 'keyboard', 'volume', 'bluetooth',
|
|
||||||
'network', 'battery', 'userMenu'
|
|
||||||
],
|
|
||||||
implementation: STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function listModes() {
|
|
||||||
let modes = Object.getOwnPropertyNames(_modes);
|
|
||||||
for (let i = 0; i < modes.length; i++)
|
|
||||||
print(modes[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const SessionMode = new Lang.Class({
|
|
||||||
Name: 'SessionMode',
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
let params = _modes[global.session_mode];
|
|
||||||
|
|
||||||
params = Params.parse(params, _modes[DEFAULT_MODE]);
|
|
||||||
|
|
||||||
this._createSession = params.createSession;
|
|
||||||
delete params.createSession;
|
|
||||||
|
|
||||||
Lang.copyProperties(params, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
createSession: function() {
|
|
||||||
if (this._createSession)
|
|
||||||
this._createSession();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -7,7 +7,6 @@ const Shell = imports.gi.Shell;
|
|||||||
|
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const Flashspot = imports.ui.flashspot;
|
const Flashspot = imports.ui.flashspot;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@@ -57,8 +56,15 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
|
|||||||
<arg type="i" direction="in" name="width"/>
|
<arg type="i" direction="in" name="width"/>
|
||||||
<arg type="i" direction="in" name="height"/>
|
<arg type="i" direction="in" name="height"/>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="EnableExtension">
|
||||||
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
|
</method>
|
||||||
|
<method name="DisableExtension">
|
||||||
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
|
</method>
|
||||||
<method name="InstallRemoteExtension">
|
<method name="InstallRemoteExtension">
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
|
<arg type="s" direction="in" name="version"/>
|
||||||
</method>
|
</method>
|
||||||
<method name="UninstallExtension">
|
<method name="UninstallExtension">
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
@@ -67,9 +73,6 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
|
|||||||
<method name="LaunchExtensionPrefs">
|
<method name="LaunchExtensionPrefs">
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
<arg type="s" direction="in" name="uuid"/>
|
||||||
</method>
|
</method>
|
||||||
<method name="ReloadExtension">
|
|
||||||
<arg type="s" direction="in" name="uuid"/>
|
|
||||||
</method>
|
|
||||||
<property name="OverviewActive" type="b" access="readwrite" />
|
<property name="OverviewActive" type="b" access="readwrite" />
|
||||||
<property name="ApiVersion" type="i" access="read" />
|
<property name="ApiVersion" type="i" access="read" />
|
||||||
<property name="ShellVersion" type="s" access="read" />
|
<property name="ShellVersion" type="s" access="read" />
|
||||||
@@ -257,12 +260,26 @@ const GnomeShell = new Lang.Class({
|
|||||||
return extension.errors;
|
return extension.errors;
|
||||||
},
|
},
|
||||||
|
|
||||||
InstallRemoteExtension: function(uuid) {
|
EnableExtension: function(uuid) {
|
||||||
ExtensionDownloader.installExtensionFromUUID(uuid);
|
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
|
||||||
|
if (enabledExtensions.indexOf(uuid) == -1)
|
||||||
|
enabledExtensions.push(uuid);
|
||||||
|
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
||||||
|
},
|
||||||
|
|
||||||
|
DisableExtension: function(uuid) {
|
||||||
|
let enabledExtensions = global.settings.get_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY);
|
||||||
|
while (enabledExtensions.indexOf(uuid) != -1)
|
||||||
|
enabledExtensions.splice(enabledExtensions.indexOf(uuid), 1);
|
||||||
|
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
||||||
|
},
|
||||||
|
|
||||||
|
InstallRemoteExtension: function(uuid, version_tag) {
|
||||||
|
ExtensionSystem.installExtensionFromUUID(uuid, version_tag);
|
||||||
},
|
},
|
||||||
|
|
||||||
UninstallExtension: function(uuid) {
|
UninstallExtension: function(uuid) {
|
||||||
return ExtensionDownloader.uninstallExtensionFromUUID(uuid);
|
return ExtensionSystem.uninstallExtensionFromUUID(uuid);
|
||||||
},
|
},
|
||||||
|
|
||||||
LaunchExtensionPrefs: function(uuid) {
|
LaunchExtensionPrefs: function(uuid) {
|
||||||
@@ -272,11 +289,6 @@ const GnomeShell = new Lang.Class({
|
|||||||
['extension:///' + uuid], -1, null);
|
['extension:///' + uuid], -1, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
ReloadExtension: function(uuid) {
|
|
||||||
ExtensionSystem.unloadExtension(uuid);
|
|
||||||
ExtensionSystem.loadExtension(uuid);
|
|
||||||
},
|
|
||||||
|
|
||||||
get OverviewActive() {
|
get OverviewActive() {
|
||||||
return Main.overview.visible;
|
return Main.overview.visible;
|
||||||
},
|
},
|
||||||
@@ -288,6 +300,8 @@ const GnomeShell = new Lang.Class({
|
|||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ApiVersion: ExtensionSystem.API_VERSION,
|
||||||
|
|
||||||
ShellVersion: Config.PACKAGE_VERSION,
|
ShellVersion: Config.PACKAGE_VERSION,
|
||||||
|
|
||||||
_extensionStateChanged: function(_, newState) {
|
_extensionStateChanged: function(_, newState) {
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const CheckBox = imports.ui.checkBox;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const ShellEntry = imports.ui.shellEntry;
|
|
||||||
|
|
||||||
const LIST_ITEM_ICON_SIZE = 48;
|
const LIST_ITEM_ICON_SIZE = 48;
|
||||||
|
|
||||||
@@ -52,11 +48,6 @@ function _setLabelsForMessage(dialog, message) {
|
|||||||
_setLabelText(dialog.descriptionLabel, labels[1]);
|
_setLabelText(dialog.descriptionLabel, labels[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createIcon(gicon) {
|
|
||||||
return new St.Icon({ gicon: gicon,
|
|
||||||
style_class: 'shell-mount-operation-icon' })
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
|
|
||||||
const ListItem = new Lang.Class({
|
const ListItem = new Lang.Class({
|
||||||
@@ -100,11 +91,11 @@ const ShellMountOperation = new Lang.Class({
|
|||||||
Name: 'ShellMountOperation',
|
Name: 'ShellMountOperation',
|
||||||
|
|
||||||
_init: function(source, params) {
|
_init: function(source, params) {
|
||||||
params = Params.parse(params, { existingDialog: null });
|
params = Params.parse(params, { reaskPassword: false });
|
||||||
|
|
||||||
|
this._reaskPassword = params.reaskPassword;
|
||||||
|
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
this._dialogId = 0;
|
|
||||||
this._existingDialog = params.existingDialog;
|
|
||||||
this._processesDialog = null;
|
this._processesDialog = null;
|
||||||
|
|
||||||
this.mountOp = new Shell.MountOperation();
|
this.mountOp = new Shell.MountOperation();
|
||||||
@@ -116,120 +107,99 @@ const ShellMountOperation = new Lang.Class({
|
|||||||
this.mountOp.connect('show-processes-2',
|
this.mountOp.connect('show-processes-2',
|
||||||
Lang.bind(this, this._onShowProcesses2));
|
Lang.bind(this, this._onShowProcesses2));
|
||||||
this.mountOp.connect('aborted',
|
this.mountOp.connect('aborted',
|
||||||
Lang.bind(this, this.close));
|
Lang.bind(this, this._onAborted));
|
||||||
|
|
||||||
this._gicon = source.get_icon();
|
this._icon = new St.Icon({ gicon: source.get_icon(),
|
||||||
},
|
style_class: 'shell-mount-operation-icon' });
|
||||||
|
|
||||||
_closeExistingDialog: function() {
|
|
||||||
if (!this._existingDialog)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._existingDialog.close();
|
|
||||||
this._existingDialog = null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAskQuestion: function(op, message, choices) {
|
_onAskQuestion: function(op, message, choices) {
|
||||||
this._closeExistingDialog();
|
this._dialog = new ShellMountQuestionDialog(this._icon);
|
||||||
this._dialog = new ShellMountQuestionDialog(this._gicon);
|
|
||||||
|
|
||||||
this._dialogId = this._dialog.connect('response', Lang.bind(this,
|
this._dialog.connect('response',
|
||||||
function(object, choice) {
|
Lang.bind(this, function(object, choice) {
|
||||||
this.mountOp.set_choice(choice);
|
this.mountOp.set_choice(choice);
|
||||||
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
||||||
|
|
||||||
this.close();
|
this._dialog.close(global.get_current_time());
|
||||||
}));
|
this._dialog = null;
|
||||||
|
}));
|
||||||
|
|
||||||
this._dialog.update(message, choices);
|
this._dialog.update(message, choices);
|
||||||
this._dialog.open();
|
this._dialog.open(global.get_current_time());
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAskPassword: function(op, message, defaultUser, defaultDomain, flags) {
|
_onAskPassword: function(op, message) {
|
||||||
if (this._existingDialog) {
|
this._notificationShowing = true;
|
||||||
this._dialog = this._existingDialog;
|
this._source = new ShellMountPasswordSource(message, this._icon, this._reaskPassword);
|
||||||
this._dialog.reaskPassword();
|
|
||||||
} else {
|
|
||||||
this._dialog = new ShellMountPasswordDialog(message, this._gicon, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._dialogId = this._dialog.connect('response', Lang.bind(this,
|
this._source.connect('password-ready',
|
||||||
function(object, choice, password, remember) {
|
Lang.bind(this, function(source, password) {
|
||||||
if (choice == -1) {
|
this.mountOp.set_password(password);
|
||||||
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
||||||
} else {
|
|
||||||
if (remember)
|
|
||||||
this.mountOp.set_password_save(Gio.PasswordSave.PERMANENTLY);
|
|
||||||
else
|
|
||||||
this.mountOp.set_password_save(Gio.PasswordSave.NEVER);
|
|
||||||
|
|
||||||
this.mountOp.set_password(password);
|
this._notificationShowing = false;
|
||||||
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
this._source.destroy();
|
||||||
}
|
}));
|
||||||
}));
|
|
||||||
this._dialog.open();
|
this._source.connect('destroy',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
if (!this._notificationShowing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._notificationShowing = false;
|
||||||
|
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function(op) {
|
_onAborted: function(op) {
|
||||||
this._closeExistingDialog();
|
if (!this._dialog)
|
||||||
this._processesDialog = null;
|
return;
|
||||||
|
|
||||||
if (this._dialog) {
|
this._dialog.close(global.get_current_time());
|
||||||
this._dialog.close();
|
this._dialog = null;
|
||||||
this._dialog = null;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onShowProcesses2: function(op) {
|
_onShowProcesses2: function(op) {
|
||||||
this._closeExistingDialog();
|
|
||||||
|
|
||||||
let processes = op.get_show_processes_pids();
|
let processes = op.get_show_processes_pids();
|
||||||
let choices = op.get_show_processes_choices();
|
let choices = op.get_show_processes_choices();
|
||||||
let message = op.get_show_processes_message();
|
let message = op.get_show_processes_message();
|
||||||
|
|
||||||
if (!this._processesDialog) {
|
if (!this._processesDialog) {
|
||||||
this._processesDialog = new ShellProcessesDialog(this._gicon);
|
this._processesDialog = new ShellProcessesDialog(this._icon);
|
||||||
this._dialog = this._processesDialog;
|
this._dialog = this._processesDialog;
|
||||||
|
|
||||||
this._dialogId = this._processesDialog.connect('response', Lang.bind(this,
|
this._processesDialog.connect('response',
|
||||||
function(object, choice) {
|
Lang.bind(this, function(object, choice) {
|
||||||
if (choice == -1) {
|
if (choice == -1) {
|
||||||
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
this.mountOp.reply(Gio.MountOperationResult.ABORTED);
|
||||||
} else {
|
} else {
|
||||||
this.mountOp.set_choice(choice);
|
this.mountOp.set_choice(choice);
|
||||||
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
this.mountOp.reply(Gio.MountOperationResult.HANDLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.close();
|
this._processesDialog.close(global.get_current_time());
|
||||||
}));
|
this._dialog = null;
|
||||||
this._processesDialog.open();
|
}));
|
||||||
|
this._processesDialog.open(global.get_current_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
this._processesDialog.update(message, processes, choices);
|
this._processesDialog.update(message, processes, choices);
|
||||||
},
|
},
|
||||||
|
|
||||||
borrowDialog: function() {
|
|
||||||
if (this._dialogId != 0) {
|
|
||||||
this._dialog.disconnect(this._dialogId);
|
|
||||||
this._dialogId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._dialog;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ShellMountQuestionDialog = new Lang.Class({
|
const ShellMountQuestionDialog = new Lang.Class({
|
||||||
Name: 'ShellMountQuestionDialog',
|
Name: 'ShellMountQuestionDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
_init: function(gicon) {
|
_init: function(icon) {
|
||||||
this.parent({ styleClass: 'mount-question-dialog' });
|
this.parent({ styleClass: 'mount-question-dialog' });
|
||||||
|
|
||||||
let mainContentLayout = new St.BoxLayout();
|
let mainContentLayout = new St.BoxLayout();
|
||||||
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
||||||
y_fill: false });
|
y_fill: false });
|
||||||
|
|
||||||
this._iconBin = new St.Bin({ child: _createIcon(gicon) });
|
this._iconBin = new St.Bin({ child: icon });
|
||||||
mainContentLayout.add(this._iconBin,
|
mainContentLayout.add(this._iconBin,
|
||||||
{ x_fill: true,
|
{ x_fill: true,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
@@ -264,107 +234,62 @@ const ShellMountQuestionDialog = new Lang.Class({
|
|||||||
});
|
});
|
||||||
Signals.addSignalMethods(ShellMountQuestionDialog.prototype);
|
Signals.addSignalMethods(ShellMountQuestionDialog.prototype);
|
||||||
|
|
||||||
const ShellMountPasswordDialog = new Lang.Class({
|
const ShellMountPasswordSource = new Lang.Class({
|
||||||
Name: 'ShellMountPasswordDialog',
|
Name: 'ShellMountPasswordSource',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(message, gicon, flags) {
|
_init: function(message, icon, reaskPassword) {
|
||||||
let strings = message.split('\n');
|
let strings = message.split('\n');
|
||||||
this.parent({ styleClass: 'prompt-dialog' });
|
this.parent(strings[0]);
|
||||||
|
|
||||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
this._notification = new ShellMountPasswordNotification(this, strings, icon, reaskPassword);
|
||||||
vertical: false });
|
|
||||||
this.contentLayout.add(mainContentBox);
|
|
||||||
|
|
||||||
let icon = _createIcon(gicon);
|
// add ourselves as a source, and popup the notification
|
||||||
mainContentBox.add(icon,
|
Main.messageTray.add(this);
|
||||||
{ x_fill: true,
|
this.notify(this._notification);
|
||||||
y_fill: false,
|
},
|
||||||
x_align: St.Align.END,
|
});
|
||||||
y_align: St.Align.START });
|
Signals.addSignalMethods(ShellMountPasswordSource.prototype);
|
||||||
|
|
||||||
this._messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
|
const ShellMountPasswordNotification = new Lang.Class({
|
||||||
vertical: true });
|
Name: 'ShellMountPasswordNotification',
|
||||||
mainContentBox.add(this._messageBox,
|
Extends: MessageTray.Notification,
|
||||||
{ y_align: St.Align.START, expand: true, x_fill: true, y_fill: true });
|
|
||||||
|
|
||||||
let subject = new St.Label({ style_class: 'prompt-dialog-headline' });
|
_init: function(source, strings, icon, reaskPassword) {
|
||||||
this._messageBox.add(subject,
|
this.parent(source, strings[0], null, { customContent: true, icon: icon });
|
||||||
{ y_fill: false,
|
|
||||||
y_align: St.Align.START });
|
// set the notification to transient and urgent, so that it
|
||||||
if (strings[0])
|
// expands out
|
||||||
subject.set_text(strings[0]);
|
this.setTransient(true);
|
||||||
|
this.setUrgency(MessageTray.Urgency.CRITICAL);
|
||||||
|
|
||||||
let description = new St.Label({ style_class: 'prompt-dialog-description' });
|
|
||||||
description.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
|
||||||
description.clutter_text.line_wrap = true;
|
|
||||||
this._messageBox.add(description,
|
|
||||||
{ y_fill: true,
|
|
||||||
y_align: St.Align.START });
|
|
||||||
if (strings[1])
|
if (strings[1])
|
||||||
description.set_text(strings[1]);
|
this.addBody(strings[1]);
|
||||||
|
|
||||||
this._passwordBox = new St.BoxLayout({ vertical: false });
|
if (reaskPassword) {
|
||||||
this._messageBox.add(this._passwordBox);
|
let label = new St.Label({ style_class: 'mount-password-reask',
|
||||||
|
text: _("Wrong password, please try again") });
|
||||||
|
|
||||||
this._passwordLabel = new St.Label(({ style_class: 'prompt-dialog-password-label',
|
this.addActor(label);
|
||||||
text: _("Passphrase") }));
|
|
||||||
this._passwordBox.add(this._passwordLabel);
|
|
||||||
|
|
||||||
this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
|
|
||||||
text: "",
|
|
||||||
can_focus: true});
|
|
||||||
ShellEntry.addContextMenu(this._passwordEntry, { isPassword: true });
|
|
||||||
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
|
|
||||||
this._passwordEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
|
|
||||||
this._passwordBox.add(this._passwordEntry, {expand: true });
|
|
||||||
this.setInitialKeyFocus(this._passwordEntry);
|
|
||||||
|
|
||||||
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label',
|
|
||||||
text: _("Sorry, that didn\'t work. Please try again.") });
|
|
||||||
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
|
||||||
this._errorMessageLabel.clutter_text.line_wrap = true;
|
|
||||||
this._errorMessageLabel.hide();
|
|
||||||
this._messageBox.add(this._errorMessageLabel);
|
|
||||||
|
|
||||||
if (flags & Gio.AskPasswordFlags.SAVING_SUPPORTED) {
|
|
||||||
this._rememberChoice = new CheckBox.CheckBox();
|
|
||||||
this._rememberChoice.getLabelActor().text = _("Remember Passphrase");
|
|
||||||
this._rememberChoice.actor.checked = true;
|
|
||||||
this._messageBox.add(this._rememberChoice.actor);
|
|
||||||
} else {
|
|
||||||
this._rememberChoice = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttons = [{ label: _("Cancel"),
|
this._responseEntry = new St.Entry({ style_class: 'mount-password-entry',
|
||||||
action: Lang.bind(this, this._onCancelButton),
|
can_focus: true });
|
||||||
key: Clutter.Escape
|
this.setActionArea(this._responseEntry);
|
||||||
},
|
|
||||||
{ label: _("Unlock"),
|
|
||||||
action: Lang.bind(this, this._onUnlockButton)
|
|
||||||
}];
|
|
||||||
|
|
||||||
this.setButtons(buttons);
|
this._responseEntry.clutter_text.connect('activate',
|
||||||
|
Lang.bind(this, this._onEntryActivated));
|
||||||
|
this._responseEntry.clutter_text.set_password_char('\u25cf'); // ● U+25CF BLACK CIRCLE
|
||||||
|
|
||||||
|
this._responseEntry.grab_key_focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
reaskPassword: function() {
|
_onEntryActivated: function() {
|
||||||
this._passwordEntry.set_text('');
|
let text = this._responseEntry.get_text();
|
||||||
this._errorMessageLabel.show();
|
if (text == '')
|
||||||
},
|
return;
|
||||||
|
|
||||||
_onCancelButton: function() {
|
this.source.emit('password-ready', text);
|
||||||
this.emit('response', -1, '', false);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onUnlockButton: function() {
|
|
||||||
this._onEntryActivate();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onEntryActivate: function() {
|
|
||||||
this.emit('response', 1,
|
|
||||||
this._passwordEntry.get_text(),
|
|
||||||
this._rememberChoice &&
|
|
||||||
this._rememberChoice.actor.checked);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -372,14 +297,14 @@ const ShellProcessesDialog = new Lang.Class({
|
|||||||
Name: 'ShellProcessesDialog',
|
Name: 'ShellProcessesDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
_init: function(gicon) {
|
_init: function(icon) {
|
||||||
this.parent({ styleClass: 'show-processes-dialog' });
|
this.parent({ styleClass: 'show-processes-dialog' });
|
||||||
|
|
||||||
let mainContentLayout = new St.BoxLayout();
|
let mainContentLayout = new St.BoxLayout();
|
||||||
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
this.contentLayout.add(mainContentLayout, { x_fill: true,
|
||||||
y_fill: false });
|
y_fill: false });
|
||||||
|
|
||||||
this._iconBin = new St.Bin({ child: _createIcon(gicon) });
|
this._iconBin = new St.Bin({ child: icon });
|
||||||
mainContentLayout.add(this._iconBin,
|
mainContentLayout.add(this._iconBin,
|
||||||
{ x_fill: true,
|
{ x_fill: true,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
@@ -421,13 +346,13 @@ const ShellProcessesDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._applicationList.connect('actor-added',
|
this._applicationList.connect('actor-added',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_n_children() == 1)
|
if (this._applicationList.get_children().length == 1)
|
||||||
scrollView.show();
|
scrollView.show();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._applicationList.connect('actor-removed',
|
this._applicationList.connect('actor-removed',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
if (this._applicationList.get_n_children() == 0)
|
if (this._applicationList.get_children().length == 0)
|
||||||
scrollView.hide();
|
scrollView.hide();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
@@ -461,253 +386,3 @@ const ShellProcessesDialog = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ShellProcessesDialog.prototype);
|
Signals.addSignalMethods(ShellProcessesDialog.prototype);
|
||||||
|
|
||||||
const GnomeShellMountOpIface = <interface name="org.Gtk.MountOperationHandler">
|
|
||||||
<method name="AskPassword">
|
|
||||||
<arg type="s" direction="in" name="object_id"/>
|
|
||||||
<arg type="s" direction="in" name="message"/>
|
|
||||||
<arg type="s" direction="in" name="icon_name"/>
|
|
||||||
<arg type="s" direction="in" name="default_user"/>
|
|
||||||
<arg type="s" direction="in" name="default_domain"/>
|
|
||||||
<arg type="u" direction="in" name="flags"/>
|
|
||||||
<arg type="u" direction="out" name="response"/>
|
|
||||||
<arg type="a{sv}" direction="out" name="response_details"/>
|
|
||||||
</method>
|
|
||||||
<method name="AskQuestion">
|
|
||||||
<arg type="s" direction="in" name="object_id"/>
|
|
||||||
<arg type="s" direction="in" name="message"/>
|
|
||||||
<arg type="s" direction="in" name="icon_name"/>
|
|
||||||
<arg type="as" direction="in" name="choices"/>
|
|
||||||
<arg type="u" direction="out" name="response"/>
|
|
||||||
<arg type="a{sv}" direction="out" name="response_details"/>
|
|
||||||
</method>
|
|
||||||
<method name="ShowProcesses">
|
|
||||||
<arg type="s" direction="in" name="object_id"/>
|
|
||||||
<arg type="s" direction="in" name="message"/>
|
|
||||||
<arg type="s" direction="in" name="icon_name"/>
|
|
||||||
<arg type="ai" direction="in" name="application_pids"/>
|
|
||||||
<arg type="as" direction="in" name="choices"/>
|
|
||||||
<arg type="u" direction="out" name="response"/>
|
|
||||||
<arg type="a{sv}" direction="out" name="response_details"/>
|
|
||||||
</method>
|
|
||||||
<method name="Close"/>
|
|
||||||
</interface>;
|
|
||||||
|
|
||||||
const ShellMountOperationType = {
|
|
||||||
NONE: 0,
|
|
||||||
ASK_PASSWORD: 1,
|
|
||||||
ASK_QUESTION: 2,
|
|
||||||
SHOW_PROCESSES: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
const GnomeShellMountOpHandler = new Lang.Class({
|
|
||||||
Name: 'GnomeShellMountOpHandler',
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellMountOpIface, this);
|
|
||||||
this._dbusImpl.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
|
|
||||||
Gio.bus_own_name_on_connection(Gio.DBus.session, 'org.gtk.MountOperationHandler',
|
|
||||||
Gio.BusNameOwnerFlags.REPLACE, null, null);
|
|
||||||
|
|
||||||
this._dialog = null;
|
|
||||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
|
||||||
|
|
||||||
this._ensureEmptyRequest();
|
|
||||||
},
|
|
||||||
|
|
||||||
_ensureEmptyRequest: function() {
|
|
||||||
this._currentId = null;
|
|
||||||
this._currentInvocation = null;
|
|
||||||
this._currentType = ShellMountOperationType.NONE;
|
|
||||||
},
|
|
||||||
|
|
||||||
_clearCurrentRequest: function(response, details) {
|
|
||||||
if (this._currentInvocation) {
|
|
||||||
this._currentInvocation.return_value(
|
|
||||||
GLib.Variant.new('(ua{sv})', [response, details]));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._ensureEmptyRequest();
|
|
||||||
},
|
|
||||||
|
|
||||||
_setCurrentRequest: function(invocation, id, type) {
|
|
||||||
let oldId = this._currentId;
|
|
||||||
let oldType = this._currentType;
|
|
||||||
let requestId = id + '@' + invocation.get_sender();
|
|
||||||
|
|
||||||
this._clearCurrentRequest(Gio.MountOperationResult.UNHANDLED, {});
|
|
||||||
|
|
||||||
this._currentInvocation = invocation;
|
|
||||||
this._currentId = requestId;
|
|
||||||
this._currentType = type;
|
|
||||||
|
|
||||||
if (this._dialog && (oldId == requestId) && (oldType == type))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_closeDialog: function() {
|
|
||||||
if (this._dialog) {
|
|
||||||
this._dialog.close();
|
|
||||||
this._dialog = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_createGIcon: function(iconName) {
|
|
||||||
let realIconName = iconName ? iconName : 'drive-harddisk';
|
|
||||||
return new Gio.ThemedIcon({ name: realIconName,
|
|
||||||
use_default_fallbacks: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AskPassword:
|
|
||||||
* @id: an opaque ID identifying the object for which the operation is requested
|
|
||||||
* The ID must be unique in the context of the calling process.
|
|
||||||
* @message: the message to display
|
|
||||||
* @icon_name: the name of an icon to display
|
|
||||||
* @default_user: the default username for display
|
|
||||||
* @default_domain: the default domain for display
|
|
||||||
* @flags: a set of GAskPasswordFlags
|
|
||||||
* @response: a GMountOperationResult
|
|
||||||
* @response_details: a dictionary containing the response details as
|
|
||||||
* entered by the user. The dictionary MAY contain the following properties:
|
|
||||||
* - "password" -> (s): a password to be used to complete the mount operation
|
|
||||||
* - "password_save" -> (u): a GPasswordSave
|
|
||||||
*
|
|
||||||
* The dialog will stay visible until clients call the Close() method, or
|
|
||||||
* another dialog becomes visible.
|
|
||||||
* Calling AskPassword again for the same id will have the effect to clear
|
|
||||||
* the existing dialog and update it with a message indicating the previous
|
|
||||||
* attempt went wrong.
|
|
||||||
*/
|
|
||||||
AskPasswordAsync: function(params, invocation) {
|
|
||||||
let [id, message, iconName, defaultUser, defaultDomain, flags] = params;
|
|
||||||
|
|
||||||
if (this._setCurrentRequest(invocation, id, ShellMountOperationType.ASK_PASSWORD)) {
|
|
||||||
this._dialog.reaskPassword();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._closeDialog();
|
|
||||||
|
|
||||||
this._dialog = new ShellMountPasswordDialog(message, this._createGIcon(iconName), flags);
|
|
||||||
this._dialog.connect('response', Lang.bind(this,
|
|
||||||
function(object, choice, password, remember) {
|
|
||||||
let details = {};
|
|
||||||
let response;
|
|
||||||
|
|
||||||
if (choice == -1) {
|
|
||||||
response = Gio.MountOperationResult.ABORTED;
|
|
||||||
} else {
|
|
||||||
response = Gio.MountOperationResult.HANDLED;
|
|
||||||
|
|
||||||
let passSave = remember ? Gio.PasswordSave.PERMANENTLY : Gio.PasswordSave.NEVER;
|
|
||||||
details['password_save'] = GLib.Variant.new('u', passSave);
|
|
||||||
details['password'] = GLib.Variant.new('s', password);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._clearCurrentRequest(response, details);
|
|
||||||
}));
|
|
||||||
this._dialog.open();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AskQuestion:
|
|
||||||
* @id: an opaque ID identifying the object for which the operation is requested
|
|
||||||
* The ID must be unique in the context of the calling process.
|
|
||||||
* @message: the message to display
|
|
||||||
* @icon_name: the name of an icon to display
|
|
||||||
* @choices: an array of choice strings
|
|
||||||
* GetResponse:
|
|
||||||
* @response: a GMountOperationResult
|
|
||||||
* @response_details: a dictionary containing the response details as
|
|
||||||
* entered by the user. The dictionary MAY contain the following properties:
|
|
||||||
* - "choice" -> (i): the chosen answer among the array of strings passed in
|
|
||||||
*
|
|
||||||
* The dialog will stay visible until clients call the Close() method, or
|
|
||||||
* another dialog becomes visible.
|
|
||||||
* Calling AskQuestion again for the same id will have the effect to clear
|
|
||||||
* update the dialog with the new question.
|
|
||||||
*/
|
|
||||||
AskQuestionAsync: function(params, invocation) {
|
|
||||||
let [id, message, iconName, choices] = params;
|
|
||||||
|
|
||||||
if (this._setCurrentRequest(invocation, id, ShellMountOperationType.ASK_QUESTION)) {
|
|
||||||
this._dialog.update(message, choices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._closeDialog();
|
|
||||||
|
|
||||||
this._dialog = new ShellMountQuestionDialog(this._createGIcon(iconName), message);
|
|
||||||
this._dialog.connect('response', Lang.bind(this,
|
|
||||||
function(object, choice) {
|
|
||||||
this._clearCurrentRequest(Gio.MountOperationResult.HANDLED,
|
|
||||||
{ choice: GLib.Variant.new('i', choice) });
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._dialog.update(message, choices);
|
|
||||||
this._dialog.open();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ShowProcesses:
|
|
||||||
* @id: an opaque ID identifying the object for which the operation is requested
|
|
||||||
* The ID must be unique in the context of the calling process.
|
|
||||||
* @message: the message to display
|
|
||||||
* @icon_name: the name of an icon to display
|
|
||||||
* @application_pids: the PIDs of the applications to display
|
|
||||||
* @choices: an array of choice strings
|
|
||||||
* @response: a GMountOperationResult
|
|
||||||
* @response_details: a dictionary containing the response details as
|
|
||||||
* entered by the user. The dictionary MAY contain the following properties:
|
|
||||||
* - "choice" -> (i): the chosen answer among the array of strings passed in
|
|
||||||
*
|
|
||||||
* The dialog will stay visible until clients call the Close() method, or
|
|
||||||
* another dialog becomes visible.
|
|
||||||
* Calling ShowProcesses again for the same id will have the effect to clear
|
|
||||||
* the existing dialog and update it with the new message and the new list
|
|
||||||
* of processes.
|
|
||||||
*/
|
|
||||||
ShowProcessesAsync: function(params, invocation) {
|
|
||||||
let [id, message, iconName, applicationPids, choices] = params;
|
|
||||||
|
|
||||||
if (this._setCurrentRequest(invocation, id, ShellMountOperationType.SHOW_PROCESSES)) {
|
|
||||||
this._dialog.update(message, applicationPids, choices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._closeDialog();
|
|
||||||
|
|
||||||
this._dialog = new ShellProcessesDialog(this._createGIcon(iconName));
|
|
||||||
this._dialog.connect('response', Lang.bind(this,
|
|
||||||
function(object, choice) {
|
|
||||||
let response;
|
|
||||||
let details = {};
|
|
||||||
|
|
||||||
if (choice == -1) {
|
|
||||||
response = Gio.MountOperationResult.ABORTED;
|
|
||||||
} else {
|
|
||||||
response = Gio.MountOperationResult.HANDLED;
|
|
||||||
details['choice'] = GLib.Variant.new('i', choice);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._clearCurrentRequest(response, details);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._dialog.update(message, applicationPids, choices);
|
|
||||||
this._dialog.open();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close:
|
|
||||||
*
|
|
||||||
* Closes a dialog previously opened by AskPassword, AskQuestion or ShowProcesses.
|
|
||||||
* If no dialog is open, does nothing.
|
|
||||||
*/
|
|
||||||
Close: function(params, invocation) {
|
|
||||||
this._clearCurrentRequest(Gio.MountOperationResult.UNHANDLED, {});
|
|
||||||
this._closeDialog();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ const ATIndicator = new Lang.Class({
|
|||||||
let textZoom = this._buildFontItem();
|
let textZoom = this._buildFontItem();
|
||||||
this.menu.addMenuItem(textZoom);
|
this.menu.addMenuItem(textZoom);
|
||||||
|
|
||||||
let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
|
// let screenReader = this._buildItem(_("Screen Reader"), APPLICATIONS_SCHEMA,
|
||||||
'screen-reader-enabled');
|
// 'screen-reader-enabled');
|
||||||
this.menu.addMenuItem(screenReader);
|
// this.menu.addMenuItem(screenReader);
|
||||||
|
|
||||||
let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
|
let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
|
||||||
'screen-keyboard-enabled');
|
'screen-keyboard-enabled');
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ const Indicator = new Lang.Class({
|
|||||||
|
|
||||||
_ensureSource: function() {
|
_ensureSource: function() {
|
||||||
if (!this._source) {
|
if (!this._source) {
|
||||||
this._source = new MessageTray.Source(_("Bluetooth"), 'bluetooth-active', St.IconType.SYMBOLIC);
|
this._source = new Source();
|
||||||
Main.messageTray.add(this._source);
|
Main.messageTray.add(this._source);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -330,6 +330,35 @@ const Indicator = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const Source = new Lang.Class({
|
||||||
|
Name: 'BluetoothSource',
|
||||||
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent(_("Bluetooth"));
|
||||||
|
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
},
|
||||||
|
|
||||||
|
notify: function(notification) {
|
||||||
|
this._private_destroyId = notification.connect('destroy', Lang.bind(this, function(notification) {
|
||||||
|
if (this.notification == notification) {
|
||||||
|
// the destroyed notification is the last for this source
|
||||||
|
this.notification.disconnect(this._private_destroyId);
|
||||||
|
this.destroy();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.parent(notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
return new St.Icon({ icon_name: 'bluetooth-active',
|
||||||
|
icon_type: St.IconType.SYMBOLIC,
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const AuthNotification = new Lang.Class({
|
const AuthNotification = new Lang.Class({
|
||||||
Name: 'AuthNotification',
|
Name: 'AuthNotification',
|
||||||
Extends: MessageTray.Notification,
|
Extends: MessageTray.Notification,
|
||||||
@@ -380,7 +409,7 @@ const ConfirmNotification = new Lang.Class({
|
|||||||
this._applet = applet;
|
this._applet = applet;
|
||||||
this._devicePath = device_path;
|
this._devicePath = device_path;
|
||||||
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
|
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
|
||||||
this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin));
|
this.addBody(_("Please confirm whether the PIN '%s' matches the one on the device.").format(pin));
|
||||||
|
|
||||||
this.addButton('matches', _("Matches"));
|
this.addButton('matches', _("Matches"));
|
||||||
this.addButton('does-not-match', _("Does not match"));
|
this.addButton('does-not-match', _("Does not match"));
|
||||||
@@ -416,8 +445,7 @@ const PinNotification = new Lang.Class({
|
|||||||
this._entry.connect('key-release-event', Lang.bind(this, function(entry, event) {
|
this._entry.connect('key-release-event', Lang.bind(this, function(entry, event) {
|
||||||
let key = event.get_key_symbol();
|
let key = event.get_key_symbol();
|
||||||
if (key == Clutter.KEY_Return) {
|
if (key == Clutter.KEY_Return) {
|
||||||
if (this._canActivateOkButton())
|
this.emit('action-invoked', 'ok');
|
||||||
this.emit('action-invoked', 'ok');
|
|
||||||
return true;
|
return true;
|
||||||
} else if (key == Clutter.KEY_Escape) {
|
} else if (key == Clutter.KEY_Escape) {
|
||||||
this.emit('action-invoked', 'cancel');
|
this.emit('action-invoked', 'cancel');
|
||||||
@@ -430,12 +458,6 @@ const PinNotification = new Lang.Class({
|
|||||||
this.addButton('ok', _("OK"));
|
this.addButton('ok', _("OK"));
|
||||||
this.addButton('cancel', _("Cancel"));
|
this.addButton('cancel', _("Cancel"));
|
||||||
|
|
||||||
this.setButtonSensitive('ok', this._canActivateOkButton());
|
|
||||||
this._entry.clutter_text.connect('text-changed', Lang.bind(this,
|
|
||||||
function() {
|
|
||||||
this.setButtonSensitive('ok', this._canActivateOkButton());
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||||
if (action == 'ok') {
|
if (action == 'ok') {
|
||||||
if (this._numeric) {
|
if (this._numeric) {
|
||||||
@@ -458,11 +480,6 @@ const PinNotification = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_canActivateOkButton: function() {
|
|
||||||
// PINs have a fixed length of 6
|
|
||||||
return this._entry.clutter_text.text.length == 6;
|
|
||||||
},
|
|
||||||
|
|
||||||
grabFocus: function(lockTray) {
|
grabFocus: function(lockTray) {
|
||||||
this.parent(lockTray);
|
this.parent(lockTray);
|
||||||
global.stage.set_key_focus(this._entry);
|
global.stage.set_key_focus(this._entry);
|
||||||
|
|||||||
584
js/ui/status/candidatePanel.js
Normal file
584
js/ui/status/candidatePanel.js
Normal file
@@ -0,0 +1,584 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Red Hat, Inc.
|
||||||
|
* Copyright 2012 Peng Huang <shawn.p.huang@gmail.com>
|
||||||
|
* Copyright 2012 Takao Fujiwara <tfujiwar@redhat.com>
|
||||||
|
* Copyright 2012 Tiger Soldier <tigersoldi@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const IBus = imports.gi.IBus;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const BoxPointer = imports.ui.boxpointer;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
|
const ORIENTATION_HORIZONTAL = 0;
|
||||||
|
const ORIENTATION_VERTICAL = 1;
|
||||||
|
const ORIENTATION_SYSTEM = 2;
|
||||||
|
|
||||||
|
const StCandidateArea = new Lang.Class({
|
||||||
|
Name: 'StCandidateArea',
|
||||||
|
|
||||||
|
_init: function(orientation) {
|
||||||
|
this.actor = new St.BoxLayout({ style_class: 'candidate-area' });
|
||||||
|
this._orientation = orientation;
|
||||||
|
this._labels = [];
|
||||||
|
this._labelBoxes = [];
|
||||||
|
this._createUI();
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeOldWidgets: function() {
|
||||||
|
this.actor.destroy_all_children();
|
||||||
|
this._labels = [];
|
||||||
|
this._labelBoxes = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
_createUI: function() {
|
||||||
|
let vbox = null;
|
||||||
|
let hbox = null;
|
||||||
|
if (this._orientation == ORIENTATION_VERTICAL) {
|
||||||
|
vbox = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'candidate-vertical' });
|
||||||
|
this.actor.add_child(vbox,
|
||||||
|
{ expand: true,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
hbox = new St.BoxLayout({ vertical: false,
|
||||||
|
style_class: 'candidate-horizontal' });
|
||||||
|
this.actor.add_child(hbox,
|
||||||
|
{ expand: true,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (let i = 0; i < 16; i++) {
|
||||||
|
let label1 = new St.Label({ text: '1234567890abcdef'.charAt(i) + '.',
|
||||||
|
style_class: 'popup-menu-item',
|
||||||
|
reactive: true });
|
||||||
|
|
||||||
|
let label2 = new St.Label({ text: '' ,
|
||||||
|
style_class: 'popup-menu-item',
|
||||||
|
reactive: true });
|
||||||
|
|
||||||
|
if (this._orientation == ORIENTATION_VERTICAL) {
|
||||||
|
let candidateHBox = new St.BoxLayout({vertical: false});
|
||||||
|
let labelBox = new St.Bin({ style_class: 'candidate-hlabel-content' });
|
||||||
|
labelBox.set_child(label1);
|
||||||
|
labelBox.set_fill(true, true);
|
||||||
|
let textBox = new St.Bin({ style_class: 'candidate-htext-content' });
|
||||||
|
|
||||||
|
textBox.set_child(label2);
|
||||||
|
textBox.set_fill(true, true);
|
||||||
|
candidateHBox.add_child(labelBox,
|
||||||
|
{ expand: false,
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: true
|
||||||
|
});
|
||||||
|
candidateHBox.add_child(textBox,
|
||||||
|
{ expand: true,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: true
|
||||||
|
});
|
||||||
|
vbox.add_child(candidateHBox);
|
||||||
|
this._labelBoxes.push(candidateHBox);
|
||||||
|
} else {
|
||||||
|
let candidateHBox = new St.BoxLayout({ style_class: 'candidate-vcontent',
|
||||||
|
vertical: false });
|
||||||
|
candidateHBox.add_child(label1);
|
||||||
|
candidateHBox.add_child(label2);
|
||||||
|
hbox.add_child(candidateHBox);
|
||||||
|
this._labelBoxes.push(candidateHBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._labels.push([label1, label2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this._labels.length; i++) {
|
||||||
|
for(let j = 0; j < this._labels[i].length; j++) {
|
||||||
|
let widget = this._labels[i][j];
|
||||||
|
widget.candidateIndex = i;
|
||||||
|
widget.connect('button-press-event',
|
||||||
|
Lang.bind(this, function (widget, event) {
|
||||||
|
this._candidateClickedCB(widget, event);
|
||||||
|
}));
|
||||||
|
widget.connect('enter-event',
|
||||||
|
function(widget, event) {
|
||||||
|
widget.add_style_pseudo_class('hover');
|
||||||
|
});
|
||||||
|
widget.connect('leave-event',
|
||||||
|
function(widget, event) {
|
||||||
|
widget.remove_style_pseudo_class('hover');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_recreateUI: function() {
|
||||||
|
this._removeOldWidgets();
|
||||||
|
this._createUI();
|
||||||
|
},
|
||||||
|
|
||||||
|
_candidateClickedCB: function(widget, event) {
|
||||||
|
this.emit('candidate-clicked',
|
||||||
|
widget.candidateIndex,
|
||||||
|
event.get_button(),
|
||||||
|
event.get_state());
|
||||||
|
},
|
||||||
|
|
||||||
|
setLabels: function(labels) {
|
||||||
|
if (!labels || labels.length == 0) {
|
||||||
|
for (let i = 0; i < 16; i++) {
|
||||||
|
this._labels[i][0].set_text('1234567890abcdef'.charAt(i) + '.');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < labels.length && i < this._labels.length; i++) {
|
||||||
|
/* Use a ClutterActor attribute of Shell's theme instead of
|
||||||
|
* Pango.AttrList for the lookup window GUI and
|
||||||
|
* can ignore 'attrs' simply from IBus engines?
|
||||||
|
*/
|
||||||
|
let [text, attrs] = labels[i];
|
||||||
|
this._labels[i][0].set_text(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setCandidates: function(candidates, focusCandidate, showCursor) {
|
||||||
|
if (focusCandidate == undefined) {
|
||||||
|
focusCandidate = 0;
|
||||||
|
}
|
||||||
|
if (showCursor == undefined) {
|
||||||
|
showCursor = true;
|
||||||
|
}
|
||||||
|
if (candidates.length > this._labels.length) {
|
||||||
|
assert();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < candidates.length; i++) {
|
||||||
|
/* Use a ClutterActor attribute of Shell's theme instead of
|
||||||
|
* Pango.AttrList for the lookup window GUI and
|
||||||
|
* can ignore 'attrs' simply from IBus engines?
|
||||||
|
*/
|
||||||
|
let [text, attrs] = candidates[i];
|
||||||
|
if (i == focusCandidate && showCursor) {
|
||||||
|
this._labels[i][1].add_style_pseudo_class('active');
|
||||||
|
} else {
|
||||||
|
this._labels[i][1].remove_style_pseudo_class('active');
|
||||||
|
}
|
||||||
|
this._labels[i][1].set_text(text);
|
||||||
|
this._labelBoxes[i].show();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = this._labelBoxes.length - 1; i >= candidates.length; i--) {
|
||||||
|
this._labelBoxes[i].hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setOrientation: function(orientation) {
|
||||||
|
if (orientation == this._orientation)
|
||||||
|
return;
|
||||||
|
this._orientation = orientation;
|
||||||
|
this._recreateUI();
|
||||||
|
},
|
||||||
|
|
||||||
|
showAll: function() {
|
||||||
|
this.actor.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideAll: function() {
|
||||||
|
this.actor.hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(StCandidateArea.prototype);
|
||||||
|
|
||||||
|
const CandidatePanel = new Lang.Class({
|
||||||
|
Name: 'CandidatePanel',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._orientation = ORIENTATION_VERTICAL;
|
||||||
|
this._currentOrientation = this._orientation;
|
||||||
|
this._preeditVisible = false;
|
||||||
|
this._auxStringVisible = false;
|
||||||
|
this._lookupTableVisible = false;
|
||||||
|
this._lookupTable = null;
|
||||||
|
|
||||||
|
this._cursorLocation = [0, 0, 0, 0];
|
||||||
|
this._movedCursorLocation = null;
|
||||||
|
|
||||||
|
this._initSt();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_initSt: function() {
|
||||||
|
this._arrowSide = St.Side.TOP;
|
||||||
|
this._arrowAlignment = 0.0;
|
||||||
|
this._boxPointer = new BoxPointer.BoxPointer(this._arrowSide,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
this.actor = this._boxPointer.actor;
|
||||||
|
this.actor._delegate = this;
|
||||||
|
this.actor.style_class = 'popup-menu-boxpointer';
|
||||||
|
this.actor.add_style_class_name('popup-menu');
|
||||||
|
this.actor.add_style_class_name('candidate-panel');
|
||||||
|
this._cursorActor = new Shell.GenericContainer();
|
||||||
|
Main.uiGroup.add_actor(this.actor);
|
||||||
|
Main.uiGroup.add_actor(this._cursorActor);
|
||||||
|
|
||||||
|
this._stCandidatePanel = new St.BoxLayout({ style_class: 'candidate-panel',
|
||||||
|
vertical: true });
|
||||||
|
this._boxPointer.bin.set_child(this._stCandidatePanel);
|
||||||
|
|
||||||
|
this._stPreeditLabel = new St.Label({ style_class: 'popup-menu-item',
|
||||||
|
text: '' });
|
||||||
|
if (!this._preeditVisible) {
|
||||||
|
this._stPreeditLabel.hide();
|
||||||
|
}
|
||||||
|
this._stAuxLabel = new St.Label({ style_class: 'popup-menu-item',
|
||||||
|
text: '' });
|
||||||
|
if (!this._auxVisible) {
|
||||||
|
this._stAuxLabel.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._separator = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
|
if (!this._preeditVisible && !this._auxVisible) {
|
||||||
|
this._separator.actor.hide();
|
||||||
|
}
|
||||||
|
// create candidates area
|
||||||
|
this._stCandidateArea = new StCandidateArea(this._currentOrientation);
|
||||||
|
this._stCandidateArea.connect('candidate-clicked',
|
||||||
|
Lang.bind(this, function(x, i, b, s) {
|
||||||
|
this.emit('candidate-clicked', i, b, s);}));
|
||||||
|
this.updateLookupTable(this._lookupTable, this._lookupTableVisible);
|
||||||
|
|
||||||
|
// TODO: page up/down GUI
|
||||||
|
|
||||||
|
this._packAllStWidgets();
|
||||||
|
this._isVisible = true;
|
||||||
|
this.hideAll();
|
||||||
|
this._checkShowStates();
|
||||||
|
},
|
||||||
|
|
||||||
|
_packAllStWidgets: function() {
|
||||||
|
this._stCandidatePanel.add_child(this._stPreeditLabel,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.MIDDLE,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
this._stCandidatePanel.add_child(this._stAuxLabel,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.MIDDLE,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
this._stCandidatePanel.add_child(this._separator.actor,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.MIDDLE,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
this._stCandidatePanel.add_child(this._stCandidateArea.actor,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.MIDDLE,
|
||||||
|
y_align: St.Align.END });
|
||||||
|
},
|
||||||
|
|
||||||
|
showPreeditText: function() {
|
||||||
|
this._preeditVisible = true;
|
||||||
|
this._stPreeditLabel.show();
|
||||||
|
this._checkShowStates();
|
||||||
|
},
|
||||||
|
|
||||||
|
hidePreeditText: function() {
|
||||||
|
this._preeditVisible = false;
|
||||||
|
this._checkShowStates();
|
||||||
|
this._stPreeditLabel.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
updatePreeditText: function(text, cursorPos, visible) {
|
||||||
|
if (visible) {
|
||||||
|
this.showPreeditText();
|
||||||
|
} else {
|
||||||
|
this.hidePreeditText();
|
||||||
|
}
|
||||||
|
let str = text.get_text();
|
||||||
|
this._stPreeditLabel.set_text(str);
|
||||||
|
|
||||||
|
let attrs = text.get_attributes();
|
||||||
|
for (let i = 0; attrs != null && attrs.get(i) != null; i++) {
|
||||||
|
let attr = attrs.get(i);
|
||||||
|
if (attr.get_attr_type() == IBus.AttrType.BACKGROUND) {
|
||||||
|
let startIndex = attr.get_start_index();
|
||||||
|
let endIndex = attr.get_end_index();
|
||||||
|
let len = GLib.utf8_strlen(str, -1);
|
||||||
|
let markup = '';
|
||||||
|
if (startIndex == 0 &&
|
||||||
|
endIndex == GLib.utf8_strlen(str, -1)) {
|
||||||
|
markup = markup.concat(str);
|
||||||
|
} else {
|
||||||
|
if (startIndex > 0) {
|
||||||
|
markup = markup.concat(GLib.utf8_substring(str,
|
||||||
|
0,
|
||||||
|
startIndex));
|
||||||
|
}
|
||||||
|
if (startIndex != endIndex) {
|
||||||
|
markup = markup.concat('<span background=\"#555555\">');
|
||||||
|
markup = markup.concat(GLib.utf8_substring(str,
|
||||||
|
startIndex,
|
||||||
|
endIndex));
|
||||||
|
markup = markup.concat('</span>');
|
||||||
|
}
|
||||||
|
if (endIndex < len) {
|
||||||
|
markup = markup.concat(GLib.utf8_substring(str,
|
||||||
|
endIndex,
|
||||||
|
len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let clutter_text = this._stPreeditLabel.get_clutter_text();
|
||||||
|
clutter_text.set_markup(markup);
|
||||||
|
clutter_text.queue_redraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
showAuxiliaryText: function() {
|
||||||
|
this._auxStringVisible = true;
|
||||||
|
this._stAuxLabel.show();
|
||||||
|
this._checkShowStates();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideAuxiliaryText: function() {
|
||||||
|
this._auxStringVisible = false;
|
||||||
|
this._checkShowStates();
|
||||||
|
this._stAuxLabel.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAuxiliaryText: function(text, show) {
|
||||||
|
if (show) {
|
||||||
|
this.showAuxiliaryText();
|
||||||
|
} else {
|
||||||
|
this.hideAuxiliaryText();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._stAuxLabel.set_text(text.get_text());
|
||||||
|
},
|
||||||
|
|
||||||
|
_refreshLabels: function() {
|
||||||
|
let newLabels = [];
|
||||||
|
for (let i = 0; this._lookupTable.get_label(i) != null; i++) {
|
||||||
|
let label = this._lookupTable.get_label(i);
|
||||||
|
newLabels.push([label.get_text(), label.get_attributes()]);
|
||||||
|
}
|
||||||
|
this._stCandidateArea.setLabels(newLabels);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
_getCandidatesInCurrentPage: function() {
|
||||||
|
let cursorPos = this._lookupTable.get_cursor_pos();
|
||||||
|
let pageSize = this._lookupTable.get_page_size();
|
||||||
|
let page = ((cursorPos == 0) ? 0 : Math.floor(cursorPos / pageSize));
|
||||||
|
let startIndex = page * pageSize;
|
||||||
|
let endIndex = Math.min((page + 1) * pageSize,
|
||||||
|
this._lookupTable.get_number_of_candidates());
|
||||||
|
let candidates = [];
|
||||||
|
for (let i = startIndex; i < endIndex; i++) {
|
||||||
|
candidates.push(this._lookupTable.get_candidate(i));
|
||||||
|
}
|
||||||
|
return candidates;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getCursorPosInCurrentPage: function() {
|
||||||
|
let cursorPos = this._lookupTable.get_cursor_pos();
|
||||||
|
let pageSize = this._lookupTable.get_page_size();
|
||||||
|
let posInPage = cursorPos % pageSize;
|
||||||
|
return posInPage;
|
||||||
|
},
|
||||||
|
|
||||||
|
_refreshCandidates: function() {
|
||||||
|
let candidates = this._getCandidatesInCurrentPage();
|
||||||
|
let newCandidates = [];
|
||||||
|
for (let i = 0; i < candidates.length; i++) {
|
||||||
|
let candidate = candidates[i];
|
||||||
|
newCandidates.push([candidate.get_text(),
|
||||||
|
candidate.get_attributes()]);
|
||||||
|
}
|
||||||
|
this._stCandidateArea.setCandidates(newCandidates,
|
||||||
|
this._getCursorPosInCurrentPage(),
|
||||||
|
this._lookupTable.is_cursor_visible());
|
||||||
|
},
|
||||||
|
|
||||||
|
updateLookupTable: function(lookupTable, visible) {
|
||||||
|
// hide lookup table
|
||||||
|
if (!visible) {
|
||||||
|
this.hideLookupTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._lookupTable = lookupTable || new IBus.LookupTable();
|
||||||
|
let orientation = this._lookupTable.get_orientation();
|
||||||
|
if (orientation != ORIENTATION_HORIZONTAL &&
|
||||||
|
orientation != ORIENTATION_VERTICAL) {
|
||||||
|
orientation = this._orientation;
|
||||||
|
}
|
||||||
|
this.setCurrentOrientation(orientation);
|
||||||
|
this._refreshCandidates();
|
||||||
|
this._refreshLabels();
|
||||||
|
|
||||||
|
// show lookup table
|
||||||
|
if (visible) {
|
||||||
|
this.showLookupTable();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
showLookupTable: function() {
|
||||||
|
this._lookupTableVisible = true;
|
||||||
|
this._stCandidateArea.showAll();
|
||||||
|
this._checkShowStates();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideLookupTable: function() {
|
||||||
|
this._lookupTableVisible = false;
|
||||||
|
this._checkShowStates();
|
||||||
|
this._stCandidateArea.hideAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
pageUpLookupTable: function() {
|
||||||
|
this._lookupTable.page_up();
|
||||||
|
this._refreshCandidates();
|
||||||
|
},
|
||||||
|
|
||||||
|
pageDownLookup_table: function() {
|
||||||
|
this._lookupTable.page_down();
|
||||||
|
this._refreshCandidates();
|
||||||
|
},
|
||||||
|
|
||||||
|
cursorUpLookupTable: function() {
|
||||||
|
this._lookupTable.cursor_up();
|
||||||
|
this._refreshCandidates();
|
||||||
|
},
|
||||||
|
|
||||||
|
cursorDownLookupTable: function() {
|
||||||
|
this._lookupTable.cursor_down();
|
||||||
|
this._refreshCandidates();
|
||||||
|
},
|
||||||
|
|
||||||
|
setCursorLocation: function(x, y, w, h) {
|
||||||
|
// if cursor location is changed, we reset the moved cursor location
|
||||||
|
if (this._cursorLocation.join() != [x, y, w, h].join()) {
|
||||||
|
this._cursorLocation = [x, y, w, h];
|
||||||
|
this._movedCursorLocation = null;
|
||||||
|
this._checkPosition();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_checkShowStates: function() {
|
||||||
|
this._checkSeparatorShowStates();
|
||||||
|
if (this._preeditVisible ||
|
||||||
|
this._auxStringVisible ||
|
||||||
|
this._lookupTableVisible) {
|
||||||
|
this._checkPosition();
|
||||||
|
this.showAll();
|
||||||
|
this.emit('show');
|
||||||
|
} else {
|
||||||
|
this.hideAll();
|
||||||
|
this.emit('hide');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_checkSeparatorShowStates: function() {
|
||||||
|
if (this._preeditVisible || this._auxStringVisible) {
|
||||||
|
this._separator.actor.show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this._separator.actor.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function() {
|
||||||
|
let text = IBus.Text.new_from_string('');
|
||||||
|
this.updatePreeditText(text, 0, false);
|
||||||
|
text = IBus.Text.new_from_string('');
|
||||||
|
this.updateAuxiliaryText(text, false);
|
||||||
|
this.updateLookupTable(null, false);
|
||||||
|
this.hideAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
setCurrentOrientation: function(orientation) {
|
||||||
|
if (this._currentOrientation == orientation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._currentOrientation = orientation;
|
||||||
|
this._stCandidateArea.setOrientation(orientation);
|
||||||
|
},
|
||||||
|
|
||||||
|
setOrientation: function(orientation) {
|
||||||
|
this._orientation = orientation;
|
||||||
|
this.updateLookupTable(this._lookupTable, this._lookupTableVisible);
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurrentOrientation: function() {
|
||||||
|
return this._currentOrientation;
|
||||||
|
},
|
||||||
|
|
||||||
|
_checkPosition: function() {
|
||||||
|
let cursorLocation = this._movedCursorLocation || this._cursorLocation;
|
||||||
|
let [cursorX, cursorY, cursorWidth, cursorHeight] = cursorLocation;
|
||||||
|
|
||||||
|
let windowRight = cursorX + cursorWidth + this.actor.get_width();
|
||||||
|
let windowBottom = cursorY + cursorHeight + this.actor.get_height();
|
||||||
|
|
||||||
|
this._cursorActor.set_position(cursorX, cursorY);
|
||||||
|
this._cursorActor.set_size(cursorWidth, cursorHeight);
|
||||||
|
|
||||||
|
let monitor = Main.layoutManager.findMonitorForActor(this._cursorActor);
|
||||||
|
let [sx, sy] = [monitor.x + monitor.width, monitor.y + monitor.height];
|
||||||
|
|
||||||
|
if (windowBottom > sy) {
|
||||||
|
this._arrowSide = St.Side.BOTTOM;
|
||||||
|
} else {
|
||||||
|
this._arrowSide = St.Side.TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._boxPointer._arrowSide = this._arrowSide;
|
||||||
|
this._boxPointer.setArrowOrigin(this._arrowSide);
|
||||||
|
this._boxPointer.setPosition(this._cursorActor, this._arrowAlignment);
|
||||||
|
},
|
||||||
|
|
||||||
|
showAll: function() {
|
||||||
|
if (!this._isVisible) {
|
||||||
|
this.actor.opacity = 255;
|
||||||
|
this.actor.show();
|
||||||
|
this._isVisible = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hideAll: function() {
|
||||||
|
if (this._isVisible) {
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
this.actor.hide();
|
||||||
|
this._isVisible = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
move: function(x, y) {
|
||||||
|
this.actor.set_position(x, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(CandidatePanel.prototype);
|
||||||
@@ -4,33 +4,45 @@ const Clutter = imports.gi.Clutter;
|
|||||||
const GdkPixbuf = imports.gi.GdkPixbuf;
|
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var IBus = imports.gi.IBus;
|
||||||
|
const CandidatePanel = imports.ui.status.candidatePanel;
|
||||||
|
} catch (e) {
|
||||||
|
var IBus = null;
|
||||||
|
}
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
|
const DESKTOP_INPUT_SOURCES_KEYBINDINGS_SCHEMA = 'org.gnome.desktop.input-sources.keybindings';
|
||||||
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
|
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
|
||||||
const KEY_CURRENT_INPUT_SOURCE = 'current';
|
const KEY_CURRENT_IS = 'current';
|
||||||
const KEY_INPUT_SOURCES = 'sources';
|
const KEY_INPUT_SOURCES = 'sources';
|
||||||
|
|
||||||
const INPUT_SOURCE_TYPE_XKB = 'xkb';
|
|
||||||
|
|
||||||
const LayoutMenuItem = new Lang.Class({
|
const LayoutMenuItem = new Lang.Class({
|
||||||
Name: 'LayoutMenuItem',
|
Name: 'LayoutMenuItem',
|
||||||
Extends: PopupMenu.PopupBaseMenuItem,
|
Extends: PopupMenu.PopupBaseMenuItem,
|
||||||
|
|
||||||
_init: function(displayName, shortName) {
|
_init: function(name, shortName, xkbLayout, xkbVariant, ibusEngine) {
|
||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
this.label = new St.Label({ text: displayName });
|
this.label = new St.Label({ text: name });
|
||||||
this.indicator = new St.Label({ text: shortName });
|
this.indicator = new St.Label({ text: shortName });
|
||||||
this.addActor(this.label);
|
this.addActor(this.label);
|
||||||
this.addActor(this.indicator);
|
this.addActor(this.indicator);
|
||||||
|
|
||||||
|
this.sourceName = name;
|
||||||
|
this.shortName = shortName;
|
||||||
|
this.xkbLayout = xkbLayout;
|
||||||
|
this.xkbVariant = xkbVariant;
|
||||||
|
this.ibusEngine = ibusEngine;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -48,144 +60,312 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this.actor.add_actor(this._container);
|
this.actor.add_actor(this._container);
|
||||||
this.actor.add_style_class_name('panel-status-button');
|
this.actor.add_style_class_name('panel-status-button');
|
||||||
|
|
||||||
this._labelActors = {};
|
this._labelActors = [ ];
|
||||||
this._layoutItems = {};
|
this._layoutItems = [ ];
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
||||||
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
|
this._settings.connect('changed::' + KEY_CURRENT_IS, Lang.bind(this, this._currentISChanged));
|
||||||
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
|
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
|
||||||
|
|
||||||
this._currentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
if (IBus)
|
||||||
this._xkbInfo = new GnomeDesktop.XkbInfo();
|
this._ibusInit();
|
||||||
|
|
||||||
this._inputSourcesChanged();
|
this._inputSourcesChanged();
|
||||||
|
|
||||||
// re-using "allowSettings" for the keyboard layout is a bit shady,
|
if (global.session_type == Shell.SessionType.USER) {
|
||||||
// but at least for now it is used as "allow popping up windows
|
|
||||||
// from shell menus"; we can always add a separate sessionMode
|
|
||||||
// option if need arises.
|
|
||||||
if (Main.sessionMode.allowSettings) {
|
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
|
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, function() {
|
||||||
|
Main.overview.hide();
|
||||||
|
let description = this._selectedLayout.xkbLayout;
|
||||||
|
if (this._selectedLayout.xkbVariant.length > 0)
|
||||||
|
description = description + '\t' + this._selectedLayout.xkbVariant;
|
||||||
|
Util.spawn(['gkbd-keyboard-display', '-l', description]);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
|
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
|
||||||
|
|
||||||
|
global.display.add_keybinding('switch-next',
|
||||||
|
new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_KEYBINDINGS_SCHEMA }),
|
||||||
|
Meta.KeyBindingFlags.NONE,
|
||||||
|
Lang.bind(this, this._switchNext));
|
||||||
|
global.display.add_keybinding('switch-previous',
|
||||||
|
new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_KEYBINDINGS_SCHEMA }),
|
||||||
|
Meta.KeyBindingFlags.NONE,
|
||||||
|
Lang.bind(this, this._switchPrevious));
|
||||||
},
|
},
|
||||||
|
|
||||||
_currentInputSourceChanged: function() {
|
_ibusInit: function() {
|
||||||
let nVisibleSources = Object.keys(this._layoutItems).length;
|
IBus.init();
|
||||||
if (nVisibleSources < 2)
|
this._ibus = new IBus.Bus();
|
||||||
|
if (!this._ibus.is_connected()) {
|
||||||
|
log('ibus-daemon is not running');
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let nSources = this._settings.get_value(KEY_INPUT_SOURCES).n_children();
|
|
||||||
let newCurrentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
|
||||||
if (newCurrentSourceIndex >= nSources)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!this._layoutItems[newCurrentSourceIndex]) {
|
|
||||||
// This source index is invalid as we weren't able to
|
|
||||||
// build a menu item for it, so we hide ourselves since we
|
|
||||||
// can't fix it here. *shrug*
|
|
||||||
this.menu.close();
|
|
||||||
this.actor.hide();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
this.actor.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._layoutItems[this._currentSourceIndex]) {
|
this._ibus.request_name(IBus.SERVICE_PANEL,
|
||||||
this._layoutItems[this._currentSourceIndex].setShowDot(false);
|
IBus.BusNameFlag.ALLOW_REPLACEMENT |
|
||||||
this._container.set_skip_paint(this._labelActors[this._currentSourceIndex], true);
|
IBus.BusNameFlag.REPLACE_EXISTING);
|
||||||
|
this._panel = new IBus.PanelService({ connection: this._ibus.get_connection(),
|
||||||
|
object_path: IBus.PATH_PANEL });
|
||||||
|
this._ibusInitPanelService();
|
||||||
|
|
||||||
|
this._candidatePanel = new CandidatePanel.CandidatePanel();
|
||||||
|
this._ibusInitCandidatePanel();
|
||||||
|
},
|
||||||
|
|
||||||
|
_ibusInitCandidatePanel: function() {
|
||||||
|
this._candidatePanel.connect('cursor-up',
|
||||||
|
Lang.bind(this, function(widget) {
|
||||||
|
this.cursorUp();
|
||||||
|
}));
|
||||||
|
this._candidatePanel.connect('cursor-down',
|
||||||
|
Lang.bind(this, function(widget) {
|
||||||
|
this.cursorDown();
|
||||||
|
}));
|
||||||
|
this._candidatePanel.connect('page-up',
|
||||||
|
Lang.bind(this, function(widget) {
|
||||||
|
this.pageUp();
|
||||||
|
}));
|
||||||
|
this._candidatePanel.connect('page-down',
|
||||||
|
Lang.bind(this, function(widget) {
|
||||||
|
this.pageDown();
|
||||||
|
}));
|
||||||
|
this._candidatePanel.connect('candidate-clicked',
|
||||||
|
Lang.bind(this, function(widget, index, button, state) {
|
||||||
|
this.candidateClicked(index, button, state);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_ibusInitPanelService: function() {
|
||||||
|
this._panel.connect('set-cursor-location',
|
||||||
|
Lang.bind(this, this.setCursorLocation));
|
||||||
|
this._panel.connect('update-preedit-text',
|
||||||
|
Lang.bind(this, this.updatePreeditText));
|
||||||
|
this._panel.connect('show-preedit-text',
|
||||||
|
Lang.bind(this, this.showPreeditText));
|
||||||
|
this._panel.connect('hide-preedit-text',
|
||||||
|
Lang.bind(this, this.hidePreeditText));
|
||||||
|
this._panel.connect('update-auxiliary-text',
|
||||||
|
Lang.bind(this, this.updateAuxiliaryText));
|
||||||
|
this._panel.connect('show-auxiliary-text',
|
||||||
|
Lang.bind(this, this.showAuxiliaryText));
|
||||||
|
this._panel.connect('hide-auxiliary-text',
|
||||||
|
Lang.bind(this, this.hideAuxiliaryText));
|
||||||
|
this._panel.connect('update-lookup-table',
|
||||||
|
Lang.bind(this, this.updateLookupTable));
|
||||||
|
this._panel.connect('show-lookup-table',
|
||||||
|
Lang.bind(this, this.showLookupTable));
|
||||||
|
this._panel.connect('hide-lookup-table',
|
||||||
|
Lang.bind(this, this.hideLookupTable));
|
||||||
|
this._panel.connect('page-up-lookup-table',
|
||||||
|
Lang.bind(this, this.pageUpLookupTable));
|
||||||
|
this._panel.connect('page-down-lookup-table',
|
||||||
|
Lang.bind(this, this.pageDownLookupTable));
|
||||||
|
this._panel.connect('cursor-up-lookup-table',
|
||||||
|
Lang.bind(this, this.cursorUpLookupTable));
|
||||||
|
this._panel.connect('cursor-down-lookup-table',
|
||||||
|
Lang.bind(this, this.cursorDownLookupTable));
|
||||||
|
this._panel.connect('focus-in', Lang.bind(this, this.focusIn));
|
||||||
|
this._panel.connect('focus-out', Lang.bind(this, this.focusOut));
|
||||||
|
},
|
||||||
|
|
||||||
|
setCursorLocation: function(panel, x, y, w, h) {
|
||||||
|
this._candidatePanel.setCursorLocation(x, y, w, h);
|
||||||
|
},
|
||||||
|
|
||||||
|
updatePreeditText: function(panel, text, cursorPos, visible) {
|
||||||
|
this._candidatePanel.updatePreeditText(text, cursorPos, visible);
|
||||||
|
},
|
||||||
|
|
||||||
|
showPreeditText: function(panel) {
|
||||||
|
this._candidatePanel.showPreeditText();
|
||||||
|
},
|
||||||
|
|
||||||
|
hidePreeditText: function(panel) {
|
||||||
|
this._candidatePanel.hidePreeditText();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAuxiliaryText: function(panel, text, visible) {
|
||||||
|
this._candidatePanel.updateAuxiliaryText(text, visible);
|
||||||
|
},
|
||||||
|
|
||||||
|
showAuxiliaryText: function(panel) {
|
||||||
|
this._candidatePanel.showAuxiliaryText();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideAuxiliaryText: function(panel) {
|
||||||
|
this._candidatePanel.hideAuxiliaryText();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateLookupTable: function(panel, lookupTable, visible) {
|
||||||
|
this._candidatePanel.updateLookupTable(lookupTable, visible);
|
||||||
|
},
|
||||||
|
|
||||||
|
showLookupTable: function(panel) {
|
||||||
|
this._candidatePanel.showLookupTable();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideLookupTable: function(panel) {
|
||||||
|
this._candidatePanel.hideLookupTable();
|
||||||
|
},
|
||||||
|
|
||||||
|
pageUpLookupTable: function(panel) {
|
||||||
|
this._candidatePanel.pageUpLookupTable();
|
||||||
|
},
|
||||||
|
|
||||||
|
pageDownLookupTable: function(panel) {
|
||||||
|
this._candidatePanel.pageDownLookupTable();
|
||||||
|
},
|
||||||
|
|
||||||
|
cursorUpLookupTable: function(panel) {
|
||||||
|
this._candidatePanel.cursorUpLookupTable();
|
||||||
|
},
|
||||||
|
|
||||||
|
cursorDownLookupTable: function(panel) {
|
||||||
|
this._candidatePanel.cursorDownLookupTable();
|
||||||
|
},
|
||||||
|
|
||||||
|
focusIn: function(panel, path) {
|
||||||
|
},
|
||||||
|
|
||||||
|
focusOut: function(panel, path) {
|
||||||
|
this._candidatePanel.reset();
|
||||||
|
},
|
||||||
|
|
||||||
|
cursorUp: function() {
|
||||||
|
this._panel.cursor_up();
|
||||||
|
},
|
||||||
|
|
||||||
|
cursorDown: function() {
|
||||||
|
this._panel.cursor_down();
|
||||||
|
},
|
||||||
|
|
||||||
|
pageUp: function() {
|
||||||
|
this._panel.page_up();
|
||||||
|
},
|
||||||
|
|
||||||
|
pageDown: function() {
|
||||||
|
this._panel.page_down();
|
||||||
|
},
|
||||||
|
|
||||||
|
candidateClicked: function(index, button, state) {
|
||||||
|
this._panel.candidate_clicked(index, button, state);
|
||||||
|
},
|
||||||
|
|
||||||
|
_currentISChanged: function() {
|
||||||
|
let source = this._settings.get_value(KEY_CURRENT_IS);
|
||||||
|
let name = source.get_child_value(0).get_string()[0];
|
||||||
|
|
||||||
|
if (this._selectedLayout) {
|
||||||
|
this._selectedLayout.setShowDot(false);
|
||||||
|
this._selectedLayout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._layoutItems[newCurrentSourceIndex].setShowDot(true);
|
if (this._selectedLabel) {
|
||||||
this._container.set_skip_paint(this._labelActors[newCurrentSourceIndex], false);
|
this._container.set_skip_paint(this._selectedLabel, true);
|
||||||
|
this._selectedLabel = null;
|
||||||
|
}
|
||||||
|
|
||||||
this._currentSourceIndex = newCurrentSourceIndex;
|
for (let i = 0; i < this._layoutItems.length; ++i) {
|
||||||
|
let item = this._layoutItems[i];
|
||||||
|
if (item.sourceName == name) {
|
||||||
|
item.setShowDot(true);
|
||||||
|
this._selectedLayout = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this._labelActors.length; ++i) {
|
||||||
|
let actor = this._labelActors[i];
|
||||||
|
if (actor.sourceName == name) {
|
||||||
|
this._selectedLabel = actor;
|
||||||
|
this._container.set_skip_paint(actor, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._selectedLayout || !this._selectedLabel)
|
||||||
|
this._layoutItems[0].activate();
|
||||||
},
|
},
|
||||||
|
|
||||||
_inputSourcesChanged: function() {
|
_inputSourcesChanged: function() {
|
||||||
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
||||||
let nSources = sources.n_children();
|
if (sources.n_children() > 1) {
|
||||||
|
|
||||||
for (let i in this._layoutItems)
|
|
||||||
this._layoutItems[i].destroy();
|
|
||||||
|
|
||||||
for (let i in this._labelActors)
|
|
||||||
this._labelActors[i].destroy();
|
|
||||||
|
|
||||||
this._layoutItems = {};
|
|
||||||
this._labelActors = {};
|
|
||||||
|
|
||||||
let infos = [];
|
|
||||||
let infosByShortName = {};
|
|
||||||
|
|
||||||
for (let i = 0; i < nSources; i++) {
|
|
||||||
let [type, id] = sources.get_child_value(i).deep_unpack();
|
|
||||||
if (type != INPUT_SOURCE_TYPE_XKB)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let info = {};
|
|
||||||
[info.exists, info.displayName, info.shortName, , ] =
|
|
||||||
this._xkbInfo.get_layout_info(id);
|
|
||||||
|
|
||||||
if (!info.exists)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
info.sourceIndex = i;
|
|
||||||
|
|
||||||
if (!(info.shortName in infosByShortName))
|
|
||||||
infosByShortName[info.shortName] = [];
|
|
||||||
infosByShortName[info.shortName].push(info);
|
|
||||||
infos.push(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (infos.length > 1) {
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
} else {
|
} else {
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < infos.length; i++) {
|
for (let i = 0; i < this._layoutItems.length; i++)
|
||||||
let info = infos[i];
|
this._layoutItems[i].destroy();
|
||||||
if (infosByShortName[info.shortName].length > 1) {
|
|
||||||
let sub = infosByShortName[info.shortName].indexOf(info) + 1;
|
|
||||||
info.shortName += String.fromCharCode(0x2080 + sub);
|
|
||||||
}
|
|
||||||
|
|
||||||
let item = new LayoutMenuItem(info.displayName, info.shortName);
|
for (let i = 0; i < this._labelActors.length; i++)
|
||||||
this._layoutItems[info.sourceIndex] = item;
|
this._labelActors[i].destroy();
|
||||||
|
|
||||||
|
this._selectedLayout = null;
|
||||||
|
this._layoutItems = [ ];
|
||||||
|
this._selectedLabel = null;
|
||||||
|
this._labelActors = [ ];
|
||||||
|
|
||||||
|
for (let i = 0; i < sources.n_children(); ++i) {
|
||||||
|
let name = sources.get_child_value(i).get_child_value(0).get_string()[0];
|
||||||
|
let shortName = sources.get_child_value(i).get_child_value(1).get_string()[0];
|
||||||
|
let xkbLayout = sources.get_child_value(i).get_child_value(2).get_string()[0];
|
||||||
|
let xkbVariant = sources.get_child_value(i).get_child_value(3).get_string()[0];
|
||||||
|
let ibusEngine = sources.get_child_value(i).get_child_value(4).get_string()[0];
|
||||||
|
|
||||||
|
let item = new LayoutMenuItem(name, shortName, xkbLayout, xkbVariant, ibusEngine);
|
||||||
|
this._layoutItems.push(item);
|
||||||
this.menu.addMenuItem(item, i);
|
this.menu.addMenuItem(item, i);
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
|
if (this._selectedLayout == null || item.sourceName != this._selectedLayout.sourceName) {
|
||||||
GLib.Variant.new_uint32(info.sourceIndex));
|
let name = GLib.Variant.new_string(item.sourceName);
|
||||||
|
let shortName = GLib.Variant.new_string(item.shortName);
|
||||||
|
let xkbLayout = GLib.Variant.new_string(item.xkbLayout);
|
||||||
|
let xkbVariant = GLib.Variant.new_string(item.xkbVariant);
|
||||||
|
let ibusEngine = GLib.Variant.new_string(item.ibusEngine);
|
||||||
|
let tuple = GLib.Variant.new_tuple([name, shortName, xkbLayout, xkbVariant, ibusEngine], 5);
|
||||||
|
this._settings.set_value(KEY_CURRENT_IS, tuple);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let shortLabel = new St.Label({ text: info.shortName });
|
let shortLabel = new St.Label({ text: shortName });
|
||||||
this._labelActors[info.sourceIndex] = shortLabel;
|
shortLabel.sourceName = name;
|
||||||
|
this._labelActors.push(shortLabel);
|
||||||
this._container.add_actor(shortLabel);
|
this._container.add_actor(shortLabel);
|
||||||
this._container.set_skip_paint(shortLabel, true);
|
this._container.set_skip_paint(shortLabel, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._currentInputSourceChanged();
|
this._currentISChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
_showLayout: function() {
|
_switchNext: function() {
|
||||||
Main.overview.hide();
|
if (!this._selectedLayout || !this._selectedLabel) {
|
||||||
|
this._layoutItems[0].activate();
|
||||||
let sources = this._settings.get_value(KEY_INPUT_SOURCES);
|
|
||||||
let current = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
|
||||||
let id = sources.get_child_value(current).deep_unpack()[1];
|
|
||||||
let [, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(id);
|
|
||||||
|
|
||||||
if (!xkbLayout || xkbLayout.length == 0)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < this._layoutItems.length; ++i) {
|
||||||
|
let item = this._layoutItems[i];
|
||||||
|
if (item.sourceName == this._selectedLayout.sourceName) {
|
||||||
|
this._layoutItems[(++i == this._layoutItems.length) ? 0 : i].activate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
let description = xkbLayout;
|
_switchPrevious: function() {
|
||||||
if (xkbVariant.length > 0)
|
if (!this._selectedLayout || !this._selectedLabel) {
|
||||||
description = description + '\t' + xkbVariant;
|
this._layoutItems[0].activate();
|
||||||
|
return;
|
||||||
Util.spawn(['gkbd-keyboard-display', '-l', description]);
|
}
|
||||||
|
for (let i = 0; i < this._layoutItems.length; ++i) {
|
||||||
|
let item = this._layoutItems[i];
|
||||||
|
if (item.sourceName == this._selectedLayout.sourceName) {
|
||||||
|
this._layoutItems[(--i == -1) ? (this._layoutItems.length - 1) : i].activate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_containerGetPreferredWidth: function(container, for_height, alloc) {
|
_containerGetPreferredWidth: function(container, for_height, alloc) {
|
||||||
@@ -194,7 +374,7 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
// for those we don't actually display.
|
// for those we don't actually display.
|
||||||
let max_min_width = 0, max_natural_width = 0;
|
let max_min_width = 0, max_natural_width = 0;
|
||||||
|
|
||||||
for (let i in this._labelActors) {
|
for (let i = 0; i < this._labelActors.length; i++) {
|
||||||
let [min_width, natural_width] = this._labelActors[i].get_preferred_width(for_height);
|
let [min_width, natural_width] = this._labelActors[i].get_preferred_width(for_height);
|
||||||
max_min_width = Math.max(max_min_width, min_width);
|
max_min_width = Math.max(max_min_width, min_width);
|
||||||
max_natural_width = Math.max(max_natural_width, natural_width);
|
max_natural_width = Math.max(max_natural_width, natural_width);
|
||||||
@@ -207,7 +387,7 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
_containerGetPreferredHeight: function(container, for_width, alloc) {
|
_containerGetPreferredHeight: function(container, for_width, alloc) {
|
||||||
let max_min_height = 0, max_natural_height = 0;
|
let max_min_height = 0, max_natural_height = 0;
|
||||||
|
|
||||||
for (let i in this._labelActors) {
|
for (let i = 0; i < this._labelActors.length; i++) {
|
||||||
let [min_height, natural_height] = this._labelActors[i].get_preferred_height(for_width);
|
let [min_height, natural_height] = this._labelActors[i].get_preferred_height(for_width);
|
||||||
max_min_height = Math.max(max_min_height, min_height);
|
max_min_height = Math.max(max_min_height, min_height);
|
||||||
max_natural_height = Math.max(max_natural_height, natural_height);
|
max_natural_height = Math.max(max_natural_height, natural_height);
|
||||||
@@ -224,7 +404,7 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
box.y2 -= box.y1;
|
box.y2 -= box.y1;
|
||||||
box.y1 = 0;
|
box.y1 = 0;
|
||||||
|
|
||||||
for (let i in this._labelActors)
|
for (let i = 0; i < this._labelActors.length; i++)
|
||||||
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
|
this._labelActors[i].allocate_align_fill(box, 0.5, 0, false, false, flags);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -101,10 +101,11 @@ const NMNetworkMenuItem = new Lang.Class({
|
|||||||
Name: 'NMNetworkMenuItem',
|
Name: 'NMNetworkMenuItem',
|
||||||
Extends: PopupMenu.PopupBaseMenuItem,
|
Extends: PopupMenu.PopupBaseMenuItem,
|
||||||
|
|
||||||
_init: function(bestAP, title, params) {
|
_init: function(accessPoints, title, params) {
|
||||||
this.parent(params);
|
this.parent(params);
|
||||||
|
|
||||||
this.bestAP = bestAP;
|
accessPoints = sortAccessPoints(accessPoints);
|
||||||
|
this.bestAP = accessPoints[0];
|
||||||
|
|
||||||
if (!title) {
|
if (!title) {
|
||||||
let ssid = this.bestAP.get_ssid();
|
let ssid = this.bestAP.get_ssid();
|
||||||
@@ -126,10 +127,24 @@ const NMNetworkMenuItem = new Lang.Class({
|
|||||||
this.bestAP._secType != NMAccessPointSecurity.NONE)
|
this.bestAP._secType != NMAccessPointSecurity.NONE)
|
||||||
this._secureIcon.icon_name = 'network-wireless-encrypted';
|
this._secureIcon.icon_name = 'network-wireless-encrypted';
|
||||||
this._icons.add_actor(this._secureIcon);
|
this._icons.add_actor(this._secureIcon);
|
||||||
|
|
||||||
|
this._accessPoints = [ ];
|
||||||
|
for (let i = 0; i < accessPoints.length; i++) {
|
||||||
|
let ap = accessPoints[i];
|
||||||
|
// need a wrapper object here, because the access points can be shared
|
||||||
|
// between many NMNetworkMenuItems
|
||||||
|
let apObj = {
|
||||||
|
ap: ap,
|
||||||
|
updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
|
||||||
|
};
|
||||||
|
this._accessPoints.push(apObj);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateBestAP: function(ap) {
|
_updated: function(ap) {
|
||||||
this.bestAP = ap;
|
if (ap.strength > this.bestAP.strength)
|
||||||
|
this.bestAP = ap;
|
||||||
|
|
||||||
this._signalIcon.icon_name = this._getIcon();
|
this._signalIcon.icon_name = this._getIcon();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -138,6 +153,36 @@ const NMNetworkMenuItem = new Lang.Class({
|
|||||||
return 'network-workgroup';
|
return 'network-workgroup';
|
||||||
else
|
else
|
||||||
return 'network-wireless-signal-' + signalToIcon(this.bestAP.strength);
|
return 'network-wireless-signal-' + signalToIcon(this.bestAP.strength);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAccessPoints: function(accessPoints) {
|
||||||
|
for (let i = 0; i < this._accessPoints.length; i++) {
|
||||||
|
let apObj = this._accessPoints[i];
|
||||||
|
apObj.ap.disconnect(apObj.updateId);
|
||||||
|
apObj.updateId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
accessPoints = sortAccessPoints(accessPoints);
|
||||||
|
this.bestAP = accessPoints[0];
|
||||||
|
this._accessPoints = [ ];
|
||||||
|
for (let i = 0; i < accessPoints; i++) {
|
||||||
|
let ap = accessPoints[i];
|
||||||
|
let apObj = {
|
||||||
|
ap: ap,
|
||||||
|
updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
|
||||||
|
};
|
||||||
|
this._accessPoints.push(apObj);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
for (let i = 0; i < this._accessPoints.length; i++) {
|
||||||
|
let apObj = this._accessPoints[i];
|
||||||
|
apObj.ap.disconnect(apObj.updateId);
|
||||||
|
apObj.updateId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.parent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -252,17 +297,16 @@ const NMDevice = new Lang.Class({
|
|||||||
this._client = client;
|
this._client = client;
|
||||||
this._connections = [ ];
|
this._connections = [ ];
|
||||||
for (let i = 0; i < connections.length; i++) {
|
for (let i = 0; i < connections.length; i++) {
|
||||||
if (!connections[i].get_uuid())
|
if (!connections[i]._uuid)
|
||||||
continue;
|
continue;
|
||||||
if (!this.connectionValid(connections[i]))
|
if (!this.connectionValid(connections[i]))
|
||||||
continue;
|
continue;
|
||||||
// record the connection
|
// record the connection
|
||||||
let obj = {
|
let obj = {
|
||||||
connection: connections[i],
|
connection: connections[i],
|
||||||
name: connections[i].get_id(),
|
name: connections[i]._name,
|
||||||
uuid: connections[i].get_uuid(),
|
uuid: connections[i]._uuid,
|
||||||
timestamp: connections[i]._timestamp,
|
timestamp: connections[i]._timestamp,
|
||||||
item: null,
|
|
||||||
};
|
};
|
||||||
this._connections.push(obj);
|
this._connections.push(obj);
|
||||||
}
|
}
|
||||||
@@ -357,46 +401,48 @@ const NMDevice = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
checkConnection: function(connection) {
|
checkConnection: function(connection) {
|
||||||
let pos = this._findConnection(connection.get_uuid());
|
let pos = this._findConnection(connection._uuid);
|
||||||
let exists = pos != -1;
|
let exists = pos != -1;
|
||||||
let valid = this.connectionValid(connection);
|
let valid = this.connectionValid(connection);
|
||||||
let similar = false;
|
|
||||||
if (exists) {
|
|
||||||
let existing = this._connections[pos];
|
|
||||||
|
|
||||||
// Check if connection changed name or id
|
if (exists && !valid)
|
||||||
similar = existing.name == connection.get_id() &&
|
|
||||||
existing.timestamp == connection._timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exists && valid && similar) {
|
|
||||||
// Nothing to do
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exists)
|
|
||||||
this.removeConnection(connection);
|
this.removeConnection(connection);
|
||||||
if (valid)
|
else if (!exists && valid)
|
||||||
this.addConnection(connection);
|
this.addConnection(connection);
|
||||||
|
else if (exists && valid) {
|
||||||
|
// propagate changes and update the UI
|
||||||
|
|
||||||
|
if (this._connections[pos].timestamp != connection._timestamp) {
|
||||||
|
this._connections[pos].timestamp = connection._timestamp;
|
||||||
|
this._connections.sort(this._connectionSortFunction);
|
||||||
|
|
||||||
|
this._clearSection();
|
||||||
|
this._queueCreateSection();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addConnection: function(connection) {
|
addConnection: function(connection) {
|
||||||
// record the connection
|
// record the connection
|
||||||
let obj = {
|
let obj = {
|
||||||
connection: connection,
|
connection: connection,
|
||||||
name: connection.get_id(),
|
name: connection._name,
|
||||||
uuid: connection.get_uuid(),
|
uuid: connection._uuid,
|
||||||
timestamp: connection._timestamp,
|
timestamp: connection._timestamp,
|
||||||
item: null,
|
|
||||||
};
|
};
|
||||||
Util.insertSorted(this._connections, obj, this._connectionSortFunction);
|
this._connections.push(obj);
|
||||||
|
this._connections.sort(this._connectionSortFunction);
|
||||||
|
|
||||||
this._clearSection();
|
this._clearSection();
|
||||||
this._queueCreateSection();
|
this._queueCreateSection();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeConnection: function(connection) {
|
removeConnection: function(connection) {
|
||||||
let pos = this._findConnection(connection.get_uuid());
|
if (!connection._uuid) {
|
||||||
|
log('Cannot remove a connection without an UUID');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let pos = this._findConnection(connection._uuid);
|
||||||
if (pos == -1) {
|
if (pos == -1) {
|
||||||
// this connection was never added, nothing to do here
|
// this connection was never added, nothing to do here
|
||||||
return;
|
return;
|
||||||
@@ -568,7 +614,7 @@ const NMDevice = new Lang.Class({
|
|||||||
let title;
|
let title;
|
||||||
let active = this._activeConnection._connection;
|
let active = this._activeConnection._connection;
|
||||||
if (active) {
|
if (active) {
|
||||||
title = active.get_id();
|
title = active._name;
|
||||||
} else {
|
} else {
|
||||||
/* TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
/* TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||||
and we cannot access its settings (including the name) */
|
and we cannot access its settings (including the name) */
|
||||||
@@ -666,10 +712,10 @@ const NMDeviceWired = new Lang.Class({
|
|||||||
|
|
||||||
_createAutomaticConnection: function() {
|
_createAutomaticConnection: function() {
|
||||||
let connection = new NetworkManager.Connection();
|
let connection = new NetworkManager.Connection();
|
||||||
let uuid = NetworkManager.utils_uuid_generate();
|
connection._uuid = NetworkManager.utils_uuid_generate();
|
||||||
connection.add_setting(new NetworkManager.SettingWired());
|
connection.add_setting(new NetworkManager.SettingWired());
|
||||||
connection.add_setting(new NetworkManager.SettingConnection({
|
connection.add_setting(new NetworkManager.SettingConnection({
|
||||||
uuid: uuid,
|
uuid: connection._uuid,
|
||||||
id: this._autoConnectionName,
|
id: this._autoConnectionName,
|
||||||
type: NetworkManager.SETTING_WIRED_SETTING_NAME,
|
type: NetworkManager.SETTING_WIRED_SETTING_NAME,
|
||||||
autoconnect: true
|
autoconnect: true
|
||||||
@@ -813,10 +859,10 @@ const NMDeviceBluetooth = new Lang.Class({
|
|||||||
|
|
||||||
_createAutomaticConnection: function() {
|
_createAutomaticConnection: function() {
|
||||||
let connection = new NetworkManager.Connection;
|
let connection = new NetworkManager.Connection;
|
||||||
let uuid = NetworkManager.utils_uuid_generate();
|
connection._uuid = NetworkManager.utils_uuid_generate();
|
||||||
connection.add_setting(new NetworkManager.SettingBluetooth);
|
connection.add_setting(new NetworkManager.SettingBluetooth);
|
||||||
connection.add_setting(new NetworkManager.SettingConnection({
|
connection.add_setting(new NetworkManager.SettingConnection({
|
||||||
uuid: uuid,
|
uuid: connection._uuid,
|
||||||
id: this._autoConnectionName,
|
id: this._autoConnectionName,
|
||||||
type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
|
type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
|
||||||
autoconnect: false
|
autoconnect: false
|
||||||
@@ -851,12 +897,12 @@ const NMDeviceVPN = new Lang.Class({
|
|||||||
Name: 'NMDeviceVPN',
|
Name: 'NMDeviceVPN',
|
||||||
Extends: NMDevice,
|
Extends: NMDevice,
|
||||||
|
|
||||||
_init: function(client, device, connections) {
|
_init: function(client) {
|
||||||
// Disable autoconnections
|
// Disable autoconnections
|
||||||
this._autoConnectionName = null;
|
this._autoConnectionName = null;
|
||||||
this.category = NMConnectionCategory.VPN;
|
this.category = NMConnectionCategory.VPN;
|
||||||
|
|
||||||
this.parent(client, null, connections);
|
this.parent(client, null, [ ]);
|
||||||
},
|
},
|
||||||
|
|
||||||
connectionValid: function(connection) {
|
connectionValid: function(connection) {
|
||||||
@@ -868,24 +914,13 @@ const NMDeviceVPN = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
get connected() {
|
get connected() {
|
||||||
if (!this._activeConnection)
|
return !!this._activeConnection;
|
||||||
return false;
|
|
||||||
|
|
||||||
return this._activeConnection.vpn_state == NetworkManager.VPNConnectionState.ACTIVATED;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setActiveConnection: function(activeConnection) {
|
setActiveConnection: function(activeConnection) {
|
||||||
if (this._stateChangeId)
|
|
||||||
this._activeConnection.disconnect(this._stateChangeId);
|
|
||||||
this._stateChangeId = 0;
|
|
||||||
|
|
||||||
this.parent(activeConnection);
|
this.parent(activeConnection);
|
||||||
|
|
||||||
if (this._activeConnection)
|
this.emit('active-connection-changed');
|
||||||
this._stateChangeId = this._activeConnection.connect('vpn-state-changed',
|
|
||||||
Lang.bind(this, this._connectionStateChanged));
|
|
||||||
|
|
||||||
this.emit('state-changed');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldShowConnectionList: function() {
|
_shouldShowConnectionList: function() {
|
||||||
@@ -898,39 +933,7 @@ const NMDeviceVPN = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getStatusLabel: function() {
|
getStatusLabel: function() {
|
||||||
if (!this._activeConnection) // Same as DISCONNECTED
|
return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
switch(this._activeConnection.vpn_state) {
|
|
||||||
case NetworkManager.VPNConnectionState.DISCONNECTED:
|
|
||||||
case NetworkManager.VPNConnectionState.ACTIVATED:
|
|
||||||
return null;
|
|
||||||
case NetworkManager.VPNConnectionState.PREPARE:
|
|
||||||
case NetworkManager.VPNConnectionState.CONNECT:
|
|
||||||
case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
|
|
||||||
return _("connecting...");
|
|
||||||
case NetworkManager.VPNConnectionState.NEED_AUTH:
|
|
||||||
/* Translators: this is for network connections that require some kind of key or password */
|
|
||||||
return _("authentication required");
|
|
||||||
case NetworkManager.VPNConnectionState.FAILED:
|
|
||||||
return _("connection failed");
|
|
||||||
default:
|
|
||||||
log('VPN connection state invalid, is %d'.format(this.device.state));
|
|
||||||
return 'invalid';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_connectionStateChanged: function(connection, newstate, reason) {
|
|
||||||
if (newstate == NetworkManager.VPNConnectionState.FAILED) {
|
|
||||||
// FIXME: if we ever want to show something based on reason,
|
|
||||||
// we need to convert from NetworkManager.VPNConnectionStateReason
|
|
||||||
// to NetworkManager.DeviceStateReason
|
|
||||||
this.emit('activation-failed', reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Differently from real NMDevices, there is no need to queue
|
|
||||||
// an update of the menu section, contents wouldn't change anyway
|
|
||||||
this.emit('state-changed');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -981,7 +984,6 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
obj.ssidText = ssidToLabel(obj.ssid);
|
obj.ssidText = ssidToLabel(obj.ssid);
|
||||||
this._networks.push(obj);
|
this._networks.push(obj);
|
||||||
}
|
}
|
||||||
ap._updateId = ap.connect('notify::strength', Lang.bind(this, this._onApStrengthChanged));
|
|
||||||
|
|
||||||
// Check if some connection is valid for this AP
|
// Check if some connection is valid for this AP
|
||||||
for (let j = 0; j < validConnections.length; j++) {
|
for (let j = 0; j < validConnections.length; j++) {
|
||||||
@@ -993,10 +995,6 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort APs within each network by strength
|
|
||||||
for (let i = 0; i < this._networks.length; i++)
|
|
||||||
sortAccessPoints(this._networks[i].accessPoints);
|
|
||||||
|
|
||||||
if (this.device.active_access_point) {
|
if (this.device.active_access_point) {
|
||||||
let networkPos = this._findNetwork(this.device.active_access_point);
|
let networkPos = this._findNetwork(this.device.active_access_point);
|
||||||
|
|
||||||
@@ -1079,7 +1077,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
// the user toggles the switch and has more than one wireless device)
|
// the user toggles the switch and has more than one wireless device)
|
||||||
if (this._networks.length > 0) {
|
if (this._networks.length > 0) {
|
||||||
let connection = this._createAutomaticConnection(this._networks[0]);
|
let connection = this._createAutomaticConnection(this._networks[0]);
|
||||||
let accessPoints = this._networks[0].accessPoints;
|
let accessPoints = sortAccessPoints(this._networks[0].accessPoints);
|
||||||
this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null);
|
this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1149,13 +1147,6 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
else if (!oneHasConnection && twoHasConnection)
|
else if (!oneHasConnection && twoHasConnection)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
let oneStrength = one.accessPoints[0].strength;
|
|
||||||
let twoStrength = two.accessPoints[0].strength;
|
|
||||||
|
|
||||||
// place stronger connections first
|
|
||||||
if (oneStrength != twoStrength)
|
|
||||||
return oneStrength < twoStrength ? 1 : -1;
|
|
||||||
|
|
||||||
let oneHasSecurity = one.security != NMAccessPointSecurity.NONE;
|
let oneHasSecurity = one.security != NMAccessPointSecurity.NONE;
|
||||||
let twoHasSecurity = two.security != NMAccessPointSecurity.NONE;
|
let twoHasSecurity = two.security != NMAccessPointSecurity.NONE;
|
||||||
|
|
||||||
@@ -1205,28 +1196,6 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
return -1;
|
return -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onApStrengthChanged: function(ap) {
|
|
||||||
let res = this._findExistingNetwork(ap);
|
|
||||||
if (res == null) {
|
|
||||||
// Uhm... stale signal?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let network = this._networks[res.network];
|
|
||||||
network.accessPoints.splice(res.ap, 1);
|
|
||||||
Util.insertSorted(network.accessPoints, ap, function(one, two) {
|
|
||||||
return two.strength - one.strength;
|
|
||||||
});
|
|
||||||
|
|
||||||
this._networks.splice(res.network, 1);
|
|
||||||
let newPos = Util.insertSorted(this._networks, network, Lang.bind(this, this._networkSortFunction));
|
|
||||||
|
|
||||||
if (newPos != res.network) {
|
|
||||||
this._clearSection();
|
|
||||||
this._queueCreateSection();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_accessPointAdded: function(device, accessPoint) {
|
_accessPointAdded: function(device, accessPoint) {
|
||||||
if (accessPoint.get_ssid() == null) {
|
if (accessPoint.get_ssid() == null) {
|
||||||
// This access point is not visible yet
|
// This access point is not visible yet
|
||||||
@@ -1246,11 +1215,9 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Util.insertSorted(apObj.accessPoints, accessPoint, function(one, two) {
|
apObj.accessPoints.push(accessPoint);
|
||||||
return two.strength - one.strength;
|
|
||||||
});
|
|
||||||
if (apObj.item)
|
if (apObj.item)
|
||||||
apObj.item.updateBestAP(apObj.accessPoints[0]);
|
apObj.item.updateAccessPoints(apObj.accessPoints);
|
||||||
} else {
|
} else {
|
||||||
apObj = { ssid: accessPoint.get_ssid(),
|
apObj = { ssid: accessPoint.get_ssid(),
|
||||||
mode: accessPoint.mode,
|
mode: accessPoint.mode,
|
||||||
@@ -1261,7 +1228,6 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
};
|
};
|
||||||
apObj.ssidText = ssidToLabel(apObj.ssid);
|
apObj.ssidText = ssidToLabel(apObj.ssid);
|
||||||
}
|
}
|
||||||
accessPoint._updateId = accessPoint.connect('notify::strength', Lang.bind(this, this._onApStrengthChanged));
|
|
||||||
|
|
||||||
// check if this enables new connections for this group
|
// check if this enables new connections for this group
|
||||||
for (let i = 0; i < this._connections.length; i++) {
|
for (let i = 0; i < this._connections.length; i++) {
|
||||||
@@ -1269,26 +1235,23 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
if (accessPoint.connection_valid(connection) &&
|
if (accessPoint.connection_valid(connection) &&
|
||||||
apObj.connections.indexOf(connection) == -1) {
|
apObj.connections.indexOf(connection) == -1) {
|
||||||
apObj.connections.push(connection);
|
apObj.connections.push(connection);
|
||||||
|
|
||||||
|
// this potentially changes the order
|
||||||
|
needsupdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos != -1)
|
if (pos == -1 || needsupdate) {
|
||||||
this._networks.splice(pos, 1);
|
if (pos != -1)
|
||||||
let newPos = Util.insertSorted(this._networks, apObj, this._networkSortFunction);
|
this._networks.splice(pos, 1);
|
||||||
|
pos = Util.insertSorted(this._networks, apObj, this._networkSortFunction);
|
||||||
|
|
||||||
// Queue an update of the UI if we changed the order
|
|
||||||
if (newPos != pos) {
|
|
||||||
this._clearSection();
|
this._clearSection();
|
||||||
this._queueCreateSection();
|
this._queueCreateSection();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_accessPointRemoved: function(device, accessPoint) {
|
_accessPointRemoved: function(device, accessPoint) {
|
||||||
if (accessPoint._updateId) {
|
|
||||||
accessPoint.disconnect(accessPoint._updateId);
|
|
||||||
accessPoint._updateId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = this._findExistingNetwork(accessPoint);
|
let res = this._findExistingNetwork(accessPoint);
|
||||||
|
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
@@ -1330,30 +1293,17 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
this._overflowItem = null;
|
this._overflowItem = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._networks.splice(res.network, 1);
|
this._networks.splice(res.network, 1);
|
||||||
} else {
|
|
||||||
let okPrev = true, okNext = true;
|
|
||||||
|
|
||||||
if (res.network > 0)
|
} else if (apObj.item)
|
||||||
okPrev = this._networkSortFunction(this._networks[res.network - 1], apObj) >= 0;
|
apObj.item.updateAccessPoints(apObj.accessPoints);
|
||||||
if (res.network < this._networks.length-1)
|
|
||||||
okNext = this._networkSortFunction(this._networks[res.network + 1], apObj) <= 0;
|
|
||||||
|
|
||||||
if (!okPrev || !okNext) {
|
|
||||||
this._clearSection();
|
|
||||||
this._queueCreateSection();
|
|
||||||
} else if (apObj.item) {
|
|
||||||
apObj.item.updateBestAP(apObj.accessPoints[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_createAPItem: function(connection, accessPointObj, useConnectionName) {
|
_createAPItem: function(connection, accessPointObj, useConnectionName) {
|
||||||
let item = new NMNetworkMenuItem(accessPointObj.accessPoints[0], useConnectionName ? connection.get_id() : undefined);
|
let item = new NMNetworkMenuItem(accessPointObj.accessPoints, useConnectionName ? connection._name : undefined);
|
||||||
item._connection = connection;
|
item._connection = connection;
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
let accessPoints = accessPointObj.accessPoints;
|
let accessPoints = sortAccessPoints(accessPointObj.accessPoints);
|
||||||
for (let i = 0; i < accessPoints.length; i++) {
|
for (let i = 0; i < accessPoints.length; i++) {
|
||||||
if (accessPoints[i].connection_valid(connection)) {
|
if (accessPoints[i].connection_valid(connection)) {
|
||||||
this._client.activate_connection(connection, this.device, accessPoints[i].dbus_path, null);
|
this._client.activate_connection(connection, this.device, accessPoints[i].dbus_path, null);
|
||||||
@@ -1373,7 +1323,9 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeConnection: function(connection) {
|
removeConnection: function(connection) {
|
||||||
let pos = this._findConnection(connection.get_uuid());
|
if (!connection._uuid)
|
||||||
|
return;
|
||||||
|
let pos = this._findConnection(connection._uuid);
|
||||||
if (pos == -1) {
|
if (pos == -1) {
|
||||||
// removing connection that was never added
|
// removing connection that was never added
|
||||||
return;
|
return;
|
||||||
@@ -1387,7 +1339,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
let apObj = this._networks[i];
|
let apObj = this._networks[i];
|
||||||
let connections = apObj.connections;
|
let connections = apObj.connections;
|
||||||
for (let k = 0; k < connections.length; k++) {
|
for (let k = 0; k < connections.length; k++) {
|
||||||
if (connections[k].get_uuid() == connection.get_uuid()) {
|
if (connections[k]._uuid == connection._uuid) {
|
||||||
// remove the connection from the access point group
|
// remove the connection from the access point group
|
||||||
connections.splice(k);
|
connections.splice(k);
|
||||||
forceupdate = forceupdate || connections.length == 0;
|
forceupdate = forceupdate || connections.length == 0;
|
||||||
@@ -1403,7 +1355,7 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
forceupdate = true;
|
forceupdate = true;
|
||||||
} else {
|
} else {
|
||||||
for (let j = 0; j < items.length; j++) {
|
for (let j = 0; j < items.length; j++) {
|
||||||
if (items[j]._connection.get_uuid() == connection.get_uuid()) {
|
if (items[j]._connection._uuid == connection._uuid) {
|
||||||
items[j].destroy();
|
items[j].destroy();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1430,8 +1382,8 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
// record the connection
|
// record the connection
|
||||||
let obj = {
|
let obj = {
|
||||||
connection: connection,
|
connection: connection,
|
||||||
name: connection.get_id(),
|
name: connection._name,
|
||||||
uuid: connection.get_uuid(),
|
uuid: connection._uuid,
|
||||||
};
|
};
|
||||||
this._connections.push(obj);
|
this._connections.push(obj);
|
||||||
|
|
||||||
@@ -1460,19 +1412,27 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_createActiveConnectionItem: function() {
|
_createActiveConnectionItem: function() {
|
||||||
let title;
|
let icon, title;
|
||||||
if (this._activeConnection && this._activeConnection._connection)
|
if (this._activeConnection && this._activeConnection._connection) {
|
||||||
title = this._activeConnection._connection.get_id();
|
let connection = this._activeConnection._connection;
|
||||||
else
|
if (this._activeNetwork)
|
||||||
title = _("Connected (private)");
|
this._activeConnectionItem = new NMNetworkMenuItem(this._activeNetwork.accessPoints, undefined,
|
||||||
|
{ reactive: false });
|
||||||
if (this._activeNetwork)
|
else
|
||||||
this._activeConnectionItem = new NMNetworkMenuItem(this.device.active_access_point, undefined,
|
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(connection._name,
|
||||||
{ reactive: false });
|
'network-wireless-connected',
|
||||||
else
|
{ reactive: false });
|
||||||
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(title,
|
} else {
|
||||||
'network-wireless-connected',
|
// We cannot read the connection (due to ACL, or API incompatibility), but we still show signal if we have it
|
||||||
{ reactive: false });
|
let menuItem;
|
||||||
|
if (this._activeNetwork)
|
||||||
|
this._activeConnectionItem = new NMNetworkMenuItem(this._activeNetwork.accessPoints, undefined,
|
||||||
|
{ reactive: false });
|
||||||
|
else
|
||||||
|
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(_("Connected (private)"),
|
||||||
|
'network-wireless-connected',
|
||||||
|
{ reactive: false });
|
||||||
|
}
|
||||||
this._activeConnectionItem.setShowDot(true);
|
this._activeConnectionItem.setShowDot(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1512,9 +1472,9 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
|
apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
apObj.item = new NMNetworkMenuItem(apObj.accessPoints[0]);
|
apObj.item = new NMNetworkMenuItem(apObj.accessPoints);
|
||||||
apObj.item.connect('activate', Lang.bind(this, function() {
|
apObj.item.connect('activate', Lang.bind(this, function() {
|
||||||
let accessPoints = apObj.accessPoints;
|
let accessPoints = sortAccessPoints(apObj.accessPoints);
|
||||||
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
|
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
|
||||||
|| (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
|
|| (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
|
||||||
// 802.1x-enabled APs require further configuration, so they're
|
// 802.1x-enabled APs require further configuration, so they're
|
||||||
@@ -1567,25 +1527,10 @@ const NMDeviceWireless = new Lang.Class({
|
|||||||
|
|
||||||
const NMApplet = new Lang.Class({
|
const NMApplet = new Lang.Class({
|
||||||
Name: 'NMApplet',
|
Name: 'NMApplet',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.SystemStatusButton,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent(0.0, _('Network'));
|
this.parent('network-offline', _("Network"));
|
||||||
|
|
||||||
this._box = new St.BoxLayout({ name: 'networkMenu' });
|
|
||||||
this.actor.add_actor (this._box);
|
|
||||||
this.actor.add_style_class_name('panel-status-button');
|
|
||||||
|
|
||||||
this._primaryIcon = new St.Icon({ icon_name: 'network-offline',
|
|
||||||
icon_type: St.IconType.SYMBOLIC,
|
|
||||||
style_class: 'system-status-icon' });
|
|
||||||
this._box.add_actor(this._primaryIcon);
|
|
||||||
|
|
||||||
this._secondaryIcon = new St.Icon({ icon_name: 'network-vpn',
|
|
||||||
icon_type: St.IconType.SYMBOLIC,
|
|
||||||
style_class: 'system-status-icon',
|
|
||||||
visible: false });
|
|
||||||
this._box.add_actor(this._secondaryIcon);
|
|
||||||
|
|
||||||
this._client = NMClient.Client.new();
|
this._client = NMClient.Client.new();
|
||||||
|
|
||||||
@@ -1599,16 +1544,6 @@ const NMApplet = new Lang.Class({
|
|||||||
this.menu.addMenuItem(this._statusSection);
|
this.menu.addMenuItem(this._statusSection);
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
|
||||||
this._activeConnections = [ ];
|
|
||||||
this._connections = [ ];
|
|
||||||
|
|
||||||
this._mainConnection = null;
|
|
||||||
this._vpnConnection = null;
|
|
||||||
this._activeAccessPointUpdateId = 0;
|
|
||||||
this._activeAccessPoint = null;
|
|
||||||
this._mobileUpdateId = 0;
|
|
||||||
this._mobileUpdateDevice = null;
|
|
||||||
|
|
||||||
this._devices = { };
|
this._devices = { };
|
||||||
|
|
||||||
this._devices.wired = {
|
this._devices.wired = {
|
||||||
@@ -1644,9 +1579,13 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
this._devices.vpn = {
|
this._devices.vpn = {
|
||||||
section: new PopupMenu.PopupMenuSection(),
|
section: new PopupMenu.PopupMenuSection(),
|
||||||
device: this._makeWrapperDevice(NMDeviceVPN, null),
|
device: new NMDeviceVPN(this._client),
|
||||||
item: new NMWiredSectionTitleMenuItem(_("VPN Connections"))
|
item: new NMWiredSectionTitleMenuItem(_("VPN Connections"))
|
||||||
};
|
};
|
||||||
|
this._devices.vpn.device.connect('active-connection-changed', Lang.bind(this, function() {
|
||||||
|
this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
|
||||||
|
}));
|
||||||
|
this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
|
||||||
this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
|
this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
|
||||||
this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
|
this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
|
||||||
this._devices.vpn.section.actor.hide();
|
this._devices.vpn.section.actor.hide();
|
||||||
@@ -1654,6 +1593,15 @@ const NMApplet = new Lang.Class({
|
|||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
|
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
|
||||||
|
|
||||||
|
this._activeConnections = [ ];
|
||||||
|
this._connections = [ ];
|
||||||
|
|
||||||
|
this._mainConnection = null;
|
||||||
|
this._activeAccessPointUpdateId = 0;
|
||||||
|
this._activeAccessPoint = null;
|
||||||
|
this._mobileUpdateId = 0;
|
||||||
|
this._mobileUpdateDevice = null;
|
||||||
|
|
||||||
// Device types
|
// Device types
|
||||||
this._dtypes = { };
|
this._dtypes = { };
|
||||||
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
|
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
|
||||||
@@ -1694,16 +1642,9 @@ const NMApplet = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
setIcon: function(iconName) {
|
|
||||||
this._primaryIcon.icon_name = iconName;
|
|
||||||
},
|
|
||||||
|
|
||||||
_ensureSource: function() {
|
_ensureSource: function() {
|
||||||
if (!this._source) {
|
if (!this._source) {
|
||||||
this._source = new MessageTray.Source(_("Network Manager"),
|
this._source = new NMMessageTraySource();
|
||||||
'network-transmit-receive',
|
|
||||||
St.IconType.SYMBOLIC);
|
|
||||||
|
|
||||||
this._source.connect('destroy', Lang.bind(this, function() {
|
this._source.connect('destroy', Lang.bind(this, function() {
|
||||||
this._source = null;
|
this._source = null;
|
||||||
}));
|
}));
|
||||||
@@ -1724,18 +1665,6 @@ const NMApplet = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_syncSectionTitle: function(category) {
|
_syncSectionTitle: function(category) {
|
||||||
if (category == NMConnectionCategory.VPN) {
|
|
||||||
// Special case VPN: it's only one device (and a fake one
|
|
||||||
// actually), and we don't show it if empty
|
|
||||||
let device = this._devices.vpn.device;
|
|
||||||
let section = this._devices.vpn.section;
|
|
||||||
let item = this._devices.vpn.item;
|
|
||||||
|
|
||||||
section.actor.visible = !device.empty;
|
|
||||||
item.updateForDevice(device);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let devices = this._devices[category].devices;
|
let devices = this._devices[category].devices;
|
||||||
let item = this._devices[category].item;
|
let item = this._devices[category].item;
|
||||||
let section = this._devices[category].section;
|
let section = this._devices[category].section;
|
||||||
@@ -1786,29 +1715,6 @@ const NMApplet = new Lang.Class({
|
|||||||
this._source.notify(device._notification);
|
this._source.notify(device._notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
_makeWrapperDevice: function(wrapperClass, device) {
|
|
||||||
let wrapper = new wrapperClass(this._client, device, this._connections);
|
|
||||||
|
|
||||||
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
|
|
||||||
// XXX: nm-applet has no special text depending on reason
|
|
||||||
// but I'm not sure of this generic message
|
|
||||||
this._notifyForDevice(device, 'network-error',
|
|
||||||
_("Connection failed"),
|
|
||||||
_("Activation of network connection failed"),
|
|
||||||
MessageTray.Urgency.HIGH);
|
|
||||||
}));
|
|
||||||
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
|
|
||||||
this._syncSectionTitle(dev.category);
|
|
||||||
}));
|
|
||||||
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
|
|
||||||
wrapper.disconnect(wrapper._activationFailedId);
|
|
||||||
wrapper.disconnect(wrapper._deviceStateChangedId);
|
|
||||||
wrapper.disconnect(wrapper._destroyId);
|
|
||||||
});
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
},
|
|
||||||
|
|
||||||
_deviceAdded: function(client, device) {
|
_deviceAdded: function(client, device) {
|
||||||
if (device._delegate) {
|
if (device._delegate) {
|
||||||
// already seen, not adding again
|
// already seen, not adding again
|
||||||
@@ -1816,8 +1722,24 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
let wrapperClass = this._dtypes[device.get_device_type()];
|
let wrapperClass = this._dtypes[device.get_device_type()];
|
||||||
if (wrapperClass) {
|
if (wrapperClass) {
|
||||||
let wrapper = this._makeWrapperDevice(wrapperClass, device);
|
let wrapper = new wrapperClass(this._client, device, this._connections);
|
||||||
|
|
||||||
|
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
|
||||||
|
// XXX: nm-applet has no special text depending on reason
|
||||||
|
// but I'm not sure of this generic message
|
||||||
|
this._notifyForDevice(device, 'network-error',
|
||||||
|
_("Connection failed"),
|
||||||
|
_("Activation of network connection failed"),
|
||||||
|
MessageTray.Urgency.HIGH);
|
||||||
|
}));
|
||||||
|
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
|
||||||
|
this._syncSectionTitle(dev.category);
|
||||||
|
}));
|
||||||
|
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
|
||||||
|
wrapper.disconnect(wrapper._activationFailedId);
|
||||||
|
wrapper.disconnect(wrapper._deviceStateChangedId);
|
||||||
|
wrapper.disconnect(wrapper._destroyId);
|
||||||
|
});
|
||||||
let section = this._devices[wrapper.category].section;
|
let section = this._devices[wrapper.category].section;
|
||||||
let devices = this._devices[wrapper.category].devices;
|
let devices = this._devices[wrapper.category].devices;
|
||||||
|
|
||||||
@@ -1871,8 +1793,6 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
this._activeConnections = newActiveConnections;
|
this._activeConnections = newActiveConnections;
|
||||||
this._mainConnection = null;
|
this._mainConnection = null;
|
||||||
this._vpnConnection = null;
|
|
||||||
|
|
||||||
let activating = null;
|
let activating = null;
|
||||||
let default_ip4 = null;
|
let default_ip4 = null;
|
||||||
let default_ip6 = null;
|
let default_ip6 = null;
|
||||||
@@ -1906,10 +1826,10 @@ const NMApplet = new Lang.Class({
|
|||||||
default_ip4 = a;
|
default_ip4 = a;
|
||||||
if (a.default6)
|
if (a.default6)
|
||||||
default_ip6 = a;
|
default_ip6 = a;
|
||||||
|
|
||||||
if (a._type == 'vpn')
|
if (a._type == 'vpn')
|
||||||
active_vpn = a;
|
active_vpn = a;
|
||||||
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
|
||||||
|
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
||||||
activating = a;
|
activating = a;
|
||||||
|
|
||||||
if (!a._primaryDevice) {
|
if (!a._primaryDevice) {
|
||||||
@@ -1938,8 +1858,7 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
|
this._mainConnection = activating || active_vpn || default_ip4 || default_ip6 || this._activeConnections[0] || null;
|
||||||
this._vpnConnection = active_vpn;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_notifyActivated: function(activeConnection) {
|
_notifyActivated: function(activeConnection) {
|
||||||
@@ -1956,7 +1875,7 @@ const NMApplet = new Lang.Class({
|
|||||||
let connections = this._settings.list_connections();
|
let connections = this._settings.list_connections();
|
||||||
for (let i = 0; i < connections.length; i++) {
|
for (let i = 0; i < connections.length; i++) {
|
||||||
let connection = connections[i];
|
let connection = connections[i];
|
||||||
if (connection._updatedId) {
|
if (connection._uuid) {
|
||||||
// connection was already seen (for example because NetworkManager was restarted)
|
// connection was already seen (for example because NetworkManager was restarted)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1969,7 +1888,7 @@ const NMApplet = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_newConnection: function(settings, connection) {
|
_newConnection: function(settings, connection) {
|
||||||
if (connection._updatedId) {
|
if (connection._uuid) {
|
||||||
// connection was already seen
|
// connection was already seen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1992,31 +1911,35 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
if (section == NMConnectionCategory.VPN) {
|
if (section == NMConnectionCategory.VPN) {
|
||||||
this._devices.vpn.device.removeConnection(connection);
|
this._devices.vpn.device.removeConnection(connection);
|
||||||
this._syncSectionTitle(section);
|
if (this._devices.vpn.device.empty)
|
||||||
|
this._devices.vpn.section.actor.hide();
|
||||||
} else if (section != NMConnectionCategory.INVALID) {
|
} else if (section != NMConnectionCategory.INVALID) {
|
||||||
let devices = this._devices[section].devices;
|
let devices = this._devices[section].devices;
|
||||||
for (let i = 0; i < devices.length; i++)
|
for (let i = 0; i < devices.length; i++)
|
||||||
devices[i].removeConnection(connection);
|
devices[i].removeConnection(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connection._uuid = null;
|
||||||
connection.disconnect(connection._removedId);
|
connection.disconnect(connection._removedId);
|
||||||
connection.disconnect(connection._updatedId);
|
connection.disconnect(connection._updatedId);
|
||||||
connection._removedId = connection._updatedId = 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateConnection: function(connection) {
|
_updateConnection: function(connection) {
|
||||||
let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
|
let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
|
||||||
connection._type = connectionSettings.type;
|
connection._type = connectionSettings.type;
|
||||||
|
|
||||||
connection._section = this._ctypes[connection._type] || NMConnectionCategory.INVALID;
|
connection._section = this._ctypes[connection._type] || NMConnectionCategory.INVALID;
|
||||||
|
connection._name = connectionSettings.id;
|
||||||
|
connection._uuid = connectionSettings.uuid;
|
||||||
connection._timestamp = connectionSettings.timestamp;
|
connection._timestamp = connectionSettings.timestamp;
|
||||||
|
|
||||||
let section = connection._section;
|
let section = connection._section;
|
||||||
|
|
||||||
if (section == NMConnectionCategory.INVALID)
|
if (connection._section == NMConnectionCategory.INVALID)
|
||||||
return;
|
return;
|
||||||
if (section == NMConnectionCategory.VPN) {
|
if (section == NMConnectionCategory.VPN) {
|
||||||
this._devices.vpn.device.checkConnection(connection);
|
this._devices.vpn.device.checkConnection(connection);
|
||||||
this._syncSectionTitle(section);
|
this._devices.vpn.section.actor.show();
|
||||||
} else {
|
} else {
|
||||||
let devices = this._devices[section].devices;
|
let devices = this._devices[section].devices;
|
||||||
for (let i = 0; i < devices.length; i++) {
|
for (let i = 0; i < devices.length; i++) {
|
||||||
@@ -2039,10 +1962,12 @@ const NMApplet = new Lang.Class({
|
|||||||
|
|
||||||
this._statusSection.actor.hide();
|
this._statusSection.actor.hide();
|
||||||
|
|
||||||
this._syncSectionTitle(NMConnectionCategory.WIRED);
|
this._syncSectionTitle('wired');
|
||||||
this._syncSectionTitle(NMConnectionCategory.WIRELESS);
|
this._syncSectionTitle('wireless');
|
||||||
this._syncSectionTitle(NMConnectionCategory.WWAN);
|
this._syncSectionTitle('wwan');
|
||||||
this._syncSectionTitle(NMConnectionCategory.VPN);
|
|
||||||
|
if (!this._devices.vpn.device.empty)
|
||||||
|
this._devices.vpn.section.actor.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
_syncNMState: function() {
|
_syncNMState: function() {
|
||||||
@@ -2085,6 +2010,9 @@ const NMApplet = new Lang.Class({
|
|||||||
case NMConnectionCategory.WIRED:
|
case NMConnectionCategory.WIRED:
|
||||||
this.setIcon('network-wired-acquiring');
|
this.setIcon('network-wired-acquiring');
|
||||||
break;
|
break;
|
||||||
|
case NMConnectionCategory.VPN:
|
||||||
|
this.setIcon('network-vpn-acquiring');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// fallback to a generic connected icon
|
// fallback to a generic connected icon
|
||||||
// (it could be a private connection of some other user)
|
// (it could be a private connection of some other user)
|
||||||
@@ -2147,6 +2075,9 @@ const NMApplet = new Lang.Class({
|
|||||||
this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
|
this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
|
||||||
hasMobileIcon = true;
|
hasMobileIcon = true;
|
||||||
break;
|
break;
|
||||||
|
case NMConnectionCategory.VPN:
|
||||||
|
this.setIcon('network-vpn');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// fallback to a generic connected icon
|
// fallback to a generic connected icon
|
||||||
// (it could be a private connection of some other user)
|
// (it could be a private connection of some other user)
|
||||||
@@ -2155,25 +2086,6 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update VPN indicator
|
|
||||||
if (this._vpnConnection) {
|
|
||||||
let vpnIconName = 'network-vpn';
|
|
||||||
if (this._vpnConnection.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
|
||||||
vpnIconName = 'network-vpn-acquiring';
|
|
||||||
|
|
||||||
// only show a separate icon when we're using a wireless/3g connection
|
|
||||||
if (mc._section == NMConnectionCategory.WIRELESS ||
|
|
||||||
mc._section == NMConnectionCategory.WWAN) {
|
|
||||||
this._secondaryIcon.icon_name = vpnIconName;
|
|
||||||
this._secondaryIcon.visible = true;
|
|
||||||
} else {
|
|
||||||
this.setIcon(vpnIconName);
|
|
||||||
this._secondaryIcon.visible = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._secondaryIcon.visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup stale signal connections
|
// cleanup stale signal connections
|
||||||
|
|
||||||
if (!hasApIcon && this._activeAccessPointUpdateId) {
|
if (!hasApIcon && this._activeAccessPointUpdateId) {
|
||||||
@@ -2188,3 +2100,18 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const NMMessageTraySource = new Lang.Class({
|
||||||
|
Name: 'NMMessageTraySource',
|
||||||
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent(_("Network Manager"));
|
||||||
|
|
||||||
|
let icon = new St.Icon({ icon_name: 'network-transmit-receive',
|
||||||
|
icon_type: St.IconType.SYMBOLIC,
|
||||||
|
icon_size: this.ICON_SIZE
|
||||||
|
});
|
||||||
|
this._setSummaryIcon(icon);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ const DeviceItem = new Lang.Class({
|
|||||||
case UPDeviceType.COMPUTER:
|
case UPDeviceType.COMPUTER:
|
||||||
return _("Computer");
|
return _("Computer");
|
||||||
default:
|
default:
|
||||||
return C_("device", "Unknown");
|
return _("Unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -132,9 +132,6 @@ const Client = new Lang.Class({
|
|||||||
let channel = channels[i];
|
let channel = channels[i];
|
||||||
let [targetHandle, targetHandleType] = channel.get_handle();
|
let [targetHandle, targetHandleType] = channel.get_handle();
|
||||||
|
|
||||||
if (Shell.is_channel_invalidated(channel))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Only observe contact text channels */
|
/* Only observe contact text channels */
|
||||||
if ((!(channel instanceof Tp.TextChannel)) ||
|
if ((!(channel instanceof Tp.TextChannel)) ||
|
||||||
targetHandleType != Tp.HandleType.CONTACT)
|
targetHandleType != Tp.HandleType.CONTACT)
|
||||||
@@ -184,9 +181,6 @@ const Client = new Lang.Class({
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Shell.is_channel_invalidated(channel))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// 'notify' will be true when coming from an actual HandleChannels
|
// 'notify' will be true when coming from an actual HandleChannels
|
||||||
// call, and not when from a successful Claim call. The point is
|
// call, and not when from a successful Claim call. The point is
|
||||||
// we don't want to notify for a channel we just claimed which
|
// we don't want to notify for a channel we just claimed which
|
||||||
@@ -237,19 +231,12 @@ const Client = new Lang.Class({
|
|||||||
let channel = channels[0];
|
let channel = channels[0];
|
||||||
let chanType = channel.get_channel_type();
|
let chanType = channel.get_channel_type();
|
||||||
|
|
||||||
if (Shell.is_channel_invalidated(channel)) {
|
|
||||||
Shell.decline_dispatch_op(context, 'Channel is invalidated');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chanType == Tp.IFACE_CHANNEL_TYPE_TEXT)
|
if (chanType == Tp.IFACE_CHANNEL_TYPE_TEXT)
|
||||||
this._approveTextChannel(account, conn, channel, dispatchOp, context);
|
this._approveTextChannel(account, conn, channel, dispatchOp, context);
|
||||||
else if (chanType == Tp.IFACE_CHANNEL_TYPE_CALL)
|
else if (chanType == Tp.IFACE_CHANNEL_TYPE_CALL)
|
||||||
this._approveCall(account, conn, channel, dispatchOp, context);
|
this._approveCall(account, conn, channel, dispatchOp, context);
|
||||||
else if (chanType == Tp.IFACE_CHANNEL_TYPE_FILE_TRANSFER)
|
else if (chanType == Tp.IFACE_CHANNEL_TYPE_FILE_TRANSFER)
|
||||||
this._approveFileTransfer(account, conn, channel, dispatchOp, context);
|
this._approveFileTransfer(account, conn, channel, dispatchOp, context);
|
||||||
else
|
|
||||||
Shell.decline_dispatch_op(context, 'Unsupported channel type');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_approveTextChannel: function(account, conn, channel, dispatchOp, context) {
|
_approveTextChannel: function(account, conn, channel, dispatchOp, context) {
|
||||||
@@ -378,9 +365,8 @@ const Client = new Lang.Class({
|
|||||||
|
|
||||||
_ensureSubscriptionSource: function() {
|
_ensureSubscriptionSource: function() {
|
||||||
if (this._subscriptionSource == null) {
|
if (this._subscriptionSource == null) {
|
||||||
this._subscriptionSource = new MessageTray.Source(_("Subscription request"),
|
this._subscriptionSource = new MultiNotificationSource(
|
||||||
'gtk-dialog-question',
|
_("Subscription request"), 'gtk-dialog-question');
|
||||||
St.IconType.FULLCOLOR);
|
|
||||||
Main.messageTray.add(this._subscriptionSource);
|
Main.messageTray.add(this._subscriptionSource);
|
||||||
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
|
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
|
||||||
this._subscriptionSource = null;
|
this._subscriptionSource = null;
|
||||||
@@ -415,9 +401,8 @@ const Client = new Lang.Class({
|
|||||||
|
|
||||||
_ensureAccountSource: function() {
|
_ensureAccountSource: function() {
|
||||||
if (this._accountSource == null) {
|
if (this._accountSource == null) {
|
||||||
this._accountSource = new MessageTray.Source(_("Connection error"),
|
this._accountSource = new MultiNotificationSource(
|
||||||
'gtk-dialog-error',
|
_("Connection error"), 'gtk-dialog-error');
|
||||||
St.IconType.FULLCOLOR);
|
|
||||||
Main.messageTray.add(this._accountSource);
|
Main.messageTray.add(this._accountSource);
|
||||||
this._accountSource.connect('destroy', Lang.bind(this, function () {
|
this._accountSource.connect('destroy', Lang.bind(this, function () {
|
||||||
this._accountSource = null;
|
this._accountSource = null;
|
||||||
@@ -433,13 +418,14 @@ const ChatSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(account, conn, channel, contact, client) {
|
_init: function(account, conn, channel, contact, client) {
|
||||||
|
this.parent(contact.get_alias());
|
||||||
|
|
||||||
|
this.isChat = true;
|
||||||
|
|
||||||
this._account = account;
|
this._account = account;
|
||||||
this._contact = contact;
|
this._contact = contact;
|
||||||
this._client = client;
|
this._client = client;
|
||||||
|
|
||||||
this.parent(contact.get_alias());
|
|
||||||
|
|
||||||
this.isChat = true;
|
|
||||||
this._pendingMessages = [];
|
this._pendingMessages = [];
|
||||||
|
|
||||||
this._conn = conn;
|
this._conn = conn;
|
||||||
@@ -460,6 +446,8 @@ const ChatSource = new Lang.Class({
|
|||||||
this._receivedId = this._channel.connect('message-received', Lang.bind(this, this._messageReceived));
|
this._receivedId = this._channel.connect('message-received', Lang.bind(this, this._messageReceived));
|
||||||
this._pendingId = this._channel.connect('pending-message-removed', Lang.bind(this, this._pendingRemoved));
|
this._pendingId = this._channel.connect('pending-message-removed', Lang.bind(this, this._pendingRemoved));
|
||||||
|
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
|
||||||
this._notifyAliasId = this._contact.connect('notify::alias', Lang.bind(this, this._updateAlias));
|
this._notifyAliasId = this._contact.connect('notify::alias', Lang.bind(this, this._updateAlias));
|
||||||
this._notifyAvatarId = this._contact.connect('notify::avatar-file', Lang.bind(this, this._updateAvatarIcon));
|
this._notifyAvatarId = this._contact.connect('notify::avatar-file', Lang.bind(this, this._updateAvatarIcon));
|
||||||
this._presenceChangedId = this._contact.connect('presence-changed', Lang.bind(this, this._presenceChanged));
|
this._presenceChangedId = this._contact.connect('presence-changed', Lang.bind(this, this._presenceChanged));
|
||||||
@@ -522,10 +510,10 @@ const ChatSource = new Lang.Class({
|
|||||||
_getLogMessages: function() {
|
_getLogMessages: function() {
|
||||||
let logManager = Tpl.LogManager.dup_singleton();
|
let logManager = Tpl.LogManager.dup_singleton();
|
||||||
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
|
let entity = Tpl.Entity.new_from_tp_contact(this._contact, Tpl.EntityType.CONTACT);
|
||||||
|
Shell.get_contact_events(logManager,
|
||||||
logManager.get_filtered_events_async(this._account, entity,
|
this._account, entity,
|
||||||
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
|
SCROLLBACK_HISTORY_LINES,
|
||||||
null, Lang.bind(this, this._displayPendingMessages));
|
Lang.bind(this, this._displayPendingMessages));
|
||||||
},
|
},
|
||||||
|
|
||||||
_displayPendingMessages: function(logManager, result) {
|
_displayPendingMessages: function(logManager, result) {
|
||||||
@@ -815,7 +803,7 @@ const ChatNotification = new Lang.Class({
|
|||||||
let groups = this._contentArea.get_children();
|
let groups = this._contentArea.get_children();
|
||||||
for (let i = 0; i < groups.length; i++) {
|
for (let i = 0; i < groups.length; i++) {
|
||||||
let group = groups[i];
|
let group = groups[i];
|
||||||
if (group.get_n_children() == 0)
|
if (group.get_children().length == 0)
|
||||||
group.destroy();
|
group.destroy();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1014,10 +1002,11 @@ const ApproverSource = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(dispatchOp, text, gicon) {
|
_init: function(dispatchOp, text, gicon) {
|
||||||
this._gicon = gicon;
|
|
||||||
|
|
||||||
this.parent(text);
|
this.parent(text);
|
||||||
|
|
||||||
|
this._gicon = gicon;
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
|
||||||
this._dispatchOp = dispatchOp;
|
this._dispatchOp = dispatchOp;
|
||||||
|
|
||||||
// Destroy the source if the channel dispatch operation is invalidated
|
// Destroy the source if the channel dispatch operation is invalidated
|
||||||
@@ -1039,6 +1028,7 @@ const ApproverSource = new Lang.Class({
|
|||||||
|
|
||||||
createNotificationIcon: function() {
|
createNotificationIcon: function() {
|
||||||
return new St.Icon({ gicon: this._gicon,
|
return new St.Icon({ gicon: this._gicon,
|
||||||
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
icon_size: this.ICON_SIZE });
|
icon_size: this.ICON_SIZE });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1161,6 +1151,40 @@ const FileTransferNotification = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// A notification source that can embed multiple notifications
|
||||||
|
const MultiNotificationSource = new Lang.Class({
|
||||||
|
Name: 'MultiNotificationSource',
|
||||||
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
|
_init: function(title, icon) {
|
||||||
|
this.parent(title);
|
||||||
|
|
||||||
|
this._icon = icon;
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
this._nbNotifications = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
notify: function(notification) {
|
||||||
|
this.parent(notification);
|
||||||
|
|
||||||
|
this._nbNotifications += 1;
|
||||||
|
|
||||||
|
// Display the source while there is at least one notification
|
||||||
|
notification.connect('destroy', Lang.bind(this, function () {
|
||||||
|
this._nbNotifications -= 1;
|
||||||
|
|
||||||
|
if (this._nbNotifications == 0)
|
||||||
|
this.destroy();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
return new St.Icon({ gicon: Gio.icon_new_for_string(this._icon),
|
||||||
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Subscription request
|
// Subscription request
|
||||||
const SubscriptionRequestNotification = new Lang.Class({
|
const SubscriptionRequestNotification = new Lang.Class({
|
||||||
Name: 'SubscriptionRequestNotification',
|
Name: 'SubscriptionRequestNotification',
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const AccountsService = imports.gi.AccountsService;
|
const AccountsService = imports.gi.AccountsService;
|
||||||
const GdmGreeter = imports.gi.GdmGreeter;
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@@ -133,7 +132,7 @@ const IMStatusChooserItem = new Lang.Class({
|
|||||||
item = new IMStatusItem(_("Busy"), 'user-busy');
|
item = new IMStatusItem(_("Busy"), 'user-busy');
|
||||||
this._combo.addMenuItem(item, IMStatus.BUSY);
|
this._combo.addMenuItem(item, IMStatus.BUSY);
|
||||||
|
|
||||||
item = new IMStatusItem(_("Invisible"), 'user-invisible');
|
item = new IMStatusItem(_("Hidden"), 'user-invisible');
|
||||||
this._combo.addMenuItem(item, IMStatus.HIDDEN);
|
this._combo.addMenuItem(item, IMStatus.HIDDEN);
|
||||||
|
|
||||||
item = new IMStatusItem(_("Away"), 'user-away');
|
item = new IMStatusItem(_("Away"), 'user-away');
|
||||||
@@ -474,22 +473,13 @@ const UserMenuButton = new Lang.Class({
|
|||||||
style_class: 'popup-menu-icon' });
|
style_class: 'popup-menu-icon' });
|
||||||
this._idleIcon = new St.Icon({ icon_name: 'user-idle',
|
this._idleIcon = new St.Icon({ icon_name: 'user-idle',
|
||||||
style_class: 'popup-menu-icon' });
|
style_class: 'popup-menu-icon' });
|
||||||
this._pendingIcon = new St.Icon({ icon_name: 'user-status-pending',
|
|
||||||
style_class: 'popup-menu-icon' });
|
|
||||||
|
|
||||||
this._accountMgr.connect('most-available-presence-changed',
|
this._accountMgr.connect('most-available-presence-changed',
|
||||||
Lang.bind(this, this._updatePresenceIcon));
|
Lang.bind(this, this._updatePresenceIcon));
|
||||||
this._accountMgr.connect('account-enabled',
|
|
||||||
Lang.bind(this, this._onAccountEnabled));
|
|
||||||
this._accountMgr.connect('account-disabled',
|
|
||||||
Lang.bind(this, this._onAccountDisabled));
|
|
||||||
this._accountMgr.connect('account-removed',
|
|
||||||
Lang.bind(this, this._onAccountDisabled));
|
|
||||||
this._accountMgr.prepare_async(null, Lang.bind(this,
|
this._accountMgr.prepare_async(null, Lang.bind(this,
|
||||||
function(mgr) {
|
function(mgr) {
|
||||||
let [presence, s, msg] = mgr.get_most_available_presence();
|
let [presence, s, msg] = mgr.get_most_available_presence();
|
||||||
this._updatePresenceIcon(mgr, presence, s, msg);
|
this._updatePresenceIcon(mgr, presence, s, msg);
|
||||||
this._setupAccounts();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._name = new St.Label();
|
this._name = new St.Label();
|
||||||
@@ -507,13 +497,13 @@ const UserMenuButton = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
this._userManager.connect('notify::is-loaded',
|
this._userManager.connect('notify::is-loaded',
|
||||||
Lang.bind(this, this._updateMultiUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._userManager.connect('notify::has-multiple-users',
|
this._userManager.connect('notify::has-multiple-users',
|
||||||
Lang.bind(this, this._updateMultiUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._userManager.connect('user-added',
|
this._userManager.connect('user-added',
|
||||||
Lang.bind(this, this._updateMultiUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._userManager.connect('user-removed',
|
this._userManager.connect('user-removed',
|
||||||
Lang.bind(this, this._updateMultiUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
|
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
|
||||||
Lang.bind(this, this._updateSwitchUser));
|
Lang.bind(this, this._updateSwitchUser));
|
||||||
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
||||||
@@ -552,32 +542,24 @@ const UserMenuButton = new Lang.Class({
|
|||||||
this._name.set_text("");
|
this._name.set_text("");
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateMultiUser: function() {
|
|
||||||
this._updateSwitchUser();
|
|
||||||
this._updateLogout();
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateSwitchUser: function() {
|
_updateSwitchUser: function() {
|
||||||
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
|
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
|
||||||
let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users;
|
if (allowSwitch &&
|
||||||
let multiSession = GdmGreeter.get_session_ids().length > 1;
|
this._userManager.can_switch() &&
|
||||||
|
this._userManager.has_multiple_users)
|
||||||
this._loginScreenItem.label.set_text(multiUser ? _("Switch User")
|
this._loginScreenItem.actor.show();
|
||||||
: _("Switch Session"));
|
else
|
||||||
this._loginScreenItem.actor.visible = allowSwitch && (multiUser || multiSession);
|
this._loginScreenItem.actor.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateLogout: function() {
|
_updateLogout: function() {
|
||||||
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
|
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
|
||||||
let multiUser = this._userManager.has_multiple_users;
|
this._logoutItem.actor.visible = allowLogout;
|
||||||
let multiSession = GdmGreeter.get_session_ids().length > 1;
|
|
||||||
|
|
||||||
this._logoutItem.actor.visible = allowLogout && (multiUser || multiSession);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateLockScreen: function() {
|
_updateLockScreen: function() {
|
||||||
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
||||||
this._lockScreenItem.actor.visible = allowLockScreen;
|
this._logoutItem.actor.visible = allowLockScreen;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateHaveShutdown: function() {
|
_updateHaveShutdown: function() {
|
||||||
@@ -598,14 +580,14 @@ const UserMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
this._suspendOrPowerOffItem.actor.visible = this._haveShutdown || this._haveSuspend;
|
this._suspendOrPowerOffItem.actor.visible = this._haveShutdown || this._haveSuspend;
|
||||||
|
|
||||||
// If we can't power off show Suspend instead
|
// If we can't suspend show Power Off... instead
|
||||||
// and disable the alt key
|
// and disable the alt key
|
||||||
if (!this._haveShutdown) {
|
if (!this._haveSuspend) {
|
||||||
|
this._suspendOrPowerOffItem.updateText(_("Power Off..."), null);
|
||||||
|
} else if (!this._haveShutdown) {
|
||||||
this._suspendOrPowerOffItem.updateText(_("Suspend"), null);
|
this._suspendOrPowerOffItem.updateText(_("Suspend"), null);
|
||||||
} else if (!this._haveSuspend) {
|
|
||||||
this._suspendOrPowerOffItem.updateText(_("Power Off"), null);
|
|
||||||
} else {
|
} else {
|
||||||
this._suspendOrPowerOffItem.updateText(_("Power Off"), _("Suspend"));
|
this._suspendOrPowerOffItem.updateText(_("Suspend"), _("Power Off..."));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -629,52 +611,11 @@ const UserMenuButton = new Lang.Class({
|
|||||||
this._iconBox.child = this._offlineIcon;
|
this._iconBox.child = this._offlineIcon;
|
||||||
},
|
},
|
||||||
|
|
||||||
_setupAccounts: function() {
|
|
||||||
let accounts = this._accountMgr.get_valid_accounts();
|
|
||||||
for (let i = 0; i < accounts.length; i++) {
|
|
||||||
accounts[i]._changingId = accounts[i].connect('notify::connection-status',
|
|
||||||
Lang.bind(this, this._updateChangingPresence));
|
|
||||||
}
|
|
||||||
this._updateChangingPresence();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onAccountEnabled: function(accountMgr, account) {
|
|
||||||
if (!account._changingId)
|
|
||||||
account._changingId = account.connect('notify::connection-status',
|
|
||||||
Lang.bind(this, this._updateChangingPresence));
|
|
||||||
this._updateChangingPresence();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onAccountDisabled: function(accountMgr, account) {
|
|
||||||
account.disconnect(account._changingId);
|
|
||||||
account._changingId = 0;
|
|
||||||
this._updateChangingPresence();
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateChangingPresence: function() {
|
|
||||||
let accounts = this._accountMgr.get_valid_accounts();
|
|
||||||
let changing = false;
|
|
||||||
for (let i = 0; i < accounts.length; i++) {
|
|
||||||
if (accounts[i].connection_status == Tp.ConnectionStatus.CONNECTING) {
|
|
||||||
changing = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changing) {
|
|
||||||
this._iconBox.child = this._pendingIcon;
|
|
||||||
} else {
|
|
||||||
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
|
|
||||||
this._updatePresenceIcon(this._accountMgr, presence, s, msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_createSubMenu: function() {
|
_createSubMenu: function() {
|
||||||
let item;
|
let item;
|
||||||
|
|
||||||
item = new IMStatusChooserItem();
|
item = new IMStatusChooserItem();
|
||||||
if (Main.sessionMode.allowSettings)
|
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
|
||||||
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
|
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._statusChooser = item;
|
this._statusChooser = item;
|
||||||
|
|
||||||
@@ -686,28 +627,28 @@ const UserMenuButton = new Lang.Class({
|
|||||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
|
|
||||||
if (Main.sessionMode.allowSettings) {
|
item = new PopupMenu.PopupMenuItem(_("Online Accounts"));
|
||||||
item = new PopupMenu.PopupMenuItem(_("System Settings"));
|
item.connect('activate', Lang.bind(this, this._onOnlineAccountsActivate));
|
||||||
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
this.menu.addMenuItem(item);
|
||||||
this.menu.addMenuItem(item);
|
|
||||||
}
|
item = new PopupMenu.PopupMenuItem(_("System Settings"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
||||||
item = new PopupMenu.PopupAlternatingMenuItem(_("Power Off"),
|
|
||||||
_("Suspend"));
|
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate));
|
|
||||||
this._suspendOrPowerOffItem = item;
|
|
||||||
this._updateSuspendOrPowerOff();
|
|
||||||
|
|
||||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Lock Screen"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
||||||
|
this.menu.addMenuItem(item);
|
||||||
|
this._lockScreenItem = item;
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("Switch User"));
|
item = new PopupMenu.PopupMenuItem(_("Switch User"));
|
||||||
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._loginScreenItem = item;
|
this._loginScreenItem = item;
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("Log Out"));
|
item = new PopupMenu.PopupMenuItem(_("Log Out..."));
|
||||||
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._logoutItem = item;
|
this._logoutItem = item;
|
||||||
@@ -715,10 +656,12 @@ const UserMenuButton = new Lang.Class({
|
|||||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
|
|
||||||
item = new PopupMenu.PopupMenuItem(_("Lock"));
|
item = new PopupMenu.PopupAlternatingMenuItem(_("Suspend"),
|
||||||
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
_("Power Off..."));
|
||||||
this.menu.addMenuItem(item);
|
this.menu.addMenuItem(item);
|
||||||
this._lockScreenItem = item;
|
this._suspendOrPowerOffItem = item;
|
||||||
|
item.connect('activate', Lang.bind(this, this._onSuspendOrPowerOffActivate));
|
||||||
|
this._updateSuspendOrPowerOff();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updatePresenceStatus: function(item, event) {
|
_updatePresenceStatus: function(item, event) {
|
||||||
@@ -746,6 +689,12 @@ const UserMenuButton = new Lang.Class({
|
|||||||
app.activate();
|
app.activate();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onOnlineAccountsActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
|
let app = Shell.AppSystem.get_default().lookup_setting('gnome-online-accounts-panel.desktop');
|
||||||
|
app.activate(-1);
|
||||||
|
},
|
||||||
|
|
||||||
_onPreferencesActivate: function() {
|
_onPreferencesActivate: function() {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop');
|
let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop');
|
||||||
@@ -774,14 +723,14 @@ const UserMenuButton = new Lang.Class({
|
|||||||
_onSuspendOrPowerOffActivate: function() {
|
_onSuspendOrPowerOffActivate: function() {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
|
|
||||||
if (this._haveShutdown &&
|
if (this._haveSuspend &&
|
||||||
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
|
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
|
||||||
this._session.ShutdownRemote();
|
|
||||||
} else {
|
|
||||||
// Ensure we only suspend after locking the screen
|
// Ensure we only suspend after locking the screen
|
||||||
this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
|
this._screenSaverProxy.LockRemote(Lang.bind(this, function() {
|
||||||
this._upClient.suspend_sync(null);
|
this._upClient.suspend_sync(null);
|
||||||
}));
|
}));
|
||||||
|
} else {
|
||||||
|
this._session.ShutdownRemote();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -168,35 +168,34 @@ const WandaSearchProvider = new Lang.Class({
|
|||||||
this.parent(_("Your favorite Easter Egg"));
|
this.parent(_("Your favorite Easter Egg"));
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMetas: function(fish, callback) {
|
getResultMetas: function(fish) {
|
||||||
callback([{ 'id': fish[0], // there may be many fish in the sea, but
|
return [{ 'id': fish[0], // there may be many fish in the sea, but
|
||||||
// only one which speaks the truth!
|
// only one which speaks the truth!
|
||||||
'name': capitalize(fish[0]),
|
'name': capitalize(fish[0]),
|
||||||
'createIcon': function(iconSize) {
|
'createIcon': function(iconSize) {
|
||||||
// for DND only (maybe could be improved)
|
// for DND only (maybe could be improved)
|
||||||
// DON'T use St.Icon here, it crashes the shell
|
// DON'T use St.Icon here, it crashes the shell
|
||||||
// (dnd.js code assumes it can query the actor size
|
// (dnd.js code assumes it can query the actor size
|
||||||
// without parenting it, while StWidget accesses
|
// without parenting it, while StWidget accesses
|
||||||
// StThemeNode in get_preferred_width/height, which
|
// StThemeNode in get_preferred_width/height, which
|
||||||
// triggers an assertion failure)
|
// triggers an assertion failure)
|
||||||
return St.TextureCache.get_default().load_icon_name(null,
|
return St.TextureCache.get_default().load_icon_name(null,
|
||||||
'face-smile',
|
'face-smile',
|
||||||
St.IconType.FULLCOLOR,
|
St.IconType.FULLCOLOR,
|
||||||
iconSize);
|
iconSize);
|
||||||
}
|
}
|
||||||
}]);
|
}];
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
if (terms.join(' ') == MAGIC_FISH_KEY) {
|
if (terms.join(' ') == MAGIC_FISH_KEY) {
|
||||||
this.searchSystem.pushResults(this, [ FISH_NAME ]);
|
return [ FISH_NAME ];
|
||||||
} else {
|
|
||||||
this.searchSystem.pushResults(this, []);
|
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
this.getInitialResultSet(terms);
|
return this.getInitialResultSet(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(fish, params) {
|
activateResult: function(fish, params) {
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ const Source = new Lang.Class({
|
|||||||
Extends: MessageTray.Source,
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
_init: function(app, window) {
|
_init: function(app, window) {
|
||||||
|
this.parent(app.get_name());
|
||||||
this._window = window;
|
this._window = window;
|
||||||
this._app = app;
|
this._app = app;
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
this.parent(app.get_name());
|
|
||||||
|
|
||||||
this.signalIDs = [];
|
this.signalIDs = [];
|
||||||
this.signalIDs.push(this._window.connect('notify::demands-attention', Lang.bind(this, function() { this.destroy(); })));
|
this.signalIDs.push(this._window.connect('notify::demands-attention', Lang.bind(this, function() { this.destroy(); })));
|
||||||
|
|||||||
@@ -1121,6 +1121,25 @@ const Workspace = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_showAllOverlays: function() {
|
||||||
|
let currentWorkspace = global.screen.get_active_workspace();
|
||||||
|
for (let i = 0; i < this._windows.length; i++) {
|
||||||
|
let clone = this._windows[i];
|
||||||
|
let overlay = this._windowOverlays[i];
|
||||||
|
this._showWindowOverlay(clone, overlay,
|
||||||
|
this.metaWorkspace == null || this.metaWorkspace == currentWorkspace);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_hideAllOverlays: function() {
|
||||||
|
for (let i = 0; i < this._windows.length; i++) {
|
||||||
|
let clone = this._windows[i];
|
||||||
|
let overlay = this._windowOverlays[i];
|
||||||
|
if (overlay)
|
||||||
|
overlay.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_delayedWindowRepositioning: function() {
|
_delayedWindowRepositioning: function() {
|
||||||
if (this._windowIsZooming)
|
if (this._windowIsZooming)
|
||||||
return true;
|
return true;
|
||||||
@@ -1320,10 +1339,6 @@ const Workspace = new Lang.Class({
|
|||||||
// Position and scale the windows.
|
// Position and scale the windows.
|
||||||
for (let i = 0; i < this._windows.length; i++) {
|
for (let i = 0; i < this._windows.length; i++) {
|
||||||
let clone = this._windows[i];
|
let clone = this._windows[i];
|
||||||
let overlay = this._windowOverlays[i];
|
|
||||||
|
|
||||||
if (overlay)
|
|
||||||
overlay.hide();
|
|
||||||
|
|
||||||
clone.zoomFromOverview();
|
clone.zoomFromOverview();
|
||||||
|
|
||||||
@@ -1348,6 +1363,8 @@ const Workspace = new Lang.Class({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._hideAllOverlays();
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy : function() {
|
destroy : function() {
|
||||||
|
|||||||
@@ -529,11 +529,9 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
this._updateAlwaysZoom();
|
this._updateAlwaysZoom();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
global.screen.connect('notify::n-workspaces',
|
|
||||||
Lang.bind(this, this._workspacesChanged));
|
|
||||||
|
|
||||||
this._switchWorkspaceNotifyId = 0;
|
this._switchWorkspaceNotifyId = 0;
|
||||||
|
|
||||||
|
this._nWorkspacesChangedId = 0;
|
||||||
this._itemDragBeginId = 0;
|
this._itemDragBeginId = 0;
|
||||||
this._itemDragCancelledId = 0;
|
this._itemDragCancelledId = 0;
|
||||||
this._itemDragEndId = 0;
|
this._itemDragEndId = 0;
|
||||||
@@ -572,6 +570,9 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
global.screen.connect('restacked',
|
global.screen.connect('restacked',
|
||||||
Lang.bind(this, this._onRestacked));
|
Lang.bind(this, this._onRestacked));
|
||||||
|
|
||||||
|
if (this._nWorkspacesChangedId == 0)
|
||||||
|
this._nWorkspacesChangedId = global.screen.connect('notify::n-workspaces',
|
||||||
|
Lang.bind(this, this._workspacesChanged));
|
||||||
if (this._itemDragBeginId == 0)
|
if (this._itemDragBeginId == 0)
|
||||||
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
||||||
Lang.bind(this, this._dragBegin));
|
Lang.bind(this, this._dragBegin));
|
||||||
@@ -924,16 +925,19 @@ const WorkspacesDisplay = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_workspacesChanged: function() {
|
_workspacesChanged: function() {
|
||||||
|
let oldNumWorkspaces = this._workspaces[0].length;
|
||||||
|
let newNumWorkspaces = global.screen.n_workspaces;
|
||||||
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
|
||||||
|
if (oldNumWorkspaces == newNumWorkspaces)
|
||||||
|
return;
|
||||||
|
|
||||||
this._updateAlwaysZoom();
|
this._updateAlwaysZoom();
|
||||||
this._updateZoom();
|
this._updateZoom();
|
||||||
|
|
||||||
if (this._workspacesViews == null)
|
if (this._workspacesViews == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let oldNumWorkspaces = this._workspaces[0].length;
|
|
||||||
let newNumWorkspaces = global.screen.n_workspaces;
|
|
||||||
let active = global.screen.get_active_workspace_index();
|
|
||||||
|
|
||||||
let lostWorkspaces = [];
|
let lostWorkspaces = [];
|
||||||
if (newNumWorkspaces > oldNumWorkspaces) {
|
if (newNumWorkspaces > oldNumWorkspaces) {
|
||||||
let monitors = Main.layoutManager.monitors;
|
let monitors = Main.layoutManager.monitors;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
data/gnome-shell.desktop.in.in
|
data/gnome-shell.desktop.in.in
|
||||||
data/gnome-shell-extension-prefs.desktop.in.in
|
data/gnome-shell-extension-prefs.desktop.in.in
|
||||||
data/org.gnome.shell.gschema.xml.in.in
|
data/org.gnome.shell.gschema.xml.in
|
||||||
js/extensionPrefs/main.js
|
js/extensionPrefs/main.js
|
||||||
js/gdm/loginDialog.js
|
js/gdm/loginDialog.js
|
||||||
js/gdm/powerMenu.js
|
js/gdm/powerMenu.js
|
||||||
@@ -13,7 +13,6 @@ js/ui/contactDisplay.js
|
|||||||
js/ui/dash.js
|
js/ui/dash.js
|
||||||
js/ui/dateMenu.js
|
js/ui/dateMenu.js
|
||||||
js/ui/endSessionDialog.js
|
js/ui/endSessionDialog.js
|
||||||
js/ui/extensionDownloader.js
|
|
||||||
js/ui/extensionSystem.js
|
js/ui/extensionSystem.js
|
||||||
js/ui/keyboard.js
|
js/ui/keyboard.js
|
||||||
js/ui/keyringPrompt.js
|
js/ui/keyringPrompt.js
|
||||||
|
|||||||
44
po/ko.po
44
po/ko.po
@@ -13,7 +13,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-04-19 21:14+0000\n"
|
"POT-Creation-Date: 2012-04-19 21:14+0000\n"
|
||||||
"PO-Revision-Date: 2012-05-19 22:57+0900\n"
|
"PO-Revision-Date: 2012-04-26 01:05+0900\n"
|
||||||
"Last-Translator: Changwoo Ryu <cwryu@debian.org>\n"
|
"Last-Translator: Changwoo Ryu <cwryu@debian.org>\n"
|
||||||
"Language-Team: GNOME Korea <gnome-kr@googlegroups.com>\n"
|
"Language-Team: GNOME Korea <gnome-kr@googlegroups.com>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -51,7 +51,7 @@ msgstr "Alt-F2 대화 상자에서 내부 디버깅 및 감시 기능에 접근
|
|||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
||||||
msgid "Uuids of extensions to enable"
|
msgid "Uuids of extensions to enable"
|
||||||
msgstr "사용할 확장의 UUID 목록"
|
msgstr "사용할 확장 기능의 UUID 목록"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:4
|
#: ../data/org.gnome.shell.gschema.xml.in.h:4
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -71,7 +71,11 @@ msgid ""
|
|||||||
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
||||||
"want to disable this for privacy reasons. Please note that doing so won't "
|
"want to disable this for privacy reasons. Please note that doing so won't "
|
||||||
"remove already saved data."
|
"remove already saved data."
|
||||||
msgstr "셸에서는 최근에 사용한 프로그램을(실행 메뉴 등에서) 표시하는 목적으로, 현재 사용 중인 프로그램을 감시합니다. 이 데이터는 비공개 데이터이지만 사생활 문제가 걱정된다면 이 기능을 끌 수도 있습니다. 단 이 기능을 사용하지 않더라도 이미 저장된 데이터를 제거하지는 않습니다."
|
msgstr ""
|
||||||
|
"셸에서는 최근에 사용한 프로그램을 (실행 메뉴 등에서) 표시하는 목적으로, 현재 "
|
||||||
|
"사용 중인 프로그램을 감시합니다. 이 데이터는 비공개 데이터이지만 사생활 문제"
|
||||||
|
"가 걱정된다면 이 기능을 끌 수도 있습니다. 단 이 기능을 사용하지 않더라도 이"
|
||||||
|
"미 저장된 데이터를 제거하지는 않습니다."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:7
|
#: ../data/org.gnome.shell.gschema.xml.in.h:7
|
||||||
msgid "List of desktop file IDs for favorite applications"
|
msgid "List of desktop file IDs for favorite applications"
|
||||||
@@ -89,7 +93,7 @@ msgstr "사용하지 않는 OpenSearch 서비스"
|
|||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:10
|
#: ../data/org.gnome.shell.gschema.xml.in.h:10
|
||||||
msgid "History for command (Alt-F2) dialog"
|
msgid "History for command (Alt-F2) dialog"
|
||||||
msgstr "명령어 대화 상자에(Alt-F2) 기록 기능"
|
msgstr "명령어 대화 상자에 (Alt-F2) 기록 기능"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
||||||
msgid "History for the looking glass dialog"
|
msgid "History for the looking glass dialog"
|
||||||
@@ -162,7 +166,7 @@ msgid "The gstreamer pipeline used to encode the screencast"
|
|||||||
msgstr "스크린 방송 인코딩에 사용할 gstreamer 파이프라인"
|
msgstr "스크린 방송 인코딩에 사용할 gstreamer 파이프라인"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
"used for gst-launch. The pipeline should have an unconnected sink pad where "
|
"used for gst-launch. The pipeline should have an unconnected sink pad where "
|
||||||
@@ -174,31 +178,45 @@ msgid ""
|
|||||||
"'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux' and records to WEBM "
|
"'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux' and records to WEBM "
|
||||||
"using the VP8 codec. %T is used as a placeholder for a guess at the optimal "
|
"using the VP8 codec. %T is used as a placeholder for a guess at the optimal "
|
||||||
"thread count on the system."
|
"thread count on the system."
|
||||||
msgstr "녹화 인코딩에 사용할 GStreamer 파이프라인을 지정합니다. gst-launch 프로그램에 사용하는 문법을 따릅니다. 녹화한 영상이 입력되는 싱크 패드는 이 파이프라인에 연결하지 않은 상태여야 합니다. 보통은 소스 패드도 연결하지 않고, 소스 패드의 출력을 출력 파일에 기록합니다. 하지만 파이프라인에서 이 출력을 처리할 수도 있습니다. shout2send 같은 프로그램을 이용해 아이스캐스트 서버로 출력을 보내거나 하는 용도로 사용할 수 있습니다. 설정을 취소하거나 빈 값으로 설정하면, 기본 파이프라인을 사용합니다. 기본 파이프라인은 'vp8enc quality=8 speed=6 threads=%T ! queue ! webmmux'이고 VP8 코덱을 사용해 WEBM 형식으로 녹화합니다. '%T' 기호는 시스템에서 최적으로 생각되는 스레드 수로 대체됩니다."
|
msgstr ""
|
||||||
|
"녹화 인코딩에 사용할 GStreamer 파이프라인을 지정합니다. gst-launch에 사용하"
|
||||||
|
"는 문법을 따릅니다. 파이프라인은 녹화한 영상이 있는 싱크 패드를 연결하지 않"
|
||||||
|
"은 상태여야 합니다. 보통 소스 패드와 연결하지 않았을 것입니다. 이 패드의 출력"
|
||||||
|
"은 출력 파일에 기록할 것입니다. 그러나 파이프라인은 이 출력을 다룰 수 있기도 "
|
||||||
|
"합니다 - 아마 shout2send와 같은 것을 통해 icecast 서버로 출력을 보내는데 사용"
|
||||||
|
"할지도 모릅니다. 만약 설정을 취소하거나 빈 값으로 설정한다면, 기본 파이프라인"
|
||||||
|
"을 사용할 것입니다. 이것은 현재 'vp8enc quality=8 speed=6 threads=%T ! "
|
||||||
|
"queue ! webmmux' 이며 VP8 코덱을 사용하여 WEBM으로 녹화합니다. %T는 시스템 상"
|
||||||
|
"의 최적의 스레드 수를 추측하기 위해 대체기호로 사용합니다."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "스크린 방송을 저장할 때 사용할 파일 확장자"
|
msgstr "스크린 방송을 저장할 때 사용할 파일 확장자"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
"a different container format."
|
"a different container format."
|
||||||
msgstr "녹화한 스크린 방송 영상 파일은, 현재 날짜와 여기서 설정하는 확장자를 붙여 파일 이름을 만듭니다. 다른 컨테이너 형식으로 녹화하려면 이 값을 바꿔야 합니다."
|
msgstr ""
|
||||||
|
"스크린 방송 녹화 파일 이름은 현재 날짜와 이 확장자를 사용해서 결정됩니다. 녹"
|
||||||
|
"화할 때 다른 형식으로 바꿀 수도 있습니다."
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:125
|
#: ../js/extensionPrefs/main.js:125
|
||||||
#, c-format
|
#, c-format, fuzzy
|
||||||
msgid "There was an error loading the preferences dialog for %s:"
|
msgid "There was an error loading the preferences dialog for %s:"
|
||||||
msgstr "%s에 대한 기본 설정 대화상자를 불러오는데 오류가 발생했습니다:"
|
msgstr "%s에 대한 기본 설정 대화상자를 불러오는데 오류가 발생했습니다:"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:165
|
#: ../js/extensionPrefs/main.js:165
|
||||||
|
#, fuzzy
|
||||||
msgid "<b>Extension</b>"
|
msgid "<b>Extension</b>"
|
||||||
msgstr "<b>확장</b>"
|
msgstr "<b>확장</b>"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:189
|
#: ../js/extensionPrefs/main.js:189
|
||||||
|
#, fuzzy
|
||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "위의 콤보상자를 사용해 설정할 확장을 선택하십시오."
|
msgstr "위의 콤보상자를 사용하여 설정할 확장을 선택하십시오."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:627
|
#: ../js/gdm/loginDialog.js:627
|
||||||
msgid "Session..."
|
msgid "Session..."
|
||||||
@@ -656,13 +674,13 @@ msgstr "다시 입력하십시오:"
|
|||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:732
|
#: ../js/ui/lookingGlass.js:732
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "확장을 설치하지 않았습니다"
|
msgstr "확장 기능을 설치하지 않았습니다"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:786
|
#: ../js/ui/lookingGlass.js:786
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s에서 발생한 에러가 없습니다."
|
msgstr "%s이(가) 발생한 에러가 없습니다."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:792
|
#: ../js/ui/lookingGlass.js:792
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
@@ -1149,7 +1167,7 @@ msgstr "더 보기..."
|
|||||||
#. and we cannot access its settings (including the name)
|
#. and we cannot access its settings (including the name)
|
||||||
#: ../js/ui/status/network.js:621 ../js/ui/status/network.js:1440
|
#: ../js/ui/status/network.js:621 ../js/ui/status/network.js:1440
|
||||||
msgid "Connected (private)"
|
msgid "Connected (private)"
|
||||||
msgstr "연결됨(개인)"
|
msgstr "연결됨 (개인)"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:696
|
#: ../js/ui/status/network.js:696
|
||||||
msgid "Auto Ethernet"
|
msgid "Auto Ethernet"
|
||||||
@@ -1555,7 +1573,7 @@ msgstr "내부 오류"
|
|||||||
#. translators: argument is the account name, like
|
#. translators: argument is the account name, like
|
||||||
#. * name@jabber.org for example.
|
#. * name@jabber.org for example.
|
||||||
#: ../js/ui/telepathyClient.js:1345
|
#: ../js/ui/telepathyClient.js:1345
|
||||||
#, c-format
|
#, c-format, fuzzy
|
||||||
msgid "Connection to %s failed"
|
msgid "Connection to %s failed"
|
||||||
msgstr "%s에 연결이 실패했습니다"
|
msgstr "%s에 연결이 실패했습니다"
|
||||||
|
|
||||||
|
|||||||
161
po/lt.po
161
po/lt.po
@@ -3,20 +3,19 @@
|
|||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
# Žygimantas Beručka <zygis@gnome.org>, 2010, 2011, 2012.
|
# Žygimantas Beručka <zygis@gnome.org>, 2010, 2011, 2012.
|
||||||
# Algimantas Margevičius <gymka@mail.ru>, 2011.
|
# Algimantas Margevičius <gymka@mail.ru>, 2011.
|
||||||
# Mantas Kriaučiūnas <mantas@akl.lt>, 2012.
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-05-19 13:58+0000\n"
|
"POT-Creation-Date: 2012-03-30 17:59+0000\n"
|
||||||
"PO-Revision-Date: 2012-04-05 15:14+0300\n"
|
"PO-Revision-Date: 2012-04-05 15:14+0300\n"
|
||||||
"Last-Translator: Mantas Kriaučiūnas <mantas@akl.lt>\n"
|
"Last-Translator: Žygimantas Beručka <zygis@gnome.org>\n"
|
||||||
"Language-Team: Lithuanian\n"
|
"Language-Team: Lithuanian\n"
|
||||||
|
"Language: lt\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Language: lt\n"
|
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%"
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%"
|
||||||
"100<10 || n%100>=20) ? 1 : 2);\n"
|
"100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
"X-Generator: Virtaal 0.7.0\n"
|
"X-Generator: Virtaal 0.7.0\n"
|
||||||
@@ -24,7 +23,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||||
msgid "GNOME Shell"
|
msgid "GNOME Shell"
|
||||||
msgstr "GNOME Shell aplinka"
|
msgstr "GNOME Shell"
|
||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
@@ -80,11 +79,10 @@ msgid ""
|
|||||||
"want to disable this for privacy reasons. Please note that doing so won't "
|
"want to disable this for privacy reasons. Please note that doing so won't "
|
||||||
"remove already saved data."
|
"remove already saved data."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Įprastai GNOME aplinka stebi aktyvias programas siekiant pateikti "
|
"Apvalkalas paprastai stebi aktyvias programas siekiant pateikti dažniausiai "
|
||||||
"dažniausiai naudojamas (pvz., leistukuose). Nors šie duomenys "
|
"naudojamas (pvz., leistukuose). Nors šie duomenys konfidencialiai saugomi, "
|
||||||
"konfidencialiai saugomi, jei norite, saugumo sumetimais galite šią funkciją "
|
"jei norite, saugumo sumetimais galite šią funkciją išjungti. Atminkite, kad "
|
||||||
"išjungti. Atminkite, kad išjungus šią funkciją anksčiau įrašyti duomenys "
|
"tai padarius jau įrašyti duomenys jau nebus įrašyti."
|
||||||
"nebus pašalinti."
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:7
|
#: ../data/org.gnome.shell.gschema.xml.in.h:7
|
||||||
msgid "List of desktop file IDs for favorite applications"
|
msgid "List of desktop file IDs for favorite applications"
|
||||||
@@ -224,7 +222,7 @@ msgstr ""
|
|||||||
#: ../js/extensionPrefs/main.js:125
|
#: ../js/extensionPrefs/main.js:125
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "There was an error loading the preferences dialog for %s:"
|
msgid "There was an error loading the preferences dialog for %s:"
|
||||||
msgstr "Įvyko klaida įkeliant %s nustatymų dialogą:"
|
msgstr "Kilo klaida įkeliant %s nustatymų dialogą:"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:165
|
#: ../js/extensionPrefs/main.js:165
|
||||||
msgid "<b>Extension</b>"
|
msgid "<b>Extension</b>"
|
||||||
@@ -234,40 +232,40 @@ msgstr "<b>Plėtinys</b>"
|
|||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "Išskleidžiamajame sąraše pasirinkite konfigūruotiną plėtinį."
|
msgstr "Išskleidžiamajame sąraše pasirinkite konfigūruotiną plėtinį."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:627
|
#: ../js/gdm/loginDialog.js:624
|
||||||
msgid "Session..."
|
msgid "Session..."
|
||||||
msgstr "Seansas..."
|
msgstr "Seansas..."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:789
|
#: ../js/gdm/loginDialog.js:786
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Prisijungti"
|
msgstr "Prisijungti"
|
||||||
|
|
||||||
#. Translators: this message is shown below the password entry field
|
#. Translators: this message is shown below the password entry field
|
||||||
#. to indicate the user can swipe their finger instead
|
#. to indicate the user can swipe their finger instead
|
||||||
#: ../js/gdm/loginDialog.js:834
|
#: ../js/gdm/loginDialog.js:831
|
||||||
msgid "(or swipe finger)"
|
msgid "(or swipe finger)"
|
||||||
msgstr "(arba perbraukite pirštu)"
|
msgstr "(arba perbraukite pirštu)"
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:855
|
#: ../js/gdm/loginDialog.js:852
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr "Nėra sąraše?"
|
msgstr "Nėra sąraše?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
|
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
|
||||||
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
|
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Atsisakyti"
|
msgstr "Atšaukti"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1028
|
#: ../js/gdm/loginDialog.js:1025
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Prisijungti"
|
msgstr "Prisijungti"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1380
|
#: ../js/gdm/loginDialog.js:1377
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "Prisijungimo langas"
|
msgstr "Prisijungimo langas"
|
||||||
|
|
||||||
@@ -675,11 +673,11 @@ msgstr[2] "Sistema bus paleista iš naujo po %d sekundžių."
|
|||||||
msgid "Restarting the system."
|
msgid "Restarting the system."
|
||||||
msgstr "Sistema paleidžiama iš naujo."
|
msgstr "Sistema paleidžiama iš naujo."
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:404
|
#: ../js/ui/extensionSystem.js:403
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "Įdiegti"
|
msgstr "Įdiegti"
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:408
|
#: ../js/ui/extensionSystem.js:407
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "Atsiųsti ir įdiegti „%s“ iš extensions.gnome.org?"
|
msgstr "Atsiųsti ir įdiegti „%s“ iš extensions.gnome.org?"
|
||||||
@@ -688,8 +686,7 @@ msgstr "Atsiųsti ir įdiegti „%s“ iš extensions.gnome.org?"
|
|||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "dėklas"
|
msgstr "dėklas"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
|
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
|
||||||
#: ../js/ui/status/power.js:203
|
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "Klaviatūra"
|
msgstr "Klaviatūra"
|
||||||
|
|
||||||
@@ -725,7 +722,7 @@ msgstr "Įjungta"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Išjungta"
|
msgstr "Išjungta"
|
||||||
|
|
||||||
@@ -942,7 +939,7 @@ msgstr "Įveskite komandą:"
|
|||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "Ieškoma..."
|
msgstr "Ieškoma..."
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:415
|
#: ../js/ui/searchDisplay.js:414
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "Nerasta atitikmenų."
|
msgstr "Nerasta atitikmenų."
|
||||||
|
|
||||||
@@ -1100,7 +1097,7 @@ msgstr "Visada leisti prieigą"
|
|||||||
msgid "Grant this time only"
|
msgid "Grant this time only"
|
||||||
msgstr "Leisti tik šį kartą"
|
msgstr "Leisti tik šį kartą"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1093
|
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1091
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "Atmesti"
|
msgstr "Atmesti"
|
||||||
|
|
||||||
@@ -1177,7 +1174,7 @@ msgstr "Trūksta integruotos programinės įrangos (firmware)"
|
|||||||
#. Translators: this is for wired network devices that are physically disconnected
|
#. Translators: this is for wired network devices that are physically disconnected
|
||||||
#: ../js/ui/status/network.js:517
|
#: ../js/ui/status/network.js:517
|
||||||
msgid "cable unplugged"
|
msgid "cable unplugged"
|
||||||
msgstr "atjungtas laidas"
|
msgstr "kabelis neįjungtas"
|
||||||
|
|
||||||
#. Translators: this is for a network device that cannot be activated (for example it
|
#. Translators: this is for a network device that cannot be activated (for example it
|
||||||
#. is disabled by rfkill, or it has no coverage
|
#. is disabled by rfkill, or it has no coverage
|
||||||
@@ -1191,7 +1188,7 @@ msgstr "nepavyko prisijungti"
|
|||||||
|
|
||||||
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1505
|
#: ../js/ui/status/network.js:585 ../js/ui/status/network.js:1505
|
||||||
msgid "More..."
|
msgid "More..."
|
||||||
msgstr "Rodyti daugiau tinklų..."
|
msgstr "Daugiau..."
|
||||||
|
|
||||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||||
#. and we cannot access its settings (including the name)
|
#. and we cannot access its settings (including the name)
|
||||||
@@ -1388,7 +1385,7 @@ msgstr "Skambutis"
|
|||||||
#. We got the TpContact
|
#. We got the TpContact
|
||||||
#: ../js/ui/telepathyClient.js:287
|
#: ../js/ui/telepathyClient.js:287
|
||||||
msgid "File Transfer"
|
msgid "File Transfer"
|
||||||
msgstr "Failo persiuntimas"
|
msgstr "Failo perdavimas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:369
|
#: ../js/ui/telepathyClient.js:369
|
||||||
msgid "Subscription request"
|
msgid "Subscription request"
|
||||||
@@ -1421,35 +1418,35 @@ msgstr "%s yra užsiėmęs (-usi)."
|
|||||||
#. Translators: this is a time format string followed by a date.
|
#. Translators: this is a time format string followed by a date.
|
||||||
#. If applicable, replace %X with a strftime format valid for your
|
#. If applicable, replace %X with a strftime format valid for your
|
||||||
#. locale, without seconds.
|
#. locale, without seconds.
|
||||||
#: ../js/ui/telepathyClient.js:889
|
#: ../js/ui/telepathyClient.js:887
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Sent at <b>%X</b> on <b>%A</b>"
|
msgid "Sent at <b>%X</b> on <b>%A</b>"
|
||||||
msgstr "Išsiųsta <b>%X</b> <b>%A</b>"
|
msgstr "Išsiųsta <b>%X</b> <b>%A</b>"
|
||||||
|
|
||||||
#. Translators: this is a time format in the style of "Wednesday, May 25",
|
#. Translators: this is a time format in the style of "Wednesday, May 25",
|
||||||
#. shown when you get a chat message in the same year.
|
#. shown when you get a chat message in the same year.
|
||||||
#: ../js/ui/telepathyClient.js:895
|
#: ../js/ui/telepathyClient.js:893
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
|
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
|
||||||
msgstr "Išsiųsta <b>%B %d</b>, <b>%A</b>"
|
msgstr "Išsiųsta <b>%B %d</b>, <b>%A</b>"
|
||||||
|
|
||||||
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
|
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
|
||||||
#. shown when you get a chat message in a different year.
|
#. shown when you get a chat message in a different year.
|
||||||
#: ../js/ui/telepathyClient.js:900
|
#: ../js/ui/telepathyClient.js:898
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
|
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
|
||||||
msgstr "Išsiųsta %Y <b>%B %d</b>, <b>%A</b>"
|
msgstr "Išsiųsta %Y <b>%B %d</b>, <b>%A</b>"
|
||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
#: ../js/ui/telepathyClient.js:942
|
#: ../js/ui/telepathyClient.js:940
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is now known as %s"
|
msgid "%s is now known as %s"
|
||||||
msgstr "%s nuo šiol vadinasi %s"
|
msgstr "%s nuo šiol vadinasi %s"
|
||||||
|
|
||||||
#. translators: argument is a room name like
|
#. translators: argument is a room name like
|
||||||
#. * room@jabber.org for example.
|
#. * room@jabber.org for example.
|
||||||
#: ../js/ui/telepathyClient.js:1044
|
#: ../js/ui/telepathyClient.js:1042
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Invitation to %s"
|
msgid "Invitation to %s"
|
||||||
msgstr "Kvietimas į %s"
|
msgstr "Kvietimas į %s"
|
||||||
@@ -1457,35 +1454,35 @@ msgstr "Kvietimas į %s"
|
|||||||
#. translators: first argument is the name of a contact and the second
|
#. translators: first argument is the name of a contact and the second
|
||||||
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
||||||
#. * for example.
|
#. * for example.
|
||||||
#: ../js/ui/telepathyClient.js:1052
|
#: ../js/ui/telepathyClient.js:1050
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is inviting you to join %s"
|
msgid "%s is inviting you to join %s"
|
||||||
msgstr "%s jus kviečia prisijungti prie %s"
|
msgstr "%s jus kviečia prisijungti prie %s"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1054 ../js/ui/telepathyClient.js:1133
|
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
|
||||||
#: ../js/ui/telepathyClient.js:1231
|
#: ../js/ui/telepathyClient.js:1229
|
||||||
msgid "Decline"
|
msgid "Decline"
|
||||||
msgstr "Atmesti"
|
msgstr "Atmesti"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1055 ../js/ui/telepathyClient.js:1134
|
#: ../js/ui/telepathyClient.js:1053 ../js/ui/telepathyClient.js:1132
|
||||||
#: ../js/ui/telepathyClient.js:1232
|
#: ../js/ui/telepathyClient.js:1230
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Priimti"
|
msgstr "Priimti"
|
||||||
|
|
||||||
#. translators: argument is a contact name like Alice for example.
|
#. translators: argument is a contact name like Alice for example.
|
||||||
#: ../js/ui/telepathyClient.js:1085
|
#: ../js/ui/telepathyClient.js:1083
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Video call from %s"
|
msgid "Video call from %s"
|
||||||
msgstr "Vaizdo skambutis nuo %s"
|
msgstr "Vaizdo skambutis nuo %s"
|
||||||
|
|
||||||
#. translators: argument is a contact name like Alice for example.
|
#. translators: argument is a contact name like Alice for example.
|
||||||
#: ../js/ui/telepathyClient.js:1088
|
#: ../js/ui/telepathyClient.js:1086
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Call from %s"
|
msgid "Call from %s"
|
||||||
msgstr "Skambutis nuo %s"
|
msgstr "Skambutis nuo %s"
|
||||||
|
|
||||||
#. translators: this is a button label (verb), not a noun
|
#. translators: this is a button label (verb), not a noun
|
||||||
#: ../js/ui/telepathyClient.js:1095
|
#: ../js/ui/telepathyClient.js:1093
|
||||||
msgid "Answer"
|
msgid "Answer"
|
||||||
msgstr "Atsiliepti"
|
msgstr "Atsiliepti"
|
||||||
|
|
||||||
@@ -1494,110 +1491,110 @@ msgstr "Atsiliepti"
|
|||||||
#. * file name. The string will be something
|
#. * file name. The string will be something
|
||||||
#. * like: "Alice is sending you test.ogg"
|
#. * like: "Alice is sending you test.ogg"
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/telepathyClient.js:1127
|
#: ../js/ui/telepathyClient.js:1125
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is sending you %s"
|
msgid "%s is sending you %s"
|
||||||
msgstr "%s jums siunčia %s"
|
msgstr "%s jums siunčia %s"
|
||||||
|
|
||||||
#. To translators: The parameter is the contact's alias
|
#. To translators: The parameter is the contact's alias
|
||||||
#: ../js/ui/telepathyClient.js:1196
|
#: ../js/ui/telepathyClient.js:1194
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s would like permission to see when you are online"
|
msgid "%s would like permission to see when you are online"
|
||||||
msgstr "%s pageidauja matyti, kai esate prisijungę prie interneto"
|
msgstr "%s pageidauja matyti, kai esate prisijungę prie interneto"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1289
|
#: ../js/ui/telepathyClient.js:1287
|
||||||
msgid "Network error"
|
msgid "Network error"
|
||||||
msgstr "Tinklo klaida"
|
msgstr "Tinklo klaida"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1291
|
#: ../js/ui/telepathyClient.js:1289
|
||||||
msgid "Authentication failed"
|
msgid "Authentication failed"
|
||||||
msgstr "Nepavyko patvirtinti tapatybės"
|
msgstr "Nepavyko patvirtinti tapatybės"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1293
|
#: ../js/ui/telepathyClient.js:1291
|
||||||
msgid "Encryption error"
|
msgid "Encryption error"
|
||||||
msgstr "Šifravimo klaida"
|
msgstr "Šifravimo klaida"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1295
|
#: ../js/ui/telepathyClient.js:1293
|
||||||
msgid "Certificate not provided"
|
msgid "Certificate not provided"
|
||||||
msgstr "Liudijimas nepateiktas"
|
msgstr "Liudijimas nepateiktas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1297
|
#: ../js/ui/telepathyClient.js:1295
|
||||||
msgid "Certificate untrusted"
|
msgid "Certificate untrusted"
|
||||||
msgstr "Liudijimas nepatikimas"
|
msgstr "Liudijimas nepatikimas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1299
|
#: ../js/ui/telepathyClient.js:1297
|
||||||
msgid "Certificate expired"
|
msgid "Certificate expired"
|
||||||
msgstr "Liudijimo galiojimas pasibaigęs"
|
msgstr "Liudijimo galiojimas pasibaigęs"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1301
|
#: ../js/ui/telepathyClient.js:1299
|
||||||
msgid "Certificate not activated"
|
msgid "Certificate not activated"
|
||||||
msgstr "Liudijimas neaktyvuotas"
|
msgstr "Liudijimas neaktyvuotas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1303
|
#: ../js/ui/telepathyClient.js:1301
|
||||||
msgid "Certificate hostname mismatch"
|
msgid "Certificate hostname mismatch"
|
||||||
msgstr "Liudijimo serverio vardo nesutapimas"
|
msgstr "Liudijimo serverio vardo nesutapimas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1305
|
#: ../js/ui/telepathyClient.js:1303
|
||||||
msgid "Certificate fingerprint mismatch"
|
msgid "Certificate fingerprint mismatch"
|
||||||
msgstr "Liudijimo piršto atspaudo nesutapimas"
|
msgstr "Liudijimo piršto atspaudo nesutapimas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1307
|
#: ../js/ui/telepathyClient.js:1305
|
||||||
msgid "Certificate self-signed"
|
msgid "Certificate self-signed"
|
||||||
msgstr "Liudijimas pačių pasirašytas"
|
msgstr "Liudijimas pačių pasirašytas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1309
|
#: ../js/ui/telepathyClient.js:1307
|
||||||
msgid "Status is set to offline"
|
msgid "Status is set to offline"
|
||||||
msgstr "Nustatyta atsijungimo būsena"
|
msgstr "Nustatyta atsijungimo būsena"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1311
|
#: ../js/ui/telepathyClient.js:1309
|
||||||
msgid "Encryption is not available"
|
msgid "Encryption is not available"
|
||||||
msgstr "Šifravimas negalimas"
|
msgstr "Šifravimas negalimas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1313
|
#: ../js/ui/telepathyClient.js:1311
|
||||||
msgid "Certificate is invalid"
|
msgid "Certificate is invalid"
|
||||||
msgstr "Liudijimas netinkamas"
|
msgstr "Liudijimas netinkamas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1315
|
#: ../js/ui/telepathyClient.js:1313
|
||||||
msgid "Connection has been refused"
|
msgid "Connection has been refused"
|
||||||
msgstr "Ryšys atmestas"
|
msgstr "Ryšys atmestas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1317
|
#: ../js/ui/telepathyClient.js:1315
|
||||||
msgid "Connection can't be established"
|
msgid "Connection can't be established"
|
||||||
msgstr "Nepavyko užmegzti ryšio"
|
msgstr "Nepavyko užmegzti ryšio"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1319
|
#: ../js/ui/telepathyClient.js:1317
|
||||||
msgid "Connection has been lost"
|
msgid "Connection has been lost"
|
||||||
msgstr "Ryšys nutrūko"
|
msgstr "Ryšys nutrūko"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1321
|
#: ../js/ui/telepathyClient.js:1319
|
||||||
msgid "This account is already connected to the server"
|
msgid "This account is already connected to the server"
|
||||||
msgstr "Ši paskyra jau prijungta prie serverio"
|
msgstr "Ši paskyra jau prijungta prie serverio"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1323
|
#: ../js/ui/telepathyClient.js:1321
|
||||||
msgid ""
|
msgid ""
|
||||||
"Connection has been replaced by a new connection using the same resource"
|
"Connection has been replaced by a new connection using the same resource"
|
||||||
msgstr "Ryšys pakeistas nauju ryšiu naudojant tą patį išteklių"
|
msgstr "Ryšys pakeistas nauju ryšiu naudojant tą patį išteklių"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1325
|
#: ../js/ui/telepathyClient.js:1323
|
||||||
msgid "The account already exists on the server"
|
msgid "The account already exists on the server"
|
||||||
msgstr "Tokia paskyra serveryje jau yra"
|
msgstr "Tokia paskyra serveryje jau yra"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1327
|
#: ../js/ui/telepathyClient.js:1325
|
||||||
msgid "Server is currently too busy to handle the connection"
|
msgid "Server is currently too busy to handle the connection"
|
||||||
msgstr "Šiuo metu serveris per daug užimtas šiai užklausai apdoroti"
|
msgstr "Šiuo metu serveris per daug užimtas šiai užklausai apdoroti"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1329
|
#: ../js/ui/telepathyClient.js:1327
|
||||||
msgid "Certificate has been revoked"
|
msgid "Certificate has been revoked"
|
||||||
msgstr "Liudijimas atšauktas"
|
msgstr "Liudijimas atšauktas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1331
|
#: ../js/ui/telepathyClient.js:1329
|
||||||
msgid ""
|
msgid ""
|
||||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Liudijimui naudojamas nesaugus šifravimo algoritmas arba jis kriptografiškai "
|
"Liudijimui naudojamas nesaugus šifravimo algoritmas arba jis kriptografiškai "
|
||||||
"silpnas"
|
"silpnas"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1333
|
#: ../js/ui/telepathyClient.js:1331
|
||||||
msgid ""
|
msgid ""
|
||||||
"The length of the server certificate, or the depth of the server certificate "
|
"The length of the server certificate, or the depth of the server certificate "
|
||||||
"chain, exceed the limits imposed by the cryptography library"
|
"chain, exceed the limits imposed by the cryptography library"
|
||||||
@@ -1605,26 +1602,26 @@ msgstr ""
|
|||||||
"Serverio liudijimo ilgis arba liudijimų eilės dydis viršija kriptografijos "
|
"Serverio liudijimo ilgis arba liudijimų eilės dydis viršija kriptografijos "
|
||||||
"bibliotekos apribojimus"
|
"bibliotekos apribojimus"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1335
|
#: ../js/ui/telepathyClient.js:1333
|
||||||
msgid "Internal error"
|
msgid "Internal error"
|
||||||
msgstr "Vidinė klaida"
|
msgstr "Vidinė klaida"
|
||||||
|
|
||||||
#. translators: argument is the account name, like
|
#. translators: argument is the account name, like
|
||||||
#. * name@jabber.org for example.
|
#. * name@jabber.org for example.
|
||||||
#: ../js/ui/telepathyClient.js:1345
|
#: ../js/ui/telepathyClient.js:1343
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Connection to %s failed"
|
msgid "Connection to %s failed"
|
||||||
msgstr "Nepavyko prisijungti prie %s"
|
msgstr "Nepavyko prisijungti prie %s"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1354
|
#: ../js/ui/telepathyClient.js:1352
|
||||||
msgid "Reconnect"
|
msgid "Reconnect"
|
||||||
msgstr "Prisijungti iš naujo"
|
msgstr "Prisijungti iš naujo"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1355
|
#: ../js/ui/telepathyClient.js:1353
|
||||||
msgid "Edit account"
|
msgid "Edit account"
|
||||||
msgstr "Taisyti paskyrą"
|
msgstr "Taisyti paskyrą"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1401
|
#: ../js/ui/telepathyClient.js:1399
|
||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "Nežinoma priežastis"
|
msgstr "Nežinoma priežastis"
|
||||||
|
|
||||||
@@ -1650,7 +1647,7 @@ msgstr "Pranešimai"
|
|||||||
|
|
||||||
#: ../js/ui/userMenu.js:639
|
#: ../js/ui/userMenu.js:639
|
||||||
msgid "Online Accounts"
|
msgid "Online Accounts"
|
||||||
msgstr "Interneto paskyros"
|
msgstr "Tinklo paskyros"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:643
|
#: ../js/ui/userMenu.js:643
|
||||||
msgid "System Settings"
|
msgid "System Settings"
|
||||||
@@ -1705,11 +1702,11 @@ msgstr ""
|
|||||||
#: ../js/ui/wanda.js:128
|
#: ../js/ui/wanda.js:128
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s the Oracle says"
|
msgid "%s the Oracle says"
|
||||||
msgstr "Orakulė %s sako"
|
msgstr "Orakulė sako %s"
|
||||||
|
|
||||||
#: ../js/ui/wanda.js:168
|
#: ../js/ui/wanda.js:168
|
||||||
msgid "Your favorite Easter Egg"
|
msgid "Your favorite Easter Egg"
|
||||||
msgstr "Jūsų mėgstamiausias velykinis kiaušinis"
|
msgstr "Jūsų mėgstamiausias vėlykinis kiaušinis"
|
||||||
|
|
||||||
#: ../js/ui/windowAttentionHandler.js:19
|
#: ../js/ui/windowAttentionHandler.js:19
|
||||||
#, c-format
|
#, c-format
|
||||||
@@ -1718,7 +1715,7 @@ msgstr "„%s“ yra pasirengusi"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound outputs on a particular device
|
#. * The number of sound outputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1089
|
#: ../src/gvc/gvc-mixer-control.c:1100
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Output"
|
msgid "%u Output"
|
||||||
msgid_plural "%u Outputs"
|
msgid_plural "%u Outputs"
|
||||||
@@ -1728,7 +1725,7 @@ msgstr[2] "%u išvestys"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound inputs on a particular device
|
#. * The number of sound inputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1099
|
#: ../src/gvc/gvc-mixer-control.c:1110
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Input"
|
msgid "%u Input"
|
||||||
msgid_plural "%u Inputs"
|
msgid_plural "%u Inputs"
|
||||||
@@ -1736,15 +1733,15 @@ msgstr[0] "%u įvestis"
|
|||||||
msgstr[1] "%u įvestys"
|
msgstr[1] "%u įvestys"
|
||||||
msgstr[2] "%u įvestys"
|
msgstr[2] "%u įvestys"
|
||||||
|
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1397
|
#: ../src/gvc/gvc-mixer-control.c:1408
|
||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "Sistemos garsai"
|
msgstr "Sistemos garsai"
|
||||||
|
|
||||||
#: ../src/main.c:256
|
#: ../src/main.c:255
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "Išvesti versijos numerį"
|
msgstr "Išvesti versijos numerį"
|
||||||
|
|
||||||
#: ../src/main.c:262
|
#: ../src/main.c:261
|
||||||
msgid "Mode used by GDM for login screen"
|
msgid "Mode used by GDM for login screen"
|
||||||
msgstr "Veiksena, naudojama GDM prisijungimo ekrane"
|
msgstr "Veiksena, naudojama GDM prisijungimo ekrane"
|
||||||
|
|
||||||
@@ -1777,7 +1774,7 @@ msgstr "Naudotojas užvėrė tapatybės patvirtinimo dialogą"
|
|||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-util.c:97
|
#: ../src/shell-util.c:97
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "Namų aplankas"
|
msgstr "Namai"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
|
|||||||
278
po/mr.po
278
po/mr.po
@@ -8,8 +8,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: mr\n"
|
"Project-Id-Version: mr\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-04-24 15:39+0000\n"
|
"POT-Creation-Date: 2012-03-30 17:59+0000\n"
|
||||||
"PO-Revision-Date: 2012-05-10 09:57+0530\n"
|
"PO-Revision-Date: 2012-04-02 11:33+0530\n"
|
||||||
"Last-Translator: Sandeep Shedmake <sshedmak@redhat.com>\n"
|
"Last-Translator: Sandeep Shedmake <sshedmak@redhat.com>\n"
|
||||||
"Language-Team: Marathi <fedora-trans-mr@redhat.com>\n"
|
"Language-Team: Marathi <fedora-trans-mr@redhat.com>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -47,6 +47,7 @@ msgid ""
|
|||||||
msgstr "आंतरिक डिबगिंग व Alt-F2 संवादचा वापर करून निंयत्रणकरीता प्रवेश देतो."
|
msgstr "आंतरिक डिबगिंग व Alt-F2 संवादचा वापर करून निंयत्रणकरीता प्रवेश देतो."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
||||||
|
#| msgid "Uuids of extensions to disable"
|
||||||
msgid "Uuids of extensions to enable"
|
msgid "Uuids of extensions to enable"
|
||||||
msgstr "सुरू करण्याजोगी एक्सटेंशन्स्चे Uuids"
|
msgstr "सुरू करण्याजोगी एक्सटेंशन्स्चे Uuids"
|
||||||
|
|
||||||
@@ -58,10 +59,10 @@ msgid ""
|
|||||||
"DisableExtension DBus methods on org.gnome.Shell."
|
"DisableExtension DBus methods on org.gnome.Shell."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"GNOME शेल एक्सटेंशन्सकडे uuid गुणधर्म असते; हि कि एक्सटेंशन्स् दाखवते ज्यास "
|
"GNOME शेल एक्सटेंशन्सकडे uuid गुणधर्म असते; हि कि एक्सटेंशन्स् दाखवते ज्यास "
|
||||||
"लोड करणे आवश्यक "
|
"लोड करणे आवश्यक आहे. "
|
||||||
"आहे. लोड करण्याजोगी कोणत्याहि एक्सटेंशला सूचीत असणे आवश्यक आहे. org.gnome."
|
"लोड करण्याजोगी कोणत्याहि एक्सटेंशला सूचीत असणे आवश्यक आहे. "
|
||||||
"Shell वरील "
|
"org.gnome.Shell वरील EnableExtension व DisableExtension DBus मेथडससह या सूचीत "
|
||||||
"EnableExtension व DisableExtension DBus मेथडससह या सूचीत बदल करणे शक्य आहे."
|
"बदल करणे शक्य आहे."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:5
|
#: ../data/org.gnome.shell.gschema.xml.in.h:5
|
||||||
msgid "Whether to collect stats about applications usage"
|
msgid "Whether to collect stats about applications usage"
|
||||||
@@ -109,8 +110,7 @@ msgid ""
|
|||||||
"The value here is from the TpConnectionPresenceType enumeration."
|
"The value here is from the TpConnectionPresenceType enumeration."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"वापरकर्तातर्फे ठरवलेले शेवटचे IM हाजेरी साठवण्याकरीता आंतरिकपणे वापरले जाते. "
|
"वापरकर्तातर्फे ठरवलेले शेवटचे IM हाजेरी साठवण्याकरीता आंतरिकपणे वापरले जाते. "
|
||||||
"येथील मूल्य "
|
"येथील मूल्य TpConnectionPresenceType एन्युमरेशनपासूनचे आहे."
|
||||||
"TpConnectionPresenceType एन्युमरेशनपासूनचे आहे."
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -118,8 +118,8 @@ msgid ""
|
|||||||
"value here is from the GsmPresenceStatus enumeration."
|
"value here is from the GsmPresenceStatus enumeration."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"वापरकर्तातर्फे ठरवलेले शेवटचे सत्र हाजेरी साठवण्याकरीता आंतरिकपणे वापरले जाते."
|
"वापरकर्तातर्फे ठरवलेले शेवटचे सत्र हाजेरी साठवण्याकरीता आंतरिकपणे वापरले जाते."
|
||||||
" येथील मूल्य "
|
" "
|
||||||
"GsmPresenceStatus एन्युमरेशनपासूनचे आहे."
|
"येथील मूल्य GsmPresenceStatus एन्युमरेशनपासूनचे आहे."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||||
msgid "Show the week date in the calendar"
|
msgid "Show the week date in the calendar"
|
||||||
@@ -138,44 +138,34 @@ msgid "Keybinding to open the application menu."
|
|||||||
msgstr "ॲप्लिकेशन मेन्यु उघडण्यासाठी किबाइंडिंग."
|
msgstr "ॲप्लिकेशन मेन्यु उघडण्यासाठी किबाइंडिंग."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
#| msgid "Keybinding to open the application menu"
|
|
||||||
msgid "Keybinding to toggle the screen recorder"
|
|
||||||
msgstr "स्क्रीन रेकॉर्डरमधील बदलसाठी किबाइंडिंग"
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
|
||||||
#| msgid "Keybinding to open the application menu."
|
|
||||||
msgid "Keybinding to start/stop the builtin screen recorder."
|
|
||||||
msgstr "बिल्टइन स्क्रीन रेकॉर्डर सुरू किंवा थांबवण्यासाठी किबाइंडिंग."
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "कुठले किबोर्ड वापरायचे"
|
msgstr "कुठले किबोर्ड वापरायचे"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "वापरण्याजोगी किबोर्डचे प्रकार."
|
msgstr "वापरण्याजोगी किबोर्डचे प्रकार."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
msgid "Show time with seconds"
|
msgid "Show time with seconds"
|
||||||
msgstr "सेकंदात वेळ दाखवा"
|
msgstr "सेकंदात वेळ दाखवा"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
msgid "If true, display seconds in time."
|
msgid "If true, display seconds in time."
|
||||||
msgstr "खरे असल्यास, वेळेत सेकंद दाखवा."
|
msgstr "खरे असल्यास, वेळेत सेकंद दाखवा."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
msgid "Show date in clock"
|
msgid "Show date in clock"
|
||||||
msgstr "घड्याळात दिनांक दाखवा"
|
msgstr "घड्याळात दिनांक दाखवा"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
msgid "If true, display date in the clock, in addition to time."
|
msgid "If true, display date in the clock, in addition to time."
|
||||||
msgstr "खरे असल्यास,वेळेबरोबर तारीख पण घड्याळात दाखवा."
|
msgstr "खरे असल्यास,वेळेबरोबर तारीख पण घड्याळात दाखवा."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr "स्क्रिनकास्ट्स् रेकॉर्ड करण्यासाठी वापरलेले फ्रेमरेट."
|
msgstr "स्क्रिनकास्ट्स् रेकॉर्ड करण्यासाठी वापरलेले फ्रेमरेट."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@@ -184,12 +174,24 @@ msgstr ""
|
|||||||
"केलेल्या परिणामक "
|
"केलेल्या परिणामक "
|
||||||
"सक्रीनकास्टचा फ्रेमरेट."
|
"सक्रीनकास्टचा फ्रेमरेट."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "स्क्रीनकास्ट एंकोड करण्यासाठी वापरलेले gstreamer पाइपलाइन"
|
msgstr "स्क्रीनकास्ट एंकोड करण्यासाठी वापरलेले gstreamer पाइपलाइन"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
#: ../data/org.gnome.shell.gschema.xml.in.h:28
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
|
#| msgid ""
|
||||||
|
#| "Sets the GStreamer pipeline used to encode recordings. It follows the "
|
||||||
|
#| "syntax used for gst-launch. The pipeline should have an unconnected sink "
|
||||||
|
#| "pad where the recorded video is recorded. It will normally have a "
|
||||||
|
#| "unconnected source pad; output from that pad will be written into the "
|
||||||
|
#| "output file. However the pipeline can also take care of its own output - "
|
||||||
|
#| "this might be used to send the output to an icecast server via shout2send "
|
||||||
|
#| "or similar. When unset or set to an empty value, the default pipeline "
|
||||||
|
#| "will be used. This is currently 'videorate ! vp8enc quality=10 speed=2 "
|
||||||
|
#| "threads=%T ! queue ! webmmux' and records to WEBM using the VP8 codec. %T "
|
||||||
|
#| "is used as a placeholder for a guess at the optimal thread count on the "
|
||||||
|
#| "system."
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
"used for gst-launch. The pipeline should have an unconnected sink pad where "
|
"used for gst-launch. The pipeline should have an unconnected sink pad where "
|
||||||
@@ -203,26 +205,21 @@ msgid ""
|
|||||||
"thread count on the system."
|
"thread count on the system."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"रेकॉर्डिंग्स् एंकोड करण्यासाठी GStreamer पाइपलाइन ठरवतो. gst-launch सुरू "
|
"रेकॉर्डिंग्स् एंकोड करण्यासाठी GStreamer पाइपलाइन ठरवतो. gst-launch सुरू "
|
||||||
"करण्यासाठी "
|
"करण्यासाठी मांडणीचा वापर करतो. पाइपलाइनमध्ये जोडणी अशक्य सिंक पॅड असायला हवे "
|
||||||
"मांडणीचा वापर करतो. पाइपलाइनमध्ये जोडणी अशक्य सिंक पॅड असायला हवे जेथे "
|
"जेथे रेकॉर्डेड व्हिडीओ रेकॉर्ड केले जाते. सहसा जोडणी अशक्य स्रोत पॅड असते; "
|
||||||
"रेकॉर्डेड व्हिडीओ "
|
"पॅडपासूनचे आऊटपुट, आऊटपुट फाइलमध्ये लिहले जाते. तरी पाइपलाइन स्वतःच्या "
|
||||||
"रेकॉर्ड केले जाते. सहसा जोडणी अशक्य स्रोत पॅड असते; पॅडपासूनचे आऊटपुट, आऊटपुट "
|
"आऊटपुटची काळजी घेतो - याचा वापर shout2send किंवा समानतर्फे icecast "
|
||||||
"फाइलमध्ये लिहले "
|
"सर्व्हरकरीता आऊटपुट पाठवण्याकरीता केला जातो. रिकामे मूल्यकरीता सेट अशक्य "
|
||||||
"जाते. तरी पाइपलाइन स्वतःच्या आऊटपुटची काळजी घेतो - याचा वापर shout2send किंवा "
|
"किंवा शक्य केल्यावर, मूळ पाइपलाइनचा वापर केला जातो. हे सध्या 'vp8enc "
|
||||||
"समानतर्फे icecast सर्व्हरकरीता आऊटपुट पाठवण्याकरीता केला जातो. रिकामे "
|
"quality=8 speed=6 threads=%T ! queue ! webmmux' आहे व VP8 कोडेकचा वापर करून "
|
||||||
"मूल्यकरीता सेट "
|
"WEBM करीता रेकॉर्डिंग करतो. %T चा वापर प्रणालीवरील कमाल थ्रेड गणणा "
|
||||||
"अशक्य किंवा शक्य केल्यावर, मूळ पाइपलाइनचा वापर केला जातो. हे सध्या 'vp8enc "
|
"ओळखण्यासाठी प्लेसहोल्डर म्हणून केला जातो."
|
||||||
"quality=8 "
|
|
||||||
"speed=6 threads=%T ! queue ! webmmux' आहे व VP8 कोडेकचा वापर करून WEBM करीता "
|
|
||||||
"रेकॉर्डिंग करतो. %T चा वापर प्रणालीवरील कमाल थ्रेड गणणा ओळखण्यासाठी "
|
|
||||||
"प्लेसहोल्डर म्हणून "
|
|
||||||
"केला जातो."
|
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:31
|
#: ../data/org.gnome.shell.gschema.xml.in.h:29
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "स्क्रिनकास्ट साठवण्याकरीता वापरलेले फाइल एक्सटेंशन"
|
msgstr "स्क्रिनकास्ट साठवण्याकरीता वापरलेले फाइल एक्सटेंशन"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.h:32
|
#: ../data/org.gnome.shell.gschema.xml.in.h:30
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@@ -246,40 +243,42 @@ msgstr "<b>एक्सटेंशन</b>"
|
|||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "वरील कॉम्बोबॉक्सचा वापर करून संरचनाकरीता एक्सटेंशनचा वापर करा."
|
msgstr "वरील कॉम्बोबॉक्सचा वापर करून संरचनाकरीता एक्सटेंशनचा वापर करा."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:627
|
#: ../js/gdm/loginDialog.js:624
|
||||||
|
#| msgid "Searching..."
|
||||||
msgid "Session..."
|
msgid "Session..."
|
||||||
msgstr "सत्र..."
|
msgstr "सत्र..."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:789
|
#: ../js/gdm/loginDialog.js:786
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "प्रवेश करा"
|
msgstr "प्रवेश करा"
|
||||||
|
|
||||||
#. Translators: this message is shown below the password entry field
|
#. Translators: this message is shown below the password entry field
|
||||||
#. to indicate the user can swipe their finger instead
|
#. to indicate the user can swipe their finger instead
|
||||||
#: ../js/gdm/loginDialog.js:834
|
#: ../js/gdm/loginDialog.js:831
|
||||||
msgid "(or swipe finger)"
|
msgid "(or swipe finger)"
|
||||||
msgstr "(किंवा बोट फिरवा)"
|
msgstr "(किंवा बोट फिरवा)"
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:855
|
#: ../js/gdm/loginDialog.js:852
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr "सूचीत नाही?"
|
msgstr "सूचीत नाही?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1023 ../js/ui/endSessionDialog.js:401
|
#: ../js/gdm/loginDialog.js:1020 ../js/ui/endSessionDialog.js:401
|
||||||
#: ../js/ui/extensionSystem.js:400 ../js/ui/networkAgent.js:153
|
#: ../js/ui/extensionSystem.js:399 ../js/ui/networkAgent.js:153
|
||||||
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
#: ../js/ui/polkitAuthenticationAgent.js:175 ../js/ui/status/bluetooth.js:462
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "रद्द करा"
|
msgstr "रद्द करा"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1028
|
#: ../js/gdm/loginDialog.js:1025
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "प्रवेश करा"
|
msgstr "प्रवेश करा"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1380
|
#: ../js/gdm/loginDialog.js:1377
|
||||||
|
#| msgid "New Window"
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "प्रवेश पटल"
|
msgstr "प्रवेश पटल"
|
||||||
|
|
||||||
@@ -356,6 +355,7 @@ msgid "Open with %s"
|
|||||||
msgstr "%s सह उघडा"
|
msgstr "%s सह उघडा"
|
||||||
|
|
||||||
#: ../js/ui/autorunManager.js:586
|
#: ../js/ui/autorunManager.js:586
|
||||||
|
#| msgid "Reject"
|
||||||
msgid "Eject"
|
msgid "Eject"
|
||||||
msgstr "बाहेर काढा"
|
msgstr "बाहेर काढा"
|
||||||
|
|
||||||
@@ -591,11 +591,13 @@ msgstr "%A %B %e, %Y"
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:61
|
#: ../js/ui/endSessionDialog.js:61
|
||||||
#, c-format
|
#, c-format
|
||||||
|
#| msgid "Log Out %s"
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out %s"
|
msgid "Log Out %s"
|
||||||
msgstr "%s पासून बाहेर पडा"
|
msgstr "%s पासून बाहेर पडा"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:62
|
#: ../js/ui/endSessionDialog.js:62
|
||||||
|
#| msgid "Log Out"
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "बाहेर पडा"
|
msgstr "बाहेर पडा"
|
||||||
@@ -607,6 +609,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:65
|
#: ../js/ui/endSessionDialog.js:65
|
||||||
#, c-format
|
#, c-format
|
||||||
|
#| msgid "%s will be logged out automatically in %d seconds."
|
||||||
msgid "%s will be logged out automatically in %d second."
|
msgid "%s will be logged out automatically in %d second."
|
||||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "%s स्वयं, %d सेकंदात बाहेर पडेल."
|
msgstr[0] "%s स्वयं, %d सेकंदात बाहेर पडेल."
|
||||||
@@ -614,6 +617,7 @@ msgstr[1] "%s स्वयं, %d सेकंदात बाहेर पड
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:70
|
#: ../js/ui/endSessionDialog.js:70
|
||||||
#, c-format
|
#, c-format
|
||||||
|
#| msgid "You will be logged out automatically in %d seconds."
|
||||||
msgid "You will be logged out automatically in %d second."
|
msgid "You will be logged out automatically in %d second."
|
||||||
msgid_plural "You will be logged out automatically in %d seconds."
|
msgid_plural "You will be logged out automatically in %d seconds."
|
||||||
msgstr[0] "%d सेकंदात तुम्ही स्वयं बाहेर पडाल."
|
msgstr[0] "%d सेकंदात तुम्ही स्वयं बाहेर पडाल."
|
||||||
@@ -624,11 +628,13 @@ msgid "Logging out of the system."
|
|||||||
msgstr "प्रणालीतून बाहेर पडत आहे."
|
msgstr "प्रणालीतून बाहेर पडत आहे."
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:76
|
#: ../js/ui/endSessionDialog.js:76
|
||||||
|
#| msgid "Log Out"
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Log Out"
|
msgid "Log Out"
|
||||||
msgstr "बाहेर पडा"
|
msgstr "बाहेर पडा"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:81
|
#: ../js/ui/endSessionDialog.js:81
|
||||||
|
#| msgid "Power Off"
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "बंद करा"
|
msgstr "बंद करा"
|
||||||
@@ -639,6 +645,7 @@ msgstr "ॲप्लिकेशन्स् बंद करण्यासा
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:84
|
#: ../js/ui/endSessionDialog.js:84
|
||||||
#, c-format
|
#, c-format
|
||||||
|
#| msgid "The system will power off automatically in %d seconds."
|
||||||
msgid "The system will power off automatically in %d second."
|
msgid "The system will power off automatically in %d second."
|
||||||
msgid_plural "The system will power off automatically in %d seconds."
|
msgid_plural "The system will power off automatically in %d seconds."
|
||||||
msgstr[0] "प्रणाली स्वयं %d सेकंदात बंद होईल."
|
msgstr[0] "प्रणाली स्वयं %d सेकंदात बंद होईल."
|
||||||
@@ -649,16 +656,19 @@ msgid "Powering off the system."
|
|||||||
msgstr "प्रणाली बंद करत आहे."
|
msgstr "प्रणाली बंद करत आहे."
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:107
|
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:107
|
||||||
|
#| msgid "Restart"
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "पुनः सुरू करा"
|
msgstr "पुनः सुरू करा"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:92
|
#: ../js/ui/endSessionDialog.js:92
|
||||||
|
#| msgid "Power Off"
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "बंद करा"
|
msgstr "बंद करा"
|
||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:98
|
#: ../js/ui/endSessionDialog.js:98
|
||||||
|
#| msgid "Restart"
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Restart"
|
msgid "Restart"
|
||||||
msgstr "पुनः सुरू करा"
|
msgstr "पुनः सुरू करा"
|
||||||
@@ -670,6 +680,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: ../js/ui/endSessionDialog.js:101
|
#: ../js/ui/endSessionDialog.js:101
|
||||||
#, c-format
|
#, c-format
|
||||||
|
#| msgid "The system will restart automatically in %d seconds."
|
||||||
msgid "The system will restart automatically in %d second."
|
msgid "The system will restart automatically in %d second."
|
||||||
msgid_plural "The system will restart automatically in %d seconds."
|
msgid_plural "The system will restart automatically in %d seconds."
|
||||||
msgstr[0] "प्रणाली स्वयं %d सेकंदात पुनः सुरू होईल."
|
msgstr[0] "प्रणाली स्वयं %d सेकंदात पुनः सुरू होईल."
|
||||||
@@ -679,21 +690,21 @@ msgstr[1] "प्रणाली स्वयं %d सेकंदामध्
|
|||||||
msgid "Restarting the system."
|
msgid "Restarting the system."
|
||||||
msgstr "प्रणाली पुनःसुरू करत आहे."
|
msgstr "प्रणाली पुनःसुरू करत आहे."
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:404
|
#: ../js/ui/extensionSystem.js:403
|
||||||
msgid "Install"
|
msgid "Install"
|
||||||
msgstr "प्रतिष्ठापीत करा"
|
msgstr "प्रतिष्ठापीत करा"
|
||||||
|
|
||||||
#: ../js/ui/extensionSystem.js:408
|
#: ../js/ui/extensionSystem.js:407
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr " extensions.gnome.org पासून '%s' डाऊनलोड व प्रतिष्ठापीत करा?"
|
msgstr " extensions.gnome.org पासून '%s' डाऊनलोड व प्रतिष्ठापीत करा?"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:327
|
#: ../js/ui/keyboard.js:327
|
||||||
|
#| msgid "Retry"
|
||||||
msgid "tray"
|
msgid "tray"
|
||||||
msgstr "ट्रे"
|
msgstr "ट्रे"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:544 ../js/ui/status/keyboard.js:44
|
#: ../js/ui/keyboard.js:544 ../js/ui/status/power.js:203
|
||||||
#: ../js/ui/status/power.js:203
|
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "कळफलक"
|
msgstr "कळफलक"
|
||||||
|
|
||||||
@@ -716,10 +727,12 @@ msgid "%s has not emitted any errors."
|
|||||||
msgstr "%s ने कोणत्याहि त्रुटी दाखवले नाही."
|
msgstr "%s ने कोणत्याहि त्रुटी दाखवले नाही."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:792
|
#: ../js/ui/lookingGlass.js:792
|
||||||
|
#| msgid "Error"
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "त्रुटी लपवा"
|
msgstr "त्रुटी लपवा"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
#: ../js/ui/lookingGlass.js:796 ../js/ui/lookingGlass.js:847
|
||||||
|
#| msgid "Error"
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "त्रुटी दाखवा"
|
msgstr "त्रुटी दाखवा"
|
||||||
|
|
||||||
@@ -729,7 +742,7 @@ msgstr "सुरू केले"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1082
|
#: ../js/ui/lookingGlass.js:808 ../src/gvc/gvc-mixer-control.c:1093
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "बंद केले"
|
msgstr "बंद केले"
|
||||||
|
|
||||||
@@ -754,7 +767,7 @@ msgid "Web Page"
|
|||||||
msgstr "वेब पृष्ठ"
|
msgstr "वेब पृष्ठ"
|
||||||
|
|
||||||
#. Translators: this is a filename used for screencast recording
|
#. Translators: this is a filename used for screencast recording
|
||||||
#: ../js/ui/main.js:121
|
#: ../js/ui/main.js:118
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Screencast from %d %t"
|
msgid "Screencast from %d %t"
|
||||||
msgstr "%d %t पासून स्क्रीनकास्ट"
|
msgstr "%d %t पासून स्क्रीनकास्ट"
|
||||||
@@ -764,18 +777,22 @@ msgid "Open"
|
|||||||
msgstr "उघडा"
|
msgstr "उघडा"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1217
|
#: ../js/ui/messageTray.js:1217
|
||||||
|
#| msgid "minute"
|
||||||
|
#| msgid_plural "minutes"
|
||||||
msgid "Unmute"
|
msgid "Unmute"
|
||||||
msgstr "बंद करणे अशक्य करा"
|
msgstr "मंद करणे अशक्य करा"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1217
|
#: ../js/ui/messageTray.js:1217
|
||||||
|
#| msgid "Mouse"
|
||||||
msgid "Mute"
|
msgid "Mute"
|
||||||
msgstr "बंद करा"
|
msgstr "मंद करा"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2490
|
#: ../js/ui/messageTray.js:2490
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "प्रणाली माहिती"
|
msgstr "प्रणाली माहिती"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:148
|
#: ../js/ui/networkAgent.js:148
|
||||||
|
#| msgid "Connection"
|
||||||
msgid "Connect"
|
msgid "Connect"
|
||||||
msgstr "जोडणी करा"
|
msgstr "जोडणी करा"
|
||||||
|
|
||||||
@@ -783,6 +800,7 @@ msgstr "जोडणी करा"
|
|||||||
#: ../js/ui/networkAgent.js:243 ../js/ui/networkAgent.js:255
|
#: ../js/ui/networkAgent.js:243 ../js/ui/networkAgent.js:255
|
||||||
#: ../js/ui/networkAgent.js:282 ../js/ui/networkAgent.js:302
|
#: ../js/ui/networkAgent.js:282 ../js/ui/networkAgent.js:302
|
||||||
#: ../js/ui/networkAgent.js:312
|
#: ../js/ui/networkAgent.js:312
|
||||||
|
#| msgid "Password:"
|
||||||
msgid "Password: "
|
msgid "Password: "
|
||||||
msgstr "पासवर्ड: "
|
msgstr "पासवर्ड: "
|
||||||
|
|
||||||
@@ -811,6 +829,7 @@ msgid "Service: "
|
|||||||
msgstr "सर्व्हिस: "
|
msgstr "सर्व्हिस: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:329
|
#: ../js/ui/networkAgent.js:329
|
||||||
|
#| msgid "Authentication Required"
|
||||||
msgid "Authentication required by wireless network"
|
msgid "Authentication required by wireless network"
|
||||||
msgstr "वायरलेस नेटवर्कतर्फे आवश्यक ओळखपटवणे"
|
msgstr "वायरलेस नेटवर्कतर्फे आवश्यक ओळखपटवणे"
|
||||||
|
|
||||||
@@ -826,10 +845,12 @@ msgid "Wired 802.1X authentication"
|
|||||||
msgstr "वायर्ड 802.1X ओळखपटवणे"
|
msgstr "वायर्ड 802.1X ओळखपटवणे"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:336
|
#: ../js/ui/networkAgent.js:336
|
||||||
|
#| msgid "Network Manager"
|
||||||
msgid "Network name: "
|
msgid "Network name: "
|
||||||
msgstr "नेटवर्क नाव: "
|
msgstr "नेटवर्क नाव: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:341
|
#: ../js/ui/networkAgent.js:341
|
||||||
|
#| msgid "authentication required"
|
||||||
msgid "DSL authentication"
|
msgid "DSL authentication"
|
||||||
msgstr "DSL ओळख पटवणे"
|
msgstr "DSL ओळख पटवणे"
|
||||||
|
|
||||||
@@ -846,11 +867,13 @@ msgid "PIN: "
|
|||||||
msgstr "PIN: "
|
msgstr "PIN: "
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:356
|
#: ../js/ui/networkAgent.js:356
|
||||||
|
#| msgid "Mobile broadband"
|
||||||
msgid "Mobile broadband network password"
|
msgid "Mobile broadband network password"
|
||||||
msgstr "मोबाईल ब्रॉडबँड नेटवर्क पासवर्ड"
|
msgstr "मोबाईल ब्रॉडबँड नेटवर्क पासवर्ड"
|
||||||
|
|
||||||
#: ../js/ui/networkAgent.js:357
|
#: ../js/ui/networkAgent.js:357
|
||||||
#, c-format
|
#, c-format
|
||||||
|
#| msgid "You're now connected to '%s'"
|
||||||
msgid "A password is required to connect to '%s'."
|
msgid "A password is required to connect to '%s'."
|
||||||
msgstr "'%s' सह जोडणीकरीता पासवर्ड आवश्यक आहे."
|
msgstr "'%s' सह जोडणीकरीता पासवर्ड आवश्यक आहे."
|
||||||
|
|
||||||
@@ -877,6 +900,7 @@ msgid "Dash"
|
|||||||
msgstr "डॅश"
|
msgstr "डॅश"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:592
|
#: ../js/ui/panel.js:592
|
||||||
|
#| msgid "Quit %s"
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "बाहेर पडा"
|
msgstr "बाहेर पडा"
|
||||||
|
|
||||||
@@ -944,7 +968,7 @@ msgstr "कृपया आदेश द्या:"
|
|||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "शोधत आहे..."
|
msgstr "शोधत आहे..."
|
||||||
|
|
||||||
#: ../js/ui/searchDisplay.js:415
|
#: ../js/ui/searchDisplay.js:414
|
||||||
msgid "No matching results."
|
msgid "No matching results."
|
||||||
msgstr "जुळवण्याजोगी परिणाम आढळले नाही."
|
msgstr "जुळवण्याजोगी परिणाम आढळले नाही."
|
||||||
|
|
||||||
@@ -961,6 +985,7 @@ msgid "Show Text"
|
|||||||
msgstr "मजकूर दाखवा"
|
msgstr "मजकूर दाखवा"
|
||||||
|
|
||||||
#: ../js/ui/shellEntry.js:79
|
#: ../js/ui/shellEntry.js:79
|
||||||
|
#| msgid "Large Text"
|
||||||
msgid "Hide Text"
|
msgid "Hide Text"
|
||||||
msgstr "मजकूर लपवा"
|
msgstr "मजकूर लपवा"
|
||||||
|
|
||||||
@@ -969,6 +994,7 @@ msgid "Wrong password, please try again"
|
|||||||
msgstr "चुकिचा पासवर्ड, कृपया पुनः प्रयत्न करा"
|
msgstr "चुकिचा पासवर्ड, कृपया पुनः प्रयत्न करा"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:47
|
#: ../js/ui/status/accessibility.js:47
|
||||||
|
#| msgid "Visibility"
|
||||||
msgid "Accessibility"
|
msgid "Accessibility"
|
||||||
msgstr "ॲक्सेसिबिलिटि"
|
msgstr "ॲक्सेसिबिलिटि"
|
||||||
|
|
||||||
@@ -980,6 +1006,7 @@ msgstr "झूम"
|
|||||||
#. 'screen-reader-enabled');
|
#. 'screen-reader-enabled');
|
||||||
#. this.menu.addMenuItem(screenReader);
|
#. this.menu.addMenuItem(screenReader);
|
||||||
#: ../js/ui/status/accessibility.js:63
|
#: ../js/ui/status/accessibility.js:63
|
||||||
|
#| msgid "Keyboard"
|
||||||
msgid "Screen Keyboard"
|
msgid "Screen Keyboard"
|
||||||
msgstr "स्क्रीन किबोर्ड"
|
msgstr "स्क्रीन किबोर्ड"
|
||||||
|
|
||||||
@@ -1031,6 +1058,7 @@ msgid "Send Files to Device..."
|
|||||||
msgstr "फाइल्स्ना साधनावर पाठवा..."
|
msgstr "फाइल्स्ना साधनावर पाठवा..."
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:63
|
#: ../js/ui/status/bluetooth.js:63
|
||||||
|
#| msgid "Setup a New Device..."
|
||||||
msgid "Set up a New Device..."
|
msgid "Set up a New Device..."
|
||||||
msgstr "नविन साधनची मांडणी करा..."
|
msgstr "नविन साधनची मांडणी करा..."
|
||||||
|
|
||||||
@@ -1040,6 +1068,7 @@ msgstr "ब्ल्यूटूथ सेटिंग्स्"
|
|||||||
|
|
||||||
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
|
#. TRANSLATORS: this means that bluetooth was disabled by hardware rfkill
|
||||||
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:256
|
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/network.js:256
|
||||||
|
#| msgid "disabled"
|
||||||
msgid "hardware disabled"
|
msgid "hardware disabled"
|
||||||
msgstr "हार्डवेअर बंद केले"
|
msgstr "हार्डवेअर बंद केले"
|
||||||
|
|
||||||
@@ -1048,6 +1077,7 @@ msgid "Connection"
|
|||||||
msgstr "जोडणी"
|
msgstr "जोडणी"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:214 ../js/ui/status/network.js:491
|
#: ../js/ui/status/bluetooth.js:214 ../js/ui/status/network.js:491
|
||||||
|
#| msgid "connecting..."
|
||||||
msgid "disconnecting..."
|
msgid "disconnecting..."
|
||||||
msgstr "जोडणी खंडीत करत आहे..."
|
msgstr "जोडणी खंडीत करत आहे..."
|
||||||
|
|
||||||
@@ -1102,7 +1132,7 @@ msgstr "नेहमी प्रवेश द्या"
|
|||||||
msgid "Grant this time only"
|
msgid "Grant this time only"
|
||||||
msgstr "फक्त याचवेळी मान्य करा"
|
msgstr "फक्त याचवेळी मान्य करा"
|
||||||
|
|
||||||
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1093
|
#: ../js/ui/status/bluetooth.js:382 ../js/ui/telepathyClient.js:1091
|
||||||
msgid "Reject"
|
msgid "Reject"
|
||||||
msgstr "नकारा"
|
msgstr "नकारा"
|
||||||
|
|
||||||
@@ -1143,10 +1173,12 @@ msgid "OK"
|
|||||||
msgstr "ठीक आहे"
|
msgstr "ठीक आहे"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:68
|
#: ../js/ui/status/keyboard.js:68
|
||||||
|
#| msgid "Show Keyboard Layout..."
|
||||||
msgid "Show Keyboard Layout"
|
msgid "Show Keyboard Layout"
|
||||||
msgstr "किबोर्ड लेआऊट दाखवा"
|
msgstr "किबोर्ड लेआऊट दाखवा"
|
||||||
|
|
||||||
#: ../js/ui/status/keyboard.js:73
|
#: ../js/ui/status/keyboard.js:73
|
||||||
|
#| msgid "Date and Time Settings"
|
||||||
msgid "Region and Language Settings"
|
msgid "Region and Language Settings"
|
||||||
msgstr "क्षेत्र व भाषा सेटिंग्स्"
|
msgstr "क्षेत्र व भाषा सेटिंग्स्"
|
||||||
|
|
||||||
@@ -1228,6 +1260,7 @@ msgid "Auto wireless"
|
|||||||
msgstr "स्वयं वायरलेस्"
|
msgstr "स्वयं वायरलेस्"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1541
|
#: ../js/ui/status/network.js:1541
|
||||||
|
#| msgid "Network Manager"
|
||||||
msgid "Network"
|
msgid "Network"
|
||||||
msgstr "नेटवर्क"
|
msgstr "नेटवर्क"
|
||||||
|
|
||||||
@@ -1256,10 +1289,12 @@ msgid "Network Settings"
|
|||||||
msgstr "जाळं संयोजना"
|
msgstr "जाळं संयोजना"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1739
|
#: ../js/ui/status/network.js:1739
|
||||||
|
#| msgid "connection failed"
|
||||||
msgid "Connection failed"
|
msgid "Connection failed"
|
||||||
msgstr "जोडणी अपयशी"
|
msgstr "जोडणी अपयशी"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:1740
|
#: ../js/ui/status/network.js:1740
|
||||||
|
#| msgid "connection failed"
|
||||||
msgid "Activation of network connection failed"
|
msgid "Activation of network connection failed"
|
||||||
msgstr "नेटवर्क जोडणी सुरू करणे अपयशी"
|
msgstr "नेटवर्क जोडणी सुरू करणे अपयशी"
|
||||||
|
|
||||||
@@ -1380,6 +1415,7 @@ msgstr "आमंत्रण"
|
|||||||
|
|
||||||
#. We got the TpContact
|
#. We got the TpContact
|
||||||
#: ../js/ui/telepathyClient.js:271
|
#: ../js/ui/telepathyClient.js:271
|
||||||
|
#| msgid "Cancel"
|
||||||
msgid "Call"
|
msgid "Call"
|
||||||
msgstr "कॉल"
|
msgstr "कॉल"
|
||||||
|
|
||||||
@@ -1389,10 +1425,12 @@ msgid "File Transfer"
|
|||||||
msgstr "फाइल स्थानांतरन"
|
msgstr "फाइल स्थानांतरन"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:369
|
#: ../js/ui/telepathyClient.js:369
|
||||||
|
#| msgid "Authorization request from %s"
|
||||||
msgid "Subscription request"
|
msgid "Subscription request"
|
||||||
msgstr "सबस्क्रिप्शन विनंती"
|
msgstr "सबस्क्रिप्शन विनंती"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:405
|
#: ../js/ui/telepathyClient.js:405
|
||||||
|
#| msgid "Connection"
|
||||||
msgid "Connection error"
|
msgid "Connection error"
|
||||||
msgstr "जोडणी त्रुटी"
|
msgstr "जोडणी त्रुटी"
|
||||||
|
|
||||||
@@ -1419,35 +1457,36 @@ msgstr "%s व्यग्र आहे."
|
|||||||
#. Translators: this is a time format string followed by a date.
|
#. Translators: this is a time format string followed by a date.
|
||||||
#. If applicable, replace %X with a strftime format valid for your
|
#. If applicable, replace %X with a strftime format valid for your
|
||||||
#. locale, without seconds.
|
#. locale, without seconds.
|
||||||
#: ../js/ui/telepathyClient.js:889
|
#: ../js/ui/telepathyClient.js:887
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
|
#| msgid "Sent at %X on %A"
|
||||||
msgid "Sent at <b>%X</b> on <b>%A</b>"
|
msgid "Sent at <b>%X</b> on <b>%A</b>"
|
||||||
msgstr "<b>%X</b> वेळी, <b>%A</b> ला पाठवले"
|
msgstr "<b>%X</b> वेळी, <b>%A</b> ला पाठवले"
|
||||||
|
|
||||||
#. Translators: this is a time format in the style of "Wednesday, May 25",
|
#. Translators: this is a time format in the style of "Wednesday, May 25",
|
||||||
#. shown when you get a chat message in the same year.
|
#. shown when you get a chat message in the same year.
|
||||||
#: ../js/ui/telepathyClient.js:895
|
#: ../js/ui/telepathyClient.js:893
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
|
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
|
||||||
msgstr "<b>%A</b> वेळी, <b>%B %d</b> ला पाठवले"
|
msgstr "<b>%A</b> वेळी, <b>%B %d</b> ला पाठवले"
|
||||||
|
|
||||||
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
|
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
|
||||||
#. shown when you get a chat message in a different year.
|
#. shown when you get a chat message in a different year.
|
||||||
#: ../js/ui/telepathyClient.js:900
|
#: ../js/ui/telepathyClient.js:898
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
|
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
|
||||||
msgstr "<b>%A</b>, <b>%B %d</b>, %Y वेळी पाठवले"
|
msgstr "<b>%A</b>, <b>%B %d</b>, %Y वेळी पाठवले"
|
||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
#: ../js/ui/telepathyClient.js:942
|
#: ../js/ui/telepathyClient.js:940
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is now known as %s"
|
msgid "%s is now known as %s"
|
||||||
msgstr "%s ला %s म्हणून ओळखले जाते"
|
msgstr "%s ला %s म्हणून ओळखले जाते"
|
||||||
|
|
||||||
#. translators: argument is a room name like
|
#. translators: argument is a room name like
|
||||||
#. * room@jabber.org for example.
|
#. * room@jabber.org for example.
|
||||||
#: ../js/ui/telepathyClient.js:1044
|
#: ../js/ui/telepathyClient.js:1042
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Invitation to %s"
|
msgid "Invitation to %s"
|
||||||
msgstr "%s करीता आमंत्रण"
|
msgstr "%s करीता आमंत्रण"
|
||||||
@@ -1455,35 +1494,35 @@ msgstr "%s करीता आमंत्रण"
|
|||||||
#. translators: first argument is the name of a contact and the second
|
#. translators: first argument is the name of a contact and the second
|
||||||
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
||||||
#. * for example.
|
#. * for example.
|
||||||
#: ../js/ui/telepathyClient.js:1052
|
#: ../js/ui/telepathyClient.js:1050
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is inviting you to join %s"
|
msgid "%s is inviting you to join %s"
|
||||||
msgstr "%s तुम्हाला %s सह जोडणीकरीता आमंत्रण देत आहे"
|
msgstr "%s तुम्हाला %s सह जोडणीकरीता आमंत्रण देत आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1054 ../js/ui/telepathyClient.js:1133
|
#: ../js/ui/telepathyClient.js:1052 ../js/ui/telepathyClient.js:1131
|
||||||
#: ../js/ui/telepathyClient.js:1231
|
#: ../js/ui/telepathyClient.js:1229
|
||||||
msgid "Decline"
|
msgid "Decline"
|
||||||
msgstr "नकारा"
|
msgstr "नकारा"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1055 ../js/ui/telepathyClient.js:1134
|
#: ../js/ui/telepathyClient.js:1053 ../js/ui/telepathyClient.js:1132
|
||||||
#: ../js/ui/telepathyClient.js:1232
|
#: ../js/ui/telepathyClient.js:1230
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "स्वीकारा"
|
msgstr "स्वीकारा"
|
||||||
|
|
||||||
#. translators: argument is a contact name like Alice for example.
|
#. translators: argument is a contact name like Alice for example.
|
||||||
#: ../js/ui/telepathyClient.js:1085
|
#: ../js/ui/telepathyClient.js:1083
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Video call from %s"
|
msgid "Video call from %s"
|
||||||
msgstr "%s पासून व्हिडीओ कॉल्स्"
|
msgstr "%s पासून व्हिडीओ कॉल्स्"
|
||||||
|
|
||||||
#. translators: argument is a contact name like Alice for example.
|
#. translators: argument is a contact name like Alice for example.
|
||||||
#: ../js/ui/telepathyClient.js:1088
|
#: ../js/ui/telepathyClient.js:1086
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Call from %s"
|
msgid "Call from %s"
|
||||||
msgstr "%s पासून कॉल"
|
msgstr "%s पासून कॉल"
|
||||||
|
|
||||||
#. translators: this is a button label (verb), not a noun
|
#. translators: this is a button label (verb), not a noun
|
||||||
#: ../js/ui/telepathyClient.js:1095
|
#: ../js/ui/telepathyClient.js:1093
|
||||||
msgid "Answer"
|
msgid "Answer"
|
||||||
msgstr "उत्तर"
|
msgstr "उत्तर"
|
||||||
|
|
||||||
@@ -1492,138 +1531,147 @@ msgstr "उत्तर"
|
|||||||
#. * file name. The string will be something
|
#. * file name. The string will be something
|
||||||
#. * like: "Alice is sending you test.ogg"
|
#. * like: "Alice is sending you test.ogg"
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/telepathyClient.js:1127
|
#: ../js/ui/telepathyClient.js:1125
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is sending you %s"
|
msgid "%s is sending you %s"
|
||||||
msgstr "%s तुम्हाला %s पाठवत आहे"
|
msgstr "%s तुम्हाला %s पाठवत आहे"
|
||||||
|
|
||||||
#. To translators: The parameter is the contact's alias
|
#. To translators: The parameter is the contact's alias
|
||||||
#: ../js/ui/telepathyClient.js:1196
|
#: ../js/ui/telepathyClient.js:1194
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s would like permission to see when you are online"
|
msgid "%s would like permission to see when you are online"
|
||||||
msgstr "ऑनलाइन असल्यावर %s परवानगी दृष्यास्पद करायची"
|
msgstr "ऑनलाइन असल्यावर %s परवानगी दृष्यास्पद करायची"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1289
|
#: ../js/ui/telepathyClient.js:1287
|
||||||
|
#| msgid "Network Manager"
|
||||||
msgid "Network error"
|
msgid "Network error"
|
||||||
msgstr "नेटवर्क त्रुटी"
|
msgstr "नेटवर्क त्रुटी"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1291
|
#: ../js/ui/telepathyClient.js:1289
|
||||||
|
#| msgid "Authentication Required"
|
||||||
msgid "Authentication failed"
|
msgid "Authentication failed"
|
||||||
msgstr "ओळख पटवणे अपयशी"
|
msgstr "ओळख पटवणे अपयशी"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1293
|
#: ../js/ui/telepathyClient.js:1291
|
||||||
msgid "Encryption error"
|
msgid "Encryption error"
|
||||||
msgstr "एंक्रिप्शन त्रुटी"
|
msgstr "एंक्रिप्शन त्रुटी"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1295
|
#: ../js/ui/telepathyClient.js:1293
|
||||||
msgid "Certificate not provided"
|
msgid "Certificate not provided"
|
||||||
msgstr "प्रमाणपत्र पुरवले नाही"
|
msgstr "प्रमाणपत्र पुरवले नाही"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1297
|
#: ../js/ui/telepathyClient.js:1295
|
||||||
msgid "Certificate untrusted"
|
msgid "Certificate untrusted"
|
||||||
msgstr "प्रमाणपत्र अविश्वासर्ह आहे"
|
msgstr "प्रमाणपत्र अविश्वासर्ह आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1299
|
#: ../js/ui/telepathyClient.js:1297
|
||||||
msgid "Certificate expired"
|
msgid "Certificate expired"
|
||||||
msgstr "प्रमाणपत्राची वेळसमाप्ति"
|
msgstr "प्रमाणपत्राची वेळसमाप्ति"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1301
|
#: ../js/ui/telepathyClient.js:1299
|
||||||
msgid "Certificate not activated"
|
msgid "Certificate not activated"
|
||||||
msgstr "प्रमाणपत्र सुरू केले नाही"
|
msgstr "प्रमाणपत्र सुरू केले नाही"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1303
|
#: ../js/ui/telepathyClient.js:1301
|
||||||
msgid "Certificate hostname mismatch"
|
msgid "Certificate hostname mismatch"
|
||||||
msgstr "प्रमाणपत्र यजमाननाव जुळत नाही"
|
msgstr "प्रमाणपत्र यजमाननाव जुळत नाही"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1305
|
#: ../js/ui/telepathyClient.js:1303
|
||||||
msgid "Certificate fingerprint mismatch"
|
msgid "Certificate fingerprint mismatch"
|
||||||
msgstr "प्रमाणपत्र फिंग्ररप्रिंट जुळत नाही"
|
msgstr "प्रमाणपत्र फिंग्ररप्रिंट जुळत नाही"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1307
|
#: ../js/ui/telepathyClient.js:1305
|
||||||
msgid "Certificate self-signed"
|
msgid "Certificate self-signed"
|
||||||
msgstr "प्रमाणपत्र स्वयं स्वाक्षरि"
|
msgstr "प्रमाणपत्र स्वयं स्वाक्षरि"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1309
|
#: ../js/ui/telepathyClient.js:1307
|
||||||
|
#| msgid "%s is offline."
|
||||||
msgid "Status is set to offline"
|
msgid "Status is set to offline"
|
||||||
msgstr "स्थिती ऑफलाइनकरीता ठरवली आहे"
|
msgstr "स्थिती ऑफलाइनकरीता ठरवली आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1311
|
#: ../js/ui/telepathyClient.js:1309
|
||||||
msgid "Encryption is not available"
|
msgid "Encryption is not available"
|
||||||
msgstr "एंक्रिप्शन अनुपलब्ध"
|
msgstr "एंक्रिप्शन अनुपलब्ध"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1313
|
#: ../js/ui/telepathyClient.js:1311
|
||||||
msgid "Certificate is invalid"
|
msgid "Certificate is invalid"
|
||||||
msgstr "प्रमाणपत्र अवैध आहे"
|
msgstr "प्रमाणपत्र अवैध आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1315
|
#: ../js/ui/telepathyClient.js:1313
|
||||||
|
#| msgid "Connection established"
|
||||||
msgid "Connection has been refused"
|
msgid "Connection has been refused"
|
||||||
msgstr "जोडणी नकारली गेली"
|
msgstr "जोडणी नकारली गेली"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1317
|
#: ../js/ui/telepathyClient.js:1315
|
||||||
|
#| msgid "Connection established"
|
||||||
msgid "Connection can't be established"
|
msgid "Connection can't be established"
|
||||||
msgstr "जोडणी स्थापीत करणे अशक्य"
|
msgstr "जोडणी स्थापीत करणे अशक्य"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1319
|
#: ../js/ui/telepathyClient.js:1317
|
||||||
|
#| msgid "Connection established"
|
||||||
msgid "Connection has been lost"
|
msgid "Connection has been lost"
|
||||||
msgstr "जोडणी खंडीत झाली"
|
msgstr "जोडणी खंडीत झाली"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1321
|
#: ../js/ui/telepathyClient.js:1319
|
||||||
msgid "This account is already connected to the server"
|
msgid "This account is already connected to the server"
|
||||||
msgstr "हे खाते आधिपासूनच सर्व्हरसह जुळले आहे"
|
msgstr "हे खाते आधिपासूनच सर्व्हरसह जुळले आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1323
|
#: ../js/ui/telepathyClient.js:1321
|
||||||
msgid ""
|
msgid ""
|
||||||
"Connection has been replaced by a new connection using the same resource"
|
"Connection has been replaced by a new connection using the same resource"
|
||||||
msgstr "समान स्रोतचा वापर करून जोडणीला नविन जोडणीसह बदलाबदल केले आहे"
|
msgstr "समान स्रोतचा वापर करून जोडणीला नविन जोडणीसह बदलाबदल केले आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1325
|
#: ../js/ui/telepathyClient.js:1323
|
||||||
msgid "The account already exists on the server"
|
msgid "The account already exists on the server"
|
||||||
msgstr "खाते आधिपासूनच सर्व्हरवर अस्तित्वात आहे"
|
msgstr "खाते आधिपासूनच सर्व्हरवर अस्तित्वात आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1327
|
#: ../js/ui/telepathyClient.js:1325
|
||||||
msgid "Server is currently too busy to handle the connection"
|
msgid "Server is currently too busy to handle the connection"
|
||||||
msgstr "जोडणी हाताळण्यासाठी सर्व्हर सध्या खूप व्यस्थ आहे"
|
msgstr "जोडणी हाताळण्यासाठी सर्व्हर सध्या खूप व्यस्थ आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1329
|
#: ../js/ui/telepathyClient.js:1327
|
||||||
msgid "Certificate has been revoked"
|
msgid "Certificate has been revoked"
|
||||||
msgstr "प्रमाणपत्र रद्द केले"
|
msgstr "प्रमाणपत्र रद्द केले"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1331
|
#: ../js/ui/telepathyClient.js:1329
|
||||||
msgid ""
|
msgid ""
|
||||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"प्रमाणपत्र असुरक्षित सिफर अल्गोरिदमचा वापर करते किंवा क्रिप्टोग्राफिकरित्या "
|
"प्रमाणपत्र असुरक्षित सिफर अल्गोरिदमचा वापर करते किंवा क्रिप्टोग्राफिकरित्या "
|
||||||
"खूप कमजोर आहे"
|
"खूप कमजोर आहे"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1333
|
#: ../js/ui/telepathyClient.js:1331
|
||||||
msgid ""
|
msgid ""
|
||||||
"The length of the server certificate, or the depth of the server certificate "
|
"The length of the server certificate, or the depth of the server certificate "
|
||||||
"chain, exceed the limits imposed by the cryptography library"
|
"chain, exceed the limits imposed by the cryptography library"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"सर्व्हर प्रमाणपत्राची लांबी, किंवा सर्व्हर प्रमाणपत्र चैनचे गांभीर्य, "
|
"सर्व्हर प्रमाणपत्राची लांबी, किंवा सर्व्हर प्रमाणपत्र चैनचे गांभीर्य, "
|
||||||
"क्रिप्टोग्राफि "
|
"क्रिप्टोग्राफि लाइब्ररितर्फे लादलेल्या मर्यादापेक्षा जास्त आहे"
|
||||||
"लाइब्ररितर्फे लादलेल्या मर्यादापेक्षा जास्त आहे"
|
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1335
|
#: ../js/ui/telepathyClient.js:1333
|
||||||
msgid "Internal error"
|
msgid "Internal error"
|
||||||
msgstr "आंतरिक त्रुटी"
|
msgstr "आंतरिक त्रुटी"
|
||||||
|
|
||||||
#. translators: argument is the account name, like
|
#. translators: argument is the account name, like
|
||||||
#. * name@jabber.org for example.
|
#. * name@jabber.org for example.
|
||||||
#: ../js/ui/telepathyClient.js:1345
|
#: ../js/ui/telepathyClient.js:1343
|
||||||
#, c-format
|
#, c-format
|
||||||
|
#| msgid "connection failed"
|
||||||
msgid "Connection to %s failed"
|
msgid "Connection to %s failed"
|
||||||
msgstr "%s सह जोडणी अपयशी"
|
msgstr "%s सह जोडणी अपयशी"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1354
|
#: ../js/ui/telepathyClient.js:1352
|
||||||
|
#| msgid "Reject"
|
||||||
msgid "Reconnect"
|
msgid "Reconnect"
|
||||||
msgstr "पुनःजोडणी करा"
|
msgstr "पुनःजोडणी करा"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1355
|
#: ../js/ui/telepathyClient.js:1353
|
||||||
|
#| msgid "My Account"
|
||||||
msgid "Edit account"
|
msgid "Edit account"
|
||||||
msgstr "खाते संपादित करा"
|
msgstr "खाते संपादित करा"
|
||||||
|
|
||||||
#: ../js/ui/telepathyClient.js:1401
|
#: ../js/ui/telepathyClient.js:1399
|
||||||
|
#| msgid "Unknown"
|
||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "अपरिचीत कारण"
|
msgstr "अपरिचीत कारण"
|
||||||
|
|
||||||
@@ -1636,6 +1684,7 @@ msgid "Idle"
|
|||||||
msgstr "रिकामे"
|
msgstr "रिकामे"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:144
|
#: ../js/ui/userMenu.js:144
|
||||||
|
#| msgid "unavailable"
|
||||||
msgid "Unavailable"
|
msgid "Unavailable"
|
||||||
msgstr "अनुपलब्ध"
|
msgstr "अनुपलब्ध"
|
||||||
|
|
||||||
@@ -1644,10 +1693,12 @@ msgid "Power Off..."
|
|||||||
msgstr "बंद करा..."
|
msgstr "बंद करा..."
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:631
|
#: ../js/ui/userMenu.js:631
|
||||||
|
#| msgid "Applications"
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "सूचना"
|
msgstr "सूचना"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:639
|
#: ../js/ui/userMenu.js:639
|
||||||
|
#| msgid "My Account"
|
||||||
msgid "Online Accounts"
|
msgid "Online Accounts"
|
||||||
msgstr "ऑनलाइन खाते"
|
msgstr "ऑनलाइन खाते"
|
||||||
|
|
||||||
@@ -1677,8 +1728,7 @@ msgid ""
|
|||||||
"has been adjusted to let others know that you might not see their messages."
|
"has been adjusted to let others know that you might not see their messages."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"सूचना आता बंद केले आहे, चॅट संदेश समाविष्टीत. इतरांना तुमचे संदेश दिसणार नाही "
|
"सूचना आता बंद केले आहे, चॅट संदेश समाविष्टीत. इतरांना तुमचे संदेश दिसणार नाही "
|
||||||
"हे कळवण्यासाठी "
|
"हे कळवण्यासाठी ऑनलाइन स्थिती सुस्थीत केली आहे."
|
||||||
"ऑनलाइन स्थिती सुस्थीत केली आहे."
|
|
||||||
|
|
||||||
#. Translators: this is the text displayed
|
#. Translators: this is the text displayed
|
||||||
#. in the search entry when no search is
|
#. in the search entry when no search is
|
||||||
@@ -1717,7 +1767,7 @@ msgstr "'%s' सज्ज आहे"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound outputs on a particular device
|
#. * The number of sound outputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1089
|
#: ../src/gvc/gvc-mixer-control.c:1100
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Output"
|
msgid "%u Output"
|
||||||
msgid_plural "%u Outputs"
|
msgid_plural "%u Outputs"
|
||||||
@@ -1726,14 +1776,14 @@ msgstr[1] "%u आऊटपुट"
|
|||||||
|
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The number of sound inputs on a particular device
|
#. * The number of sound inputs on a particular device
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1099
|
#: ../src/gvc/gvc-mixer-control.c:1110
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%u Input"
|
msgid "%u Input"
|
||||||
msgid_plural "%u Inputs"
|
msgid_plural "%u Inputs"
|
||||||
msgstr[0] "%u इंपुट"
|
msgstr[0] "%u इंपुट"
|
||||||
msgstr[1] "%u इंपुट"
|
msgstr[1] "%u इंपुट"
|
||||||
|
|
||||||
#: ../src/gvc/gvc-mixer-control.c:1397
|
#: ../src/gvc/gvc-mixer-control.c:1408
|
||||||
msgid "System Sounds"
|
msgid "System Sounds"
|
||||||
msgstr "प्रणाली आवाज"
|
msgstr "प्रणाली आवाज"
|
||||||
|
|
||||||
@@ -1751,6 +1801,7 @@ msgid "Failed to launch '%s'"
|
|||||||
msgstr "'%s' सुरू करण्यास अपयशी"
|
msgstr "'%s' सुरू करण्यास अपयशी"
|
||||||
|
|
||||||
#: ../src/shell-keyring-prompt.c:708
|
#: ../src/shell-keyring-prompt.c:708
|
||||||
|
#| msgid "Does not match"
|
||||||
msgid "Passwords do not match."
|
msgid "Passwords do not match."
|
||||||
msgstr "पासवर्डस् जुळत नाही."
|
msgstr "पासवर्डस् जुळत नाही."
|
||||||
|
|
||||||
@@ -1773,6 +1824,7 @@ msgstr "ओळख पटवा संवाद वापरकर्त्या
|
|||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-util.c:97
|
#: ../src/shell-util.c:97
|
||||||
|
#| msgid "Volume"
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "होम"
|
msgstr "होम"
|
||||||
|
|
||||||
|
|||||||
@@ -93,8 +93,7 @@ gnome_shell_cflags = \
|
|||||||
-DGNOME_SHELL_LIBEXECDIR=\"$(libexecdir)\" \
|
-DGNOME_SHELL_LIBEXECDIR=\"$(libexecdir)\" \
|
||||||
-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
|
-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
|
||||||
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
|
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||||
-DJSDIR=\"$(pkgdatadir)/js\" \
|
-DJSDIR=\"$(pkgdatadir)/js\"
|
||||||
-DMUTTER_TYPELIB_DIR=\"$(MUTTER_TYPELIB_DIR)\"
|
|
||||||
|
|
||||||
privlibdir = $(pkglibdir)
|
privlibdir = $(pkglibdir)
|
||||||
privlib_LTLIBRARIES = libgnome-shell.la libgnome-shell-js.la
|
privlib_LTLIBRARIES = libgnome-shell.la libgnome-shell-js.la
|
||||||
@@ -109,12 +108,12 @@ shell_public_headers_h = \
|
|||||||
shell-app.h \
|
shell-app.h \
|
||||||
shell-app-system.h \
|
shell-app-system.h \
|
||||||
shell-app-usage.h \
|
shell-app-usage.h \
|
||||||
|
shell-contact-system.h \
|
||||||
shell-embedded-window.h \
|
shell-embedded-window.h \
|
||||||
shell-generic-container.h \
|
shell-generic-container.h \
|
||||||
shell-gtk-embed.h \
|
shell-gtk-embed.h \
|
||||||
shell-global.h \
|
shell-global.h \
|
||||||
shell-idle-monitor.h \
|
shell-idle-monitor.h \
|
||||||
shell-invert-lightness-effect.h \
|
|
||||||
shell-mobile-providers.h \
|
shell-mobile-providers.h \
|
||||||
shell-mount-operation.h \
|
shell-mount-operation.h \
|
||||||
shell-network-agent.h \
|
shell-network-agent.h \
|
||||||
@@ -131,10 +130,6 @@ shell_public_headers_h = \
|
|||||||
shell-wm.h \
|
shell-wm.h \
|
||||||
shell-xfixes-cursor.h
|
shell-xfixes-cursor.h
|
||||||
|
|
||||||
if BUILD_WITH_FOLKS
|
|
||||||
shell_public_headers_h += shell-contact-system.h
|
|
||||||
endif
|
|
||||||
|
|
||||||
shell_private_sources = \
|
shell_private_sources = \
|
||||||
gactionmuxer.h \
|
gactionmuxer.h \
|
||||||
gactionmuxer.c \
|
gactionmuxer.c \
|
||||||
@@ -156,14 +151,16 @@ libgnome_shell_la_SOURCES = \
|
|||||||
shell-wm-private.h \
|
shell-wm-private.h \
|
||||||
gnome-shell-plugin.c \
|
gnome-shell-plugin.c \
|
||||||
shell-app.c \
|
shell-app.c \
|
||||||
|
shell-a11y.h \
|
||||||
|
shell-a11y.c \
|
||||||
shell-app-system.c \
|
shell-app-system.c \
|
||||||
shell-app-usage.c \
|
shell-app-usage.c \
|
||||||
|
shell-contact-system.c \
|
||||||
shell-embedded-window.c \
|
shell-embedded-window.c \
|
||||||
shell-generic-container.c \
|
shell-generic-container.c \
|
||||||
shell-gtk-embed.c \
|
shell-gtk-embed.c \
|
||||||
shell-global.c \
|
shell-global.c \
|
||||||
shell-idle-monitor.c \
|
shell-idle-monitor.c \
|
||||||
shell-invert-lightness-effect.c \
|
|
||||||
shell-keyring-prompt.h \
|
shell-keyring-prompt.h \
|
||||||
shell-keyring-prompt.c \
|
shell-keyring-prompt.c \
|
||||||
shell-mobile-providers.c \
|
shell-mobile-providers.c \
|
||||||
@@ -187,9 +184,6 @@ libgnome_shell_la_SOURCES = \
|
|||||||
shell-xfixes-cursor.c \
|
shell-xfixes-cursor.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
if BUILD_WITH_FOLKS
|
|
||||||
libgnome_shell_la_SOURCES += shell-contact-system.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
libgnome_shell_la_gir_sources = \
|
libgnome_shell_la_gir_sources = \
|
||||||
$(filter-out %-private.h $(shell_private_sources), $(shell_public_headers_h) $(libgnome_shell_la_SOURCES))
|
$(filter-out %-private.h $(shell_private_sources), $(shell_public_headers_h) $(libgnome_shell_la_SOURCES))
|
||||||
@@ -197,7 +191,7 @@ libgnome_shell_la_gir_sources = \
|
|||||||
gnome_shell_real_SOURCES = \
|
gnome_shell_real_SOURCES = \
|
||||||
main.c
|
main.c
|
||||||
gnome_shell_real_CPPFLAGS = $(gnome_shell_cflags)
|
gnome_shell_real_CPPFLAGS = $(gnome_shell_cflags)
|
||||||
gnome_shell_real_LDADD = libgnome-shell.la libgnome-shell-js.la $(libgnome_shell_la_LIBADD)
|
gnome_shell_real_LDADD = libgnome-shell.la $(libgnome_shell_la_LIBADD)
|
||||||
gnome_shell_real_DEPENDENCIES = libgnome-shell.la
|
gnome_shell_real_DEPENDENCIES = libgnome-shell.la
|
||||||
|
|
||||||
EXTRA_DIST += test-gapplication.js
|
EXTRA_DIST += test-gapplication.js
|
||||||
@@ -306,10 +300,7 @@ libgnome_shell_la_LIBADD = \
|
|||||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||||
|
|
||||||
Shell-0.1.gir: libgnome-shell.la St-1.0.gir
|
Shell-0.1.gir: libgnome-shell.la St-1.0.gir
|
||||||
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0
|
Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0 Folks-0.6
|
||||||
if BUILD_WITH_FOLKS
|
|
||||||
Shell_0_1_gir_INCLUDES += Folks-0.6
|
|
||||||
endif
|
|
||||||
Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
|
Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir)
|
||||||
Shell_0_1_gir_LIBS = libgnome-shell.la
|
Shell_0_1_gir_LIBS = libgnome-shell.la
|
||||||
Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources)
|
Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources)
|
||||||
|
|||||||
@@ -29,9 +29,11 @@
|
|||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <gconf/gconf-client.h>
|
||||||
#define HANDLE_LIBICAL_MEMORY
|
#define HANDLE_LIBICAL_MEMORY
|
||||||
#include <libecal/libecal.h>
|
#include <libecal/e-cal-client.h>
|
||||||
#include <libedataserverui/libedataserverui.h>
|
#include <libedataserver/e-source-list.h>
|
||||||
|
#include <libedataserverui/e-client-utils.h>
|
||||||
|
|
||||||
#undef CALENDAR_ENABLE_DEBUG
|
#undef CALENDAR_ENABLE_DEBUG
|
||||||
#include "calendar-debug.h"
|
#include "calendar-debug.h"
|
||||||
@@ -46,14 +48,18 @@
|
|||||||
|
|
||||||
#define CALENDAR_SOURCES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CALENDAR_TYPE_SOURCES, CalendarSourcesPrivate))
|
#define CALENDAR_SOURCES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CALENDAR_TYPE_SOURCES, CalendarSourcesPrivate))
|
||||||
|
|
||||||
typedef struct _ClientData ClientData;
|
#define CALENDAR_SOURCES_EVO_DIR "/apps/evolution"
|
||||||
typedef struct _CalendarSourceData CalendarSourceData;
|
#define CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/calendar/sources"
|
||||||
|
#define CALENDAR_SOURCES_TASK_SOURCES_KEY CALENDAR_SOURCES_EVO_DIR "/tasks/sources"
|
||||||
|
|
||||||
struct _ClientData
|
/* org.gnome.shell.evolution.calendar has the same data behind it
|
||||||
{
|
* as org.gnome.evolution.calendar, but is a small schema we install
|
||||||
ECalClient *client;
|
* ourselves */
|
||||||
gulong backend_died_id;
|
#define CALENDAR_SELECTED_SOURCES_SCHEMA "org.gnome.shell.evolution.calendar"
|
||||||
};
|
#define CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY "selected-calendars"
|
||||||
|
#define CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY "selected-tasks"
|
||||||
|
|
||||||
|
typedef struct _CalendarSourceData CalendarSourceData;
|
||||||
|
|
||||||
struct _CalendarSourceData
|
struct _CalendarSourceData
|
||||||
{
|
{
|
||||||
@@ -61,8 +67,11 @@ struct _CalendarSourceData
|
|||||||
CalendarSources *sources;
|
CalendarSources *sources;
|
||||||
guint changed_signal;
|
guint changed_signal;
|
||||||
|
|
||||||
/* ESource -> EClient */
|
GSList *clients;
|
||||||
GHashTable *clients;
|
char **selected_sources;
|
||||||
|
ESourceList *esource_list;
|
||||||
|
|
||||||
|
guint selected_sources_handler_id;
|
||||||
|
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
|
|
||||||
@@ -71,13 +80,11 @@ struct _CalendarSourceData
|
|||||||
|
|
||||||
struct _CalendarSourcesPrivate
|
struct _CalendarSourcesPrivate
|
||||||
{
|
{
|
||||||
ESourceRegistry *registry;
|
|
||||||
gulong source_added_id;
|
|
||||||
gulong source_changed_id;
|
|
||||||
gulong source_removed_id;
|
|
||||||
|
|
||||||
CalendarSourceData appointment_sources;
|
CalendarSourceData appointment_sources;
|
||||||
CalendarSourceData task_sources;
|
CalendarSourceData task_sources;
|
||||||
|
|
||||||
|
GConfClient *gconf_client;
|
||||||
|
GSettings *settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void calendar_sources_class_init (CalendarSourcesClass *klass);
|
static void calendar_sources_class_init (CalendarSourcesClass *klass);
|
||||||
@@ -85,12 +92,8 @@ static void calendar_sources_init (CalendarSources *sources);
|
|||||||
static void calendar_sources_finalize (GObject *object);
|
static void calendar_sources_finalize (GObject *object);
|
||||||
|
|
||||||
static void backend_died_cb (EClient *client, CalendarSourceData *source_data);
|
static void backend_died_cb (EClient *client, CalendarSourceData *source_data);
|
||||||
static void calendar_sources_registry_source_changed_cb (ESourceRegistry *registry,
|
static void calendar_sources_esource_list_changed (ESourceList *source_list,
|
||||||
ESource *source,
|
CalendarSourceData *source_data);
|
||||||
CalendarSources *sources);
|
|
||||||
static void calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
|
|
||||||
ESource *source,
|
|
||||||
CalendarSources *sources);
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -103,14 +106,6 @@ static guint signals [LAST_SIGNAL] = { 0, };
|
|||||||
static GObjectClass *parent_class = NULL;
|
static GObjectClass *parent_class = NULL;
|
||||||
static CalendarSources *calendar_sources_singleton = NULL;
|
static CalendarSources *calendar_sources_singleton = NULL;
|
||||||
|
|
||||||
static void
|
|
||||||
client_data_free (ClientData *data)
|
|
||||||
{
|
|
||||||
g_signal_handler_disconnect (data->client, data->backend_died_id);
|
|
||||||
g_object_unref (data->client);
|
|
||||||
g_slice_free (ClientData, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
calendar_sources_get_type (void)
|
calendar_sources_get_type (void)
|
||||||
{
|
{
|
||||||
@@ -178,49 +173,20 @@ calendar_sources_class_init (CalendarSourcesClass *klass)
|
|||||||
static void
|
static void
|
||||||
calendar_sources_init (CalendarSources *sources)
|
calendar_sources_init (CalendarSources *sources)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
sources->priv = CALENDAR_SOURCES_GET_PRIVATE (sources);
|
sources->priv = CALENDAR_SOURCES_GET_PRIVATE (sources);
|
||||||
|
|
||||||
/* XXX Not sure what to do if this fails.
|
|
||||||
* Should this class implement GInitable or pass the
|
|
||||||
* registry in as a G_PARAM_CONSTRUCT_ONLY property? */
|
|
||||||
sources->priv->registry = e_source_registry_new_sync (NULL, &error);
|
|
||||||
if (error != NULL)
|
|
||||||
{
|
|
||||||
g_error ("%s: %s", G_STRFUNC, error->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
sources->priv->source_added_id = g_signal_connect (sources->priv->registry,
|
|
||||||
"source-added",
|
|
||||||
G_CALLBACK (calendar_sources_registry_source_changed_cb),
|
|
||||||
sources);
|
|
||||||
sources->priv->source_changed_id = g_signal_connect (sources->priv->registry,
|
|
||||||
"source-changed",
|
|
||||||
G_CALLBACK (calendar_sources_registry_source_changed_cb),
|
|
||||||
sources);
|
|
||||||
sources->priv->source_removed_id = g_signal_connect (sources->priv->registry,
|
|
||||||
"source-removed",
|
|
||||||
G_CALLBACK (calendar_sources_registry_source_removed_cb),
|
|
||||||
sources);
|
|
||||||
|
|
||||||
sources->priv->appointment_sources.source_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
|
sources->priv->appointment_sources.source_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
|
||||||
sources->priv->appointment_sources.sources = sources;
|
sources->priv->appointment_sources.sources = sources;
|
||||||
sources->priv->appointment_sources.changed_signal = signals [APPOINTMENT_SOURCES_CHANGED];
|
sources->priv->appointment_sources.changed_signal = signals [APPOINTMENT_SOURCES_CHANGED];
|
||||||
sources->priv->appointment_sources.clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
|
|
||||||
(GEqualFunc) e_source_equal,
|
|
||||||
(GDestroyNotify) g_object_unref,
|
|
||||||
(GDestroyNotify) client_data_free);
|
|
||||||
sources->priv->appointment_sources.timeout_id = 0;
|
sources->priv->appointment_sources.timeout_id = 0;
|
||||||
|
|
||||||
sources->priv->task_sources.source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
|
sources->priv->task_sources.source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
|
||||||
sources->priv->task_sources.sources = sources;
|
sources->priv->task_sources.sources = sources;
|
||||||
sources->priv->task_sources.changed_signal = signals [TASK_SOURCES_CHANGED];
|
sources->priv->task_sources.changed_signal = signals [TASK_SOURCES_CHANGED];
|
||||||
sources->priv->task_sources.clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
|
|
||||||
(GEqualFunc) e_source_equal,
|
|
||||||
(GDestroyNotify) g_object_unref,
|
|
||||||
(GDestroyNotify) client_data_free);
|
|
||||||
sources->priv->task_sources.timeout_id = 0;
|
sources->priv->task_sources.timeout_id = 0;
|
||||||
|
|
||||||
|
sources->priv->gconf_client = gconf_client_get_default ();
|
||||||
|
sources->priv->settings = g_settings_new (CALENDAR_SELECTED_SOURCES_SCHEMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -229,9 +195,37 @@ calendar_sources_finalize_source_data (CalendarSources *sources,
|
|||||||
{
|
{
|
||||||
if (source_data->loaded)
|
if (source_data->loaded)
|
||||||
{
|
{
|
||||||
g_hash_table_destroy (source_data->clients);
|
GSList *l;
|
||||||
|
|
||||||
|
if (source_data->selected_sources_handler_id)
|
||||||
|
{
|
||||||
|
g_signal_handler_disconnect (sources->priv->settings,
|
||||||
|
source_data->selected_sources_handler_id);
|
||||||
|
source_data->selected_sources_handler_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = source_data->clients; l; l = l->next)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
|
||||||
|
G_CALLBACK (backend_died_cb),
|
||||||
|
source_data);
|
||||||
|
g_object_unref (l->data);
|
||||||
|
}
|
||||||
|
g_slist_free (source_data->clients);
|
||||||
source_data->clients = NULL;
|
source_data->clients = NULL;
|
||||||
|
|
||||||
|
if (source_data->esource_list)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (source_data->esource_list,
|
||||||
|
G_CALLBACK (calendar_sources_esource_list_changed),
|
||||||
|
source_data);
|
||||||
|
g_object_unref (source_data->esource_list);
|
||||||
|
}
|
||||||
|
source_data->esource_list = NULL;
|
||||||
|
|
||||||
|
g_strfreev (source_data->selected_sources);
|
||||||
|
source_data->selected_sources = NULL;
|
||||||
|
|
||||||
if (source_data->timeout_id != 0)
|
if (source_data->timeout_id != 0)
|
||||||
{
|
{
|
||||||
g_source_remove (source_data->timeout_id);
|
g_source_remove (source_data->timeout_id);
|
||||||
@@ -247,21 +241,17 @@ calendar_sources_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
CalendarSources *sources = CALENDAR_SOURCES (object);
|
CalendarSources *sources = CALENDAR_SOURCES (object);
|
||||||
|
|
||||||
if (sources->priv->registry)
|
|
||||||
{
|
|
||||||
g_signal_handler_disconnect (sources->priv->registry,
|
|
||||||
sources->priv->source_added_id);
|
|
||||||
g_signal_handler_disconnect (sources->priv->registry,
|
|
||||||
sources->priv->source_changed_id);
|
|
||||||
g_signal_handler_disconnect (sources->priv->registry,
|
|
||||||
sources->priv->source_removed_id);
|
|
||||||
g_object_unref (sources->priv->registry);
|
|
||||||
}
|
|
||||||
sources->priv->registry = NULL;
|
|
||||||
|
|
||||||
calendar_sources_finalize_source_data (sources, &sources->priv->appointment_sources);
|
calendar_sources_finalize_source_data (sources, &sources->priv->appointment_sources);
|
||||||
calendar_sources_finalize_source_data (sources, &sources->priv->task_sources);
|
calendar_sources_finalize_source_data (sources, &sources->priv->task_sources);
|
||||||
|
|
||||||
|
if (sources->priv->gconf_client)
|
||||||
|
g_object_unref (sources->priv->gconf_client);
|
||||||
|
sources->priv->gconf_client = NULL;
|
||||||
|
|
||||||
|
if (sources->priv->settings)
|
||||||
|
g_object_unref (sources->priv->settings);
|
||||||
|
sources->priv->settings = NULL;
|
||||||
|
|
||||||
if (G_OBJECT_CLASS (parent_class)->finalize)
|
if (G_OBJECT_CLASS (parent_class)->finalize)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -281,72 +271,133 @@ calendar_sources_get (void)
|
|||||||
return calendar_sources_singleton;
|
return calendar_sources_singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The clients are just created here but not loaded */
|
static gboolean
|
||||||
static void
|
is_source_selected (ESource *esource,
|
||||||
create_client_for_source (ESource *source,
|
char **selected_sources)
|
||||||
ECalClientSourceType source_type,
|
|
||||||
CalendarSourceData *source_data)
|
|
||||||
{
|
{
|
||||||
ClientData *data;
|
const char *uid;
|
||||||
ECalClient *client;
|
char **source;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
client = g_hash_table_lookup (source_data->clients, source);
|
uid = e_source_peek_uid (esource);
|
||||||
g_return_if_fail (client == NULL);
|
|
||||||
|
|
||||||
client = e_cal_client_new (source, source_type, &error);
|
for (source = selected_sources; *source; source++)
|
||||||
if (!client)
|
|
||||||
{
|
{
|
||||||
g_warning ("Could not load source '%s': %s",
|
if (!strcmp (*source, uid))
|
||||||
e_source_get_uid (source),
|
return TRUE;
|
||||||
error->message);
|
|
||||||
g_clear_error(&error);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data = g_slice_new0 (ClientData);
|
return FALSE;
|
||||||
data->client = client; /* takes ownership */
|
}
|
||||||
data->backend_died_id = g_signal_connect (client,
|
|
||||||
"backend-died",
|
|
||||||
G_CALLBACK (backend_died_cb),
|
|
||||||
source_data);
|
|
||||||
|
|
||||||
g_hash_table_insert (source_data->clients, g_object_ref (source), data);
|
/* The clients are just created here but not loaded */
|
||||||
|
static ECalClient *
|
||||||
|
get_ecal_from_source (ESource *esource,
|
||||||
|
ECalClientSourceType source_type,
|
||||||
|
GSList *existing_clients)
|
||||||
|
{
|
||||||
|
ECalClient *retval;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (existing_clients)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
for (l = existing_clients; l; l = l->next)
|
||||||
|
{
|
||||||
|
EClient *client = E_CLIENT (l->data);
|
||||||
|
|
||||||
|
if (e_source_equal (esource, e_client_get_source (client)))
|
||||||
|
{
|
||||||
|
dprintf (" load_esource: found existing source ... returning that\n");
|
||||||
|
|
||||||
|
return g_object_ref (client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = e_cal_client_new (esource, source_type, &error);
|
||||||
|
if (!retval)
|
||||||
|
{
|
||||||
|
g_warning ("Could not load source '%s' from '%s': %s",
|
||||||
|
e_source_peek_name (esource),
|
||||||
|
e_source_peek_relative_uri (esource),
|
||||||
|
error->message);
|
||||||
|
g_clear_error(&error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_connect (retval, "authenticate",
|
||||||
|
G_CALLBACK (e_client_utils_authenticate_handler), NULL);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* - Order doesn't matter
|
||||||
|
* - Can just compare object pointers since we
|
||||||
|
* re-use client connections
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
compare_ecal_lists (GSList *a,
|
||||||
|
GSList *b)
|
||||||
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
if (g_slist_length (a) != g_slist_length (b))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (l = a; l; l = l->next)
|
||||||
|
{
|
||||||
|
if (!g_slist_find (b, l->data))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
debug_dump_ecal_list (GHashTable *clients)
|
debug_dump_selected_sources (char **selected_sources)
|
||||||
{
|
{
|
||||||
#ifdef CALENDAR_ENABLE_DEBUG
|
#ifdef CALENDAR_ENABLE_DEBUG
|
||||||
GList *list, *link;
|
char **source;
|
||||||
|
|
||||||
|
dprintf ("Selected sources:\n");
|
||||||
|
for (source = selected_sources; *source; source++)
|
||||||
|
{
|
||||||
|
dprintf (" %s\n", *source);
|
||||||
|
}
|
||||||
|
dprintf ("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
debug_dump_ecal_list (GSList *ecal_list)
|
||||||
|
{
|
||||||
|
#ifdef CALENDAR_ENABLE_DEBUG
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
dprintf ("Loaded clients:\n");
|
dprintf ("Loaded clients:\n");
|
||||||
list = g_hash_table_get_keys (clients);
|
for (l = ecal_list; l; l = l->next)
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
|
||||||
{
|
{
|
||||||
ESource *source = E_SOURCE (link->data);
|
EClient *client = l->data;
|
||||||
|
ESource *source = e_client_get_source (client);
|
||||||
|
|
||||||
dprintf (" %s %s\n",
|
dprintf (" %s %s %s\n",
|
||||||
e_source_get_uid (source),
|
e_source_peek_uid (source),
|
||||||
e_source_get_display_name (source));
|
e_source_peek_name (source),
|
||||||
|
e_client_get_uri (client));
|
||||||
}
|
}
|
||||||
g_list_free (list);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_load_esource_list (ESourceRegistry *registry,
|
calendar_sources_load_esource_list (CalendarSourceData *source_data);
|
||||||
CalendarSourceData *source_data);
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
backend_restart (gpointer data)
|
backend_restart (gpointer data)
|
||||||
{
|
{
|
||||||
CalendarSourceData *source_data = data;
|
CalendarSourceData *source_data = data;
|
||||||
ESourceRegistry *registry;
|
|
||||||
|
|
||||||
registry = source_data->sources->priv->registry;
|
calendar_sources_load_esource_list (source_data);
|
||||||
calendar_sources_load_esource_list (registry, source_data);
|
|
||||||
g_signal_emit (source_data->sources, source_data->changed_signal, 0);
|
|
||||||
|
|
||||||
source_data->timeout_id = 0;
|
source_data->timeout_id = 0;
|
||||||
|
|
||||||
@@ -356,13 +407,16 @@ backend_restart (gpointer data)
|
|||||||
static void
|
static void
|
||||||
backend_died_cb (EClient *client, CalendarSourceData *source_data)
|
backend_died_cb (EClient *client, CalendarSourceData *source_data)
|
||||||
{
|
{
|
||||||
ESource *source;
|
const char *uristr;
|
||||||
const char *display_name;
|
|
||||||
|
|
||||||
source = e_client_get_source (client);
|
source_data->clients = g_slist_remove (source_data->clients, client);
|
||||||
display_name = e_source_get_display_name (source);
|
if (g_slist_length (source_data->clients) < 1)
|
||||||
g_warning ("The calendar backend for '%s' has crashed.", display_name);
|
{
|
||||||
g_hash_table_remove (source_data->clients, source);
|
g_slist_free (source_data->clients);
|
||||||
|
source_data->clients = NULL;
|
||||||
|
}
|
||||||
|
uristr = e_client_get_uri (client);
|
||||||
|
g_warning ("The calendar backend for %s has crashed.", uristr);
|
||||||
|
|
||||||
if (source_data->timeout_id != 0)
|
if (source_data->timeout_id != 0)
|
||||||
{
|
{
|
||||||
@@ -375,162 +429,169 @@ backend_died_cb (EClient *client, CalendarSourceData *source_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_load_esource_list (ESourceRegistry *registry,
|
calendar_sources_load_esource_list (CalendarSourceData *source_data)
|
||||||
CalendarSourceData *source_data)
|
|
||||||
{
|
{
|
||||||
GList *list, *link;
|
GSList *clients = NULL;
|
||||||
const gchar *extension_name;
|
GSList *groups, *l;
|
||||||
|
gboolean emit_signal = FALSE;
|
||||||
|
|
||||||
switch (source_data->source_type)
|
g_return_if_fail (source_data->esource_list != NULL);
|
||||||
|
|
||||||
|
debug_dump_selected_sources (source_data->selected_sources);
|
||||||
|
|
||||||
|
dprintf ("Source groups:\n");
|
||||||
|
groups = e_source_list_peek_groups (source_data->esource_list);
|
||||||
|
for (l = groups; l; l = l->next)
|
||||||
{
|
{
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
|
GSList *esources, *s;
|
||||||
extension_name = E_SOURCE_EXTENSION_CALENDAR;
|
|
||||||
break;
|
dprintf (" %s\n", e_source_group_peek_uid (l->data));
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
|
dprintf (" sources:\n");
|
||||||
extension_name = E_SOURCE_EXTENSION_TASK_LIST;
|
|
||||||
break;
|
esources = e_source_group_peek_sources (l->data);
|
||||||
default:
|
for (s = esources; s; s = s->next)
|
||||||
g_return_if_reached ();
|
{
|
||||||
|
ESource *esource = E_SOURCE (s->data);
|
||||||
|
ECalClient *client;
|
||||||
|
|
||||||
|
dprintf (" type = '%s' uid = '%s', name = '%s', relative uri = '%s': \n",
|
||||||
|
source_data->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS ? "appointment" : "task",
|
||||||
|
e_source_peek_uid (esource),
|
||||||
|
e_source_peek_name (esource),
|
||||||
|
e_source_peek_relative_uri (esource));
|
||||||
|
|
||||||
|
if (is_source_selected (esource, source_data->selected_sources) &&
|
||||||
|
(client = get_ecal_from_source (esource, source_data->source_type, source_data->clients)))
|
||||||
|
{
|
||||||
|
clients = g_slist_prepend (clients, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dprintf ("\n");
|
||||||
|
|
||||||
|
if (source_data->loaded &&
|
||||||
|
!compare_ecal_lists (source_data->clients, clients))
|
||||||
|
emit_signal = TRUE;
|
||||||
|
|
||||||
|
for (l = source_data->clients; l; l = l->next)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (l->data),
|
||||||
|
G_CALLBACK (backend_died_cb),
|
||||||
|
source_data);
|
||||||
|
|
||||||
|
g_object_unref (l->data);
|
||||||
|
}
|
||||||
|
g_slist_free (source_data->clients);
|
||||||
|
source_data->clients = g_slist_reverse (clients);
|
||||||
|
|
||||||
|
/* connect to backend_died after we disconnected the previous signal
|
||||||
|
* handlers. If we do it before, we'll lose some handlers (for clients that
|
||||||
|
* were already there before) */
|
||||||
|
for (l = source_data->clients; l; l = l->next)
|
||||||
|
{
|
||||||
|
g_signal_connect (G_OBJECT (l->data), "backend-died",
|
||||||
|
G_CALLBACK (backend_died_cb), source_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
list = e_source_registry_list_sources (registry, extension_name);
|
if (emit_signal)
|
||||||
|
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
|
||||||
{
|
{
|
||||||
ESource *source = E_SOURCE (link->data);
|
dprintf ("Emitting %s-sources-changed signal\n",
|
||||||
ESourceSelectable *extension;
|
source_data->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS ? "appointment" : "task");
|
||||||
gboolean show_source;
|
g_signal_emit (source_data->sources, source_data->changed_signal, 0);
|
||||||
|
|
||||||
extension = e_source_get_extension (source, extension_name);
|
|
||||||
show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
|
|
||||||
|
|
||||||
if (show_source)
|
|
||||||
create_client_for_source (source, source_data->source_type, source_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_dump_ecal_list (source_data->clients);
|
debug_dump_ecal_list (source_data->clients);
|
||||||
|
|
||||||
g_list_free_full (list, g_object_unref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_registry_source_changed_cb (ESourceRegistry *registry,
|
calendar_sources_esource_list_changed (ESourceList *source_list,
|
||||||
ESource *source,
|
CalendarSourceData *source_data)
|
||||||
CalendarSources *sources)
|
|
||||||
{
|
{
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
|
dprintf ("ESourceList changed, reloading\n");
|
||||||
{
|
|
||||||
CalendarSourceData *source_data;
|
|
||||||
ESourceSelectable *extension;
|
|
||||||
gboolean have_client;
|
|
||||||
gboolean show_source;
|
|
||||||
|
|
||||||
source_data = &sources->priv->appointment_sources;
|
calendar_sources_load_esource_list (source_data);
|
||||||
extension = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
|
|
||||||
have_client = (g_hash_table_lookup (source_data->clients, source) != NULL);
|
|
||||||
show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
|
|
||||||
|
|
||||||
if (!show_source && have_client)
|
|
||||||
{
|
|
||||||
g_hash_table_remove (source_data->clients, source);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
if (show_source && !have_client)
|
|
||||||
{
|
|
||||||
create_client_for_source (source, source_data->source_type, source_data);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
|
|
||||||
{
|
|
||||||
CalendarSourceData *source_data;
|
|
||||||
ESourceSelectable *extension;
|
|
||||||
gboolean have_client;
|
|
||||||
gboolean show_source;
|
|
||||||
|
|
||||||
source_data = &sources->priv->task_sources;
|
|
||||||
extension = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
|
|
||||||
have_client = (g_hash_table_lookup (source_data->clients, source) != NULL);
|
|
||||||
show_source = e_source_get_enabled (source) && e_source_selectable_get_selected (extension);
|
|
||||||
|
|
||||||
if (!show_source && have_client)
|
|
||||||
{
|
|
||||||
g_hash_table_remove (source_data->clients, source);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
if (show_source && !have_client)
|
|
||||||
{
|
|
||||||
create_client_for_source (source, source_data->source_type, source_data);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calendar_sources_registry_source_removed_cb (ESourceRegistry *registry,
|
calendar_sources_selected_sources_notify (GSettings *settings,
|
||||||
ESource *source,
|
const gchar *key,
|
||||||
CalendarSources *sources)
|
CalendarSourceData *source_data)
|
||||||
{
|
{
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
|
dprintf ("Selected sources key (%s) changed, reloading\n", key);
|
||||||
{
|
|
||||||
CalendarSourceData *source_data;
|
|
||||||
|
|
||||||
source_data = &sources->priv->appointment_sources;
|
g_strfreev (source_data->selected_sources);
|
||||||
g_hash_table_remove (source_data->clients, source);
|
source_data->selected_sources = g_settings_get_strv (settings, key);
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
|
calendar_sources_load_esource_list (source_data);
|
||||||
{
|
|
||||||
CalendarSourceData *source_data;
|
|
||||||
|
|
||||||
source_data = &sources->priv->task_sources;
|
|
||||||
g_hash_table_remove (source_data->clients, source);
|
|
||||||
g_signal_emit (sources, source_data->changed_signal, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *
|
static void
|
||||||
calendar_sources_get_appointment_clients (CalendarSources *sources)
|
calendar_sources_load_sources (CalendarSources *sources,
|
||||||
|
CalendarSourceData *source_data,
|
||||||
|
const char *sources_key,
|
||||||
|
const char *selected_sources_key)
|
||||||
{
|
{
|
||||||
GList *list, *link;
|
GConfClient *gconf_client;
|
||||||
|
GSettings *settings;
|
||||||
|
char *signal_name;
|
||||||
|
|
||||||
|
dprintf ("---------------------------\n");
|
||||||
|
dprintf ("Loading sources:\n");
|
||||||
|
dprintf (" sources_key: %s\n", sources_key);
|
||||||
|
dprintf (" selected_sources_key: %s\n", selected_sources_key);
|
||||||
|
|
||||||
|
gconf_client = sources->priv->gconf_client;
|
||||||
|
settings = sources->priv->settings;
|
||||||
|
|
||||||
|
source_data->selected_sources = g_settings_get_strv (settings, selected_sources_key);
|
||||||
|
|
||||||
|
signal_name = g_strconcat ("changed::", selected_sources_key, NULL);
|
||||||
|
source_data->selected_sources_handler_id =
|
||||||
|
g_signal_connect (settings, signal_name,
|
||||||
|
G_CALLBACK (calendar_sources_selected_sources_notify), source_data);
|
||||||
|
g_free (signal_name);
|
||||||
|
|
||||||
|
source_data->esource_list = e_source_list_new_for_gconf (gconf_client, sources_key);
|
||||||
|
g_signal_connect (source_data->esource_list, "changed",
|
||||||
|
G_CALLBACK (calendar_sources_esource_list_changed),
|
||||||
|
source_data);
|
||||||
|
|
||||||
|
calendar_sources_load_esource_list (source_data);
|
||||||
|
|
||||||
|
source_data->loaded = TRUE;
|
||||||
|
|
||||||
|
dprintf ("---------------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
GSList *
|
||||||
|
calendar_sources_get_appointment_sources (CalendarSources *sources)
|
||||||
|
{
|
||||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
||||||
|
|
||||||
if (!sources->priv->appointment_sources.loaded)
|
if (!sources->priv->appointment_sources.loaded)
|
||||||
{
|
{
|
||||||
calendar_sources_load_esource_list (sources->priv->registry,
|
calendar_sources_load_sources (sources,
|
||||||
&sources->priv->appointment_sources);
|
&sources->priv->appointment_sources,
|
||||||
sources->priv->appointment_sources.loaded = TRUE;
|
CALENDAR_SOURCES_APPOINTMENT_SOURCES_KEY,
|
||||||
|
CALENDAR_SOURCES_SELECTED_APPOINTMENT_SOURCES_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
list = g_hash_table_get_values (sources->priv->appointment_sources.clients);
|
return sources->priv->appointment_sources.clients;
|
||||||
|
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
|
||||||
link->data = ((ClientData *) link->data)->client;
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GList *
|
GSList *
|
||||||
calendar_sources_get_task_clients (CalendarSources *sources)
|
calendar_sources_get_task_sources (CalendarSources *sources)
|
||||||
{
|
{
|
||||||
GList *list, *link;
|
|
||||||
|
|
||||||
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
g_return_val_if_fail (CALENDAR_IS_SOURCES (sources), NULL);
|
||||||
|
|
||||||
if (!sources->priv->task_sources.loaded)
|
if (!sources->priv->task_sources.loaded)
|
||||||
{
|
{
|
||||||
calendar_sources_load_esource_list (sources->priv->registry,
|
calendar_sources_load_sources (sources,
|
||||||
&sources->priv->task_sources);
|
&sources->priv->task_sources,
|
||||||
sources->priv->task_sources.loaded = TRUE;
|
CALENDAR_SOURCES_TASK_SOURCES_KEY,
|
||||||
|
CALENDAR_SOURCES_SELECTED_TASK_SOURCES_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
list = g_hash_table_get_values (sources->priv->task_sources.clients);
|
return sources->priv->task_sources.clients;
|
||||||
|
|
||||||
for (link = list; link != NULL; link = g_list_next (link))
|
|
||||||
link->data = ((ClientData *) link->data)->client;
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ struct _CalendarSourcesClass
|
|||||||
|
|
||||||
GType calendar_sources_get_type (void) G_GNUC_CONST;
|
GType calendar_sources_get_type (void) G_GNUC_CONST;
|
||||||
CalendarSources *calendar_sources_get (void);
|
CalendarSources *calendar_sources_get (void);
|
||||||
GList *calendar_sources_get_appointment_clients (CalendarSources *sources);
|
GSList *calendar_sources_get_appointment_sources (CalendarSources *sources);
|
||||||
GList *calendar_sources_get_task_clients (CalendarSources *sources);
|
GSList *calendar_sources_get_task_sources (CalendarSources *sources);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,13 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#define HANDLE_LIBICAL_MEMORY
|
#define HANDLE_LIBICAL_MEMORY
|
||||||
#include <libecal/libecal.h>
|
#include <libecal/e-cal-client.h>
|
||||||
|
#include <libecal/e-cal-time-util.h>
|
||||||
|
#include <libecal/e-cal-recur.h>
|
||||||
|
#include <libecal/e-cal-system-timezone.h>
|
||||||
|
|
||||||
|
#define CALENDAR_CONFIG_PREFIX "/apps/evolution/calendar"
|
||||||
|
#define CALENDAR_CONFIG_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/timezone"
|
||||||
|
|
||||||
#include "calendar-sources.h"
|
#include "calendar-sources.h"
|
||||||
|
|
||||||
@@ -84,7 +90,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
char *uid;
|
char *uid;
|
||||||
char *rid;
|
char *rid;
|
||||||
char *backend_name;
|
char *uri;
|
||||||
char *summary;
|
char *summary;
|
||||||
char *description;
|
char *description;
|
||||||
char *color_string;
|
char *color_string;
|
||||||
@@ -247,60 +253,37 @@ static char *
|
|||||||
get_source_color (ECalClient *esource)
|
get_source_color (ECalClient *esource)
|
||||||
{
|
{
|
||||||
ESource *source;
|
ESource *source;
|
||||||
ECalClientSourceType source_type;
|
|
||||||
ESourceSelectable *extension;
|
|
||||||
const gchar *extension_name;
|
|
||||||
|
|
||||||
g_return_val_if_fail (E_IS_CAL_CLIENT (esource), NULL);
|
g_return_val_if_fail (E_IS_CAL_CLIENT (esource), NULL);
|
||||||
|
|
||||||
source = e_client_get_source (E_CLIENT (esource));
|
source = e_client_get_source (E_CLIENT (esource));
|
||||||
source_type = e_cal_client_get_source_type (esource);
|
|
||||||
|
|
||||||
switch (source_type)
|
return g_strdup (e_source_peek_color_spec (source));
|
||||||
{
|
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
|
|
||||||
extension_name = E_SOURCE_EXTENSION_CALENDAR;
|
|
||||||
break;
|
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
|
|
||||||
extension_name = E_SOURCE_EXTENSION_TASK_LIST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_return_val_if_reached (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
extension = e_source_get_extension (source, extension_name);
|
|
||||||
|
|
||||||
return e_source_selectable_dup_color (extension);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
get_source_backend_name (ECalClient *esource)
|
get_source_uri (ECalClient *esource)
|
||||||
{
|
{
|
||||||
ESource *source;
|
ESource *source;
|
||||||
ECalClientSourceType source_type;
|
gchar *string;
|
||||||
ESourceBackend *extension;
|
gchar **list;
|
||||||
const gchar *extension_name;
|
|
||||||
|
|
||||||
g_return_val_if_fail (E_IS_CAL_CLIENT (esource), NULL);
|
g_return_val_if_fail (E_IS_CAL_CLIENT (esource), NULL);
|
||||||
|
|
||||||
source = e_client_get_source (E_CLIENT (esource));
|
source = e_client_get_source (E_CLIENT (esource));
|
||||||
source_type = e_cal_client_get_source_type (esource);
|
string = g_strdup (e_source_get_uri (source));
|
||||||
|
if (string) {
|
||||||
|
list = g_strsplit (string, ":", 2);
|
||||||
|
g_free (string);
|
||||||
|
|
||||||
switch (source_type)
|
if (list[0]) {
|
||||||
{
|
string = g_strdup (list[0]);
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
|
g_strfreev (list);
|
||||||
extension_name = E_SOURCE_EXTENSION_CALENDAR;
|
return string;
|
||||||
break;
|
}
|
||||||
case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
|
g_strfreev (list);
|
||||||
extension_name = E_SOURCE_EXTENSION_TASK_LIST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_return_val_if_reached (NULL);
|
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
extension = e_source_get_extension (source, extension_name);
|
|
||||||
|
|
||||||
return e_source_backend_dup_backend_name (extension);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@@ -331,7 +314,7 @@ calendar_appointment_equal (CalendarAppointment *a,
|
|||||||
|
|
||||||
return
|
return
|
||||||
null_safe_strcmp (a->uid, b->uid) == 0 &&
|
null_safe_strcmp (a->uid, b->uid) == 0 &&
|
||||||
null_safe_strcmp (a->backend_name, b->backend_name) == 0 &&
|
null_safe_strcmp (a->uri, b->uri) == 0 &&
|
||||||
null_safe_strcmp (a->summary, b->summary) == 0 &&
|
null_safe_strcmp (a->summary, b->summary) == 0 &&
|
||||||
null_safe_strcmp (a->description, b->description) == 0 &&
|
null_safe_strcmp (a->description, b->description) == 0 &&
|
||||||
null_safe_strcmp (a->color_string, b->color_string) == 0 &&
|
null_safe_strcmp (a->color_string, b->color_string) == 0 &&
|
||||||
@@ -356,8 +339,8 @@ calendar_appointment_free (CalendarAppointment *appointment)
|
|||||||
g_free (appointment->rid);
|
g_free (appointment->rid);
|
||||||
appointment->rid = NULL;
|
appointment->rid = NULL;
|
||||||
|
|
||||||
g_free (appointment->backend_name);
|
g_free (appointment->uri);
|
||||||
appointment->backend_name = NULL;
|
appointment->uri = NULL;
|
||||||
|
|
||||||
g_free (appointment->summary);
|
g_free (appointment->summary);
|
||||||
appointment->summary = NULL;
|
appointment->summary = NULL;
|
||||||
@@ -380,7 +363,7 @@ calendar_appointment_init (CalendarAppointment *appointment,
|
|||||||
{
|
{
|
||||||
appointment->uid = get_ical_uid (ical);
|
appointment->uid = get_ical_uid (ical);
|
||||||
appointment->rid = get_ical_rid (ical);
|
appointment->rid = get_ical_rid (ical);
|
||||||
appointment->backend_name = get_source_backend_name (cal);
|
appointment->uri = get_source_uri (cal);
|
||||||
appointment->summary = get_ical_summary (ical);
|
appointment->summary = get_ical_summary (ical);
|
||||||
appointment->description = get_ical_description (ical);
|
appointment->description = get_ical_description (ical);
|
||||||
appointment->color_string = get_source_color (cal);
|
appointment->color_string = get_source_color (cal);
|
||||||
@@ -484,6 +467,9 @@ struct _App
|
|||||||
CalendarSources *sources;
|
CalendarSources *sources;
|
||||||
gulong sources_signal_id;
|
gulong sources_signal_id;
|
||||||
|
|
||||||
|
guint zone_listener;
|
||||||
|
GConfClient *gconf_client;
|
||||||
|
|
||||||
/* hash from uid to CalendarAppointment objects */
|
/* hash from uid to CalendarAppointment objects */
|
||||||
GHashTable *appointments;
|
GHashTable *appointments;
|
||||||
|
|
||||||
@@ -599,8 +585,8 @@ on_objects_removed (ECalClientView *view,
|
|||||||
static void
|
static void
|
||||||
app_load_events (App *app)
|
app_load_events (App *app)
|
||||||
{
|
{
|
||||||
GList *clients;
|
GSList *sources;
|
||||||
GList *l;
|
GSList *l;
|
||||||
GList *ll;
|
GList *ll;
|
||||||
gchar *since_iso8601;
|
gchar *since_iso8601;
|
||||||
gchar *until_iso8601;
|
gchar *until_iso8601;
|
||||||
@@ -630,8 +616,8 @@ app_load_events (App *app)
|
|||||||
since_iso8601,
|
since_iso8601,
|
||||||
until_iso8601);
|
until_iso8601);
|
||||||
|
|
||||||
clients = calendar_sources_get_appointment_clients (app->sources);
|
sources = calendar_sources_get_appointment_sources (app->sources);
|
||||||
for (l = clients; l != NULL; l = l->next)
|
for (l = sources; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
ECalClient *cal = E_CAL_CLIENT (l->data);
|
ECalClient *cal = E_CAL_CLIENT (l->data);
|
||||||
GError *error;
|
GError *error;
|
||||||
@@ -644,9 +630,8 @@ app_load_events (App *app)
|
|||||||
error = NULL;
|
error = NULL;
|
||||||
if (!e_client_open_sync (E_CLIENT (cal), TRUE, NULL, &error))
|
if (!e_client_open_sync (E_CLIENT (cal), TRUE, NULL, &error))
|
||||||
{
|
{
|
||||||
ESource *source = e_client_get_source (E_CLIENT (cal));
|
|
||||||
g_warning ("Error opening calendar %s: %s\n",
|
g_warning ("Error opening calendar %s: %s\n",
|
||||||
e_source_get_uid (source), error->message);
|
e_client_get_uri (E_CLIENT (cal)), error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -663,9 +648,8 @@ app_load_events (App *app)
|
|||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
&error))
|
&error))
|
||||||
{
|
{
|
||||||
ESource *source = e_client_get_source (E_CLIENT (cal));
|
|
||||||
g_warning ("Error querying calendar %s: %s\n",
|
g_warning ("Error querying calendar %s: %s\n",
|
||||||
e_source_get_uid (source), error->message);
|
e_client_get_uri (E_CLIENT (cal)), error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
g_free (query);
|
g_free (query);
|
||||||
continue;
|
continue;
|
||||||
@@ -721,7 +705,6 @@ app_load_events (App *app)
|
|||||||
|
|
||||||
g_free (query);
|
g_free (query);
|
||||||
}
|
}
|
||||||
g_list_free (clients);
|
|
||||||
g_free (since_iso8601);
|
g_free (since_iso8601);
|
||||||
g_free (until_iso8601);
|
g_free (until_iso8601);
|
||||||
app->cache_invalid = FALSE;
|
app->cache_invalid = FALSE;
|
||||||
|
|||||||
121
src/main.c
121
src/main.c
@@ -18,18 +18,15 @@
|
|||||||
#include <meta/main.h>
|
#include <meta/main.h>
|
||||||
#include <meta/meta-plugin.h>
|
#include <meta/meta-plugin.h>
|
||||||
#include <meta/prefs.h>
|
#include <meta/prefs.h>
|
||||||
#include <atk-bridge.h>
|
|
||||||
#include <telepathy-glib/debug.h>
|
#include <telepathy-glib/debug.h>
|
||||||
#include <telepathy-glib/debug-sender.h>
|
#include <telepathy-glib/debug-sender.h>
|
||||||
|
|
||||||
|
#include "shell-a11y.h"
|
||||||
#include "shell-global.h"
|
#include "shell-global.h"
|
||||||
#include "shell-global-private.h"
|
#include "shell-global-private.h"
|
||||||
#include "shell-js.h"
|
|
||||||
#include "shell-perf-log.h"
|
#include "shell-perf-log.h"
|
||||||
#include "st.h"
|
#include "st.h"
|
||||||
|
|
||||||
#include <jsapi.h>
|
|
||||||
|
|
||||||
extern GType gnome_shell_plugin_get_type (void);
|
extern GType gnome_shell_plugin_get_type (void);
|
||||||
|
|
||||||
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
|
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
|
||||||
@@ -38,7 +35,6 @@ extern GType gnome_shell_plugin_get_type (void);
|
|||||||
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
|
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
|
||||||
|
|
||||||
static gboolean is_gdm_mode = FALSE;
|
static gboolean is_gdm_mode = FALSE;
|
||||||
static char *session_mode = NULL;
|
|
||||||
|
|
||||||
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
||||||
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
|
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
|
||||||
@@ -177,18 +173,6 @@ shell_prefs_init (void)
|
|||||||
OVERRIDES_SCHEMA);
|
OVERRIDES_SCHEMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
shell_introspection_init (void)
|
|
||||||
{
|
|
||||||
|
|
||||||
g_irepository_prepend_search_path (MUTTER_TYPELIB_DIR);
|
|
||||||
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
|
||||||
#if HAVE_BLUETOOTH
|
|
||||||
g_irepository_prepend_search_path (BLUETOOTH_DIR);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
malloc_statistics_callback (ShellPerfLog *perf_log,
|
malloc_statistics_callback (ShellPerfLog *perf_log,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
@@ -235,20 +219,6 @@ shell_perf_log_init (void)
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
shell_a11y_init (void)
|
|
||||||
{
|
|
||||||
if (clutter_get_accessibility_enabled () == FALSE)
|
|
||||||
{
|
|
||||||
g_warning ("Accessibility: clutter has no accessibility enabled"
|
|
||||||
" skipping the atk-bridge load");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
atk_bridge_adaptor_init (NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
default_log_handler (const char *log_domain,
|
default_log_handler (const char *log_domain,
|
||||||
GLogLevelFlags log_level,
|
GLogLevelFlags log_level,
|
||||||
@@ -268,48 +238,6 @@ default_log_handler (const char *log_domain,
|
|||||||
g_log_default_handler (log_domain, log_level, message, data);
|
g_log_default_handler (log_domain, log_level, message, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
shut_up (const char *domain,
|
|
||||||
GLogLevelFlags level,
|
|
||||||
const char *message,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
list_modes (const char *option_name,
|
|
||||||
const char *value,
|
|
||||||
gpointer data,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
ShellGlobal *global;
|
|
||||||
GjsContext *context;
|
|
||||||
const char *script;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
/* Many of our imports require global to be set, so rather than
|
|
||||||
* tayloring our imports carefully here to avoid that dependency,
|
|
||||||
* we just set it.
|
|
||||||
* ShellGlobal has some GTK+ dependencies, so initialize GTK+; we
|
|
||||||
* don't really care if it fails though (e.g. when running from a tty),
|
|
||||||
* so we mute all warnings */
|
|
||||||
g_log_set_default_handler (shut_up, NULL);
|
|
||||||
gtk_init_check (NULL, NULL);
|
|
||||||
|
|
||||||
_shell_global_init (NULL);
|
|
||||||
global = shell_global_get ();
|
|
||||||
context = _shell_global_get_gjs_context (global);
|
|
||||||
|
|
||||||
shell_introspection_init ();
|
|
||||||
|
|
||||||
script = "imports.ui.environment.init();"
|
|
||||||
"imports.ui.sessionMode.listModes();";
|
|
||||||
if (!gjs_context_eval (context, script, -1, "<main>", &status, NULL))
|
|
||||||
g_message ("Retrieving list of available modes failed.");
|
|
||||||
|
|
||||||
exit (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
print_version (const gchar *option_name,
|
print_version (const gchar *option_name,
|
||||||
const gchar *value,
|
const gchar *value,
|
||||||
@@ -328,23 +256,11 @@ GOptionEntry gnome_shell_options[] = {
|
|||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"gdm-mode", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
|
"gdm-mode", 0, 0, G_OPTION_ARG_NONE,
|
||||||
&is_gdm_mode,
|
&is_gdm_mode,
|
||||||
N_("Mode used by GDM for login screen"),
|
N_("Mode used by GDM for login screen"),
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"mode", 0, 0, G_OPTION_ARG_STRING,
|
|
||||||
&session_mode,
|
|
||||||
N_("Use a specific mode, e.g. \"gdm\" for login screen"),
|
|
||||||
"MODE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"list-modes", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
|
||||||
list_modes,
|
|
||||||
N_("List possible modes"),
|
|
||||||
NULL
|
|
||||||
},
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -353,6 +269,7 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
GOptionContext *ctx;
|
GOptionContext *ctx;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
ShellSessionType session_type;
|
||||||
int ecode;
|
int ecode;
|
||||||
TpDebugSender *sender;
|
TpDebugSender *sender;
|
||||||
|
|
||||||
@@ -372,11 +289,13 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
g_option_context_free (ctx);
|
g_option_context_free (ctx);
|
||||||
|
|
||||||
meta_plugin_manager_set_plugin_type (gnome_shell_plugin_get_type ());
|
meta_plugin_type_register (gnome_shell_plugin_get_type ());
|
||||||
|
|
||||||
/* Prevent meta_init() from causing gtk to load gail and at-bridge */
|
/* Prevent meta_init() from causing gtk to load gail and at-bridge */
|
||||||
|
g_setenv ("NO_GAIL", "1", TRUE);
|
||||||
g_setenv ("NO_AT_BRIDGE", "1", TRUE);
|
g_setenv ("NO_AT_BRIDGE", "1", TRUE);
|
||||||
meta_init ();
|
meta_init ();
|
||||||
|
g_unsetenv ("NO_GAIL");
|
||||||
g_unsetenv ("NO_AT_BRIDGE");
|
g_unsetenv ("NO_AT_BRIDGE");
|
||||||
|
|
||||||
/* FIXME: Add gjs API to set this stuff and don't depend on the
|
/* FIXME: Add gjs API to set this stuff and don't depend on the
|
||||||
@@ -389,7 +308,11 @@ main (int argc, char **argv)
|
|||||||
shell_a11y_init ();
|
shell_a11y_init ();
|
||||||
shell_perf_log_init ();
|
shell_perf_log_init ();
|
||||||
shell_prefs_init ();
|
shell_prefs_init ();
|
||||||
shell_introspection_init ();
|
|
||||||
|
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
|
||||||
|
#if HAVE_BLUETOOTH
|
||||||
|
g_irepository_prepend_search_path (BLUETOOTH_DIR);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Turn on telepathy-glib debugging but filter it out in
|
/* Turn on telepathy-glib debugging but filter it out in
|
||||||
* default_log_handler. This handler also exposes all the logs over D-Bus
|
* default_log_handler. This handler also exposes all the logs over D-Bus
|
||||||
@@ -400,10 +323,12 @@ main (int argc, char **argv)
|
|||||||
g_log_set_default_handler (default_log_handler, sender);
|
g_log_set_default_handler (default_log_handler, sender);
|
||||||
|
|
||||||
/* Initialize the global object */
|
/* Initialize the global object */
|
||||||
if (session_mode == NULL)
|
if (is_gdm_mode)
|
||||||
session_mode = is_gdm_mode ? "gdm" : "user";
|
session_type = SHELL_SESSION_GDM;
|
||||||
|
else
|
||||||
|
session_type = SHELL_SESSION_USER;
|
||||||
|
|
||||||
_shell_global_init ("session-mode", session_mode, NULL);
|
_shell_global_init ("session-type", session_type, NULL);
|
||||||
|
|
||||||
ecode = meta_run ();
|
ecode = meta_run ();
|
||||||
|
|
||||||
@@ -417,17 +342,3 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
return ecode;
|
return ecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HACK:
|
|
||||||
Add a dummy function that calls into libgnome-shell-js.so to ensure it's
|
|
||||||
linked to /usr/bin/gnome-shell even when linking with --as-needed.
|
|
||||||
This function is never actually called.
|
|
||||||
https://bugzilla.gnome.org/show_bug.cgi?id=670477
|
|
||||||
*/
|
|
||||||
void _shell_link_to_shell_js (void);
|
|
||||||
|
|
||||||
void
|
|
||||||
_shell_link_to_shell_js (void)
|
|
||||||
{
|
|
||||||
shell_js_add_extension_importer (NULL, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -144,9 +144,6 @@ main(int argc, char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
gjs_context_gc (js_context);
|
|
||||||
gjs_context_gc (js_context);
|
|
||||||
|
|
||||||
g_free (script);
|
g_free (script);
|
||||||
exit (code);
|
exit (code);
|
||||||
}
|
}
|
||||||
|
|||||||
164
src/shell-a11y.c
Normal file
164
src/shell-a11y.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#include "shell-a11y.h"
|
||||||
|
|
||||||
|
#define INIT_METHOD "gnome_accessibility_module_init"
|
||||||
|
#define DESKTOP_SCHEMA "org.gnome.desktop.interface"
|
||||||
|
#define ACCESSIBILITY_ENABLED_KEY "toolkit-accessibility"
|
||||||
|
#define AT_SPI_SCHEMA "org.a11y.atspi"
|
||||||
|
#define ATK_BRIDGE_LOCATION_KEY "atk-bridge-location"
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
should_enable_a11y (void)
|
||||||
|
{
|
||||||
|
GSettings *desktop_settings = NULL;
|
||||||
|
gboolean value = FALSE;
|
||||||
|
|
||||||
|
desktop_settings = g_settings_new (DESKTOP_SCHEMA);
|
||||||
|
value = g_settings_get_boolean (desktop_settings, ACCESSIBILITY_ENABLED_KEY);
|
||||||
|
|
||||||
|
g_object_unref (desktop_settings);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
get_atk_bridge_path (void)
|
||||||
|
{
|
||||||
|
GSettings *atspi_settings = NULL;
|
||||||
|
GVariant *variant = NULL;
|
||||||
|
char *value = NULL;
|
||||||
|
const char * const *schemas = NULL;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
schemas = g_settings_list_schemas ();
|
||||||
|
|
||||||
|
for (i = 0; schemas [i]; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp (schemas[i], AT_SPI_SCHEMA))
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
g_warning ("Accessibility: %s schema not found. Are you sure that at-spi or"
|
||||||
|
" at-spi2 is installed on your system?", AT_SPI_SCHEMA);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
atspi_settings = g_settings_new (AT_SPI_SCHEMA);
|
||||||
|
variant = g_settings_get_value (atspi_settings, ATK_BRIDGE_LOCATION_KEY);
|
||||||
|
value = g_variant_dup_bytestring (variant, NULL);
|
||||||
|
g_variant_unref (variant);
|
||||||
|
g_object_unref (atspi_settings);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
a11y_invoke_module (const char *module_path)
|
||||||
|
{
|
||||||
|
GModule *handle;
|
||||||
|
void (*invoke_fn) (void);
|
||||||
|
|
||||||
|
if (!module_path)
|
||||||
|
{
|
||||||
|
g_warning ("Accessibility: invalid module path (NULL)");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(handle = g_module_open (module_path, 0)))
|
||||||
|
{
|
||||||
|
g_warning ("Accessibility: failed to load module '%s': '%s'",
|
||||||
|
module_path, g_module_error ());
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_module_symbol (handle, INIT_METHOD, (gpointer *)&invoke_fn))
|
||||||
|
{
|
||||||
|
g_warning ("Accessibility: error library '%s' does not include "
|
||||||
|
"method '%s' required for accessibility support",
|
||||||
|
module_path, INIT_METHOD);
|
||||||
|
g_module_close (handle);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
invoke_fn ();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It loads the atk-bridge if required. It checks:
|
||||||
|
* * If the proper gsetting key is set
|
||||||
|
* * If clutter has already enabled the accessibility
|
||||||
|
*
|
||||||
|
* You need to ensure that the atk-bridge was not loaded before this
|
||||||
|
* call, because in that case the application would be already
|
||||||
|
* registered on at-spi using the AtkUtil implementation on that
|
||||||
|
* moment (if any, although without anyone the application would
|
||||||
|
* crash). Anyway this is the reason of NO_AT_BRIDGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shell_a11y_init (void)
|
||||||
|
{
|
||||||
|
char *bridge_path = NULL;
|
||||||
|
|
||||||
|
if (!should_enable_a11y ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (clutter_get_accessibility_enabled () == FALSE)
|
||||||
|
{
|
||||||
|
g_warning ("Accessibility: clutter has no accessibility enabled"
|
||||||
|
" skipping the atk-bridge load");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge_path = get_atk_bridge_path ();
|
||||||
|
|
||||||
|
if (a11y_invoke_module (bridge_path) == FALSE)
|
||||||
|
{
|
||||||
|
g_warning ("Accessibility: error loading the atk-bridge. Although the"
|
||||||
|
" accessibility on the system is enabled and clutter"
|
||||||
|
" accessibility is also enabled, accessibility support on"
|
||||||
|
" GNOME Shell will not work");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: We avoid to load gail module, as gail-cally interaction is
|
||||||
|
* not fully supported right now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_free (bridge_path);
|
||||||
|
}
|
||||||
32
src/shell-a11y.h
Normal file
32
src/shell-a11y.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Igalia, S.L.
|
||||||
|
*
|
||||||
|
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SHELL_A11Y_H_
|
||||||
|
#define __SHELL_A11Y_H_
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void shell_a11y_init (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __SHELL_A11Y_H_ */
|
||||||
@@ -7,13 +7,18 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
#include <gio/gdesktopappinfo.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
#include <meta/display.h>
|
||||||
|
|
||||||
#include "shell-app-private.h"
|
#include "shell-app-private.h"
|
||||||
#include "shell-window-tracker-private.h"
|
#include "shell-window-tracker-private.h"
|
||||||
#include "shell-app-system-private.h"
|
#include "shell-app-system-private.h"
|
||||||
#include "shell-global.h"
|
#include "shell-global.h"
|
||||||
#include "shell-util.h"
|
#include "shell-util.h"
|
||||||
|
#include "st.h"
|
||||||
|
|
||||||
/* Vendor prefixes are something that can be preprended to a .desktop
|
/* Vendor prefixes are something that can be preprended to a .desktop
|
||||||
* file name. Undo this.
|
* file name. Undo this.
|
||||||
@@ -41,7 +46,6 @@ struct _ShellAppSystemPrivate {
|
|||||||
GMenuTree *apps_tree;
|
GMenuTree *apps_tree;
|
||||||
|
|
||||||
GHashTable *running_apps;
|
GHashTable *running_apps;
|
||||||
GHashTable *visible_id_to_app;
|
|
||||||
GHashTable *id_to_app;
|
GHashTable *id_to_app;
|
||||||
|
|
||||||
GSList *known_vendor_prefixes;
|
GSList *known_vendor_prefixes;
|
||||||
@@ -93,16 +97,14 @@ shell_app_system_init (ShellAppSystem *self)
|
|||||||
priv->id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal,
|
priv->id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
NULL,
|
NULL,
|
||||||
(GDestroyNotify)g_object_unref);
|
(GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
/* All the objects in this hash table are owned by id_to_app */
|
|
||||||
priv->visible_id_to_app = g_hash_table_new (g_str_hash, g_str_equal);
|
|
||||||
|
|
||||||
priv->setting_id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal,
|
priv->setting_id_to_app = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
NULL,
|
NULL,
|
||||||
(GDestroyNotify)g_object_unref);
|
(GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
/* We want to track NoDisplay apps, so we add INCLUDE_NODISPLAY. We'll
|
/* For now, we want to pick up Evince, Nautilus, etc. We'll
|
||||||
* filter NoDisplay apps out when showing them to the user. */
|
* handle NODISPLAY semantics at a higher level or investigate them
|
||||||
|
* case by case.
|
||||||
|
*/
|
||||||
priv->apps_tree = gmenu_tree_new ("applications.menu", GMENU_TREE_FLAGS_INCLUDE_NODISPLAY);
|
priv->apps_tree = gmenu_tree_new ("applications.menu", GMENU_TREE_FLAGS_INCLUDE_NODISPLAY);
|
||||||
g_signal_connect (priv->apps_tree, "changed", G_CALLBACK (on_apps_tree_changed_cb), self);
|
g_signal_connect (priv->apps_tree, "changed", G_CALLBACK (on_apps_tree_changed_cb), self);
|
||||||
|
|
||||||
@@ -124,10 +126,10 @@ shell_app_system_finalize (GObject *object)
|
|||||||
|
|
||||||
g_hash_table_destroy (priv->running_apps);
|
g_hash_table_destroy (priv->running_apps);
|
||||||
g_hash_table_destroy (priv->id_to_app);
|
g_hash_table_destroy (priv->id_to_app);
|
||||||
g_hash_table_destroy (priv->visible_id_to_app);
|
|
||||||
g_hash_table_destroy (priv->setting_id_to_app);
|
g_hash_table_destroy (priv->setting_id_to_app);
|
||||||
|
|
||||||
g_slist_free_full (priv->known_vendor_prefixes, g_free);
|
g_slist_foreach (priv->known_vendor_prefixes, (GFunc)g_free, NULL);
|
||||||
|
g_slist_free (priv->known_vendor_prefixes);
|
||||||
priv->known_vendor_prefixes = NULL;
|
priv->known_vendor_prefixes = NULL;
|
||||||
|
|
||||||
G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object);
|
G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object);
|
||||||
@@ -312,8 +314,8 @@ on_apps_tree_changed_cb (GMenuTree *tree,
|
|||||||
|
|
||||||
g_assert (tree == self->priv->apps_tree);
|
g_assert (tree == self->priv->apps_tree);
|
||||||
|
|
||||||
g_hash_table_remove_all (self->priv->visible_id_to_app);
|
g_slist_foreach (self->priv->known_vendor_prefixes, (GFunc)g_free, NULL);
|
||||||
g_slist_free_full (self->priv->known_vendor_prefixes, g_free);
|
g_slist_free (self->priv->known_vendor_prefixes);
|
||||||
self->priv->known_vendor_prefixes = NULL;
|
self->priv->known_vendor_prefixes = NULL;
|
||||||
|
|
||||||
if (!gmenu_tree_load_sync (self->priv->apps_tree, &error))
|
if (!gmenu_tree_load_sync (self->priv->apps_tree, &error))
|
||||||
@@ -374,8 +376,6 @@ on_apps_tree_changed_cb (GMenuTree *tree,
|
|||||||
* string is pointed to.
|
* string is pointed to.
|
||||||
*/
|
*/
|
||||||
g_hash_table_replace (self->priv->id_to_app, (char*)id, app);
|
g_hash_table_replace (self->priv->id_to_app, (char*)id, app);
|
||||||
if (!gmenu_tree_entry_get_is_nodisplay_recurse (entry))
|
|
||||||
g_hash_table_replace (self->priv->visible_id_to_app, (char*)id, app);
|
|
||||||
|
|
||||||
if (old_entry)
|
if (old_entry)
|
||||||
gmenu_tree_item_unref (old_entry);
|
gmenu_tree_item_unref (old_entry);
|
||||||
@@ -644,6 +644,30 @@ shell_app_system_lookup_wmclass (ShellAppSystem *system,
|
|||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_app_system_get_all:
|
||||||
|
* @system:
|
||||||
|
*
|
||||||
|
* Returns: (transfer container) (element-type ShellApp): All installed applications
|
||||||
|
*/
|
||||||
|
GSList *
|
||||||
|
shell_app_system_get_all (ShellAppSystem *self)
|
||||||
|
{
|
||||||
|
GSList *result = NULL;
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, self->priv->id_to_app);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
ShellApp *app = value;
|
||||||
|
|
||||||
|
if (!g_desktop_app_info_get_nodisplay (shell_app_get_app_info (app)))
|
||||||
|
result = g_slist_prepend (result, app);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_shell_app_system_notify_app_state_changed (ShellAppSystem *self,
|
_shell_app_system_notify_app_state_changed (ShellAppSystem *self,
|
||||||
ShellApp *app)
|
ShellApp *app)
|
||||||
@@ -766,7 +790,8 @@ search_tree (ShellAppSystem *self,
|
|||||||
&prefix_results,
|
&prefix_results,
|
||||||
&substring_results);
|
&substring_results);
|
||||||
}
|
}
|
||||||
g_slist_free_full (normalized_terms, g_free);
|
g_slist_foreach (normalized_terms, (GFunc)g_free, NULL);
|
||||||
|
g_slist_free (normalized_terms);
|
||||||
|
|
||||||
return sort_and_concat_results (self, prefix_results, substring_results);
|
return sort_and_concat_results (self, prefix_results, substring_results);
|
||||||
|
|
||||||
@@ -785,7 +810,7 @@ GSList *
|
|||||||
shell_app_system_initial_search (ShellAppSystem *self,
|
shell_app_system_initial_search (ShellAppSystem *self,
|
||||||
GSList *terms)
|
GSList *terms)
|
||||||
{
|
{
|
||||||
return search_tree (self, terms, self->priv->visible_id_to_app);
|
return search_tree (self, terms, self->priv->id_to_app);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -819,7 +844,8 @@ shell_app_system_subsearch (ShellAppSystem *system,
|
|||||||
&prefix_results,
|
&prefix_results,
|
||||||
&substring_results);
|
&substring_results);
|
||||||
}
|
}
|
||||||
g_slist_free_full (normalized_terms, g_free);
|
g_slist_foreach (normalized_terms, (GFunc)g_free, NULL);
|
||||||
|
g_slist_free (normalized_terms);
|
||||||
|
|
||||||
/* Note that a shorter term might have matched as a prefix, but
|
/* Note that a shorter term might have matched as a prefix, but
|
||||||
when extended only as a substring, so we have to redo the
|
when extended only as a substring, so we have to redo the
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ ShellApp *shell_app_system_lookup_heuristic_basename (ShellAppSystem *
|
|||||||
ShellApp *shell_app_system_lookup_wmclass (ShellAppSystem *system,
|
ShellApp *shell_app_system_lookup_wmclass (ShellAppSystem *system,
|
||||||
const char *wmclass);
|
const char *wmclass);
|
||||||
|
|
||||||
|
GSList *shell_app_system_get_all (ShellAppSystem *system);
|
||||||
|
|
||||||
GSList *shell_app_system_get_running (ShellAppSystem *self);
|
GSList *shell_app_system_get_running (ShellAppSystem *self);
|
||||||
|
|
||||||
GSList *shell_app_system_initial_search (ShellAppSystem *system,
|
GSList *shell_app_system_initial_search (ShellAppSystem *system,
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ typedef struct {
|
|||||||
/* See GApplication documentation */
|
/* See GApplication documentation */
|
||||||
GDBusMenuModel *remote_menu;
|
GDBusMenuModel *remote_menu;
|
||||||
GActionMuxer *muxer;
|
GActionMuxer *muxer;
|
||||||
char * unique_bus_name;
|
|
||||||
} ShellAppRunningState;
|
} ShellAppRunningState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,6 +95,7 @@ enum {
|
|||||||
static guint shell_app_signals[LAST_SIGNAL] = { 0 };
|
static guint shell_app_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
static void create_running_state (ShellApp *app);
|
static void create_running_state (ShellApp *app);
|
||||||
|
static void setup_running_state (ShellApp *app, MetaWindow *window);
|
||||||
static void unref_running_state (ShellAppRunningState *state);
|
static void unref_running_state (ShellAppRunningState *state);
|
||||||
|
|
||||||
G_DEFINE_TYPE (ShellApp, shell_app, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (ShellApp, shell_app, G_TYPE_OBJECT)
|
||||||
@@ -371,7 +371,7 @@ shell_app_get_name (ShellApp *app)
|
|||||||
|
|
||||||
name = meta_window_get_wm_class (window);
|
name = meta_window_get_wm_class (window);
|
||||||
if (!name)
|
if (!name)
|
||||||
name = C_("program", "Unknown");
|
name = _("Unknown");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,7 +493,7 @@ shell_app_activate_window (ShellApp *app,
|
|||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GSList *windows_reversed, *iter;
|
GSList *iter;
|
||||||
ShellGlobal *global = shell_global_get ();
|
ShellGlobal *global = shell_global_get ();
|
||||||
MetaScreen *screen = shell_global_get_screen (global);
|
MetaScreen *screen = shell_global_get_screen (global);
|
||||||
MetaDisplay *display = meta_screen_get_display (screen);
|
MetaDisplay *display = meta_screen_get_display (screen);
|
||||||
@@ -511,16 +511,13 @@ shell_app_activate_window (ShellApp *app,
|
|||||||
/* Now raise all the other windows for the app that are on
|
/* Now raise all the other windows for the app that are on
|
||||||
* the same workspace, in reverse order to preserve the stacking.
|
* the same workspace, in reverse order to preserve the stacking.
|
||||||
*/
|
*/
|
||||||
windows_reversed = g_slist_copy (windows);
|
for (iter = windows; iter; iter = iter->next)
|
||||||
windows_reversed = g_slist_reverse (windows_reversed);
|
|
||||||
for (iter = windows_reversed; iter; iter = iter->next)
|
|
||||||
{
|
{
|
||||||
MetaWindow *other_window = iter->data;
|
MetaWindow *other_window = iter->data;
|
||||||
|
|
||||||
if (other_window != window)
|
if (other_window != window)
|
||||||
meta_window_raise (other_window);
|
meta_window_raise (other_window);
|
||||||
}
|
}
|
||||||
g_slist_free (windows_reversed);
|
|
||||||
|
|
||||||
/* If we have a transient that the user's interacted with more recently than
|
/* If we have a transient that the user's interacted with more recently than
|
||||||
* the window, pick that.
|
* the window, pick that.
|
||||||
@@ -975,7 +972,7 @@ _shell_app_add_window (ShellApp *app,
|
|||||||
g_signal_connect (window, "unmanaged", G_CALLBACK(shell_app_on_unmanaged), app);
|
g_signal_connect (window, "unmanaged", G_CALLBACK(shell_app_on_unmanaged), app);
|
||||||
g_signal_connect (window, "notify::user-time", G_CALLBACK(shell_app_on_user_time_changed), app);
|
g_signal_connect (window, "notify::user-time", G_CALLBACK(shell_app_on_user_time_changed), app);
|
||||||
|
|
||||||
shell_app_update_app_menu (app, window);
|
setup_running_state (app, window);
|
||||||
|
|
||||||
if (app->state != SHELL_APP_STATE_STARTING)
|
if (app->state != SHELL_APP_STATE_STARTING)
|
||||||
shell_app_state_transition (app, SHELL_APP_STATE_RUNNING);
|
shell_app_state_transition (app, SHELL_APP_STATE_RUNNING);
|
||||||
@@ -1221,14 +1218,12 @@ create_running_state (ShellApp *app)
|
|||||||
app->running_state->muxer = g_action_muxer_new ();
|
app->running_state->muxer = g_action_muxer_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
shell_app_update_app_menu (ShellApp *app,
|
setup_running_state (ShellApp *app,
|
||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
const gchar *unique_bus_name;
|
/* We assume that 'gtk-unique-bus-name', gtk-application-object-path'
|
||||||
|
* and 'gtk-app-menu-object-path' are the same for all windows which
|
||||||
/* We assume that 'gtk-application-object-path' and
|
|
||||||
* 'gtk-app-menu-object-path' are the same for all windows which
|
|
||||||
* have it set.
|
* have it set.
|
||||||
*
|
*
|
||||||
* It could be possible, however, that the first window we see
|
* It could be possible, however, that the first window we see
|
||||||
@@ -1237,27 +1232,23 @@ shell_app_update_app_menu (ShellApp *app,
|
|||||||
* all the rest (until the app is stopped and restarted).
|
* all the rest (until the app is stopped and restarted).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unique_bus_name = meta_window_get_gtk_unique_bus_name (window);
|
if (app->running_state->remote_menu == NULL)
|
||||||
|
|
||||||
if (app->running_state->remote_menu == NULL ||
|
|
||||||
g_strcmp0 (app->running_state->unique_bus_name, unique_bus_name) != 0)
|
|
||||||
{
|
{
|
||||||
const gchar *application_object_path;
|
const gchar *application_object_path;
|
||||||
const gchar *app_menu_object_path;
|
const gchar *app_menu_object_path;
|
||||||
|
const gchar *unique_bus_name;
|
||||||
GDBusConnection *session;
|
GDBusConnection *session;
|
||||||
GDBusActionGroup *actions;
|
GDBusActionGroup *actions;
|
||||||
|
|
||||||
application_object_path = meta_window_get_gtk_application_object_path (window);
|
application_object_path = meta_window_get_gtk_application_object_path (window);
|
||||||
app_menu_object_path = meta_window_get_gtk_app_menu_object_path (window);
|
app_menu_object_path = meta_window_get_gtk_app_menu_object_path (window);
|
||||||
|
unique_bus_name = meta_window_get_gtk_unique_bus_name (window);
|
||||||
|
|
||||||
if (application_object_path == NULL || app_menu_object_path == NULL || unique_bus_name == NULL)
|
if (application_object_path == NULL || app_menu_object_path == NULL || unique_bus_name == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||||
g_assert (session != NULL);
|
g_assert (session != NULL);
|
||||||
g_clear_pointer (&app->running_state->unique_bus_name, g_free);
|
|
||||||
app->running_state->unique_bus_name = g_strdup (unique_bus_name);
|
|
||||||
g_clear_object (&app->running_state->remote_menu);
|
|
||||||
app->running_state->remote_menu = g_dbus_menu_model_get (session, unique_bus_name, app_menu_object_path);
|
app->running_state->remote_menu = g_dbus_menu_model_get (session, unique_bus_name, app_menu_object_path);
|
||||||
actions = g_dbus_action_group_get (session, unique_bus_name, application_object_path);
|
actions = g_dbus_action_group_get (session, unique_bus_name, application_object_path);
|
||||||
g_action_muxer_insert (app->running_state->muxer, "app", G_ACTION_GROUP (actions));
|
g_action_muxer_insert (app->running_state->muxer, "app", G_ACTION_GROUP (actions));
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ int shell_app_compare_by_name (ShellApp *app, ShellApp *other);
|
|||||||
int shell_app_compare (ShellApp *app, ShellApp *other);
|
int shell_app_compare (ShellApp *app, ShellApp *other);
|
||||||
|
|
||||||
void shell_app_update_window_actions (ShellApp *app, MetaWindow *window);
|
void shell_app_update_window_actions (ShellApp *app, MetaWindow *window);
|
||||||
void shell_app_update_app_menu (ShellApp *app, MetaWindow *window);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ sort_and_prepare_results (GSList *results)
|
|||||||
sorted_results = g_slist_prepend (sorted_results, id);
|
sorted_results = g_slist_prepend (sorted_results, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free_full (results, (GDestroyNotify) free_result);
|
g_slist_foreach (results, (GFunc) free_result, NULL);
|
||||||
|
|
||||||
return sorted_results;
|
return sorted_results;
|
||||||
}
|
}
|
||||||
@@ -463,9 +463,6 @@ shell_contact_system_initial_search (ShellContactSystem *self,
|
|||||||
g_object_unref (individual);
|
g_object_unref (individual);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (iter);
|
|
||||||
g_slist_free_full (normalized_terms, (GDestroyNotify) g_free);
|
|
||||||
|
|
||||||
return sort_and_prepare_results (results);
|
return sort_and_prepare_results (results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,4 +16,7 @@ GjsContext *_shell_global_get_gjs_context (ShellGlobal *global);
|
|||||||
gboolean _shell_global_check_xdnd_event (ShellGlobal *global,
|
gboolean _shell_global_check_xdnd_event (ShellGlobal *global,
|
||||||
XEvent *xev);
|
XEvent *xev);
|
||||||
|
|
||||||
|
void _shell_global_set_session_type (ShellGlobal *global,
|
||||||
|
ShellSessionType session_type);
|
||||||
|
|
||||||
#endif /* __SHELL_GLOBAL_PRIVATE_H__ */
|
#endif /* __SHELL_GLOBAL_PRIVATE_H__ */
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ struct _ShellGlobal {
|
|||||||
MetaScreen *meta_screen;
|
MetaScreen *meta_screen;
|
||||||
GdkScreen *gdk_screen;
|
GdkScreen *gdk_screen;
|
||||||
|
|
||||||
char *session_mode;
|
ShellSessionType session_type;
|
||||||
|
|
||||||
/* We use this window to get a notification from GTK+ when
|
/* We use this window to get a notification from GTK+ when
|
||||||
* a widget in our process does a GTK+ grab. See
|
* a widget in our process does a GTK+ grab. See
|
||||||
@@ -97,7 +97,7 @@ struct _ShellGlobal {
|
|||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_SESSION_MODE,
|
PROP_SESSION_TYPE,
|
||||||
PROP_OVERLAY_GROUP,
|
PROP_OVERLAY_GROUP,
|
||||||
PROP_SCREEN,
|
PROP_SCREEN,
|
||||||
PROP_GDK_SCREEN,
|
PROP_GDK_SCREEN,
|
||||||
@@ -143,9 +143,8 @@ shell_global_set_property(GObject *object,
|
|||||||
case PROP_STAGE_INPUT_MODE:
|
case PROP_STAGE_INPUT_MODE:
|
||||||
shell_global_set_stage_input_mode (global, g_value_get_enum (value));
|
shell_global_set_stage_input_mode (global, g_value_get_enum (value));
|
||||||
break;
|
break;
|
||||||
case PROP_SESSION_MODE:
|
case PROP_SESSION_TYPE:
|
||||||
g_clear_pointer (&global->session_mode, g_free);
|
global->session_type = g_value_get_enum (value);
|
||||||
global->session_mode = g_ascii_strdown (g_value_get_string (value), -1);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@@ -163,8 +162,8 @@ shell_global_get_property(GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_SESSION_MODE:
|
case PROP_SESSION_TYPE:
|
||||||
g_value_set_string (value, shell_global_get_session_mode (global));
|
g_value_set_enum (value, shell_global_get_session_type (global));
|
||||||
break;
|
break;
|
||||||
case PROP_OVERLAY_GROUP:
|
case PROP_OVERLAY_GROUP:
|
||||||
g_value_set_object (value, meta_get_overlay_group_for_screen (global->meta_screen));
|
g_value_set_object (value, meta_get_overlay_group_for_screen (global->meta_screen));
|
||||||
@@ -344,12 +343,13 @@ shell_global_class_init (ShellGlobalClass *klass)
|
|||||||
G_TYPE_STRING);
|
G_TYPE_STRING);
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_SESSION_MODE,
|
PROP_SESSION_TYPE,
|
||||||
g_param_spec_string ("session-mode",
|
g_param_spec_enum ("session-type",
|
||||||
"Session Mode",
|
"Session Type",
|
||||||
"The session mode to use",
|
"The type of session",
|
||||||
"user",
|
SHELL_TYPE_SESSION_TYPE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
SHELL_SESSION_USER,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_OVERLAY_GROUP,
|
PROP_OVERLAY_GROUP,
|
||||||
g_param_spec_object ("overlay-group",
|
g_param_spec_object ("overlay-group",
|
||||||
@@ -805,9 +805,90 @@ global_stage_after_paint (ClutterStage *stage,
|
|||||||
"clutter.stagePaintDone");
|
"clutter.stagePaintDone");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_font_options (GtkSettings *settings,
|
||||||
|
ClutterStage *stage)
|
||||||
|
{
|
||||||
|
StThemeContext *context;
|
||||||
|
ClutterBackend *backend;
|
||||||
|
gint dpi;
|
||||||
|
gint hinting;
|
||||||
|
gchar *hint_style_str;
|
||||||
|
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
gint antialias;
|
||||||
|
cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE;
|
||||||
|
cairo_font_options_t *options;
|
||||||
|
|
||||||
|
g_object_get (settings,
|
||||||
|
"gtk-xft-dpi", &dpi,
|
||||||
|
"gtk-xft-antialias", &antialias,
|
||||||
|
"gtk-xft-hinting", &hinting,
|
||||||
|
"gtk-xft-hintstyle", &hint_style_str,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
context = st_theme_context_get_for_stage (stage);
|
||||||
|
|
||||||
|
if (dpi != -1)
|
||||||
|
/* GTK stores resolution as 1024 * dots/inch */
|
||||||
|
st_theme_context_set_resolution (context, dpi / 1024);
|
||||||
|
else
|
||||||
|
st_theme_context_set_default_resolution (context);
|
||||||
|
|
||||||
|
/* Clutter (as of 0.9) passes comprehensively wrong font options
|
||||||
|
* override whatever set_font_flags() did above.
|
||||||
|
*
|
||||||
|
* http://bugzilla.openedhand.com/show_bug.cgi?id=1456
|
||||||
|
*/
|
||||||
|
backend = clutter_get_default_backend ();
|
||||||
|
options = cairo_font_options_create ();
|
||||||
|
|
||||||
|
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
|
||||||
|
|
||||||
|
if (hinting >= 0 && !hinting)
|
||||||
|
{
|
||||||
|
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
}
|
||||||
|
else if (hint_style_str)
|
||||||
|
{
|
||||||
|
if (strcmp (hint_style_str, "hintnone") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
else if (strcmp (hint_style_str, "hintslight") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
||||||
|
else if (strcmp (hint_style_str, "hintmedium") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_MEDIUM;
|
||||||
|
else if (strcmp (hint_style_str, "hintfull") == 0)
|
||||||
|
hint_style = CAIRO_HINT_STYLE_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (hint_style_str);
|
||||||
|
|
||||||
|
cairo_font_options_set_hint_style (options, hint_style);
|
||||||
|
|
||||||
|
/* We don't want to turn on subpixel anti-aliasing; since Clutter
|
||||||
|
* doesn't currently have the code to support ARGB masks,
|
||||||
|
* generating them then squashing them back to A8 is pointless.
|
||||||
|
*/
|
||||||
|
antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY
|
||||||
|
: CAIRO_ANTIALIAS_NONE;
|
||||||
|
|
||||||
|
cairo_font_options_set_antialias (options, antialias_mode);
|
||||||
|
|
||||||
|
clutter_backend_set_font_options (backend, options);
|
||||||
|
cairo_font_options_destroy (options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
settings_notify_cb (GtkSettings *settings,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
update_font_options (settings, CLUTTER_STAGE (data));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shell_fonts_init (ClutterStage *stage)
|
shell_fonts_init (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
|
GtkSettings *settings;
|
||||||
CoglPangoFontMap *fontmap;
|
CoglPangoFontMap *fontmap;
|
||||||
|
|
||||||
/* Disable text mipmapping; it causes problems on pre-GEM Intel
|
/* Disable text mipmapping; it causes problems on pre-GEM Intel
|
||||||
@@ -817,6 +898,19 @@ shell_fonts_init (ClutterStage *stage)
|
|||||||
*/
|
*/
|
||||||
fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
|
fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
|
||||||
cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
|
cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
|
||||||
|
|
||||||
|
settings = gtk_settings_get_default ();
|
||||||
|
g_object_connect (settings,
|
||||||
|
"signal::notify::gtk-xft-dpi",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
"signal::notify::gtk-xft-antialias",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
"signal::notify::gtk-xft-hinting",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
"signal::notify::gtk-xft-hintstyle",
|
||||||
|
G_CALLBACK (settings_notify_cb), stage,
|
||||||
|
NULL);
|
||||||
|
update_font_options (settings, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an IBus workaround. The flow of events with IBus is that every time
|
/* This is an IBus workaround. The flow of events with IBus is that every time
|
||||||
@@ -1776,10 +1870,31 @@ shell_global_launch_calendar_server (ShellGlobal *global)
|
|||||||
g_free (calendar_server_exe);
|
g_free (calendar_server_exe);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
/**
|
||||||
shell_global_get_session_mode (ShellGlobal *global)
|
* shell_global_get_session_type:
|
||||||
|
* @global: The #ShellGlobal.
|
||||||
|
*
|
||||||
|
* Gets the type of session gnome-shell provides.
|
||||||
|
*
|
||||||
|
* The type determines what UI elements are displayed,
|
||||||
|
* what keybindings work, and generally how the shell
|
||||||
|
* behaves.
|
||||||
|
*
|
||||||
|
* A session type of #SHELL_SESSION_USER means gnome-shell
|
||||||
|
* will enable the activities overview, status menu, run dialog,
|
||||||
|
* etc. This is the default.
|
||||||
|
*
|
||||||
|
* A session type of #SHELL_SESSION_GDM means gnome-shell
|
||||||
|
* will enable a login dialog and run in a more confined
|
||||||
|
* way. This type is suitable for the display manager.
|
||||||
|
*
|
||||||
|
* Returns: the type of session gnome-shell is providing.
|
||||||
|
*/
|
||||||
|
ShellSessionType
|
||||||
|
shell_global_get_session_type (ShellGlobal *global)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (SHELL_IS_GLOBAL (global), "user");
|
g_return_val_if_fail (SHELL_IS_GLOBAL (global),
|
||||||
|
SHELL_SESSION_USER);
|
||||||
|
|
||||||
return global->session_mode;
|
return global->session_type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,12 @@ void shell_global_reexec_self (ShellGlobal *global);
|
|||||||
|
|
||||||
void shell_global_launch_calendar_server (ShellGlobal *global);
|
void shell_global_launch_calendar_server (ShellGlobal *global);
|
||||||
|
|
||||||
const char * shell_global_get_session_mode (ShellGlobal *global);
|
typedef enum {
|
||||||
|
SHELL_SESSION_USER,
|
||||||
|
SHELL_SESSION_GDM
|
||||||
|
} ShellSessionType;
|
||||||
|
|
||||||
|
ShellSessionType shell_global_get_session_type (ShellGlobal *global);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -1,214 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Author:
|
|
||||||
* Joseph Scheuhammer <clown@alum.mit.edu>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:shell-invert-lightness-effect
|
|
||||||
* @short_description: A colorization effect where lightness is inverted but
|
|
||||||
* color is not.
|
|
||||||
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
|
|
||||||
*
|
|
||||||
* #ShellInvertLightnessEffect is a sub-class of #ClutterEffect that enhances
|
|
||||||
* the appearance of a clutter actor. Specifically it inverts the lightness
|
|
||||||
* of a #ClutterActor (e.g., darker colors become lighter, white becomes black,
|
|
||||||
* and white, black).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SHELL_INVERT_LIGHTNESS_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT, ShellInvertLightnessEffectClass))
|
|
||||||
#define SHELL_IS_INVERT_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT))
|
|
||||||
#define SHELL_INVERT_LIGHTNESS_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_INVERT_LIGHTNESS_EFFEC, ShellInvertLightnessEffectClass))
|
|
||||||
|
|
||||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
|
||||||
|
|
||||||
#include "shell-invert-lightness-effect.h"
|
|
||||||
|
|
||||||
#include <cogl/cogl.h>
|
|
||||||
|
|
||||||
struct _ShellInvertLightnessEffect
|
|
||||||
{
|
|
||||||
ClutterOffscreenEffect parent_instance;
|
|
||||||
|
|
||||||
gint tex_width;
|
|
||||||
gint tex_height;
|
|
||||||
|
|
||||||
CoglPipeline *pipeline;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _ShellInvertLightnessEffectClass
|
|
||||||
{
|
|
||||||
ClutterOffscreenEffectClass parent_class;
|
|
||||||
|
|
||||||
CoglPipeline *base_pipeline;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Lightness inversion in GLSL.
|
|
||||||
*/
|
|
||||||
static const gchar *invert_lightness_source =
|
|
||||||
"cogl_texel = texture2D (cogl_sampler, cogl_tex_coord.st);\n"
|
|
||||||
"vec3 effect = vec3 (cogl_texel);\n"
|
|
||||||
"\n"
|
|
||||||
"float maxColor = max (cogl_texel.r, max (cogl_texel.g, cogl_texel.b));\n"
|
|
||||||
"float minColor = min (cogl_texel.r, min (cogl_texel.g, cogl_texel.b));\n"
|
|
||||||
"float lightness = (maxColor + minColor) / 2.0;\n"
|
|
||||||
"\n"
|
|
||||||
"float delta = (1.0 - lightness) - lightness;\n"
|
|
||||||
"effect.rgb = (effect.rgb + delta);\n"
|
|
||||||
"\n"
|
|
||||||
"cogl_texel = vec4 (effect, cogl_texel.a);\n";
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (ShellInvertLightnessEffect,
|
|
||||||
shell_invert_lightness_effect,
|
|
||||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
shell_invert_lightness_effect_pre_paint (ClutterEffect *effect)
|
|
||||||
{
|
|
||||||
ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (effect);
|
|
||||||
ClutterEffectClass *parent_class;
|
|
||||||
|
|
||||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
|
||||||
{
|
|
||||||
/* if we don't have support for GLSL shaders then we
|
|
||||||
* forcibly disable the ActorMeta
|
|
||||||
*/
|
|
||||||
g_warning ("Unable to use the ShellInvertLightnessEffect: the "
|
|
||||||
"graphics hardware or the current GL driver does not "
|
|
||||||
"implement support for the GLSL shading language.");
|
|
||||||
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (self), FALSE);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent_class =
|
|
||||||
CLUTTER_EFFECT_CLASS (shell_invert_lightness_effect_parent_class);
|
|
||||||
if (parent_class->pre_paint (effect))
|
|
||||||
{
|
|
||||||
ClutterOffscreenEffect *offscreen_effect =
|
|
||||||
CLUTTER_OFFSCREEN_EFFECT (effect);
|
|
||||||
CoglHandle texture;
|
|
||||||
|
|
||||||
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
|
|
||||||
self->tex_width = cogl_texture_get_width (texture);
|
|
||||||
self->tex_height = cogl_texture_get_height (texture);
|
|
||||||
|
|
||||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
shell_invert_lightness_effect_paint_target (ClutterOffscreenEffect *effect)
|
|
||||||
{
|
|
||||||
ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (effect);
|
|
||||||
ClutterActor *actor;
|
|
||||||
guint8 paint_opacity;
|
|
||||||
|
|
||||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
|
||||||
paint_opacity = clutter_actor_get_paint_opacity (actor);
|
|
||||||
|
|
||||||
cogl_pipeline_set_color4ub (self->pipeline,
|
|
||||||
paint_opacity,
|
|
||||||
paint_opacity,
|
|
||||||
paint_opacity,
|
|
||||||
paint_opacity);
|
|
||||||
cogl_push_source (self->pipeline);
|
|
||||||
|
|
||||||
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
|
|
||||||
|
|
||||||
cogl_pop_source ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
shell_invert_lightness_effect_dispose (GObject *gobject)
|
|
||||||
{
|
|
||||||
ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (gobject);
|
|
||||||
|
|
||||||
if (self->pipeline != NULL)
|
|
||||||
{
|
|
||||||
cogl_object_unref (self->pipeline);
|
|
||||||
self->pipeline = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (shell_invert_lightness_effect_parent_class)->dispose (gobject);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
shell_invert_lightness_effect_class_init (ShellInvertLightnessEffectClass *klass)
|
|
||||||
{
|
|
||||||
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
|
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
||||||
ClutterOffscreenEffectClass *offscreen_class;
|
|
||||||
|
|
||||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
|
||||||
offscreen_class->paint_target = shell_invert_lightness_effect_paint_target;
|
|
||||||
|
|
||||||
effect_class->pre_paint = shell_invert_lightness_effect_pre_paint;
|
|
||||||
|
|
||||||
gobject_class->dispose = shell_invert_lightness_effect_dispose;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
shell_invert_lightness_effect_init (ShellInvertLightnessEffect *self)
|
|
||||||
{
|
|
||||||
ShellInvertLightnessEffectClass *klass;
|
|
||||||
klass = SHELL_INVERT_LIGHTNESS_EFFECT_GET_CLASS (self);
|
|
||||||
|
|
||||||
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
|
||||||
{
|
|
||||||
CoglSnippet *snippet;
|
|
||||||
CoglContext *ctx =
|
|
||||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
|
||||||
|
|
||||||
klass->base_pipeline = cogl_pipeline_new (ctx);
|
|
||||||
|
|
||||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
cogl_snippet_set_replace (snippet, invert_lightness_source);
|
|
||||||
cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
|
|
||||||
cogl_object_unref (snippet);
|
|
||||||
|
|
||||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
|
|
||||||
0, /* layer number */
|
|
||||||
COGL_TEXTURE_TYPE_2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* shell_invert_lightness_effect_new:
|
|
||||||
*
|
|
||||||
* Creates a new #ShellInvertLightnessEffect to be used with
|
|
||||||
* clutter_actor_add_effect()
|
|
||||||
*
|
|
||||||
* Return value: (transfer full): the newly created
|
|
||||||
* #ShellInvertLightnessEffect or %NULL. Use g_object_unref() when done.
|
|
||||||
*/
|
|
||||||
ClutterEffect *
|
|
||||||
shell_invert_lightness_effect_new (void)
|
|
||||||
{
|
|
||||||
return g_object_new (SHELL_TYPE_INVERT_LIGHTNESS_EFFECT, NULL);
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
/*
|
|
||||||
* Copyright © 2010-2012 Inclusive Design Research Centre, OCAD University.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Author:
|
|
||||||
* Joseph Scheuhammer <clown@alum.mit.edu>
|
|
||||||
*/
|
|
||||||
#ifndef __SHELL_INVERT_LIGHTNESS_EFFECT_H__
|
|
||||||
#define __SHELL_INVERT_LIGHTNESS_EFFECT_H__
|
|
||||||
|
|
||||||
#define COGL_ENABLE_EXPERIMENTAL_API
|
|
||||||
#include <clutter/clutter.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define SHELL_TYPE_INVERT_LIGHTNESS_EFFECT (shell_invert_lightness_effect_get_type ())
|
|
||||||
#define SHELL_INVERT_LIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT, ShellInvertLightnessEffect))
|
|
||||||
#define SHELL_IS_INVERT_LIGHTNESS_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT))
|
|
||||||
|
|
||||||
typedef struct _ShellInvertLightnessEffect ShellInvertLightnessEffect;
|
|
||||||
typedef struct _ShellInvertLightnessEffectClass ShellInvertLightnessEffectClass;
|
|
||||||
|
|
||||||
GType shell_invert_lightness_effect_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
ClutterEffect *shell_invert_lightness_effect_new (void);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __SHELL_INVERT_LIGHTNESS_EFFECT_H__ */
|
|
||||||
@@ -79,3 +79,15 @@ shell_js_add_extension_importer (const char *target_object_script,
|
|||||||
JS_EndRequest (context);
|
JS_EndRequest (context);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_js_format_int_alternative_output:
|
||||||
|
* @intval:
|
||||||
|
*
|
||||||
|
* Returns: (transfer full):
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
shell_js_format_int_alternative_output (gint intval)
|
||||||
|
{
|
||||||
|
return g_strdup_printf ("%Id", intval);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ gboolean shell_js_add_extension_importer (const char *target_object_script,
|
|||||||
const char *directory,
|
const char *directory,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
gchar *shell_js_format_int_alternative_output (gint intval);
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#endif /* __SHELL_JS_H__ */
|
#endif /* __SHELL_JS_H__ */
|
||||||
|
|||||||
@@ -76,26 +76,6 @@ shell_agent_request_free (gpointer data)
|
|||||||
g_slice_free (ShellAgentRequest, request);
|
g_slice_free (ShellAgentRequest, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
shell_agent_request_cancel (ShellAgentRequest *request)
|
|
||||||
{
|
|
||||||
GError *error;
|
|
||||||
ShellNetworkAgent *self;
|
|
||||||
|
|
||||||
self = request->self;
|
|
||||||
|
|
||||||
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
||||||
NM_SECRET_AGENT_ERROR_AGENT_CANCELED,
|
|
||||||
"Canceled by NetworkManager");
|
|
||||||
request->callback (NM_SECRET_AGENT (self), request->connection,
|
|
||||||
NULL, error, request->callback_data);
|
|
||||||
|
|
||||||
g_signal_emit (self, signals[SIGNAL_CANCEL_REQUEST], 0, request->request_id);
|
|
||||||
|
|
||||||
g_hash_table_remove (self->priv->requests, request->request_id);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shell_network_agent_init (ShellNetworkAgent *agent)
|
shell_network_agent_init (ShellNetworkAgent *agent)
|
||||||
{
|
{
|
||||||
@@ -361,17 +341,6 @@ shell_network_agent_get_secrets (NMSecretAgent *agent,
|
|||||||
ShellAgentRequest *request;
|
ShellAgentRequest *request;
|
||||||
NMSettingConnection *setting_connection;
|
NMSettingConnection *setting_connection;
|
||||||
const char *connection_type;
|
const char *connection_type;
|
||||||
char *request_id;
|
|
||||||
|
|
||||||
request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
|
|
||||||
if ((request = g_hash_table_lookup (self->priv->requests, request_id)) != NULL)
|
|
||||||
{
|
|
||||||
/* We already have a request pending for this (connection, setting)
|
|
||||||
* Cancel it before starting the new one.
|
|
||||||
* This will also free the request structure and associated resources.
|
|
||||||
*/
|
|
||||||
shell_agent_request_cancel (request);
|
|
||||||
}
|
|
||||||
|
|
||||||
setting_connection = nm_connection_get_setting_connection (connection);
|
setting_connection = nm_connection_get_setting_connection (connection);
|
||||||
connection_type = nm_setting_connection_get_connection_type (setting_connection);
|
connection_type = nm_setting_connection_get_connection_type (setting_connection);
|
||||||
@@ -402,7 +371,7 @@ shell_network_agent_get_secrets (NMSecretAgent *agent,
|
|||||||
else
|
else
|
||||||
request->vpn_entries = NULL;
|
request->vpn_entries = NULL;
|
||||||
|
|
||||||
request->request_id = request_id;
|
request->request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
|
||||||
g_hash_table_replace (self->priv->requests, request->request_id, request);
|
g_hash_table_replace (self->priv->requests, request->request_id, request);
|
||||||
|
|
||||||
if ((flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) ||
|
if ((flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) ||
|
||||||
@@ -521,22 +490,30 @@ shell_network_agent_cancel_get_secrets (NMSecretAgent *agent,
|
|||||||
{
|
{
|
||||||
ShellNetworkAgent *self = SHELL_NETWORK_AGENT (agent);
|
ShellNetworkAgent *self = SHELL_NETWORK_AGENT (agent);
|
||||||
ShellNetworkAgentPrivate *priv = self->priv;
|
ShellNetworkAgentPrivate *priv = self->priv;
|
||||||
gchar *request_id;
|
|
||||||
ShellAgentRequest *request;
|
|
||||||
|
|
||||||
request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
|
gchar *request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
|
||||||
request = g_hash_table_lookup (priv->requests, request_id);
|
ShellAgentRequest *request = g_hash_table_lookup (priv->requests, request_id);
|
||||||
g_free (request_id);
|
GError *error;
|
||||||
|
|
||||||
if (!request)
|
if (!request)
|
||||||
{
|
{
|
||||||
/* We've already sent the result, but the caller cancelled the
|
/* We've already sent the result, but the caller cancelled the
|
||||||
* operation before receiving that result.
|
* operation before receiving that result.
|
||||||
*/
|
*/
|
||||||
|
g_free (request_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shell_agent_request_cancel (request);
|
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
||||||
|
NM_SECRET_AGENT_ERROR_AGENT_CANCELED,
|
||||||
|
"Canceled by NetworkManager");
|
||||||
|
request->callback (agent, request->connection, NULL, error, request->callback_data);
|
||||||
|
|
||||||
|
g_signal_emit (self, signals[SIGNAL_CANCEL_REQUEST], 0, request_id);
|
||||||
|
|
||||||
|
g_hash_table_remove (priv->requests, request_id);
|
||||||
|
g_free (request_id);
|
||||||
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************* saving of secrets ****************************************/
|
/************************* saving of secrets ****************************************/
|
||||||
|
|||||||
@@ -230,7 +230,6 @@ auth_request_free (AuthRequest *request)
|
|||||||
g_free (request->message);
|
g_free (request->message);
|
||||||
g_free (request->icon_name);
|
g_free (request->icon_name);
|
||||||
g_object_unref (request->details);
|
g_object_unref (request->details);
|
||||||
g_free (request->cookie);
|
|
||||||
g_list_foreach (request->identities, (GFunc) g_object_unref, NULL);
|
g_list_foreach (request->identities, (GFunc) g_object_unref, NULL);
|
||||||
g_list_free (request->identities);
|
g_list_free (request->identities);
|
||||||
g_object_unref (request->simple);
|
g_object_unref (request->simple);
|
||||||
|
|||||||
@@ -330,6 +330,34 @@ shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
|
|||||||
|
|
||||||
/* Telepathy utility functions */
|
/* Telepathy utility functions */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_get_contact_events:
|
||||||
|
* @log_manager: A #TplLogManager
|
||||||
|
* @account: A #TpAccount
|
||||||
|
* @entity: A #TplEntity
|
||||||
|
* @num_events: The number of events to retrieve
|
||||||
|
* @callback: (scope async): User callback to run when the contact is ready
|
||||||
|
*
|
||||||
|
* Wrap tpl_log_manager_get_filtered_events_async because gjs cannot support
|
||||||
|
* multiple callbacks in the same function call.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shell_get_contact_events (TplLogManager *log_manager,
|
||||||
|
TpAccount *account,
|
||||||
|
TplEntity *entity,
|
||||||
|
guint num_events,
|
||||||
|
GAsyncReadyCallback callback)
|
||||||
|
{
|
||||||
|
tpl_log_manager_get_filtered_events_async (log_manager,
|
||||||
|
account,
|
||||||
|
entity,
|
||||||
|
TPL_EVENT_MASK_TEXT,
|
||||||
|
num_events,
|
||||||
|
NULL, NULL,
|
||||||
|
callback, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* gjs doesn't allow us to craft a GError so we need a C wrapper */
|
/* gjs doesn't allow us to craft a GError so we need a C wrapper */
|
||||||
void
|
void
|
||||||
shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
|
shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
|
||||||
@@ -341,9 +369,3 @@ shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
|
|||||||
tp_add_dispatch_operation_context_fail (context, error);
|
tp_add_dispatch_operation_context_fail (context, error);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gjs doesn't cope with tp_proxy_get_invalidated() returning a GError */
|
|
||||||
gboolean shell_is_channel_invalidated (TpChannel *channel)
|
|
||||||
{
|
|
||||||
return tp_proxy_get_invalidated (channel) != NULL;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include <telepathy-glib/telepathy-glib.h>
|
#include <telepathy-glib/telepathy-glib.h>
|
||||||
|
#include <telepathy-logger/telepathy-logger.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@@ -102,10 +103,14 @@ void shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
|
|||||||
|
|
||||||
/* Telepathy utility functions */
|
/* Telepathy utility functions */
|
||||||
|
|
||||||
|
void shell_get_contact_events (TplLogManager *log_manager,
|
||||||
|
TpAccount *account,
|
||||||
|
TplEntity *entity,
|
||||||
|
guint num_events,
|
||||||
|
GAsyncReadyCallback callback);
|
||||||
|
|
||||||
void shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
|
void shell_decline_dispatch_op (TpAddDispatchOperationContext *context,
|
||||||
const gchar *message);
|
const gchar *message);
|
||||||
|
|
||||||
gboolean shell_is_channel_invalidated (TpChannel *channel);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* __SHELL_TP_CLIENT_H__ */
|
#endif /* __SHELL_TP_CLIENT_H__ */
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ shell_util_get_file_display_for_common_files (GFile *file)
|
|||||||
* nautilus */
|
* nautilus */
|
||||||
return g_strdup (_("Home"));
|
return g_strdup (_("Home"));
|
||||||
}
|
}
|
||||||
g_object_unref (compare);
|
|
||||||
|
|
||||||
compare = g_file_new_for_path ("/");
|
compare = g_file_new_for_path ("/");
|
||||||
if (g_file_equal (file, compare))
|
if (g_file_equal (file, compare))
|
||||||
@@ -593,6 +592,29 @@ shell_util_get_week_start ()
|
|||||||
return week_start;
|
return week_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_write_soup_message_to_stream:
|
||||||
|
* @stream: a #GOutputStream
|
||||||
|
* @message: a #SoupMessage
|
||||||
|
* @error: location to store GError
|
||||||
|
*
|
||||||
|
* Write a string to a GOutputStream as binary data. This is a
|
||||||
|
* workaround for the lack of proper binary strings in GJS.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shell_write_soup_message_to_stream (GOutputStream *stream,
|
||||||
|
SoupMessage *message,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
SoupMessageBody *body;
|
||||||
|
|
||||||
|
body = message->response_body;
|
||||||
|
|
||||||
|
g_output_stream_write_all (stream,
|
||||||
|
body->data, body->length,
|
||||||
|
NULL, NULL, error);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_write_string_to_stream:
|
* shell_write_string_to_stream:
|
||||||
* @stream: a #GOutputStream
|
* @stream: a #GOutputStream
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ char *shell_util_normalize_and_casefold (const char *str);
|
|||||||
char *shell_util_format_date (const char *format,
|
char *shell_util_format_date (const char *format,
|
||||||
gint64 time_ms);
|
gint64 time_ms);
|
||||||
|
|
||||||
|
void shell_write_soup_message_to_stream (GOutputStream *stream,
|
||||||
|
SoupMessage *message,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
gboolean shell_write_string_to_stream (GOutputStream *stream,
|
gboolean shell_write_string_to_stream (GOutputStream *stream,
|
||||||
const char *str,
|
const char *str,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|||||||
@@ -357,10 +357,7 @@ update_focus_app (ShellWindowTracker *self)
|
|||||||
new_focus_app = new_focus_win ? shell_window_tracker_get_window_app (self, new_focus_win) : NULL;
|
new_focus_app = new_focus_win ? shell_window_tracker_get_window_app (self, new_focus_win) : NULL;
|
||||||
|
|
||||||
if (new_focus_app)
|
if (new_focus_app)
|
||||||
{
|
shell_app_update_window_actions (new_focus_app, new_focus_win);
|
||||||
shell_app_update_window_actions (new_focus_app, new_focus_win);
|
|
||||||
shell_app_update_app_menu (new_focus_app, new_focus_win);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_focus_app (self, new_focus_app);
|
set_focus_app (self, new_focus_app);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ st_label_accessible_get_name (AtkObject *obj)
|
|||||||
|
|
||||||
actor = CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj)));
|
actor = CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj)));
|
||||||
|
|
||||||
if (actor == NULL || st_widget_has_style_class_name (ST_WIDGET (actor), "hidden"))
|
if (actor == NULL) /* State is defunct */
|
||||||
name = NULL;
|
name = NULL;
|
||||||
else
|
else
|
||||||
name = st_label_get_text (ST_LABEL (actor));
|
name = st_label_get_text (ST_LABEL (actor));
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user