Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
ac68251a00 | |||
6fd705e009 | |||
923a908a2a | |||
59e868b8f5 | |||
f83144b79a | |||
267a42c31c | |||
3ac7bf874c | |||
cac32dfe2a | |||
1a61f288f6 | |||
aca619ff89 | |||
6673f52df2 | |||
a70ee216b0 | |||
261514187e | |||
1bf6fa039f | |||
9360e60ed2 | |||
afb6286994 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -43,8 +43,6 @@ docs/reference/*/xml/
|
||||
docs/reference/shell/doc-gen-*
|
||||
gtk-doc.make
|
||||
js/misc/config.js
|
||||
js/js-resources.c
|
||||
js/js-resources.h
|
||||
intltool-extract.in
|
||||
intltool-merge.in
|
||||
intltool-update.in
|
||||
|
@ -1,11 +1,7 @@
|
||||
# Point to our macro directory and pick up user flags from the environment
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
SUBDIRS = data js src tests po docs
|
||||
|
||||
if BUILD_BROWSER_PLUGIN
|
||||
SUBDIRS += browser-plugin
|
||||
endif
|
||||
SUBDIRS = data js src browser-plugin tests po docs
|
||||
|
||||
if ENABLE_MAN
|
||||
SUBDIRS += man
|
||||
|
40
NEWS
40
NEWS
@ -1,41 +1,17 @@
|
||||
3.11.2
|
||||
3.10.2
|
||||
======
|
||||
* Cache search result display actors [Jasper; #704912]
|
||||
* Use username in userWidget if real name doesn't fit [Jasper; #706851]
|
||||
* Support shell_global_reexec_self() on OpenBSD [Antoine; #709571]
|
||||
* Support disabling browser plugin [Colin; #711218]
|
||||
* Restore support for 'disable-restart-buttons' [Florian; #711244]
|
||||
* Validate parameters of exposed DBus methods [Florian; #699752]
|
||||
* Connect applications to systemd journal if available [Colin; #711626]
|
||||
* Misc bug fixes and cleanups [Florian, Jasper; #711205, #698486, #711416,
|
||||
#644306, #711555, #709806, #711631, #711732]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Antoine Jacoutot, Florian Müllner, Jasper St. Pierre,
|
||||
Rico Tzschichholz, Colin Walters
|
||||
|
||||
Translations:
|
||||
Yuri Myasoedov [ru], Kjartan Maraas [nb], Efstathios Iosifidis [el],
|
||||
Benjamin Steinwender [de], eternalhui [zh_CN], Shantha kumar [ta]
|
||||
|
||||
3.11.1
|
||||
======
|
||||
* power: Use UPower directly instead of gnome-settings-daemon [Bastien; #710273]
|
||||
* Implement support for new GTK+ notification API [Jasper, Giovanni, Florian;
|
||||
#710137, #710596]
|
||||
* gdm: Don't allow user-list to fill up the entire screen [Florian; #710555]
|
||||
* Don't autostart remote search providers at login [Giovanni; #708830]
|
||||
* Fix spacing in end-session dialog [Sebastien; #710543]
|
||||
* Prepare for js24 [Tim; #711052]
|
||||
* Misc bug fixes and cleanups [Jasper, Florian, Adel, Tim, Sebastien; #710347,
|
||||
#710144, #710541, #691409, #710745, #688331, #704912]
|
||||
* Restore support for 'disable-restart-buttons' [Florian; #711244]
|
||||
* alidate parameters of exposed DBus methods [Florian; #699752]
|
||||
* Misc. bug fixes [Florian; #709806]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Adel Gadllah, Sebastien Lafargue, Tim Lunn,
|
||||
Florian Müllner, Bastien Nocera, Jasper St. Pierre, Rico Tzschichholz
|
||||
Florian Müllner
|
||||
|
||||
Translations:
|
||||
Stas Solovey [ru], Yosef Or Boczko [he], Rafael Ferreira [pt_BR]
|
||||
Ihar Hrachyshka [be], Stas Solovey [ru], Kjartan Maraas [nb],
|
||||
Dimitris Spingos [el], Rafael Ferreira [pt_BR], Yuri Myasoedov [ru],
|
||||
Sphinx Jiang [zh_CN], Shantha kumar [ta]
|
||||
|
||||
3.10.1
|
||||
======
|
||||
|
38
configure.ac
38
configure.ac
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[3.11.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AC_INIT([gnome-shell],[3.10.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||
@ -16,7 +16,6 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
|
||||
# Initialize libtool
|
||||
LT_PREREQ([2.2.6])
|
||||
@ -58,25 +57,10 @@ fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||
|
||||
AC_ARG_ENABLE([systemd],
|
||||
AS_HELP_STRING([--enable-systemd], [Use systemd]),
|
||||
[enable_systemd=$enableval],
|
||||
[enable_systemd=auto])
|
||||
AS_IF([test x$enable_systemd != xno], [
|
||||
AC_MSG_CHECKING([for libsystemd-journal])
|
||||
PKG_CHECK_EXISTS([libsystemd-journal],
|
||||
[have_systemd=yes
|
||||
AC_DEFINE([HAVE_SYSTEMD], [1], [Define if we have systemd])],
|
||||
[have_systemd=no])
|
||||
AC_MSG_RESULT($have_systemd)
|
||||
])
|
||||
|
||||
AC_MSG_RESULT($enable_systemd)
|
||||
|
||||
CLUTTER_MIN_VERSION=1.13.4
|
||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||
GJS_MIN_VERSION=1.38.1
|
||||
MUTTER_MIN_VERSION=3.11.1
|
||||
MUTTER_MIN_VERSION=3.10.2
|
||||
GTK_MIN_VERSION=3.7.9
|
||||
GIO_MIN_VERSION=2.37.0
|
||||
LIBECAL_MIN_VERSION=3.5.3
|
||||
@ -86,6 +70,7 @@ POLKIT_MIN_VERSION=0.100
|
||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||
GCR_MIN_VERSION=3.7.5
|
||||
GNOME_DESKTOP_REQUIRED_VERSION=3.7.90
|
||||
GNOME_MENUS_REQUIRED_VERSION=3.5.3
|
||||
NETWORKMANAGER_MIN_VERSION=0.9.8
|
||||
PULSE_MIN_VERS=2.0
|
||||
|
||||
@ -95,6 +80,7 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||
atk-bridge-2.0
|
||||
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
||||
libgnome-menu-3.0 >= $GNOME_MENUS_REQUIRED_VERSION
|
||||
$recorder_modules
|
||||
gdk-x11-3.0 libsoup-2.4
|
||||
xtst
|
||||
@ -108,9 +94,6 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
|
||||
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
|
||||
libsecret-unstable gcr-base-3 >= $GCR_MIN_VERSION"
|
||||
if test x$have_systemd = xyes; then
|
||||
SHARED_PCS="${SHARED_PCS} libsystemd-journal"
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS)
|
||||
PKG_CHECK_MODULES(MUTTER, libmutter >= $MUTTER_MIN_VERSION)
|
||||
@ -126,20 +109,12 @@ 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.8 x11)
|
||||
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
||||
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
||||
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
||||
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
|
||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.4)
|
||||
PKG_CHECK_MODULES(CARIBOU, caribou-1.0 >= 0.4.8)
|
||||
|
||||
AC_ARG_ENABLE(browser-plugin,
|
||||
[AS_HELP_STRING([--enable-browser-plugin],
|
||||
[Enable browser plugin [default=yes]])],,
|
||||
enable_browser_plugin=yes)
|
||||
AS_IF([test x$enable_browser_plugin = xyes], [
|
||||
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
||||
])
|
||||
AM_CONDITIONAL(BUILD_BROWSER_PLUGIN, test x$enable_browser_plugin = xyes)
|
||||
|
||||
AC_MSG_CHECKING([for bluetooth support])
|
||||
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.9.0],
|
||||
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=applet_libdir gnome-bluetooth-1.0`
|
||||
@ -172,9 +147,6 @@ AC_SUBST(MUTTER_TYPELIB_DIR)
|
||||
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
||||
AC_SUBST(GJS_CONSOLE)
|
||||
|
||||
GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0`
|
||||
AC_SUBST(GLIB_COMPILE_RESOURCES)
|
||||
|
||||
AC_CHECK_FUNCS(fdwalk)
|
||||
AC_CHECK_FUNCS(mallinfo)
|
||||
AC_CHECK_HEADERS([sys/resource.h])
|
||||
|
@ -1,3 +1,6 @@
|
||||
wandadir = $(pkgdatadir)
|
||||
dist_wanda_DATA = wanda.png
|
||||
|
||||
desktopdir=$(datadir)/applications
|
||||
desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
|
||||
if HAVE_MUTTER_WAYLAND
|
||||
|
@ -306,13 +306,16 @@ StScrollBar StButton#vhandle:active {
|
||||
font-size: 12pt;
|
||||
border-bottom: 1px solid #666;
|
||||
padding: 12px;
|
||||
spacing: 20px;
|
||||
}
|
||||
|
||||
.nm-dialog-item:selected {
|
||||
.nm-dialog-item:checked {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.nm-dialog-item-box {
|
||||
spacing: 20px;
|
||||
}
|
||||
|
||||
.nm-dialog-icons {
|
||||
spacing: .5em;
|
||||
}
|
||||
@ -1967,11 +1970,6 @@ StScrollBar StButton#vhandle:active {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
.end-session-dialog-session-list,
|
||||
.end-session-dialog-app-list {
|
||||
spacing: 1em;
|
||||
}
|
||||
|
||||
.end-session-dialog-list-header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
BIN
data/wanda.png
Normal file
BIN
data/wanda.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
132
js/Makefile.am
132
js/Makefile.am
@ -1,5 +1,7 @@
|
||||
NULL =
|
||||
BUILT_SOURCES =
|
||||
|
||||
EXTRA_DIST = misc/config.js.in
|
||||
CLEANFILES = misc/config.js
|
||||
|
||||
misc/config.js: misc/config.js.in Makefile
|
||||
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
|
||||
@ -12,26 +14,112 @@ misc/config.js: misc/config.js.in Makefile
|
||||
-e "s|[@]sysconfdir@|$(sysconfdir)|g" \
|
||||
$< > $@
|
||||
|
||||
js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/js-resources.gresource.xml)
|
||||
js-resources.h: js-resources.gresource.xml $(js_resource_files) misc/config.js
|
||||
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate --c-name shell_js_resources $<
|
||||
js-resources.c: js-resources.gresource.xml $(js_resource_files) misc/config.js
|
||||
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate --c-name shell_js_resources $<
|
||||
jsdir = $(pkgdatadir)/js
|
||||
|
||||
js_built_sources = js-resources.c js-resources.h
|
||||
|
||||
BUILT_SOURCES += $(js_built_sources)
|
||||
|
||||
all-local: $(js_built_sources)
|
||||
|
||||
js_resource_dist_files = $(filter-out misc/config.js, $(js_resource_files))
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(js_resource_dist_files) \
|
||||
js-resources.gresource.xml \
|
||||
misc/config.js.in \
|
||||
$(NULL)
|
||||
|
||||
CLEANFILES = \
|
||||
$(js_built_sources) \
|
||||
nobase_dist_js_DATA = \
|
||||
gdm/authPrompt.js \
|
||||
gdm/batch.js \
|
||||
gdm/fingerprint.js \
|
||||
gdm/loginDialog.js \
|
||||
gdm/oVirt.js \
|
||||
gdm/realmd.js \
|
||||
gdm/util.js \
|
||||
extensionPrefs/main.js \
|
||||
misc/config.js \
|
||||
misc/extensionUtils.js \
|
||||
misc/fileUtils.js \
|
||||
misc/gnomeSession.js \
|
||||
misc/hash.js \
|
||||
misc/history.js \
|
||||
misc/jsParse.js \
|
||||
misc/loginManager.js \
|
||||
misc/modemManager.js \
|
||||
misc/objectManager.js \
|
||||
misc/params.js \
|
||||
misc/smartcardManager.js \
|
||||
misc/util.js \
|
||||
perf/core.js \
|
||||
ui/altTab.js \
|
||||
ui/animation.js \
|
||||
ui/appDisplay.js \
|
||||
ui/appFavorites.js \
|
||||
ui/backgroundMenu.js \
|
||||
ui/background.js \
|
||||
ui/boxpointer.js \
|
||||
ui/calendar.js \
|
||||
ui/checkBox.js \
|
||||
ui/ctrlAltTab.js \
|
||||
ui/dash.js \
|
||||
ui/dateMenu.js \
|
||||
ui/dnd.js \
|
||||
ui/endSessionDialog.js \
|
||||
ui/extensionSystem.js \
|
||||
ui/extensionDownloader.js \
|
||||
ui/environment.js \
|
||||
ui/focusCaretTracker.js\
|
||||
ui/ibusCandidatePopup.js\
|
||||
ui/grabHelper.js \
|
||||
ui/iconGrid.js \
|
||||
ui/keyboard.js \
|
||||
ui/layout.js \
|
||||
ui/lightbox.js \
|
||||
ui/lookingGlass.js \
|
||||
ui/magnifier.js \
|
||||
ui/magnifierDBus.js \
|
||||
ui/main.js \
|
||||
ui/messageTray.js \
|
||||
ui/modalDialog.js \
|
||||
ui/separator.js \
|
||||
ui/sessionMode.js \
|
||||
ui/shellEntry.js \
|
||||
ui/shellMountOperation.js \
|
||||
ui/slider.js \
|
||||
ui/notificationDaemon.js \
|
||||
ui/osdWindow.js \
|
||||
ui/overview.js \
|
||||
ui/overviewControls.js \
|
||||
ui/panel.js \
|
||||
ui/panelMenu.js \
|
||||
ui/pointerWatcher.js \
|
||||
ui/popupMenu.js \
|
||||
ui/remoteSearch.js \
|
||||
ui/remoteMenu.js \
|
||||
ui/runDialog.js \
|
||||
ui/screencast.js \
|
||||
ui/screenshot.js \
|
||||
ui/screenShield.js \
|
||||
ui/scripting.js \
|
||||
ui/search.js \
|
||||
ui/searchDisplay.js \
|
||||
ui/shellDBus.js \
|
||||
ui/status/accessibility.js \
|
||||
ui/status/brightness.js \
|
||||
ui/status/keyboard.js \
|
||||
ui/status/network.js \
|
||||
ui/status/power.js \
|
||||
ui/status/rfkill.js \
|
||||
ui/status/volume.js \
|
||||
ui/status/bluetooth.js \
|
||||
ui/status/screencast.js \
|
||||
ui/status/system.js \
|
||||
ui/switcherPopup.js \
|
||||
ui/tweener.js \
|
||||
ui/unlockDialog.js \
|
||||
ui/userWidget.js \
|
||||
ui/viewSelector.js \
|
||||
ui/wanda.js \
|
||||
ui/windowAttentionHandler.js \
|
||||
ui/windowManager.js \
|
||||
ui/workspace.js \
|
||||
ui/workspaceThumbnail.js \
|
||||
ui/workspacesView.js \
|
||||
ui/workspaceSwitcherPopup.js \
|
||||
ui/xdndHandler.js \
|
||||
ui/components/__init__.js \
|
||||
ui/components/autorunManager.js \
|
||||
ui/components/automountManager.js \
|
||||
ui/components/networkAgent.js \
|
||||
ui/components/polkitAgent.js \
|
||||
ui/components/telepathyClient.js \
|
||||
ui/components/keyring.js \
|
||||
$(NULL)
|
||||
|
@ -13,15 +13,13 @@ const _ = Gettext.gettext;
|
||||
const Config = imports.misc.config;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
|
||||
const GnomeShellIface = '<node> \
|
||||
<interface name="org.gnome.Shell.Extensions"> \
|
||||
<signal name="ExtensionStatusChanged"> \
|
||||
<arg type="s" name="uuid"/> \
|
||||
<arg type="i" name="state"/> \
|
||||
<arg type="s" name="error"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const GnomeShellIface = <interface name="org.gnome.Shell.Extensions">
|
||||
<signal name="ExtensionStatusChanged">
|
||||
<arg type="s" name="uuid"/>
|
||||
<arg type="i" name="state"/>
|
||||
<arg type="s" name="error"/>
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
|
||||
|
||||
@ -206,11 +204,11 @@ const Application = new Lang.Class({
|
||||
_scanExtensions: function() {
|
||||
let finder = new ExtensionUtils.ExtensionFinder();
|
||||
finder.connect('extension-found', Lang.bind(this, this._extensionFound));
|
||||
finder.connect('extensions-loaded', Lang.bind(this, this._extensionsLoaded));
|
||||
finder.scanExtensions();
|
||||
this._extensionsLoaded();
|
||||
},
|
||||
|
||||
_extensionFound: function(finder, extension) {
|
||||
_extensionFound: function(signals, extension) {
|
||||
let iter = this._model.append();
|
||||
this._model.set(iter, [0, 1], [extension.uuid, extension.metadata.name]);
|
||||
this._extensionIters[extension.uuid] = iter;
|
||||
|
@ -5,13 +5,11 @@ const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const FprintManagerIface = '<node> \
|
||||
<interface name="net.reactivated.Fprint.Manager"> \
|
||||
<method name="GetDefaultDevice"> \
|
||||
<arg type="o" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
|
||||
<method name='GetDefaultDevice'>
|
||||
<arg type='o' direction='out' />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface);
|
||||
|
||||
|
@ -59,7 +59,7 @@ const UserListItem = new Lang.Class({
|
||||
this._userChangedId = this.user.connect('changed',
|
||||
Lang.bind(this, this._onUserChanged));
|
||||
|
||||
let layout = new St.BoxLayout({ vertical: true });
|
||||
let layout = new St.BoxLayout({ vertical: false });
|
||||
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||
can_focus: true,
|
||||
@ -68,18 +68,39 @@ const UserListItem = new Lang.Class({
|
||||
x_align: St.Align.START,
|
||||
x_fill: true });
|
||||
|
||||
this._userWidget = new UserWidget.UserWidget(this.user);
|
||||
layout.add(this._userWidget.actor);
|
||||
this._userAvatar = new UserWidget.Avatar(this.user,
|
||||
{ styleClass: 'login-dialog-user-list-item-icon' });
|
||||
layout.add(this._userAvatar.actor);
|
||||
let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box',
|
||||
vertical: true });
|
||||
layout.add(textLayout, { expand: true });
|
||||
|
||||
this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' });
|
||||
this.actor.label_actor = this._nameLabel;
|
||||
textLayout.add(this._nameLabel,
|
||||
{ y_fill: false,
|
||||
y_align: St.Align.MIDDLE,
|
||||
expand: true });
|
||||
|
||||
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
|
||||
scale_x: 0 });
|
||||
layout.add(this._timedLoginIndicator);
|
||||
textLayout.add(this._timedLoginIndicator,
|
||||
{ x_fill: true,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_fill: false,
|
||||
y_align: St.Align.END });
|
||||
|
||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
this._onUserChanged();
|
||||
},
|
||||
|
||||
_onUserChanged: function() {
|
||||
this._nameLabel.set_text(this.user.get_real_name());
|
||||
this._userAvatar.update();
|
||||
this._updateLoggedIn();
|
||||
},
|
||||
|
||||
syncStyleClasses: function() {
|
||||
this._updateLoggedIn();
|
||||
},
|
||||
|
||||
@ -168,6 +189,7 @@ const UserList = new Lang.Class({
|
||||
for (let userName in this._items) {
|
||||
let item = this._items[userName];
|
||||
item.actor.sync_hover();
|
||||
item.syncStyleClasses();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -4,13 +4,11 @@ const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const OVirtCredentialsIface = '<node> \
|
||||
<interface name="org.ovirt.vdsm.Credentials"> \
|
||||
<signal name="UserAuthenticated"> \
|
||||
<arg type="s" name="token"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const OVirtCredentialsIface = <interface name='org.ovirt.vdsm.Credentials'>
|
||||
<signal name="UserAuthenticated">
|
||||
<arg type="s" name="token"/>
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const OVirtCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(OVirtCredentialsIface);
|
||||
|
||||
|
@ -5,58 +5,52 @@ const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const ProviderIface = '<node> \
|
||||
<interface name="org.freedesktop.realmd.Provider"> \
|
||||
<property name="Name" type="s" access="read"/> \
|
||||
<property name="Version" type="s" access="read"/> \
|
||||
<property name="Realms" type="ao" access="read"/> \
|
||||
<method name="Discover"> \
|
||||
<arg name="string" type="s" direction="in"/> \
|
||||
<arg name="options" type="a{sv}" direction="in"/> \
|
||||
<arg name="relevance" type="i" direction="out"/> \
|
||||
<arg name="realm" type="ao" direction="out"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ProviderIface = <interface name='org.freedesktop.realmd.Provider'>
|
||||
<property name="Name" type="s" access="read"/>
|
||||
<property name="Version" type="s" access="read"/>
|
||||
<property name="Realms" type="ao" access="read"/>
|
||||
<method name="Discover">
|
||||
<arg name="string" type="s" direction="in"/>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
<arg name="relevance" type="i" direction="out"/>
|
||||
<arg name="realm" type="ao" direction="out"/>
|
||||
</method>
|
||||
</interface>;
|
||||
const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface);
|
||||
|
||||
const ServiceIface = '<node> \
|
||||
<interface name="org.freedesktop.realmd.Service"> \
|
||||
<method name="Cancel"> \
|
||||
<arg name="operation" type="s" direction="in"/> \
|
||||
</method> \
|
||||
<method name="Release" /> \
|
||||
<method name="SetLocale"> \
|
||||
<arg name="locale" type="s" direction="in"/> \
|
||||
</method> \
|
||||
<signal name="Diagnostics"> \
|
||||
<arg name="data" type="s"/> \
|
||||
<arg name="operation" type="s"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ServiceIface = <interface name="org.freedesktop.realmd.Service">
|
||||
<method name="Cancel">
|
||||
<arg name="operation" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="Release" />
|
||||
<method name="SetLocale">
|
||||
<arg name="locale" type="s" direction="in"/>
|
||||
</method>
|
||||
<signal name="Diagnostics">
|
||||
<arg name="data" type="s"/>
|
||||
<arg name="operation" type="s"/>
|
||||
</signal>
|
||||
</interface>;
|
||||
const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
|
||||
|
||||
const RealmIface = '<node> \
|
||||
<interface name="org.freedesktop.realmd.Realm"> \
|
||||
<property name="Name" type="s" access="read"/> \
|
||||
<property name="Configured" type="s" access="read"/> \
|
||||
<property name="Details" type="a(ss)" access="read"/> \
|
||||
<property name="LoginFormats" type="as" access="read"/> \
|
||||
<property name="LoginPolicy" type="s" access="read"/> \
|
||||
<property name="PermittedLogins" type="as" access="read"/> \
|
||||
<property name="SupportedInterfaces" type="as" access="read"/> \
|
||||
<method name="ChangeLoginPolicy"> \
|
||||
<arg name="login_policy" type="s" direction="in"/> \
|
||||
<arg name="permitted_add" type="as" direction="in"/> \
|
||||
<arg name="permitted_remove" type="as" direction="in"/> \
|
||||
<arg name="options" type="a{sv}" direction="in"/> \
|
||||
</method> \
|
||||
<method name="Deconfigure"> \
|
||||
<arg name="options" type="a{sv}" direction="in"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const RealmIface = <interface name="org.freedesktop.realmd.Realm">
|
||||
<property name="Name" type="s" access="read"/>
|
||||
<property name="Configured" type="s" access="read"/>
|
||||
<property name="Details" type="a(ss)" access="read"/>
|
||||
<property name="LoginFormats" type="as" access="read"/>
|
||||
<property name="LoginPolicy" type="s" access="read"/>
|
||||
<property name="PermittedLogins" type="as" access="read"/>
|
||||
<property name="SupportedInterfaces" type="as" access="read"/>
|
||||
<method name="ChangeLoginPolicy">
|
||||
<arg name="login_policy" type="s" direction="in"/>
|
||||
<arg name="permitted_add" type="as" direction="in"/>
|
||||
<arg name="permitted_remove" type="as" direction="in"/>
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
</method>
|
||||
<method name="Deconfigure">
|
||||
<arg name="options" type="a{sv}" direction="in"/>
|
||||
</method>
|
||||
</interface>;
|
||||
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
|
||||
|
||||
const Manager = new Lang.Class({
|
||||
|
@ -1,108 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/shell">
|
||||
<file>gdm/authPrompt.js</file>
|
||||
<file>gdm/batch.js</file>
|
||||
<file>gdm/fingerprint.js</file>
|
||||
<file>gdm/loginDialog.js</file>
|
||||
<file>gdm/oVirt.js</file>
|
||||
<file>gdm/realmd.js</file>
|
||||
<file>gdm/util.js</file>
|
||||
<file>extensionPrefs/main.js</file>
|
||||
<file>misc/config.js</file>
|
||||
<file>misc/extensionUtils.js</file>
|
||||
<file>misc/fileUtils.js</file>
|
||||
<file>misc/gnomeSession.js</file>
|
||||
<file>misc/hash.js</file>
|
||||
<file>misc/history.js</file>
|
||||
<file>misc/jsParse.js</file>
|
||||
<file>misc/loginManager.js</file>
|
||||
<file>misc/modemManager.js</file>
|
||||
<file>misc/objectManager.js</file>
|
||||
<file>misc/params.js</file>
|
||||
<file>misc/smartcardManager.js</file>
|
||||
<file>misc/util.js</file>
|
||||
<file>perf/core.js</file>
|
||||
<file>ui/altTab.js</file>
|
||||
<file>ui/animation.js</file>
|
||||
<file>ui/appDisplay.js</file>
|
||||
<file>ui/appFavorites.js</file>
|
||||
<file>ui/backgroundMenu.js</file>
|
||||
<file>ui/background.js</file>
|
||||
<file>ui/boxpointer.js</file>
|
||||
<file>ui/calendar.js</file>
|
||||
<file>ui/checkBox.js</file>
|
||||
<file>ui/ctrlAltTab.js</file>
|
||||
<file>ui/dash.js</file>
|
||||
<file>ui/dateMenu.js</file>
|
||||
<file>ui/dnd.js</file>
|
||||
<file>ui/endSessionDialog.js</file>
|
||||
<file>ui/extensionSystem.js</file>
|
||||
<file>ui/extensionDownloader.js</file>
|
||||
<file>ui/environment.js</file>
|
||||
<file>ui/focusCaretTracker.js</file>
|
||||
<file>ui/ibusCandidatePopup.js</file>
|
||||
<file>ui/grabHelper.js</file>
|
||||
<file>ui/iconGrid.js</file>
|
||||
<file>ui/keyboard.js</file>
|
||||
<file>ui/layout.js</file>
|
||||
<file>ui/lightbox.js</file>
|
||||
<file>ui/lookingGlass.js</file>
|
||||
<file>ui/magnifier.js</file>
|
||||
<file>ui/magnifierDBus.js</file>
|
||||
<file>ui/main.js</file>
|
||||
<file>ui/messageTray.js</file>
|
||||
<file>ui/modalDialog.js</file>
|
||||
<file>ui/separator.js</file>
|
||||
<file>ui/sessionMode.js</file>
|
||||
<file>ui/shellEntry.js</file>
|
||||
<file>ui/shellMountOperation.js</file>
|
||||
<file>ui/slider.js</file>
|
||||
<file>ui/notificationDaemon.js</file>
|
||||
<file>ui/osdWindow.js</file>
|
||||
<file>ui/overview.js</file>
|
||||
<file>ui/overviewControls.js</file>
|
||||
<file>ui/panel.js</file>
|
||||
<file>ui/panelMenu.js</file>
|
||||
<file>ui/pointerWatcher.js</file>
|
||||
<file>ui/popupMenu.js</file>
|
||||
<file>ui/remoteSearch.js</file>
|
||||
<file>ui/remoteMenu.js</file>
|
||||
<file>ui/runDialog.js</file>
|
||||
<file>ui/screencast.js</file>
|
||||
<file>ui/screenshot.js</file>
|
||||
<file>ui/screenShield.js</file>
|
||||
<file>ui/scripting.js</file>
|
||||
<file>ui/search.js</file>
|
||||
<file>ui/shellDBus.js</file>
|
||||
<file>ui/status/accessibility.js</file>
|
||||
<file>ui/status/brightness.js</file>
|
||||
<file>ui/status/keyboard.js</file>
|
||||
<file>ui/status/network.js</file>
|
||||
<file>ui/status/power.js</file>
|
||||
<file>ui/status/rfkill.js</file>
|
||||
<file>ui/status/volume.js</file>
|
||||
<file>ui/status/bluetooth.js</file>
|
||||
<file>ui/status/screencast.js</file>
|
||||
<file>ui/status/system.js</file>
|
||||
<file>ui/switcherPopup.js</file>
|
||||
<file>ui/tweener.js</file>
|
||||
<file>ui/unlockDialog.js</file>
|
||||
<file>ui/userWidget.js</file>
|
||||
<file>ui/viewSelector.js</file>
|
||||
<file>ui/windowAttentionHandler.js</file>
|
||||
<file>ui/windowManager.js</file>
|
||||
<file>ui/workspace.js</file>
|
||||
<file>ui/workspaceThumbnail.js</file>
|
||||
<file>ui/workspacesView.js</file>
|
||||
<file>ui/workspaceSwitcherPopup.js</file>
|
||||
<file>ui/xdndHandler.js</file>
|
||||
<file>ui/components/__init__.js</file>
|
||||
<file>ui/components/autorunManager.js</file>
|
||||
<file>ui/components/automountManager.js</file>
|
||||
<file>ui/components/networkAgent.js</file>
|
||||
<file>ui/components/polkitAgent.js</file>
|
||||
<file>ui/components/telepathyClient.js</file>
|
||||
<file>ui/components/keyring.js</file>
|
||||
</gresource>
|
||||
</gresources>
|
@ -174,9 +174,17 @@ const ExtensionFinder = new Lang.Class({
|
||||
this.emit('extension-found', extension);
|
||||
},
|
||||
|
||||
_extensionsLoaded: function() {
|
||||
this.emit('extensions-loaded');
|
||||
},
|
||||
|
||||
scanExtensions: function() {
|
||||
let perUserDir = Gio.File.new_for_path(global.userdatadir);
|
||||
FileUtils.collectFromDatadirs('extensions', true, Lang.bind(this, this._loadExtension, perUserDir));
|
||||
FileUtils.collectFromDatadirsAsync('extensions',
|
||||
{ processFile: Lang.bind(this, this._loadExtension),
|
||||
loadedCallback: Lang.bind(this, this._extensionsLoaded),
|
||||
includeUserDir: true,
|
||||
data: perUserDir });
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ExtensionFinder.prototype);
|
||||
|
@ -25,27 +25,60 @@ function listDirAsync(file, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function collectFromDatadirs(subdir, includeUserDir, processFile) {
|
||||
function _collectFromDirectoryAsync(dir, loadState) {
|
||||
function done() {
|
||||
loadState.numLoading--;
|
||||
if (loadState.loadedCallback &&
|
||||
loadState.numLoading == 0)
|
||||
loadState.loadedCallback(loadState.data);
|
||||
}
|
||||
|
||||
dir.query_info_async('standard::type', Gio.FileQueryInfoFlags.NONE,
|
||||
GLib.PRIORITY_DEFAULT, null, function(object, res) {
|
||||
try {
|
||||
object.query_info_finish(res);
|
||||
} catch (e) {
|
||||
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
|
||||
log(e.message);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
listDirAsync(dir, Lang.bind(this, function(infos) {
|
||||
for (let i = 0; i < infos.length; i++)
|
||||
loadState.processFile(dir.get_child(infos[i].get_name()),
|
||||
infos[i], loadState.data);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function collectFromDatadirsAsync(subdir, params) {
|
||||
params = Params.parse(params, { includeUserDir: false,
|
||||
processFile: null,
|
||||
loadedCallback: null,
|
||||
data: null });
|
||||
let loadState = { data: params.data,
|
||||
numLoading: 0,
|
||||
loadedCallback: params.loadedCallback,
|
||||
processFile: params.processFile };
|
||||
|
||||
if (params.processFile == null) {
|
||||
if (params.loadedCallback)
|
||||
params.loadedCallback(params.data);
|
||||
return;
|
||||
}
|
||||
|
||||
let dataDirs = GLib.get_system_data_dirs();
|
||||
if (includeUserDir)
|
||||
if (params.includeUserDir)
|
||||
dataDirs.unshift(GLib.get_user_data_dir());
|
||||
loadState.numLoading = dataDirs.length;
|
||||
|
||||
for (let i = 0; i < dataDirs.length; i++) {
|
||||
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', subdir]);
|
||||
let dir = Gio.File.new_for_path(path);
|
||||
|
||||
let fileEnum;
|
||||
try {
|
||||
fileEnum = dir.enumerate_children('standard::name,standard::type',
|
||||
Gio.FileQueryInfoFlags.NONE, null);
|
||||
} catch (e) {
|
||||
fileEnum = null;
|
||||
}
|
||||
if (fileEnum != null) {
|
||||
let info;
|
||||
while ((info = fileEnum.next_file(null)))
|
||||
processFile(fileEnum.get_child(info), info);
|
||||
}
|
||||
_collectFromDirectoryAsync(dir, loadState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,17 +4,15 @@ const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const PresenceIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager.Presence"> \
|
||||
<method name="SetStatus"> \
|
||||
<arg type="u" direction="in"/> \
|
||||
</method> \
|
||||
<property name="status" type="u" access="readwrite"/> \
|
||||
<signal name="StatusChanged"> \
|
||||
<arg type="u" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const PresenceIface = <interface name="org.gnome.SessionManager.Presence">
|
||||
<method name="SetStatus">
|
||||
<arg type="u" direction="in"/>
|
||||
</method>
|
||||
<property name="status" type="u" access="readwrite"/>
|
||||
<signal name="StatusChanged">
|
||||
<arg type="u" direction="out"/>
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const PresenceStatus = {
|
||||
AVAILABLE: 0,
|
||||
@ -32,16 +30,14 @@ function Presence(initCallback, cancellable) {
|
||||
// Note inhibitors are immutable objects, so they don't
|
||||
// change at runtime (changes always come in the form
|
||||
// of new inhibitors)
|
||||
const InhibitorIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager.Inhibitor"> \
|
||||
<method name="GetAppId"> \
|
||||
<arg type="s" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetReason"> \
|
||||
<arg type="s" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const InhibitorIface = <interface name="org.gnome.SessionManager.Inhibitor">
|
||||
<method name="GetAppId">
|
||||
<arg type="s" direction="out" />
|
||||
</method>
|
||||
<method name="GetReason">
|
||||
<arg type="s" direction="out" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface);
|
||||
function Inhibitor(objectPath, initCallback, cancellable) {
|
||||
@ -49,29 +45,27 @@ function Inhibitor(objectPath, initCallback, cancellable) {
|
||||
}
|
||||
|
||||
// Not the full interface, only the methods we use
|
||||
const SessionManagerIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager"> \
|
||||
<method name="Logout"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="Shutdown" /> \
|
||||
<method name="Reboot" /> \
|
||||
<method name="CanShutdown"> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<method name="IsInhibited"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<property name="SessionIsActive" type="b" access="read"/> \
|
||||
<signal name="InhibitorAdded"> \
|
||||
<arg type="o" direction="out"/> \
|
||||
</signal> \
|
||||
<signal name="InhibitorRemoved"> \
|
||||
<arg type="o" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SessionManagerIface = <interface name="org.gnome.SessionManager">
|
||||
<method name="Logout">
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
<method name="Shutdown" />
|
||||
<method name="Reboot" />
|
||||
<method name="CanShutdown">
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<method name="IsInhibited">
|
||||
<arg type="u" direction="in" />
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<property name="SessionIsActive" type="b" access="read"/>
|
||||
<signal name="InhibitorAdded">
|
||||
<arg type="o" direction="out"/>
|
||||
</signal>
|
||||
<signal name="InhibitorRemoved">
|
||||
<arg type="o" direction="out"/>
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
||||
function SessionManager(initCallback, cancellable) {
|
||||
|
@ -7,66 +7,58 @@ const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const SystemdLoginManagerIface = '<node> \
|
||||
<interface name="org.freedesktop.login1.Manager"> \
|
||||
<method name="Suspend"> \
|
||||
<arg type="b" direction="in"/> \
|
||||
</method> \
|
||||
<method name="CanSuspend"> \
|
||||
<arg type="s" direction="out"/> \
|
||||
</method> \
|
||||
<method name="Inhibit"> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="h" direction="out"/> \
|
||||
</method> \
|
||||
<method name="GetSession"> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="o" direction="out"/> \
|
||||
</method> \
|
||||
<method name="ListSessions"> \
|
||||
<arg name="sessions" type="a(susso)" direction="out"/> \
|
||||
</method> \
|
||||
<signal name="PrepareForSleep"> \
|
||||
<arg type="b" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager'>
|
||||
<method name='Suspend'>
|
||||
<arg type='b' direction='in'/>
|
||||
</method>
|
||||
<method name='CanSuspend'>
|
||||
<arg type='s' direction='out'/>
|
||||
</method>
|
||||
<method name='Inhibit'>
|
||||
<arg type='s' direction='in'/>
|
||||
<arg type='s' direction='in'/>
|
||||
<arg type='s' direction='in'/>
|
||||
<arg type='s' direction='in'/>
|
||||
<arg type='h' direction='out'/>
|
||||
</method>
|
||||
<method name='GetSession'>
|
||||
<arg type='s' direction='in'/>
|
||||
<arg type='o' direction='out'/>
|
||||
</method>
|
||||
<method name='ListSessions'>
|
||||
<arg name='sessions' type='a(susso)' direction='out'/>
|
||||
</method>
|
||||
<signal name='PrepareForSleep'>
|
||||
<arg type='b' direction='out'/>
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const SystemdLoginSessionIface = '<node> \
|
||||
<interface name="org.freedesktop.login1.Session"> \
|
||||
<signal name="Lock" /> \
|
||||
<signal name="Unlock" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session'>
|
||||
<signal name='Lock' />
|
||||
<signal name='Unlock' />
|
||||
</interface>;
|
||||
|
||||
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface);
|
||||
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
|
||||
|
||||
const ConsoleKitManagerIface = '<node> \
|
||||
<interface name="org.freedesktop.ConsoleKit.Manager"> \
|
||||
<method name="CanRestart"> \
|
||||
<arg type="b" direction="out"/> \
|
||||
</method> \
|
||||
<method name="CanStop"> \
|
||||
<arg type="b" direction="out"/> \
|
||||
</method> \
|
||||
<method name="Restart" /> \
|
||||
<method name="Stop" /> \
|
||||
<method name="GetCurrentSession"> \
|
||||
<arg type="o" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
|
||||
<method name='CanRestart'>
|
||||
<arg type='b' direction='out'/>
|
||||
</method>
|
||||
<method name='CanStop'>
|
||||
<arg type='b' direction='out'/>
|
||||
</method>
|
||||
<method name='Restart' />
|
||||
<method name='Stop' />
|
||||
<method name='GetCurrentSession'>
|
||||
<arg type='o' direction='out' />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const ConsoleKitSessionIface = '<node> \
|
||||
<interface name="org.freedesktop.ConsoleKit.Session"> \
|
||||
<signal name="Lock" /> \
|
||||
<signal name="Unlock" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ConsoleKitSessionIface = <interface name='org.freedesktop.ConsoleKit.Session'>
|
||||
<signal name='Lock' />
|
||||
<signal name='Unlock' />
|
||||
</interface>;
|
||||
|
||||
const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
|
||||
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
|
||||
|
@ -92,41 +92,37 @@ function _findProviderForSid(sid) {
|
||||
// The following are not the complete interfaces, just the methods we need
|
||||
// (or may need in the future)
|
||||
|
||||
const ModemGsmNetworkInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager.Modem.Gsm.Network"> \
|
||||
<method name="GetRegistrationInfo"> \
|
||||
<arg type="(uss)" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetSignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</method> \
|
||||
<property name="AccessTechnology" type="u" access="read" /> \
|
||||
<signal name="SignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</signal> \
|
||||
<signal name="RegistrationInfo"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
<arg type="s" direction="out" /> \
|
||||
<arg type="s" direction="out" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network">
|
||||
<method name="GetRegistrationInfo">
|
||||
<arg type="(uss)" direction="out" />
|
||||
</method>
|
||||
<method name="GetSignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</method>
|
||||
<property name="AccessTechnology" type="u" access="read" />
|
||||
<signal name="SignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</signal>
|
||||
<signal name="RegistrationInfo">
|
||||
<arg type="u" direction="out" />
|
||||
<arg type="s" direction="out" />
|
||||
<arg type="s" direction="out" />
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface);
|
||||
|
||||
const ModemCdmaInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager.Modem.Cdma"> \
|
||||
<method name="GetSignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetServingSystem"> \
|
||||
<arg type="(usu)" direction="out" /> \
|
||||
</method> \
|
||||
<signal name="SignalQuality"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
|
||||
<method name="GetSignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</method>
|
||||
<method name="GetServingSystem">
|
||||
<arg type="(usu)" direction="out" />
|
||||
</method>
|
||||
<signal name="SignalQuality">
|
||||
<arg type="u" direction="out" />
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||
|
||||
@ -222,26 +218,20 @@ Signals.addSignalMethods(ModemCdma.prototype);
|
||||
// Support for the new ModemManager1 interface (MM >= 0.7)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const BroadbandModemInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager1.Modem"> \
|
||||
<property name="SignalQuality" type="(ub)" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BroadbandModemInterface = <interface name="org.freedesktop.ModemManager1.Modem">
|
||||
<property name="SignalQuality" type="(ub)" access="read" />
|
||||
</interface>;
|
||||
const BroadbandModemProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemInterface);
|
||||
|
||||
const BroadbandModem3gppInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp"> \
|
||||
<property name="OperatorCode" type="s" access="read" /> \
|
||||
<property name="OperatorName" type="s" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BroadbandModem3gppInterface = <interface name="org.freedesktop.ModemManager1.Modem.Modem3gpp">
|
||||
<property name="OperatorCode" type="s" access="read" />
|
||||
<property name="OperatorName" type="s" access="read" />
|
||||
</interface>;
|
||||
const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gppInterface);
|
||||
|
||||
const BroadbandModemCdmaInterface = '<node> \
|
||||
<interface name="org.freedesktop.ModemManager1.Modem.ModemCdma"> \
|
||||
<property name="Sid" type="u" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BroadbandModemCdmaInterface = <interface name="org.freedesktop.ModemManager1.Modem.ModemCdma">
|
||||
<property name="Sid" type="u" access="read" />
|
||||
</interface>;
|
||||
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
|
||||
|
||||
const BroadbandModem = new Lang.Class({
|
||||
|
@ -8,21 +8,19 @@ const Signals = imports.signals;
|
||||
|
||||
// Specified in the D-Bus specification here:
|
||||
// http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
|
||||
const ObjectManagerIface = '<node> \
|
||||
<interface name="org.freedesktop.DBus.ObjectManager"> \
|
||||
<method name="GetManagedObjects"> \
|
||||
<arg name="objects" type="a{oa{sa{sv}}}" direction="out"/> \
|
||||
</method> \
|
||||
<signal name="InterfacesAdded"> \
|
||||
<arg name="objectPath" type="o"/> \
|
||||
<arg name="interfaces" type="a{sa{sv}}" /> \
|
||||
</signal> \
|
||||
<signal name="InterfacesRemoved"> \
|
||||
<arg name="objectPath" type="o"/> \
|
||||
<arg name="interfaces" type="as" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ObjectManagerIface = <interface name="org.freedesktop.DBus.ObjectManager">
|
||||
<method name="GetManagedObjects">
|
||||
<arg name="objects" type="a{oa{sa{sv}}}" direction="out"/>
|
||||
</method>
|
||||
<signal name="InterfacesAdded">
|
||||
<arg name="objectPath" type="o"/>
|
||||
<arg name="interfaces" type="a{sa{sv}}" />
|
||||
</signal>
|
||||
<signal name="InterfacesRemoved">
|
||||
<arg name="objectPath" type="o"/>
|
||||
<arg name="interfaces" type="as" />
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
|
||||
|
||||
|
@ -7,14 +7,12 @@ const Signals = imports.signals;
|
||||
|
||||
const ObjectManager = imports.misc.objectManager;
|
||||
|
||||
const SmartcardTokenIface = '<node> \
|
||||
<interface name="org.gnome.SettingsDaemon.Smartcard.Token"> \
|
||||
<property name="Name" type="s" access="read"/> \
|
||||
<property name="Driver" type="o" access="read"/> \
|
||||
<property name="IsInserted" type="b" access="read"/> \
|
||||
<property name="UsedToLogin" type="b" access="read"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SmartcardTokenIface = <interface name="org.gnome.SettingsDaemon.Smartcard.Token">
|
||||
<property name="Name" type="s" access="read"/>
|
||||
<property name="Driver" type="o" access="read"/>
|
||||
<property name="IsInserted" type="b" access="read"/>
|
||||
<property name="UsedToLogin" type="b" access="read"/>
|
||||
</interface>;
|
||||
|
||||
let _smartcardManager = null;
|
||||
|
||||
|
@ -106,8 +106,6 @@ const AppSwitcherPopup = new Lang.Class({
|
||||
|
||||
this._switcherList = new AppSwitcher(apps, this);
|
||||
this._items = this._switcherList.icons;
|
||||
if (this._items.length == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
@ -377,9 +375,6 @@ const WindowSwitcherPopup = new Lang.Class({
|
||||
this._switcherList = new WindowList(windows, mode);
|
||||
this._items = this._switcherList.icons;
|
||||
|
||||
if (this._items.length == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
@ -55,13 +55,13 @@ function _loadCategory(dir, view) {
|
||||
while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) {
|
||||
if (nextType == GMenu.TreeItemType.ENTRY) {
|
||||
let entry = iter.get_entry();
|
||||
let appInfo = entry.get_app_info();
|
||||
let app = appSystem.lookup_app(entry.get_desktop_file_id());
|
||||
if (appInfo.should_show())
|
||||
let app = appSystem.lookup_app_by_tree_entry(entry);
|
||||
if (!entry.get_app_info().get_nodisplay())
|
||||
view.addApp(app);
|
||||
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||
let itemDir = iter.get_directory();
|
||||
_loadCategory(itemDir, view);
|
||||
if (!itemDir.get_is_nodisplay())
|
||||
_loadCategory(itemDir, view);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -92,7 +92,7 @@ const BaseAppView = new Lang.Class({
|
||||
},
|
||||
|
||||
removeAll: function() {
|
||||
this._grid.destroyAll();
|
||||
this._grid.removeAll();
|
||||
this._items = {};
|
||||
this._allItems = [];
|
||||
},
|
||||
@ -613,10 +613,6 @@ const FrequentView = new Lang.Class({
|
||||
return this._usage.get_most_used("").length >= MIN_FREQUENT_APPS_COUNT;
|
||||
},
|
||||
|
||||
removeAll: function() {
|
||||
this._grid.destroyAll();
|
||||
},
|
||||
|
||||
loadApps: function() {
|
||||
let mostUsed = this._usage.get_most_used ("");
|
||||
let hasUsefulData = this.hasUsefulData();
|
||||
@ -695,7 +691,8 @@ const AppDisplay = new Lang.Class({
|
||||
Name: 'AppDisplay',
|
||||
|
||||
_init: function() {
|
||||
Shell.AppSystem.get_default().connect('installed-changed', Lang.bind(this, function() {
|
||||
this._appSystem = Shell.AppSystem.get_default();
|
||||
this._appSystem.connect('installed-changed', Lang.bind(this, function() {
|
||||
Main.queueDeferredWork(this._allAppsWorkId);
|
||||
}));
|
||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
||||
@ -816,8 +813,7 @@ const AppDisplay = new Lang.Class({
|
||||
|
||||
view.removeAll();
|
||||
|
||||
let tree = new GMenu.Tree({ menu_basename: "applications.menu" });
|
||||
tree.load_sync();
|
||||
let tree = this._appSystem.get_tree();
|
||||
let root = tree.get_root_directory();
|
||||
|
||||
let iter = root.iter();
|
||||
@ -826,6 +822,8 @@ const AppDisplay = new Lang.Class({
|
||||
while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) {
|
||||
if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||
let dir = iter.get_directory();
|
||||
if (dir.get_is_nodisplay())
|
||||
continue;
|
||||
|
||||
if (folderCategories.indexOf(dir.get_menu_id()) != -1)
|
||||
view.addFolder(dir);
|
||||
@ -873,8 +871,8 @@ const AppSearchProvider = new Lang.Class({
|
||||
getResultMetas: function(apps, callback) {
|
||||
let metas = [];
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
let app = this._appSys.lookup_app(apps[i]);
|
||||
metas.push({ 'id': app.get_id(),
|
||||
let app = apps[i];
|
||||
metas.push({ 'id': app,
|
||||
'name': app.get_name(),
|
||||
'createIcon': function(size) {
|
||||
return app.create_icon_texture(size);
|
||||
@ -888,16 +886,15 @@ const AppSearchProvider = new Lang.Class({
|
||||
return results.slice(0, maxNumber);
|
||||
},
|
||||
|
||||
getInitialResultSet: function(terms, callback, cancellable) {
|
||||
callback(this._appSys.initial_search(terms));
|
||||
getInitialResultSet: function(terms) {
|
||||
this.searchSystem.setResults(this, this._appSys.initial_search(terms));
|
||||
},
|
||||
|
||||
getSubsearchResultSet: function(previousResults, terms, callback, cancellable) {
|
||||
callback(this._appSys.subsearch(previousResults, terms));
|
||||
getSubsearchResultSet: function(previousResults, terms) {
|
||||
this.searchSystem.setResults(this, this._appSys.subsearch(previousResults, terms));
|
||||
},
|
||||
|
||||
activateResult: function(result) {
|
||||
let app = this._appSys.lookup_app(result);
|
||||
activateResult: function(app) {
|
||||
let event = Clutter.get_current_event();
|
||||
let modifiers = event ? event.get_state() : 0;
|
||||
let openNewWindow = modifiers & Clutter.ModifierType.CONTROL_MASK;
|
||||
@ -916,8 +913,8 @@ const AppSearchProvider = new Lang.Class({
|
||||
app.open_new_window(workspace);
|
||||
},
|
||||
|
||||
createResultObject: function (resultMeta) {
|
||||
let app = this._appSys.lookup_app(resultMeta['id']);
|
||||
createResultObject: function (resultMeta, terms) {
|
||||
let app = resultMeta['id'];
|
||||
return new AppIcon(app);
|
||||
}
|
||||
});
|
||||
@ -1355,9 +1352,7 @@ const AppIcon = new Lang.Class({
|
||||
this._removeMenuTimeout();
|
||||
this._menuTimeoutId = Mainloop.timeout_add(MENU_POPUP_TIMEOUT,
|
||||
Lang.bind(this, function() {
|
||||
this._menuTimeoutId = 0;
|
||||
this.popupMenu();
|
||||
return false;
|
||||
}));
|
||||
} else if (button == 3) {
|
||||
this.popupMenu();
|
||||
|
@ -315,6 +315,7 @@ const Background = new Lang.Class({
|
||||
|
||||
this._brightness = 1.0;
|
||||
this._vignetteSharpness = 0.2;
|
||||
this._saturation = 1.0;
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
this.isLoaded = false;
|
||||
|
||||
@ -415,6 +416,7 @@ const Background = new Lang.Class({
|
||||
},
|
||||
|
||||
_addImage: function(content, index, filename) {
|
||||
content.saturation = this._saturation;
|
||||
content.brightness = this._brightness;
|
||||
content.vignette_sharpness = this._vignetteSharpness;
|
||||
|
||||
@ -430,6 +432,7 @@ const Background = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateImage: function(content, index, filename) {
|
||||
content.saturation = this._saturation;
|
||||
content.brightness = this._brightness;
|
||||
content.vignette_sharpness = this._vignetteSharpness;
|
||||
|
||||
@ -587,6 +590,24 @@ const Background = new Lang.Class({
|
||||
this._loadFile(filename);
|
||||
},
|
||||
|
||||
get saturation() {
|
||||
return this._saturation;
|
||||
},
|
||||
|
||||
set saturation(saturation) {
|
||||
this._saturation = saturation;
|
||||
|
||||
if (this._pattern && this._pattern.content)
|
||||
this._pattern.content.saturation = saturation;
|
||||
|
||||
let keys = Object.keys(this._images);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let image = this._images[keys[i]];
|
||||
if (image && image.content)
|
||||
image.content.saturation = saturation;
|
||||
}
|
||||
},
|
||||
|
||||
get brightness() {
|
||||
return this._brightness;
|
||||
},
|
||||
@ -730,6 +751,7 @@ const BackgroundManager = new Lang.Class({
|
||||
let newBackground = this._createBackground(monitorIndex);
|
||||
newBackground.vignetteSharpness = background.vignetteSharpness;
|
||||
newBackground.brightness = background.brightness;
|
||||
newBackground.saturation = background.saturation;
|
||||
newBackground.visible = background.visible;
|
||||
|
||||
newBackground.loadedSignalId = newBackground.connect('loaded',
|
||||
|
@ -190,18 +190,16 @@ const EmptyEventSource = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(EmptyEventSource.prototype);
|
||||
|
||||
const CalendarServerIface = '<node> \
|
||||
<interface name="org.gnome.Shell.CalendarServer"> \
|
||||
<method name="GetEvents"> \
|
||||
<arg type="x" direction="in" /> \
|
||||
<arg type="x" direction="in" /> \
|
||||
<arg type="b" direction="in" /> \
|
||||
<arg type="a(sssbxxa{sv})" direction="out" /> \
|
||||
</method> \
|
||||
<property name="HasCalendars" type="b" access="read" /> \
|
||||
<signal name="Changed" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
|
||||
<method name="GetEvents">
|
||||
<arg type="x" direction="in" />
|
||||
<arg type="x" direction="in" />
|
||||
<arg type="b" direction="in" />
|
||||
<arg type="a(sssbxxa{sv})" direction="out" />
|
||||
</method>
|
||||
<property name="HasCalendars" type="b" access="read" />
|
||||
<signal name="Changed" />
|
||||
</interface>;
|
||||
|
||||
const CalendarServerInfo = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface);
|
||||
|
||||
|
@ -75,14 +75,12 @@ function startAppForMount(app, mount) {
|
||||
|
||||
/******************************************/
|
||||
|
||||
const HotplugSnifferIface = '<node> \
|
||||
<interface name="org.gnome.Shell.HotplugSniffer"> \
|
||||
<method name="SniffURI"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="as" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const HotplugSnifferIface = <interface name="org.gnome.Shell.HotplugSniffer">
|
||||
<method name="SniffURI">
|
||||
<arg type="s" direction="in" />
|
||||
<arg type="as" direction="out" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface);
|
||||
function HotplugSniffer() {
|
||||
|
@ -138,8 +138,6 @@ const NetworkSecretDialog = new Lang.Class({
|
||||
key: Clutter.KEY_Escape,
|
||||
},
|
||||
this._okButton]);
|
||||
|
||||
this._updateOkButton();
|
||||
},
|
||||
|
||||
_updateOkButton: function() {
|
||||
@ -434,7 +432,6 @@ const VPNRequestHandler = new Lang.Class({
|
||||
},
|
||||
|
||||
_vpnChildFinished: function(pid, status, requestObj) {
|
||||
this._childWatch = 0;
|
||||
if (this._newStylePlugin) {
|
||||
// For new style plugin, all work is done in the async reading functions
|
||||
// Just reap the process here
|
||||
|
@ -446,7 +446,6 @@ const ChatSource = new Lang.Class({
|
||||
this._closedId = this._channel.connect('invalidated', Lang.bind(this, this._channelClosed));
|
||||
|
||||
this._notification = new ChatNotification(this);
|
||||
this._notification.connect('clicked', Lang.bind(this, this.open));
|
||||
this._notification.setUrgency(MessageTray.Urgency.HIGH);
|
||||
this._notifyTimeoutId = 0;
|
||||
|
||||
@ -545,19 +544,20 @@ const ChatSource = new Lang.Class({
|
||||
this._notification.update(this._notification.title, null, { customContent: true });
|
||||
},
|
||||
|
||||
open: function() {
|
||||
if (this._client.is_handling_channel(this._channel)) {
|
||||
// We are handling the channel, try to pass it to Empathy
|
||||
this._client.delegate_channels_async([this._channel],
|
||||
global.get_current_time(),
|
||||
'org.freedesktop.Telepathy.Client.Empathy.Chat', null);
|
||||
} else {
|
||||
// We are not the handler, just ask to present the channel
|
||||
let dbus = Tp.DBusDaemon.dup();
|
||||
let cd = Tp.ChannelDispatcher.new(dbus);
|
||||
open: function(notification) {
|
||||
if (this._client.is_handling_channel(this._channel)) {
|
||||
// We are handling the channel, try to pass it to Empathy
|
||||
this._client.delegate_channels_async([this._channel],
|
||||
global.get_current_time(),
|
||||
'org.freedesktop.Telepathy.Client.Empathy.Chat', null);
|
||||
}
|
||||
else {
|
||||
// We are not the handler, just ask to present the channel
|
||||
let dbus = Tp.DBusDaemon.dup();
|
||||
let cd = Tp.ChannelDispatcher.new(dbus);
|
||||
|
||||
cd.present_channel_async(this._channel, global.get_current_time(), null);
|
||||
}
|
||||
cd.present_channel_async(this._channel, global.get_current_time(), null);
|
||||
}
|
||||
},
|
||||
|
||||
_getLogMessages: function() {
|
||||
@ -960,8 +960,6 @@ const ChatNotification = new Lang.Class({
|
||||
},
|
||||
|
||||
appendTimestamp: function() {
|
||||
this._timestampTimeoutId = 0;
|
||||
|
||||
let lastMessageTime = this._history[0].time;
|
||||
let lastMessageDate = new Date(lastMessageTime * 1000);
|
||||
|
||||
@ -1097,16 +1095,22 @@ const RoomInviteNotification = new Lang.Class({
|
||||
* for example. */
|
||||
this.addBody(_("%s is inviting you to join %s").format(inviter.get_alias(), channel.get_identifier()));
|
||||
|
||||
this.addAction(_("Decline"), Lang.bind(this, function() {
|
||||
dispatchOp.leave_channels_async(Tp.ChannelGroupChangeReason.NONE, '', function(src, result) {
|
||||
src.leave_channels_finish(result);
|
||||
});
|
||||
this.destroy();
|
||||
}));
|
||||
this.addAction(_("Accept"), Lang.bind(this, function() {
|
||||
dispatchOp.handle_with_time_async('', global.get_current_time(), function(src, result) {
|
||||
src.handle_with_time_finish(result);
|
||||
});
|
||||
this.addButton('decline', _("Decline"));
|
||||
this.addButton('accept', _("Accept"));
|
||||
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
switch (action) {
|
||||
case 'decline':
|
||||
dispatchOp.leave_channels_async(Tp.ChannelGroupChangeReason.NONE,
|
||||
'', function(src, result) {
|
||||
src.leave_channels_finish(result)});
|
||||
break;
|
||||
case 'accept':
|
||||
dispatchOp.handle_with_time_async('', global.get_current_time(),
|
||||
function(src, result) {
|
||||
src.handle_with_time_finish(result)});
|
||||
break;
|
||||
}
|
||||
this.destroy();
|
||||
}));
|
||||
}
|
||||
@ -1132,17 +1136,23 @@ const AudioVideoNotification = new Lang.Class({
|
||||
|
||||
this.setUrgency(MessageTray.Urgency.CRITICAL);
|
||||
|
||||
this.addAction(_("Decline"), Lang.bind(this, function() {
|
||||
dispatchOp.leave_channels_async(Tp.ChannelGroupChangeReason.NONE, '', function(src, result) {
|
||||
src.leave_channels_finish(result);
|
||||
});
|
||||
this.destroy();
|
||||
}));
|
||||
this.addButton('reject', _("Decline"));
|
||||
/* translators: this is a button label (verb), not a noun */
|
||||
this.addAction(_("Answer"), Lang.bind(this, function() {
|
||||
dispatchOp.handle_with_time_async('', global.get_current_time(), function(src, result) {
|
||||
src.handle_with_time_finish(result);
|
||||
});
|
||||
this.addButton('answer', _("Answer"));
|
||||
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
switch (action) {
|
||||
case 'reject':
|
||||
dispatchOp.leave_channels_async(Tp.ChannelGroupChangeReason.NONE,
|
||||
'', function(src, result) {
|
||||
src.leave_channels_finish(result)});
|
||||
break;
|
||||
case 'answer':
|
||||
dispatchOp.handle_with_time_async('', global.get_current_time(),
|
||||
function(src, result) {
|
||||
src.handle_with_time_finish(result)});
|
||||
break;
|
||||
}
|
||||
this.destroy();
|
||||
}));
|
||||
}
|
||||
@ -1166,16 +1176,22 @@ const FileTransferNotification = new Lang.Class({
|
||||
{ customContent: true });
|
||||
this.setResident(true);
|
||||
|
||||
this.addAction(_("Decline"), Lang.bind(this, function() {
|
||||
dispatchOp.leave_channels_async(Tp.ChannelGroupChangeReason.NONE, '', function(src, result) {
|
||||
src.leave_channels_finish(result);
|
||||
});
|
||||
this.destroy();
|
||||
}));
|
||||
this.addAction(_("Accept"), Lang.bind(this, function() {
|
||||
dispatchOp.handle_with_time_async('', global.get_current_time(), function(src, result) {
|
||||
src.handle_with_time_finish(result);
|
||||
});
|
||||
this.addButton('decline', _("Decline"));
|
||||
this.addButton('accept', _("Accept"));
|
||||
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
switch (action) {
|
||||
case 'decline':
|
||||
dispatchOp.leave_channels_async(Tp.ChannelGroupChangeReason.NONE,
|
||||
'', function(src, result) {
|
||||
src.leave_channels_finish(result)});
|
||||
break;
|
||||
case 'accept':
|
||||
dispatchOp.handle_with_time_async('', global.get_current_time(),
|
||||
function(src, result) {
|
||||
src.handle_with_time_finish(result)});
|
||||
break;
|
||||
}
|
||||
this.destroy();
|
||||
}));
|
||||
}
|
||||
@ -1223,20 +1239,27 @@ const SubscriptionRequestNotification = new Lang.Class({
|
||||
|
||||
this.addActor(layout);
|
||||
|
||||
this.addAction(_("Decline"), Lang.bind(this, function() {
|
||||
contact.remove_async(function(src, result) {
|
||||
src.remove_finish(result);
|
||||
});
|
||||
}));
|
||||
this.addAction(_("Accept"), Lang.bind(this, function() {
|
||||
// Authorize the contact and request to see his status as well
|
||||
contact.authorize_publication_async(function(src, result) {
|
||||
src.authorize_publication_finish(result);
|
||||
});
|
||||
this.addButton('decline', _("Decline"));
|
||||
this.addButton('accept', _("Accept"));
|
||||
|
||||
contact.request_subscription_async('', function(src, result) {
|
||||
src.request_subscription_finish(result);
|
||||
});
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
switch (action) {
|
||||
case 'decline':
|
||||
contact.remove_async(function(src, result) {
|
||||
src.remove_finish(result)});
|
||||
break;
|
||||
case 'accept':
|
||||
// Authorize the contact and request to see his status as well
|
||||
contact.authorize_publication_async(function(src, result) {
|
||||
src.authorize_publication_finish(result)});
|
||||
|
||||
contact.request_subscription_async('', function(src, result) {
|
||||
src.request_subscription_finish(result)});
|
||||
break;
|
||||
}
|
||||
|
||||
// rely on _subscriptionStatesChangedCb to destroy the
|
||||
// notification
|
||||
}));
|
||||
|
||||
this._changedId = contact.connect('subscription-states-changed',
|
||||
@ -1335,11 +1358,18 @@ const AccountNotification = new Lang.Class({
|
||||
|
||||
this._account = account;
|
||||
|
||||
this.addAction(_("View account"), Lang.bind(this, function() {
|
||||
let cmd = 'empathy-accounts --select-account=' +
|
||||
account.get_path_suffix();
|
||||
let app_info = Gio.app_info_create_from_commandline(cmd, null, 0);
|
||||
app_info.launch([], global.create_app_launch_context());
|
||||
this.addButton('view', _("View account"));
|
||||
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
switch (action) {
|
||||
case 'view':
|
||||
let cmd = 'empathy-accounts --select-account=' +
|
||||
account.get_path_suffix();
|
||||
let app_info = Gio.app_info_create_from_commandline(cmd, null, 0);
|
||||
app_info.launch([], global.create_app_launch_context());
|
||||
break;
|
||||
}
|
||||
this.destroy();
|
||||
}));
|
||||
|
||||
this._enabledId = account.connect('notify::enabled',
|
||||
|
@ -576,7 +576,6 @@ const Dash = new Lang.Class({
|
||||
Lang.bind(this, function() {
|
||||
this._labelShowing = true;
|
||||
item.showLabel();
|
||||
this._showLabelTimeoutId = 0;
|
||||
return false;
|
||||
}));
|
||||
if (this._resetHoverTimeoutId > 0) {
|
||||
@ -593,7 +592,6 @@ const Dash = new Lang.Class({
|
||||
this._resetHoverTimeoutId = Mainloop.timeout_add(DASH_ITEM_HOVER_TIMEOUT,
|
||||
Lang.bind(this, function() {
|
||||
this._labelShowing = false;
|
||||
this._resetHoverTimeoutId = 0;
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
11
js/ui/dnd.js
11
js/ui/dnd.js
@ -236,7 +236,7 @@ const _Draggable = new Lang.Class({
|
||||
|
||||
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
||||
this._dragActor = this.actor._delegate.getDragActor();
|
||||
Main.uiGroup.add_child(this._dragActor);
|
||||
this._dragActor.reparent(Main.uiGroup);
|
||||
this._dragActor.raise_top();
|
||||
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
||||
|
||||
@ -285,8 +285,7 @@ const _Draggable = new Lang.Class({
|
||||
this._dragOffsetX = actorStageX - this._dragStartX;
|
||||
this._dragOffsetY = actorStageY - this._dragStartY;
|
||||
|
||||
this._dragOrigParent.remove_actor(this._dragActor);
|
||||
Main.uiGroup.add_child(this._dragActor);
|
||||
this._dragActor.reparent(Main.uiGroup);
|
||||
this._dragActor.raise_top();
|
||||
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
||||
}
|
||||
@ -346,7 +345,6 @@ const _Draggable = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateDragHover : function () {
|
||||
this._updateHoverId = 0;
|
||||
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||
this._dragX, this._dragY);
|
||||
let dragEvent = {
|
||||
@ -391,7 +389,7 @@ const _Draggable = new Lang.Class({
|
||||
|
||||
_queueUpdateDragHover: function() {
|
||||
if (this._updateHoverId)
|
||||
return;
|
||||
GLib.source_remove(this._updateHoverId);
|
||||
|
||||
this._updateHoverId = GLib.idle_add(GLib.PRIORITY_DEFAULT,
|
||||
Lang.bind(this, this._updateDragHover));
|
||||
@ -557,8 +555,7 @@ const _Draggable = new Lang.Class({
|
||||
|
||||
_onAnimationComplete : function (dragActor, eventTime) {
|
||||
if (this._dragOrigParent) {
|
||||
Main.uiGroup.remove_child(this._dragActor);
|
||||
this._dragOrigParent.add_actor(this._dragActor);
|
||||
dragActor.reparent(this._dragOrigParent);
|
||||
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
|
||||
dragActor.set_position(this._dragOrigX, this._dragOrigY);
|
||||
} else {
|
||||
|
@ -43,22 +43,20 @@ const _DIALOG_ICON_SIZE = 32;
|
||||
|
||||
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
|
||||
|
||||
const EndSessionDialogIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager.EndSessionDialog"> \
|
||||
<method name="Open"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
<arg type="u" direction="in" /> \
|
||||
<arg type="u" direction="in" /> \
|
||||
<arg type="ao" direction="in" /> \
|
||||
</method> \
|
||||
<method name="Close" /> \
|
||||
<signal name="ConfirmedLogout" /> \
|
||||
<signal name="ConfirmedReboot" /> \
|
||||
<signal name="ConfirmedShutdown" /> \
|
||||
<signal name="Canceled" /> \
|
||||
<signal name="Closed" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const EndSessionDialogIface = <interface name="org.gnome.SessionManager.EndSessionDialog">
|
||||
<method name="Open">
|
||||
<arg type="u" direction="in" />
|
||||
<arg type="u" direction="in" />
|
||||
<arg type="u" direction="in" />
|
||||
<arg type="ao" direction="in" />
|
||||
</method>
|
||||
<method name="Close" />
|
||||
<signal name="ConfirmedLogout" />
|
||||
<signal name="ConfirmedReboot" />
|
||||
<signal name="ConfirmedShutdown" />
|
||||
<signal name="Canceled" />
|
||||
<signal name="Closed" />
|
||||
</interface>;
|
||||
|
||||
const logoutDialogContent = {
|
||||
subjectWithUser: C_("title", "Log Out %s"),
|
||||
@ -133,15 +131,13 @@ const DialogContent = {
|
||||
|
||||
const MAX_USERS_IN_SESSION_DIALOG = 5;
|
||||
|
||||
const LogindSessionIface = '<node> \
|
||||
<interface name="org.freedesktop.login1.Session"> \
|
||||
<property name="Id" type="s" access="read"/> \
|
||||
<property name="Remote" type="b" access="read"/> \
|
||||
<property name="Class" type="s" access="read"/> \
|
||||
<property name="Type" type="s" access="read"/> \
|
||||
<property name="State" type="s" access="read"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const LogindSessionIface = <interface name='org.freedesktop.login1.Session'>
|
||||
<property name="Id" type="s" access="read"/>
|
||||
<property name="Remote" type="b" access="read"/>
|
||||
<property name="Class" type="s" access="read"/>
|
||||
<property name="Type" type="s" access="read"/>
|
||||
<property name="State" type="s" access="read"/>
|
||||
</interface>;
|
||||
|
||||
const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
|
||||
|
||||
@ -273,15 +269,13 @@ const EndSessionDialog = new Lang.Class({
|
||||
|
||||
this._applicationHeader = new St.Label({ style_class: 'end-session-dialog-list-header',
|
||||
text: _("Some applications are busy or have unsaved work.") });
|
||||
this._applicationList = new St.BoxLayout({ style_class: 'end-session-dialog-app-list',
|
||||
vertical: true });
|
||||
this._applicationList = new St.BoxLayout({ vertical: true });
|
||||
this._inhibitorSection.add_actor(this._applicationHeader);
|
||||
this._inhibitorSection.add_actor(this._applicationList);
|
||||
|
||||
this._sessionHeader = new St.Label({ style_class: 'end-session-dialog-list-header',
|
||||
text: _("Other users are logged in.") });
|
||||
this._sessionList = new St.BoxLayout({ style_class: 'end-session-dialog-session-list',
|
||||
vertical: true });
|
||||
this._sessionList = new St.BoxLayout({ vertical: true });
|
||||
this._inhibitorSection.add_actor(this._sessionHeader);
|
||||
this._inhibitorSection.add_actor(this._sessionList);
|
||||
|
||||
@ -415,7 +409,6 @@ const EndSessionDialog = new Lang.Class({
|
||||
let dialogContent = DialogContent[this._type];
|
||||
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
|
||||
this._confirm(button.signal);
|
||||
this._timerId = 0;
|
||||
|
||||
return false;
|
||||
}));
|
||||
|
@ -76,11 +76,7 @@ function disableExtension(uuid) {
|
||||
theme.unload_stylesheet(extension.stylesheet.get_path());
|
||||
}
|
||||
|
||||
try {
|
||||
extension.stateObj.disable();
|
||||
} catch(e) {
|
||||
logExtensionError(uuid, e);
|
||||
}
|
||||
extension.stateObj.disable();
|
||||
|
||||
for (let i = 0; i < order.length; i++) {
|
||||
let uuid = order[i];
|
||||
@ -93,10 +89,8 @@ function disableExtension(uuid) {
|
||||
|
||||
extensionOrder.splice(orderIdx, 1);
|
||||
|
||||
if ( extension.state != ExtensionState.ERROR ) {
|
||||
extension.state = ExtensionState.DISABLED;
|
||||
_signals.emit('extension-state-changed', extension);
|
||||
}
|
||||
extension.state = ExtensionState.DISABLED;
|
||||
_signals.emit('extension-state-changed', extension);
|
||||
}
|
||||
|
||||
function enableExtension(uuid) {
|
||||
@ -123,15 +117,10 @@ function enableExtension(uuid) {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
extension.stateObj.enable();
|
||||
extension.state = ExtensionState.ENABLED;
|
||||
_signals.emit('extension-state-changed', extension);
|
||||
return;
|
||||
} catch(e) {
|
||||
logExtensionError(uuid, e);
|
||||
return;
|
||||
}
|
||||
extension.stateObj.enable();
|
||||
|
||||
extension.state = ExtensionState.ENABLED;
|
||||
_signals.emit('extension-state-changed', extension);
|
||||
}
|
||||
|
||||
function logExtensionError(uuid, error) {
|
||||
@ -161,8 +150,7 @@ function loadExtension(extension) {
|
||||
} else {
|
||||
let enabled = enabledExtensions.indexOf(extension.uuid) != -1;
|
||||
if (enabled) {
|
||||
if (!initExtension(extension.uuid))
|
||||
return;
|
||||
initExtension(extension.uuid);
|
||||
if (extension.state == ExtensionState.DISABLED)
|
||||
enableExtension(extension.uuid);
|
||||
} else {
|
||||
@ -217,12 +205,7 @@ function initExtension(uuid) {
|
||||
extensionModule = extension.imports.extension;
|
||||
|
||||
if (extensionModule.init) {
|
||||
try {
|
||||
extensionState = extensionModule.init(extension);
|
||||
} catch(e) {
|
||||
logExtensionError(uuid, e);
|
||||
return false;
|
||||
}
|
||||
extensionState = extensionModule.init(extension);
|
||||
}
|
||||
|
||||
if (!extensionState)
|
||||
@ -231,7 +214,6 @@ function initExtension(uuid) {
|
||||
|
||||
extension.state = ExtensionState.DISABLED;
|
||||
_signals.emit('extension-loaded', uuid);
|
||||
return true;
|
||||
}
|
||||
|
||||
function getEnabledExtensions() {
|
||||
@ -253,7 +235,11 @@ function onEnabledExtensionsChanged() {
|
||||
newEnabledExtensions.filter(function(uuid) {
|
||||
return enabledExtensions.indexOf(uuid) == -1;
|
||||
}).forEach(function(uuid) {
|
||||
enableExtension(uuid);
|
||||
try {
|
||||
enableExtension(uuid);
|
||||
} catch(e) {
|
||||
logExtensionError(uuid, e);
|
||||
}
|
||||
});
|
||||
|
||||
// Find and disable all the newly disabled extensions: UUIDs found in the
|
||||
@ -261,7 +247,11 @@ function onEnabledExtensionsChanged() {
|
||||
enabledExtensions.filter(function(item) {
|
||||
return newEnabledExtensions.indexOf(item) == -1;
|
||||
}).forEach(function(uuid) {
|
||||
disableExtension(uuid);
|
||||
try {
|
||||
disableExtension(uuid);
|
||||
} catch(e) {
|
||||
logExtensionError(uuid, e);
|
||||
}
|
||||
});
|
||||
|
||||
enabledExtensions = newEnabledExtensions;
|
||||
@ -272,8 +262,12 @@ function _loadExtensions() {
|
||||
enabledExtensions = getEnabledExtensions();
|
||||
|
||||
let finder = new ExtensionUtils.ExtensionFinder();
|
||||
finder.connect('extension-found', function(finder, extension) {
|
||||
loadExtension(extension);
|
||||
finder.connect('extension-found', function(signals, extension) {
|
||||
try {
|
||||
loadExtension(extension);
|
||||
} catch(e) {
|
||||
logExtensionError(extension.uuid, e);
|
||||
}
|
||||
});
|
||||
finder.scanExtensions();
|
||||
}
|
||||
|
@ -413,18 +413,15 @@ const IconGrid = new Lang.Class({
|
||||
},
|
||||
|
||||
removeAll: function() {
|
||||
this._items = [];
|
||||
this._grid.remove_all_children();
|
||||
},
|
||||
|
||||
destroyAll: function() {
|
||||
this._items = [];
|
||||
this._grid.destroy_all_children();
|
||||
},
|
||||
|
||||
addItem: function(item, index) {
|
||||
if (!item.icon instanceof BaseIcon)
|
||||
throw new Error('Only items with a BaseIcon icon property can be added to IconGrid');
|
||||
if (!item.icon || !item.icon instanceof BaseIcon) {
|
||||
log('Only items with a BaseIcon icon property can be added to IconGrid');
|
||||
return;
|
||||
}
|
||||
|
||||
this._items.push(item);
|
||||
if (index !== undefined)
|
||||
|
@ -23,29 +23,27 @@ const KEYBOARD_TYPE = 'keyboard-type';
|
||||
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
|
||||
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
|
||||
|
||||
const CaribouKeyboardIface = '<node> \
|
||||
<interface name="org.gnome.Caribou.Keyboard"> \
|
||||
<method name="Show"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="Hide"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="SetCursorLocation"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
</method> \
|
||||
<method name="SetEntryLocation"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
</method> \
|
||||
<property name="Name" access="read" type="s" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const CaribouKeyboardIface = <interface name='org.gnome.Caribou.Keyboard'>
|
||||
<method name='Show'>
|
||||
<arg type='u' direction='in' />
|
||||
</method>
|
||||
<method name='Hide'>
|
||||
<arg type='u' direction='in' />
|
||||
</method>
|
||||
<method name='SetCursorLocation'>
|
||||
<arg type='i' direction='in' />
|
||||
<arg type='i' direction='in' />
|
||||
<arg type='i' direction='in' />
|
||||
<arg type='i' direction='in' />
|
||||
</method>
|
||||
<method name='SetEntryLocation'>
|
||||
<arg type='i' direction='in' />
|
||||
<arg type='i' direction='in' />
|
||||
<arg type='i' direction='in' />
|
||||
<arg type='i' direction='in' />
|
||||
</method>
|
||||
<property name='Name' access='read' type='s' />
|
||||
</interface>;
|
||||
|
||||
const Key = new Lang.Class({
|
||||
Name: 'Key',
|
||||
|
@ -629,6 +629,55 @@ const Inspector = new Lang.Class({
|
||||
|
||||
Signals.addSignalMethods(Inspector.prototype);
|
||||
|
||||
const Memory = new Lang.Class({
|
||||
Name: 'Memory',
|
||||
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ vertical: true });
|
||||
this._glibc_uordblks = new St.Label();
|
||||
this.actor.add(this._glibc_uordblks);
|
||||
|
||||
this._js_bytes = new St.Label();
|
||||
this.actor.add(this._js_bytes);
|
||||
|
||||
this._gjs_boxed = new St.Label();
|
||||
this.actor.add(this._gjs_boxed);
|
||||
|
||||
this._gjs_gobject = new St.Label();
|
||||
this.actor.add(this._gjs_gobject);
|
||||
|
||||
this._gjs_function = new St.Label();
|
||||
this.actor.add(this._gjs_function);
|
||||
|
||||
this._gjs_closure = new St.Label();
|
||||
this.actor.add(this._gjs_closure);
|
||||
|
||||
this._last_gc_seconds_ago = new St.Label();
|
||||
this.actor.add(this._last_gc_seconds_ago);
|
||||
|
||||
this._gcbutton = new St.Button({ label: 'Full GC',
|
||||
style_class: 'lg-obj-inspector-button' });
|
||||
this._gcbutton.connect('clicked', Lang.bind(this, function () { System.gc(); this._renderText(); }));
|
||||
this.actor.add(this._gcbutton, { x_align: St.Align.START,
|
||||
x_fill: false });
|
||||
|
||||
this.actor.connect('notify::mapped', Lang.bind(this, this._renderText));
|
||||
},
|
||||
|
||||
_renderText: function() {
|
||||
if (!this.actor.mapped)
|
||||
return;
|
||||
let memInfo = global.get_memory_info();
|
||||
this._glibc_uordblks.text = 'glibc_uordblks: ' + memInfo.glibc_uordblks;
|
||||
this._js_bytes.text = 'js bytes: ' + memInfo.js_bytes;
|
||||
this._gjs_boxed.text = 'gjs_boxed: ' + memInfo.gjs_boxed;
|
||||
this._gjs_gobject.text = 'gjs_gobject: ' + memInfo.gjs_gobject;
|
||||
this._gjs_function.text = 'gjs_function: ' + memInfo.gjs_function;
|
||||
this._gjs_closure.text = 'gjs_closure: ' + memInfo.gjs_closure;
|
||||
this._last_gc_seconds_ago.text = 'last_gc_seconds_ago: ' + memInfo.last_gc_seconds_ago;
|
||||
}
|
||||
});
|
||||
|
||||
const Extensions = new Lang.Class({
|
||||
Name: 'Extensions',
|
||||
|
||||
@ -831,19 +880,6 @@ const LookingGlass = new Lang.Class({
|
||||
return true;
|
||||
}));
|
||||
|
||||
let gcIcon = new St.Icon({ icon_name: 'gnome-fs-trash-full',
|
||||
icon_size: 24 });
|
||||
toolbar.add_actor(gcIcon);
|
||||
gcIcon.reactive = true;
|
||||
gcIcon.connect('button-press-event', Lang.bind(this, function () {
|
||||
gcIcon.icon_name = 'gnome-fs-trash-empty';
|
||||
System.gc();
|
||||
this._timeoutId = Mainloop.timeout_add(500, Lang.bind(this, function () {
|
||||
gcIcon.icon_name = 'gnome-fs-trash-full';
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
}));
|
||||
}));
|
||||
|
||||
let notebook = new Notebook();
|
||||
this._notebook = notebook;
|
||||
this.actor.add(notebook.actor, { expand: true });
|
||||
@ -871,6 +907,9 @@ const LookingGlass = new Lang.Class({
|
||||
this._windowList = new WindowList(this);
|
||||
notebook.appendPage('Windows', this._windowList.actor);
|
||||
|
||||
this._memory = new Memory();
|
||||
notebook.appendPage('Memory', this._memory.actor);
|
||||
|
||||
this._extensions = new Extensions(this);
|
||||
notebook.appendPage('Extensions', this._extensions.actor);
|
||||
|
||||
|
@ -9,89 +9,85 @@ const ZOOM_SERVICE_PATH = '/org/gnome/Magnifier/ZoomRegion';
|
||||
|
||||
// Subset of gnome-mag's Magnifier dbus interface -- to be expanded. See:
|
||||
// http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml
|
||||
const MagnifierIface = '<node> \
|
||||
<interface name="org.gnome.Magnifier"> \
|
||||
<method name="setActive"> \
|
||||
<arg type="b" direction="in" /> \
|
||||
</method> \
|
||||
<method name="isActive"> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<method name="showCursor" /> \
|
||||
<method name="hideCursor" /> \
|
||||
<method name="createZoomRegion"> \
|
||||
<arg type="d" direction="in" /> \
|
||||
<arg type="d" direction="in" /> \
|
||||
<arg type="ai" direction="in" /> \
|
||||
<arg type="ai" direction="in" /> \
|
||||
<arg type="o" direction="out" /> \
|
||||
</method> \
|
||||
<method name="addZoomRegion"> \
|
||||
<arg type="o" direction="in" /> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<method name="getZoomRegions"> \
|
||||
<arg type="ao" direction="out" /> \
|
||||
</method> \
|
||||
<method name="clearAllZoomRegions" /> \
|
||||
<method name="fullScreenCapable"> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<method name="setCrosswireSize"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
</method> \
|
||||
<method name="getCrosswireSize"> \
|
||||
<arg type="i" direction="out" /> \
|
||||
</method> \
|
||||
<method name="setCrosswireLength"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
</method> \
|
||||
<method name="getCrosswireLength"> \
|
||||
<arg type="i" direction="out" /> \
|
||||
</method> \
|
||||
<method name="setCrosswireClip"> \
|
||||
<arg type="b" direction="in" /> \
|
||||
</method> \
|
||||
<method name="getCrosswireClip"> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<method name="setCrosswireColor"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="getCrosswireColor"> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const MagnifierIface = <interface name="org.gnome.Magnifier">
|
||||
<method name="setActive">
|
||||
<arg type="b" direction="in" />
|
||||
</method>
|
||||
<method name="isActive">
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<method name="showCursor" />
|
||||
<method name="hideCursor" />
|
||||
<method name="createZoomRegion">
|
||||
<arg type="d" direction="in" />
|
||||
<arg type="d" direction="in" />
|
||||
<arg type="ai" direction="in" />
|
||||
<arg type="ai" direction="in" />
|
||||
<arg type="o" direction="out" />
|
||||
</method>
|
||||
<method name="addZoomRegion">
|
||||
<arg type="o" direction="in" />
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<method name="getZoomRegions">
|
||||
<arg type="ao" direction="out" />
|
||||
</method>
|
||||
<method name="clearAllZoomRegions" />
|
||||
<method name="fullScreenCapable">
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<method name="setCrosswireSize">
|
||||
<arg type="i" direction="in" />
|
||||
</method>
|
||||
<method name="getCrosswireSize">
|
||||
<arg type="i" direction="out" />
|
||||
</method>
|
||||
<method name="setCrosswireLength">
|
||||
<arg type="i" direction="in" />
|
||||
</method>
|
||||
<method name="getCrosswireLength">
|
||||
<arg type="i" direction="out" />
|
||||
</method>
|
||||
<method name="setCrosswireClip">
|
||||
<arg type="b" direction="in" />
|
||||
</method>
|
||||
<method name="getCrosswireClip">
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<method name="setCrosswireColor">
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
<method name="getCrosswireColor">
|
||||
<arg type="u" direction="out" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
// Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded. See:
|
||||
// http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml
|
||||
const ZoomRegionIface = '<node> \
|
||||
<interface name="org.gnome.Magnifier.ZoomRegion"> \
|
||||
<method name="setMagFactor"> \
|
||||
<arg type="d" direction="in" /> \
|
||||
<arg type="d" direction="in" /> \
|
||||
</method> \
|
||||
<method name="getMagFactor"> \
|
||||
<arg type="d" direction="out" /> \
|
||||
<arg type="d" direction="out" /> \
|
||||
</method> \
|
||||
<method name="setRoi"> \
|
||||
<arg type="ai" direction="in" /> \
|
||||
</method> \
|
||||
<method name="getRoi"> \
|
||||
<arg type="ai" direction="out" /> \
|
||||
</method> \
|
||||
<method name="shiftContentsTo"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="b" direction="out" /> \
|
||||
</method> \
|
||||
<method name="moveResize"> \
|
||||
<arg type="ai" direction="in" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ZoomRegionIface = <interface name="org.gnome.Magnifier.ZoomRegion">
|
||||
<method name="setMagFactor">
|
||||
<arg type="d" direction="in" />
|
||||
<arg type="d" direction="in" />
|
||||
</method>
|
||||
<method name="getMagFactor">
|
||||
<arg type="d" direction="out" />
|
||||
<arg type="d" direction="out" />
|
||||
</method>
|
||||
<method name="setRoi">
|
||||
<arg type="ai" direction="in" />
|
||||
</method>
|
||||
<method name="getRoi">
|
||||
<arg type="ai" direction="out" />
|
||||
</method>
|
||||
<method name="shiftContentsTo">
|
||||
<arg type="i" direction="in" />
|
||||
<arg type="i" direction="in" />
|
||||
<arg type="b" direction="out" />
|
||||
</method>
|
||||
<method name="moveResize">
|
||||
<arg type="ai" direction="in" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
// For making unique ZoomRegion DBus proxy object paths of the form:
|
||||
// '/org/gnome/Magnifier/ZoomRegion/zoomer0',
|
||||
|
@ -112,6 +112,11 @@ function start() {
|
||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||
|
||||
sessionMode = new SessionMode.SessionMode();
|
||||
sessionMode.connect('sessions-loaded', _sessionsLoaded);
|
||||
sessionMode.init();
|
||||
}
|
||||
|
||||
function _sessionsLoaded() {
|
||||
sessionMode.connect('updated', _sessionUpdated);
|
||||
_initializePrefs();
|
||||
_initializeUI();
|
||||
|
@ -280,6 +280,10 @@ const URLHighlighter = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
function strHasSuffix(string, suffix) {
|
||||
return string.substr(-suffix.length) == suffix;
|
||||
}
|
||||
|
||||
// NotificationPolicy:
|
||||
// An object that holds all bits of configurable policy related to a notification
|
||||
// source, such as whether to play sound or honour the critical bit.
|
||||
@ -499,6 +503,7 @@ const Notification = new Lang.Class({
|
||||
this.focused = false;
|
||||
this.acknowledged = false;
|
||||
this._destroyed = false;
|
||||
this._useActionIcons = false;
|
||||
this._customContent = false;
|
||||
this.bannerBodyText = null;
|
||||
this.bannerBodyMarkup = false;
|
||||
@ -831,7 +836,17 @@ const Notification = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
addButton: function(button, callback) {
|
||||
// addButton:
|
||||
// @id: the action ID
|
||||
// @label: the label for the action's button
|
||||
//
|
||||
// Adds a button with the given @label to the notification. All
|
||||
// action buttons will appear in a single row at the bottom of
|
||||
// the notification.
|
||||
//
|
||||
// If the button is clicked, the notification will emit the
|
||||
// %action-invoked signal with @id as a parameter
|
||||
addButton: function(id, label) {
|
||||
if (!this._buttonBox) {
|
||||
let box = new St.BoxLayout({ style_class: 'notification-actions' });
|
||||
this.setActionArea(box, { x_expand: false,
|
||||
@ -843,37 +858,43 @@ const Notification = new Lang.Class({
|
||||
global.focus_manager.add_group(this._buttonBox);
|
||||
}
|
||||
|
||||
this._buttonBox.add(button);
|
||||
button.connect('clicked', Lang.bind(this, function() {
|
||||
callback();
|
||||
let button = new St.Button({ can_focus: true });
|
||||
button._actionId = id;
|
||||
|
||||
if (!this.resident) {
|
||||
// We don't hide a resident notification when the user invokes one of its actions,
|
||||
// because it is common for such notifications to update themselves with new
|
||||
// information based on the action. We'd like to display the updated information
|
||||
// in place, rather than pop-up a new notification.
|
||||
this.emit('done-displaying');
|
||||
this.destroy();
|
||||
}
|
||||
}));
|
||||
let iconName = strHasSuffix(id, '-symbolic') ? id : id + '-symbolic';
|
||||
if (this._useActionIcons && Gtk.IconTheme.get_default().has_icon(iconName)) {
|
||||
button.add_style_class_name('notification-icon-button');
|
||||
button.child = new St.Icon({ icon_name: iconName });
|
||||
} else {
|
||||
button.add_style_class_name('notification-button');
|
||||
button.label = label;
|
||||
}
|
||||
|
||||
this._buttonBox.add(button);
|
||||
button.connect('clicked', Lang.bind(this, this._onActionInvoked, id));
|
||||
|
||||
this.updated();
|
||||
return button;
|
||||
},
|
||||
|
||||
// addAction:
|
||||
// @label: the label for the action's button
|
||||
// @callback: the callback for the action
|
||||
// setButtonSensitive:
|
||||
// @id: the action ID
|
||||
// @sensitive: whether the button should be sensitive
|
||||
//
|
||||
// Adds a button with the given @label to the notification. All
|
||||
// action buttons will appear in a single row at the bottom of
|
||||
// the notification.
|
||||
addAction: function(label, callback) {
|
||||
let button = new St.Button({ style_class: 'notification-button',
|
||||
label: label,
|
||||
can_focus: true });
|
||||
// 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;
|
||||
|
||||
return this.addButton(button, callback);
|
||||
let button = this._buttonBox.get_children().filter(function(b) {
|
||||
return b._actionId == id;
|
||||
})[0];
|
||||
|
||||
if (!button || button.reactive == sensitive)
|
||||
return;
|
||||
|
||||
button.reactive = sensitive;
|
||||
},
|
||||
|
||||
setUrgency: function(urgency) {
|
||||
@ -892,6 +913,10 @@ const Notification = new Lang.Class({
|
||||
this.forFeedback = forFeedback;
|
||||
},
|
||||
|
||||
setUseActionIcons: function(useIcons) {
|
||||
this._useActionIcons = useIcons;
|
||||
},
|
||||
|
||||
_styleChanged: function() {
|
||||
this._spacing = this._table.get_theme_node().get_length('spacing-columns');
|
||||
},
|
||||
@ -1116,6 +1141,18 @@ const Notification = new Lang.Class({
|
||||
this.actor.add_style_class_name('notification-unexpanded');
|
||||
},
|
||||
|
||||
_onActionInvoked: function(actor, mouseButtonClicked, id) {
|
||||
this.emit('action-invoked', id);
|
||||
if (!this.resident) {
|
||||
// We don't hide a resident notification when the user invokes one of its actions,
|
||||
// because it is common for such notifications to update themselves with new
|
||||
// information based on the action. We'd like to display the updated information
|
||||
// in place, rather than pop-up a new notification.
|
||||
this.emit('done-displaying');
|
||||
this.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
_onClicked: function() {
|
||||
this.emit('clicked');
|
||||
// We hide all types of notifications once the user clicks on them because the common
|
||||
@ -1381,7 +1418,9 @@ const Source = new Lang.Class({
|
||||
if (this.notifications.indexOf(notification) >= 0)
|
||||
return;
|
||||
|
||||
notification.connect('clicked', Lang.bind(this, this.open));
|
||||
notification.connect('destroy', Lang.bind(this, this._onNotificationDestroy));
|
||||
|
||||
this.notifications.push(notification);
|
||||
this.emit('notification-added', notification);
|
||||
|
||||
@ -2173,10 +2212,7 @@ const MessageTray = new Lang.Class({
|
||||
},
|
||||
|
||||
toggleAndNavigate: function() {
|
||||
if (!this.toggle())
|
||||
return;
|
||||
|
||||
if (this._traySummoned)
|
||||
if (this.toggle())
|
||||
this._summary.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
},
|
||||
|
||||
@ -2373,6 +2409,7 @@ const MessageTray = new Lang.Class({
|
||||
this._showNotification();
|
||||
}
|
||||
} else if (this._notificationState == State.SHOWN) {
|
||||
let pinned = this._pointerInNotification && !this._notificationRemoved;
|
||||
let expired = (this._userActiveWhileNotificationShown &&
|
||||
this._notificationTimeoutId == 0 &&
|
||||
!(this._notification.urgency == Urgency.CRITICAL) &&
|
||||
@ -2383,9 +2420,9 @@ const MessageTray = new Lang.Class({
|
||||
if (mustClose) {
|
||||
let animate = hasNotifications && !this._notificationRemoved;
|
||||
this._hideNotification(animate);
|
||||
} else if (this._pointerInNotification && !this._notification.expanded) {
|
||||
} else if (pinned && !this._notification.expanded) {
|
||||
this._expandNotification(false);
|
||||
} else if (this._pointerInNotification) {
|
||||
} else if (pinned) {
|
||||
this._ensureNotificationFocused();
|
||||
}
|
||||
}
|
||||
@ -2755,12 +2792,12 @@ const MessageTray = new Lang.Class({
|
||||
} else if (this._notification.y != expandedY) {
|
||||
// Tween also opacity here, to override a possible tween that's
|
||||
// currently hiding the notification.
|
||||
Tweener.addTween(this._notificationWidget,
|
||||
{ y: expandedY,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
this._tween(this._notificationWidget, '_notificationState', State.SHOWN,
|
||||
{ y: expandedY,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -4,7 +4,6 @@ const Clutter = imports.gi.Clutter;
|
||||
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Mainloop = imports.mainloop;
|
||||
@ -16,56 +15,54 @@ const MessageTray = imports.ui.messageTray;
|
||||
const Params = imports.misc.params;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
let nextNotificationId = 1;
|
||||
|
||||
// Should really be defined in Gio.js
|
||||
const BusIface = '<node> \
|
||||
<interface name="org.freedesktop.DBus"> \
|
||||
<method name="GetConnectionUnixProcessID"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="u" direction="out" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BusIface = <interface name="org.freedesktop.DBus">
|
||||
<method name="GetConnectionUnixProcessID">
|
||||
<arg type="s" direction="in" />
|
||||
<arg type="u" direction="out" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
var BusProxy = Gio.DBusProxy.makeProxyWrapper(BusIface);
|
||||
function Bus() {
|
||||
return new BusProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
|
||||
}
|
||||
|
||||
const FdoNotificationsIface = '<node> \
|
||||
<interface name="org.freedesktop.Notifications"> \
|
||||
<method name="Notify"> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="u" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="s" direction="in"/> \
|
||||
<arg type="as" direction="in"/> \
|
||||
<arg type="a{sv}" direction="in"/> \
|
||||
<arg type="i" direction="in"/> \
|
||||
<arg type="u" direction="out"/> \
|
||||
</method> \
|
||||
<method name="CloseNotification"> \
|
||||
<arg type="u" direction="in"/> \
|
||||
</method> \
|
||||
<method name="GetCapabilities"> \
|
||||
<arg type="as" direction="out"/> \
|
||||
</method> \
|
||||
<method name="GetServerInformation"> \
|
||||
<arg type="s" direction="out"/> \
|
||||
<arg type="s" direction="out"/> \
|
||||
<arg type="s" direction="out"/> \
|
||||
<arg type="s" direction="out"/> \
|
||||
</method> \
|
||||
<signal name="NotificationClosed"> \
|
||||
<arg type="u"/> \
|
||||
<arg type="u"/> \
|
||||
</signal> \
|
||||
<signal name="ActionInvoked"> \
|
||||
<arg type="u"/> \
|
||||
<arg type="s"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const NotificationDaemonIface = <interface name="org.freedesktop.Notifications">
|
||||
<method name="Notify">
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="u" direction="in"/>
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="as" direction="in"/>
|
||||
<arg type="a{sv}" direction="in"/>
|
||||
<arg type="i" direction="in"/>
|
||||
<arg type="u" direction="out"/>
|
||||
</method>
|
||||
<method name="CloseNotification">
|
||||
<arg type="u" direction="in"/>
|
||||
</method>
|
||||
<method name="GetCapabilities">
|
||||
<arg type="as" direction="out"/>
|
||||
</method>
|
||||
<method name="GetServerInformation">
|
||||
<arg type="s" direction="out"/>
|
||||
<arg type="s" direction="out"/>
|
||||
<arg type="s" direction="out"/>
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<signal name="NotificationClosed">
|
||||
<arg type="u"/>
|
||||
<arg type="u"/>
|
||||
</signal>
|
||||
<signal name="ActionInvoked">
|
||||
<arg type="u"/>
|
||||
<arg type="s"/>
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const NotificationClosedReason = {
|
||||
EXPIRED: 1,
|
||||
@ -106,11 +103,11 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
||||
'ibus-ui-gtk': 'keyboard'
|
||||
};
|
||||
|
||||
const FdoNotificationDaemon = new Lang.Class({
|
||||
Name: 'FdoNotificationDaemon',
|
||||
const NotificationDaemon = new Lang.Class({
|
||||
Name: 'NotificationDaemon',
|
||||
|
||||
_init: function() {
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(FdoNotificationsIface, this);
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(NotificationDaemonIface, this);
|
||||
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
|
||||
|
||||
this._sources = [];
|
||||
@ -118,8 +115,6 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
this._notifications = {};
|
||||
this._busProxy = new Bus();
|
||||
|
||||
this._nextNotificationId = 1;
|
||||
|
||||
this._trayManager = new Shell.TrayManager();
|
||||
this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
||||
this._trayIconRemovedId = this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
|
||||
@ -218,7 +213,7 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
}
|
||||
}
|
||||
|
||||
let source = new FdoNotificationDaemonSource(title, pid, sender, trayIcon, ndata ? ndata.hints['desktop-entry'] : null);
|
||||
let source = new Source(title, pid, sender, trayIcon, ndata ? ndata.hints['desktop-entry'] : null);
|
||||
source.setTransient(isForTransientNotification);
|
||||
|
||||
if (!isForTransientNotification) {
|
||||
@ -257,7 +252,7 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
hints['category'] == 'presence.offline')) {
|
||||
// Ignore replacesId since we already sent back a
|
||||
// NotificationClosed for that id.
|
||||
id = this._nextNotificationId++;
|
||||
id = nextNotificationId++;
|
||||
Mainloop.idle_add(Lang.bind(this,
|
||||
function () {
|
||||
this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
|
||||
@ -301,7 +296,7 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
ndata.notification = this._notifications[replacesId].notification;
|
||||
} else {
|
||||
replacesId = 0;
|
||||
ndata.id = id = this._nextNotificationId++;
|
||||
ndata.id = id = nextNotificationId++;
|
||||
}
|
||||
this._notifications[id] = ndata;
|
||||
|
||||
@ -356,19 +351,6 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
return invocation.return_value(GLib.Variant.new('(u)', [id]));
|
||||
},
|
||||
|
||||
_makeButton: function(id, label, useActionIcons) {
|
||||
let button = new St.Button({ can_focus: true });
|
||||
let iconName = id.endsWith('-symbolic') ? id : id + '-symbolic';
|
||||
if (useActionIcons && Gtk.IconTheme.get_default().has_icon(iconName)) {
|
||||
button.add_style_class_name('notification-icon-button');
|
||||
button.child = new St.Icon({ icon_name: iconName });
|
||||
} else {
|
||||
button.add_style_class_name('notification-button');
|
||||
button.label = label;
|
||||
}
|
||||
return button;
|
||||
},
|
||||
|
||||
_notifyForSource: function(source, ndata) {
|
||||
let [id, icon, summary, body, actions, hints, notification] =
|
||||
[ndata.id, ndata.icon, ndata.summary, ndata.body,
|
||||
@ -394,6 +376,10 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
}
|
||||
this._emitNotificationClosed(ndata.id, notificationClosedReason);
|
||||
}));
|
||||
notification.connect('action-invoked', Lang.bind(this,
|
||||
function(n, actionId) {
|
||||
this._emitActionInvoked(ndata.id, actionId);
|
||||
}));
|
||||
}
|
||||
|
||||
// Mark music notifications so they can be shown in the screen shield
|
||||
@ -427,33 +413,18 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
soundName: hints['sound-name'] });
|
||||
notification.setImage(image);
|
||||
|
||||
let hasDefaultAction = false;
|
||||
|
||||
if (actions.length) {
|
||||
let useActionIcons = (hints['action-icons'] == true);
|
||||
|
||||
notification.setUseActionIcons(hints['action-icons'] == true);
|
||||
for (let i = 0; i < actions.length - 1; i += 2) {
|
||||
let [actionId, label] = [actions[i], actions[i+1]];
|
||||
if (actionId == 'default') {
|
||||
hasDefaultAction = true;
|
||||
} else {
|
||||
notification.addButton(this._makeButton(actionId, label, useActionIcons), Lang.bind(this, function() {
|
||||
this._emitActionInvoked(ndata.id, actionId);
|
||||
}));
|
||||
}
|
||||
if (actions[i] == 'default')
|
||||
notification.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
this._emitActionInvoked(ndata.id, "default");
|
||||
}));
|
||||
else
|
||||
notification.addButton(actions[i], actions[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDefaultAction) {
|
||||
notification.connect('clicked', Lang.bind(this, function() {
|
||||
this._emitActionInvoked(ndata.id, 'default');
|
||||
}));
|
||||
} else {
|
||||
notification.connect('clicked', Lang.bind(this, function() {
|
||||
source.open();
|
||||
}));
|
||||
}
|
||||
|
||||
switch (hints.urgency) {
|
||||
case Urgency.LOW:
|
||||
notification.setUrgency(MessageTray.Urgency.LOW);
|
||||
@ -546,8 +517,8 @@ const FdoNotificationDaemon = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const FdoNotificationDaemonSource = new Lang.Class({
|
||||
Name: 'FdoNotificationDaemonSource',
|
||||
const Source = new Lang.Class({
|
||||
Name: 'NotificationDaemonSource',
|
||||
Extends: MessageTray.Source,
|
||||
|
||||
_init: function(title, pid, sender, trayIcon, appId) {
|
||||
@ -582,7 +553,7 @@ const FdoNotificationDaemonSource = new Lang.Class({
|
||||
},
|
||||
|
||||
_createPolicy: function() {
|
||||
if (this.app && this.app.get_app_info()) {
|
||||
if (this.app) {
|
||||
let id = this.app.get_id().replace(/\.desktop$/,'');
|
||||
return new MessageTray.NotificationApplicationPolicy(id);
|
||||
} else {
|
||||
@ -672,7 +643,7 @@ const FdoNotificationDaemonSource = new Lang.Class({
|
||||
this.parent(title);
|
||||
},
|
||||
|
||||
open: function() {
|
||||
open: function(notification) {
|
||||
this.openApp();
|
||||
this.destroyNonResidentNotifications();
|
||||
},
|
||||
@ -714,276 +685,3 @@ const FdoNotificationDaemonSource = new Lang.Class({
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const GtkNotificationDaemonNotification = new Lang.Class({
|
||||
Name: 'GtkNotificationDaemonNotification',
|
||||
Extends: MessageTray.Notification,
|
||||
|
||||
_init: function(source, notification) {
|
||||
this.parent(source);
|
||||
this._serialized = GLib.Variant.new('a{sv}', notification);
|
||||
|
||||
let { "title": title,
|
||||
"body": body,
|
||||
"icon": gicon,
|
||||
"urgent": urgent,
|
||||
"buttons": buttons,
|
||||
"default-action": defaultAction,
|
||||
"default-action-target": defaultActionTarget } = notification;
|
||||
|
||||
this.setUrgency(urgent.unpack() ? MessageTray.Urgency.CRITICAL
|
||||
: MessageTray.Urgency.NORMAL);
|
||||
|
||||
if (buttons) {
|
||||
buttons.deep_unpack().forEach(Lang.bind(this, function(button) {
|
||||
this.addAction(button.label.unpack(),
|
||||
Lang.bind(this, this._onButtonClicked, button));
|
||||
}));
|
||||
}
|
||||
|
||||
this._defaultAction = defaultAction ? defaultAction.unpack() : null;
|
||||
this._defaultActionTarget = defaultActionTarget;
|
||||
|
||||
this.update(title.unpack(), body ? body.unpack() : null,
|
||||
{ gicon: gicon ? Gio.icon_deserialize(gicon) : null });
|
||||
},
|
||||
|
||||
_activateAction: function(namespacedActionId, target) {
|
||||
if (namespacedActionId) {
|
||||
if (namespacedActionId.startsWith('app.')) {
|
||||
let actionId = namespacedActionId.slice('app.'.length);
|
||||
this.source.activateAction(actionId, target);
|
||||
}
|
||||
} else {
|
||||
this.source.open();
|
||||
}
|
||||
},
|
||||
|
||||
_onButtonClicked: function(button) {
|
||||
let { 'action': action, 'target': actionTarget } = button;
|
||||
this._activateAction(action.unpack(), actionTarget);
|
||||
},
|
||||
|
||||
_onClicked: function() {
|
||||
this._activateAction(this._defaultAction, this._defaultActionTarget);
|
||||
this.parent();
|
||||
},
|
||||
|
||||
serialize: function() {
|
||||
return this._serialized;
|
||||
},
|
||||
});
|
||||
|
||||
const FdoApplicationIface = '<node> \
|
||||
<interface name="org.freedesktop.Application"> \
|
||||
<method name="ActivateAction"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="av" direction="in" /> \
|
||||
<arg type="a{sv}" direction="in" /> \
|
||||
</method> \
|
||||
<method name="Activate"> \
|
||||
<arg type="a{sv}" direction="in" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const FdoApplicationProxy = Gio.DBusProxy.makeProxyWrapper(FdoApplicationIface);
|
||||
|
||||
function objectPathFromAppId(appId) {
|
||||
return '/' + appId.replace(/\./g, '/');
|
||||
}
|
||||
|
||||
function getPlatformData() {
|
||||
let startupId = GLib.Variant.new('s', '_TIME' + global.get_current_time());
|
||||
return { "desktop-startup-id": startupId };
|
||||
}
|
||||
|
||||
function InvalidAppError() {}
|
||||
|
||||
const GtkNotificationDaemonAppSource = new Lang.Class({
|
||||
Name: 'GtkNotificationDaemonAppSource',
|
||||
Extends: MessageTray.Source,
|
||||
|
||||
_init: function(appId) {
|
||||
this._appId = appId;
|
||||
this._objectPath = objectPathFromAppId(appId);
|
||||
|
||||
this._app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop');
|
||||
if (!this._app)
|
||||
throw new InvalidAppError();
|
||||
|
||||
this._notifications = {};
|
||||
|
||||
this.parent(this._app.get_name());
|
||||
},
|
||||
|
||||
createIcon: function(size) {
|
||||
return this._app.create_icon_texture(size);
|
||||
},
|
||||
|
||||
_createPolicy: function() {
|
||||
return new MessageTray.NotificationApplicationPolicy(this._appId);
|
||||
},
|
||||
|
||||
_createApp: function() {
|
||||
return new FdoApplicationProxy(Gio.DBus.session, this._appId, this._objectPath);
|
||||
},
|
||||
|
||||
activateAction: function(actionId, target) {
|
||||
let app = this._createApp();
|
||||
app.ActivateActionRemote(actionId, target ? [target] : [], getPlatformData());
|
||||
},
|
||||
|
||||
open: function() {
|
||||
let app = this._createApp();
|
||||
app.ActivateRemote(getPlatformData());
|
||||
},
|
||||
|
||||
addNotification: function(notificationId, notificationParams, showBanner) {
|
||||
if (this._notifications[notificationId])
|
||||
this._notifications[notificationId].destroy();
|
||||
|
||||
let notification = new GtkNotificationDaemonNotification(this, notificationParams);
|
||||
notification.connect('destroy', Lang.bind(this, function() {
|
||||
delete this._notifications[notificationId];
|
||||
}));
|
||||
this._notifications[notificationId] = notification;
|
||||
|
||||
if (showBanner)
|
||||
this.notify(notification);
|
||||
else
|
||||
this.pushNotification(notification);
|
||||
},
|
||||
|
||||
removeNotification: function(notificationId) {
|
||||
if (this._notifications[notificationId])
|
||||
this._notifications[notificationId].destroy(MessageTray.NotificationDestroyedReason.SOURCE_CLOSED);
|
||||
},
|
||||
|
||||
serialize: function() {
|
||||
let notifications = [];
|
||||
for (let notificationId in this._notifications) {
|
||||
let notification = this._notifications[notificationId];
|
||||
notifications.push([notificationId, notification.serialize()]);
|
||||
}
|
||||
return [this._appId, notifications];
|
||||
},
|
||||
});
|
||||
|
||||
const GtkNotificationsIface = '<node> \
|
||||
<interface name="org.gtk.Notifications"> \
|
||||
<method name="AddNotification"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="a{sv}" direction="in" /> \
|
||||
</method> \
|
||||
<method name="RemoveNotification"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="s" direction="in" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const GtkNotificationDaemon = new Lang.Class({
|
||||
Name: 'GtkNotificationDaemon',
|
||||
|
||||
_init: function() {
|
||||
this._sources = {};
|
||||
|
||||
this._loadNotifications();
|
||||
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GtkNotificationsIface, this);
|
||||
this._dbusImpl.export(Gio.DBus.session, '/org/gtk/Notifications');
|
||||
|
||||
Gio.DBus.session.own_name('org.gtk.Notifications', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||
},
|
||||
|
||||
_ensureAppSource: function(appId) {
|
||||
if (this._sources[appId])
|
||||
return this._sources[appId];
|
||||
|
||||
let source = new GtkNotificationDaemonAppSource(appId);
|
||||
|
||||
source.connect('destroy', Lang.bind(this, function() {
|
||||
delete this._sources[appId];
|
||||
this._saveNotifications();
|
||||
}));
|
||||
source.connect('count-updated', Lang.bind(this, this._saveNotifications));
|
||||
Main.messageTray.add(source);
|
||||
this._sources[appId] = source;
|
||||
return source;
|
||||
},
|
||||
|
||||
_loadNotifications: function() {
|
||||
this._isLoading = true;
|
||||
|
||||
let value = global.get_persistent_state('a(sa(sv))', 'notifications');
|
||||
if (value) {
|
||||
let sources = value.deep_unpack();
|
||||
sources.forEach(Lang.bind(this, function([appId, notifications]) {
|
||||
if (notifications.length == 0)
|
||||
return;
|
||||
|
||||
let source;
|
||||
try {
|
||||
source = this._ensureAppSource(appId);
|
||||
} catch(e if e instanceof InvalidAppError) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifications.forEach(function([notificationId, notification]) {
|
||||
source.addNotification(notificationId, notification.deep_unpack(), false);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
this._isLoading = false;
|
||||
},
|
||||
|
||||
_saveNotifications: function() {
|
||||
if (this._isLoading)
|
||||
return;
|
||||
|
||||
let sources = [];
|
||||
for (let appId in this._sources) {
|
||||
let source = this._sources[appId];
|
||||
sources.push(source.serialize());
|
||||
}
|
||||
|
||||
global.set_persistent_state('notifications', new GLib.Variant('a(sa(sv))', sources));
|
||||
},
|
||||
|
||||
AddNotificationAsync: function(params, invocation) {
|
||||
let [appId, notificationId, notification] = params;
|
||||
|
||||
let source;
|
||||
try {
|
||||
source = this._ensureAppSource(appId);
|
||||
} catch(e if e instanceof InvalidAppError) {
|
||||
invocation.return_dbus_error('org.gtk.Notifications.InvalidApp', 'The app by ID "%s" could not be found'.format(appId));
|
||||
return;
|
||||
}
|
||||
|
||||
source.addNotification(notificationId, notification, true);
|
||||
|
||||
invocation.return_value(null);
|
||||
},
|
||||
|
||||
RemoveNotificationAsync: function(params, invocation) {
|
||||
let [appId, notificationId] = params;
|
||||
let source = this._sources[appId];
|
||||
if (source)
|
||||
source.removeNotification(notificationId);
|
||||
|
||||
invocation.return_value(null);
|
||||
},
|
||||
});
|
||||
|
||||
const NotificationDaemon = new Lang.Class({
|
||||
Name: 'NotificationDaemon',
|
||||
|
||||
_init: function() {
|
||||
this._fdoNotificationDaemon = new FdoNotificationDaemon();
|
||||
this._gtkNotificationDaemon = new GtkNotificationDaemon();
|
||||
},
|
||||
});
|
||||
|
@ -78,8 +78,10 @@ const ShellInfo = new Lang.Class({
|
||||
}
|
||||
|
||||
this._undoCallback = undoCallback;
|
||||
if (undoCallback)
|
||||
notification.addAction(_("Undo"), Lang.bind(this, this._onUndoClicked));
|
||||
if (undoCallback) {
|
||||
notification.addButton('system-undo', _("Undo"));
|
||||
notification.connect('action-invoked', Lang.bind(this, this._onUndoClicked));
|
||||
}
|
||||
|
||||
this._source.notify(notification);
|
||||
}
|
||||
@ -363,13 +365,11 @@ const Overview = new Lang.Class({
|
||||
this._lastHoveredWindow = dragEvent.targetActor._delegate.metaWindow;
|
||||
this._windowSwitchTimeoutId = Mainloop.timeout_add(DND_WINDOW_SWITCH_TIMEOUT,
|
||||
Lang.bind(this, function() {
|
||||
this._windowSwitchTimeoutId = 0;
|
||||
this._needsFakePointerEvent = true;
|
||||
Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
|
||||
this._windowSwitchTimestamp);
|
||||
this.hide();
|
||||
this._lastHoveredWindow = null;
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
@ -445,17 +445,17 @@ const Overview = new Lang.Class({
|
||||
this._inDrag = false;
|
||||
},
|
||||
|
||||
beginWindowDrag: function(clone) {
|
||||
this.emit('window-drag-begin', clone);
|
||||
beginWindowDrag: function(source) {
|
||||
this.emit('window-drag-begin');
|
||||
this._inDrag = true;
|
||||
},
|
||||
|
||||
cancelledWindowDrag: function(clone) {
|
||||
this.emit('window-drag-cancelled', clone);
|
||||
cancelledWindowDrag: function(source) {
|
||||
this.emit('window-drag-cancelled');
|
||||
},
|
||||
|
||||
endWindowDrag: function(clone) {
|
||||
this.emit('window-drag-end', clone);
|
||||
endWindowDrag: function(source) {
|
||||
this.emit('window-drag-end');
|
||||
this._inDrag = false;
|
||||
},
|
||||
|
||||
|
@ -36,7 +36,6 @@ const SlideLayout = new Lang.Class({
|
||||
|
||||
_init: function(params) {
|
||||
this._slideX = 1;
|
||||
this._translationX = 0;
|
||||
this._direction = SlideDirection.LEFT;
|
||||
|
||||
this.parent(params);
|
||||
@ -67,9 +66,9 @@ const SlideLayout = new Lang.Class({
|
||||
let alignX = (realDirection == SlideDirection.LEFT) ? (availWidth - natWidth) : 0;
|
||||
|
||||
let actorBox = new Clutter.ActorBox();
|
||||
actorBox.x1 = box.x1 + alignX + this._translationX;
|
||||
actorBox.x2 = actorBox.x1 + (child.x_expand ? availWidth : natWidth);
|
||||
actorBox.y1 = box.y1;
|
||||
actorBox.x1 = alignX;
|
||||
actorBox.x2 = actorBox.x1 + child.x_expand ? availWidth : natWidth;
|
||||
actorBox.y1 = 0;
|
||||
actorBox.y2 = actorBox.y1 + availHeight;
|
||||
|
||||
child.allocate(actorBox, flags);
|
||||
@ -91,16 +90,7 @@ const SlideLayout = new Lang.Class({
|
||||
|
||||
get slideDirection() {
|
||||
return this._direction;
|
||||
},
|
||||
|
||||
set translationX(value) {
|
||||
this._translationX = value;
|
||||
this.layout_changed();
|
||||
},
|
||||
|
||||
get translationX() {
|
||||
return this._translationX;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
const SlidingControl = new Lang.Class({
|
||||
@ -109,8 +99,8 @@ const SlidingControl = new Lang.Class({
|
||||
_init: function(params) {
|
||||
params = Params.parse(params, { slideDirection: SlideDirection.LEFT });
|
||||
|
||||
this._visible = true;
|
||||
this._inDrag = false;
|
||||
this.visible = true;
|
||||
this.inDrag = false;
|
||||
|
||||
this.layout = new SlideLayout();
|
||||
this.layout.slideDirection = params.slideDirection;
|
||||
@ -119,7 +109,6 @@ const SlidingControl = new Lang.Class({
|
||||
clip_to_allocation: true });
|
||||
|
||||
Main.overview.connect('showing', Lang.bind(this, this._onOverviewShowing));
|
||||
Main.overview.connect('hiding', Lang.bind(this, this._onOverviewHiding));
|
||||
|
||||
Main.overview.connect('item-drag-begin', Lang.bind(this, this._onDragBegin));
|
||||
Main.overview.connect('item-drag-end', Lang.bind(this, this._onDragEnd));
|
||||
@ -130,12 +119,12 @@ const SlidingControl = new Lang.Class({
|
||||
Main.overview.connect('window-drag-end', Lang.bind(this, this._onWindowDragEnd));
|
||||
},
|
||||
|
||||
_getSlide: function() {
|
||||
getSlide: function() {
|
||||
throw new Error('getSlide() must be overridden');
|
||||
},
|
||||
|
||||
_updateSlide: function() {
|
||||
Tweener.addTween(this.layout, { slideX: this._getSlide(),
|
||||
updateSlide: function() {
|
||||
Tweener.addTween(this.layout, { slideX: this.getSlide(),
|
||||
time: SIDE_CONTROLS_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
@ -162,30 +151,28 @@ const SlidingControl = new Lang.Class({
|
||||
let translationEnd = 0;
|
||||
let translation = this._getTranslation();
|
||||
|
||||
if (this._visible) {
|
||||
if (this.visible) {
|
||||
translationStart = translation;
|
||||
} else {
|
||||
translationEnd = translation;
|
||||
}
|
||||
|
||||
if (this.layout.translationX == translationEnd)
|
||||
if (this.actor.translation_x == translationEnd)
|
||||
return;
|
||||
|
||||
this.layout.translationX = translationStart;
|
||||
Tweener.addTween(this.layout, { translationX: translationEnd,
|
||||
time: SIDE_CONTROLS_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
this.actor.translation_x = translationStart;
|
||||
Tweener.addTween(this.actor, { translation_x: translationEnd,
|
||||
time: SIDE_CONTROLS_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
_onOverviewShowing: function() {
|
||||
this._visible = true;
|
||||
this.layout.slideX = this._getSlide();
|
||||
this.layout.translationX = this._getTranslation();
|
||||
this.slideIn();
|
||||
},
|
||||
|
||||
_onOverviewHiding: function() {
|
||||
this.slideOut();
|
||||
// reset any translation and make sure the actor is visible when
|
||||
// entering the overview
|
||||
this.visible = true;
|
||||
this.layout.slideX = this.getSlide();
|
||||
this.actor.translation_x = 0;
|
||||
},
|
||||
|
||||
_onWindowDragBegin: function() {
|
||||
@ -197,14 +184,14 @@ const SlidingControl = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDragBegin: function() {
|
||||
this._inDrag = true;
|
||||
this.layout.translationX = 0;
|
||||
this._updateSlide();
|
||||
this.inDrag = true;
|
||||
this.actor.translation_x = 0;
|
||||
this.updateSlide();
|
||||
},
|
||||
|
||||
_onDragEnd: function() {
|
||||
this._inDrag = false;
|
||||
this._updateSlide();
|
||||
this.inDrag = false;
|
||||
this.updateSlide();
|
||||
},
|
||||
|
||||
fadeIn: function() {
|
||||
@ -222,13 +209,13 @@ const SlidingControl = new Lang.Class({
|
||||
},
|
||||
|
||||
slideIn: function() {
|
||||
this._visible = true;
|
||||
this.visible = true;
|
||||
this._updateTranslation();
|
||||
// we will update slideX and the translation from pageEmpty
|
||||
},
|
||||
|
||||
slideOut: function() {
|
||||
this._visible = false;
|
||||
this.visible = false;
|
||||
this._updateTranslation();
|
||||
// we will update slideX from pageEmpty
|
||||
},
|
||||
@ -238,7 +225,7 @@ const SlidingControl = new Lang.Class({
|
||||
// selector; this means we can now safely set the full slide for
|
||||
// the next page, since slideIn or slideOut might have been called,
|
||||
// changing the visiblity
|
||||
this.layout.slideX = this._getSlide();
|
||||
this.layout.slideX = this.getSlide();
|
||||
this._updateTranslation();
|
||||
}
|
||||
});
|
||||
@ -257,15 +244,16 @@ const ThumbnailsSlider = new Lang.Class({
|
||||
this.actor.track_hover = true;
|
||||
this.actor.add_actor(this._thumbnailsBox.actor);
|
||||
|
||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateSlide));
|
||||
this.actor.connect('notify::hover', Lang.bind(this, this._updateSlide));
|
||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this.updateSlide));
|
||||
Main.overview.connect('hiding', Lang.bind(this, this.slideOut));
|
||||
this.actor.connect('notify::hover', Lang.bind(this, this.updateSlide));
|
||||
this._thumbnailsBox.actor.bind_property('visible', this.actor, 'visible', GObject.BindingFlags.SYNC_CREATE);
|
||||
},
|
||||
|
||||
_getAlwaysZoomOut: function() {
|
||||
// Always show the pager when hover, during a drag, or if workspaces are
|
||||
// actually used, e.g. there are windows on more than one
|
||||
let alwaysZoomOut = this.actor.hover || this._inDrag || !Meta.prefs_get_dynamic_workspaces() || global.screen.n_workspaces > 2;
|
||||
let alwaysZoomOut = this.actor.hover || this.inDrag || !Meta.prefs_get_dynamic_workspaces() || global.screen.n_workspaces > 2;
|
||||
|
||||
if (!alwaysZoomOut) {
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
@ -285,13 +273,20 @@ const ThumbnailsSlider = new Lang.Class({
|
||||
return alwaysZoomOut;
|
||||
},
|
||||
|
||||
_onOverviewShowing: function() {
|
||||
this.visible = true;
|
||||
this.layout.slideX = this.getSlide();
|
||||
this.actor.translation_x = this._getTranslation();
|
||||
this.slideIn();
|
||||
},
|
||||
|
||||
getNonExpandedWidth: function() {
|
||||
let child = this.actor.get_first_child();
|
||||
return child.get_theme_node().get_length('visible-width');
|
||||
},
|
||||
|
||||
_getSlide: function() {
|
||||
if (!this._visible)
|
||||
getSlide: function() {
|
||||
if (!this.visible)
|
||||
return 0;
|
||||
|
||||
let alwaysZoomOut = this._getAlwaysZoomOut();
|
||||
@ -328,22 +323,29 @@ const DashSlider = new Lang.Class({
|
||||
// available allocation
|
||||
this._dash.actor.x_expand = true;
|
||||
|
||||
this.actor.x_expand = true;
|
||||
this.actor.x_align = Clutter.ActorAlign.START;
|
||||
this.actor.y_expand = true;
|
||||
|
||||
this.actor.add_actor(this._dash.actor);
|
||||
|
||||
this._dash.connect('icon-size-changed', Lang.bind(this, this._updateSlide));
|
||||
this._dash.connect('icon-size-changed', Lang.bind(this, this.updateSlide));
|
||||
Main.overview.connect('hiding', Lang.bind(this, this.slideOut));
|
||||
},
|
||||
|
||||
_getSlide: function() {
|
||||
if (this._visible || this._inDrag)
|
||||
getSlide: function() {
|
||||
if (this.visible || this.inDrag)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
},
|
||||
|
||||
_onOverviewShowing: function() {
|
||||
this.visible = true;
|
||||
this.layout.slideX = this.getSlide();
|
||||
this.actor.translation_x = this._getTranslation();
|
||||
this.slideIn();
|
||||
},
|
||||
|
||||
_onWindowDragBegin: function() {
|
||||
this.fadeHalf();
|
||||
},
|
||||
|
@ -7,63 +7,58 @@ const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
const Search = imports.ui.search;
|
||||
|
||||
const KEY_FILE_GROUP = 'Shell Search Provider';
|
||||
|
||||
const SearchProviderIface = '<node> \
|
||||
<interface name="org.gnome.Shell.SearchProvider"> \
|
||||
<method name="GetInitialResultSet"> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="as" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetSubsearchResultSet"> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="as" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetResultMetas"> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="aa{sv}" direction="out" /> \
|
||||
</method> \
|
||||
<method name="ActivateResult"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
|
||||
<method name="GetInitialResultSet">
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="as" direction="out" />
|
||||
</method>
|
||||
<method name="GetSubsearchResultSet">
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="as" direction="out" />
|
||||
</method>
|
||||
<method name="GetResultMetas">
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="aa{sv}" direction="out" />
|
||||
</method>
|
||||
<method name="ActivateResult">
|
||||
<arg type="s" direction="in" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const SearchProvider2Iface = '<node> \
|
||||
<interface name="org.gnome.Shell.SearchProvider2"> \
|
||||
<method name="GetInitialResultSet"> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="as" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetSubsearchResultSet"> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="as" direction="out" /> \
|
||||
</method> \
|
||||
<method name="GetResultMetas"> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="aa{sv}" direction="out" /> \
|
||||
</method> \
|
||||
<method name="ActivateResult"> \
|
||||
<arg type="s" direction="in" /> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="LaunchSearch"> \
|
||||
<arg type="as" direction="in" /> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const SearchProvider2Iface = <interface name="org.gnome.Shell.SearchProvider2">
|
||||
<method name="GetInitialResultSet">
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="as" direction="out" />
|
||||
</method>
|
||||
<method name="GetSubsearchResultSet">
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="as" direction="out" />
|
||||
</method>
|
||||
<method name="GetResultMetas">
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="aa{sv}" direction="out" />
|
||||
</method>
|
||||
<method name="ActivateResult">
|
||||
<arg type="s" direction="in" />
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
<method name="LaunchSearch">
|
||||
<arg type="as" direction="in" />
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
var SearchProviderProxyInfo = Gio.DBusInterfaceInfo.new_for_xml(SearchProviderIface);
|
||||
var SearchProvider2ProxyInfo = Gio.DBusInterfaceInfo.new_for_xml(SearchProvider2Iface);
|
||||
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
|
||||
var SearchProvider2Proxy = Gio.DBusProxy.makeProxyWrapper(SearchProvider2Iface);
|
||||
|
||||
function loadRemoteSearchProviders(callback) {
|
||||
function loadRemoteSearchProviders(addProviderCallback) {
|
||||
let objectPaths = {};
|
||||
let loadedProviders = [];
|
||||
|
||||
@ -117,25 +112,30 @@ function loadRemoteSearchProviders(callback) {
|
||||
}
|
||||
}
|
||||
|
||||
let dataDirs = GLib.get_system_data_dirs();
|
||||
dataDirs.forEach(function(dataDir) {
|
||||
let path = GLib.build_filenamev([dataDir, 'gnome-shell', 'search-providers']);
|
||||
let dir = Gio.File.new_for_path(path);
|
||||
let fileEnum;
|
||||
try {
|
||||
fileEnum = dir.enumerate_children('standard::name,standard::type',
|
||||
Gio.FileQueryInfoFlags.NONE, null);
|
||||
} catch (e) {
|
||||
fileEnum = null;
|
||||
}
|
||||
if (fileEnum != null) {
|
||||
let info;
|
||||
while ((info = fileEnum.next_file(null)))
|
||||
loadRemoteSearchProvider(fileEnum.get_child(info));
|
||||
}
|
||||
});
|
||||
|
||||
let searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
|
||||
if (searchSettings.get_boolean('disable-external')) {
|
||||
callback([]);
|
||||
return;
|
||||
}
|
||||
|
||||
FileUtils.collectFromDatadirs('search-providers', false, loadRemoteSearchProvider);
|
||||
|
||||
let sortOrder = searchSettings.get_strv('sort-order');
|
||||
|
||||
// Special case gnome-control-center to be always active and always first
|
||||
sortOrder.unshift('gnome-control-center.desktop');
|
||||
|
||||
loadedProviders = loadedProviders.filter(function(provider) {
|
||||
let appId = provider.appInfo.get_id();
|
||||
let disabled = searchSettings.get_strv('disabled');
|
||||
return disabled.indexOf(appId) == -1;
|
||||
});
|
||||
|
||||
loadedProviders.sort(function(providerA, providerB) {
|
||||
let idxA, idxB;
|
||||
let appIdA, appIdB;
|
||||
@ -166,28 +166,28 @@ function loadRemoteSearchProviders(callback) {
|
||||
return (idxA - idxB);
|
||||
});
|
||||
|
||||
callback(loadedProviders);
|
||||
loadedProviders.forEach(addProviderCallback);
|
||||
}
|
||||
|
||||
const RemoteSearchProvider = new Lang.Class({
|
||||
Name: 'RemoteSearchProvider',
|
||||
|
||||
_init: function(appInfo, dbusName, dbusPath, proxyInfo) {
|
||||
if (!proxyInfo)
|
||||
proxyInfo = SearchProviderProxyInfo;
|
||||
_init: function(appInfo, dbusName, dbusPath, proxyType) {
|
||||
if (!proxyType)
|
||||
proxyType = SearchProviderProxy;
|
||||
|
||||
this.proxy = new Gio.DBusProxy({ g_bus_type: Gio.BusType.SESSION,
|
||||
g_name: dbusName,
|
||||
g_object_path: dbusPath,
|
||||
g_interface_info: proxyInfo,
|
||||
g_interface_name: proxyInfo.name,
|
||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START_AT_CONSTRUCTION |
|
||||
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||
this.proxy.init_async(GLib.PRIORITY_DEFAULT, null, null);
|
||||
this.proxy = new proxyType(Gio.DBus.session,
|
||||
dbusName, dbusPath, Lang.bind(this, this._onProxyConstructed));
|
||||
|
||||
this.appInfo = appInfo;
|
||||
this.id = appInfo.get_id();
|
||||
this.isRemoteProvider = true;
|
||||
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
},
|
||||
|
||||
_onProxyConstructed: function(proxy) {
|
||||
// Do nothing
|
||||
},
|
||||
|
||||
createIcon: function(size, meta) {
|
||||
@ -217,33 +217,40 @@ const RemoteSearchProvider = new Lang.Class({
|
||||
return regularResults.slice(0, maxNumber).concat(specialResults.slice(0, maxNumber));
|
||||
},
|
||||
|
||||
_getResultsFinished: function(results, error, callback) {
|
||||
if (error) {
|
||||
if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
log('Received error from DBus search provider %s: %s'.format(this.id, String(error)));
|
||||
callback([]);
|
||||
_getResultsFinished: function(results, error) {
|
||||
if (error)
|
||||
return;
|
||||
this.searchSystem.setResults(this, results[0]);
|
||||
},
|
||||
|
||||
getInitialResultSet: function(terms) {
|
||||
this._cancellable.cancel();
|
||||
this._cancellable.reset();
|
||||
try {
|
||||
this.proxy.GetInitialResultSetRemote(terms,
|
||||
Lang.bind(this, this._getResultsFinished),
|
||||
this._cancellable);
|
||||
} catch(e) {
|
||||
log('Error calling GetInitialResultSet for provider %s: %s'.format(this.id, e.toString()));
|
||||
this.searchSystem.setResults(this, []);
|
||||
}
|
||||
|
||||
callback(results[0]);
|
||||
},
|
||||
|
||||
getInitialResultSet: function(terms, callback, cancellable) {
|
||||
this.proxy.GetInitialResultSetRemote(terms,
|
||||
Lang.bind(this, this._getResultsFinished, callback),
|
||||
cancellable);
|
||||
},
|
||||
|
||||
getSubsearchResultSet: function(previousResults, newTerms, callback, cancellable) {
|
||||
this.proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
|
||||
Lang.bind(this, this._getResultsFinished, callback),
|
||||
cancellable);
|
||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
||||
this._cancellable.cancel();
|
||||
this._cancellable.reset();
|
||||
try {
|
||||
this.proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
|
||||
Lang.bind(this, this._getResultsFinished),
|
||||
this._cancellable);
|
||||
} catch(e) {
|
||||
log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.id, e.toString()));
|
||||
this.searchSystem.setResults(this, []);
|
||||
}
|
||||
},
|
||||
|
||||
_getResultMetasFinished: function(results, error, callback) {
|
||||
if (error) {
|
||||
if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
log('Received error from DBus search provider %s during GetResultMetas: %s'.format(this.id, String(error)));
|
||||
callback([]);
|
||||
return;
|
||||
}
|
||||
@ -265,10 +272,17 @@ const RemoteSearchProvider = new Lang.Class({
|
||||
callback(resultMetas);
|
||||
},
|
||||
|
||||
getResultMetas: function(ids, callback, cancellable) {
|
||||
this.proxy.GetResultMetasRemote(ids,
|
||||
Lang.bind(this, this._getResultMetasFinished, callback),
|
||||
cancellable);
|
||||
getResultMetas: function(ids, callback) {
|
||||
this._cancellable.cancel();
|
||||
this._cancellable.reset();
|
||||
try {
|
||||
this.proxy.GetResultMetasRemote(ids,
|
||||
Lang.bind(this, this._getResultMetasFinished, callback),
|
||||
this._cancellable);
|
||||
} catch(e) {
|
||||
log('Error calling GetResultMetas for provider %s: %s'.format(this.id, e.toString()));
|
||||
callback([]);
|
||||
}
|
||||
},
|
||||
|
||||
activateResult: function(id) {
|
||||
@ -288,7 +302,7 @@ const RemoteSearchProvider2 = new Lang.Class({
|
||||
Extends: RemoteSearchProvider,
|
||||
|
||||
_init: function(appInfo, dbusName, dbusPath) {
|
||||
this.parent(appInfo, dbusName, dbusPath, SearchProvider2ProxyInfo);
|
||||
this.parent(appInfo, dbusName, dbusPath, SearchProvider2Proxy);
|
||||
|
||||
this.canLaunchSearch = true;
|
||||
},
|
||||
|
@ -198,8 +198,8 @@ const NotificationsBox = new Lang.Class({
|
||||
|
||||
let body = '';
|
||||
if (n.bannerBodyText) {
|
||||
body = n.bannerBodyMarkup ? n.bannerBodyText
|
||||
: GLib.markup_escape_text(n.bannerBodyText, -1);
|
||||
body = n.bannerBodyMarkup ? n.bannerBodyText :
|
||||
GLib.markup_escape_text(n.bannerBodyMarkup, -1);
|
||||
}
|
||||
|
||||
let label = new St.Label({ style_class: 'screen-shield-notification-count-text' });
|
||||
|
@ -9,29 +9,27 @@ const Signals = imports.signals;
|
||||
const Hash = imports.misc.hash;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const ScreencastIface = '<node> \
|
||||
<interface name="org.gnome.Shell.Screencast"> \
|
||||
<method name="Screencast"> \
|
||||
<arg type="s" direction="in" name="file_template"/> \
|
||||
<arg type="a{sv}" direction="in" name="options"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
<arg type="s" direction="out" name="filename_used"/> \
|
||||
</method> \
|
||||
<method name="ScreencastArea"> \
|
||||
<arg type="i" direction="in" name="x"/> \
|
||||
<arg type="i" direction="in" name="y"/> \
|
||||
<arg type="i" direction="in" name="width"/> \
|
||||
<arg type="i" direction="in" name="height"/> \
|
||||
<arg type="s" direction="in" name="file_template"/> \
|
||||
<arg type="a{sv}" direction="in" name="options"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
<arg type="s" direction="out" name="filename_used"/> \
|
||||
</method> \
|
||||
<method name="StopScreencast"> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ScreencastIface = <interface name="org.gnome.Shell.Screencast">
|
||||
<method name="Screencast">
|
||||
<arg type="s" direction="in" name="file_template"/>
|
||||
<arg type="a{sv}" direction="in" name="options"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
<arg type="s" direction="out" name="filename_used"/>
|
||||
</method>
|
||||
<method name="ScreencastArea">
|
||||
<arg type="i" direction="in" name="x"/>
|
||||
<arg type="i" direction="in" name="y"/>
|
||||
<arg type="i" direction="in" name="width"/>
|
||||
<arg type="i" direction="in" name="height"/>
|
||||
<arg type="s" direction="in" name="file_template"/>
|
||||
<arg type="a{sv}" direction="in" name="options"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
<arg type="s" direction="out" name="filename_used"/>
|
||||
</method>
|
||||
<method name="StopScreencast">
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const ScreencastService = new Lang.Class({
|
||||
Name: 'ScreencastService',
|
||||
|
@ -15,47 +15,45 @@ const Lightbox = imports.ui.lightbox;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const ScreenshotIface = '<node> \
|
||||
<interface name="org.gnome.Shell.Screenshot"> \
|
||||
<method name="ScreenshotArea"> \
|
||||
<arg type="i" direction="in" name="x"/> \
|
||||
<arg type="i" direction="in" name="y"/> \
|
||||
<arg type="i" direction="in" name="width"/> \
|
||||
<arg type="i" direction="in" name="height"/> \
|
||||
<arg type="b" direction="in" name="flash"/> \
|
||||
<arg type="s" direction="in" name="filename"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
<arg type="s" direction="out" name="filename_used"/> \
|
||||
</method> \
|
||||
<method name="ScreenshotWindow"> \
|
||||
<arg type="b" direction="in" name="include_frame"/> \
|
||||
<arg type="b" direction="in" name="include_cursor"/> \
|
||||
<arg type="b" direction="in" name="flash"/> \
|
||||
<arg type="s" direction="in" name="filename"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
<arg type="s" direction="out" name="filename_used"/> \
|
||||
</method> \
|
||||
<method name="Screenshot"> \
|
||||
<arg type="b" direction="in" name="include_cursor"/> \
|
||||
<arg type="b" direction="in" name="flash"/> \
|
||||
<arg type="s" direction="in" name="filename"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
<arg type="s" direction="out" name="filename_used"/> \
|
||||
</method> \
|
||||
<method name="SelectArea"> \
|
||||
<arg type="i" direction="out" name="x"/> \
|
||||
<arg type="i" direction="out" name="y"/> \
|
||||
<arg type="i" direction="out" name="width"/> \
|
||||
<arg type="i" direction="out" name="height"/> \
|
||||
</method> \
|
||||
<method name="FlashArea"> \
|
||||
<arg type="i" direction="in" name="x"/> \
|
||||
<arg type="i" direction="in" name="y"/> \
|
||||
<arg type="i" direction="in" name="width"/> \
|
||||
<arg type="i" direction="in" name="height"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ScreenshotIface = <interface name="org.gnome.Shell.Screenshot">
|
||||
<method name="ScreenshotArea">
|
||||
<arg type="i" direction="in" name="x"/>
|
||||
<arg type="i" direction="in" name="y"/>
|
||||
<arg type="i" direction="in" name="width"/>
|
||||
<arg type="i" direction="in" name="height"/>
|
||||
<arg type="b" direction="in" name="flash"/>
|
||||
<arg type="s" direction="in" name="filename"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
<arg type="s" direction="out" name="filename_used"/>
|
||||
</method>
|
||||
<method name="ScreenshotWindow">
|
||||
<arg type="b" direction="in" name="include_frame"/>
|
||||
<arg type="b" direction="in" name="include_cursor"/>
|
||||
<arg type="b" direction="in" name="flash"/>
|
||||
<arg type="s" direction="in" name="filename"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
<arg type="s" direction="out" name="filename_used"/>
|
||||
</method>
|
||||
<method name="Screenshot">
|
||||
<arg type="b" direction="in" name="include_cursor"/>
|
||||
<arg type="b" direction="in" name="flash"/>
|
||||
<arg type="s" direction="in" name="filename"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
<arg type="s" direction="out" name="filename_used"/>
|
||||
</method>
|
||||
<method name="SelectArea">
|
||||
<arg type="i" direction="out" name="x"/>
|
||||
<arg type="i" direction="out" name="y"/>
|
||||
<arg type="i" direction="out" name="width"/>
|
||||
<arg type="i" direction="out" name="height"/>
|
||||
</method>
|
||||
<method name="FlashArea">
|
||||
<arg type="i" direction="in" name="x"/>
|
||||
<arg type="i" direction="in" name="y"/>
|
||||
<arg type="i" direction="in" name="width"/>
|
||||
<arg type="i" direction="in" name="height"/>
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const ScreenshotService = new Lang.Class({
|
||||
Name: 'ScreenshotService',
|
||||
|
@ -69,18 +69,16 @@ function waitLeisure() {
|
||||
};
|
||||
}
|
||||
|
||||
const PerfHelperIface = '<node> \
|
||||
<interface name="org.gnome.Shell.PerfHelper"> \
|
||||
<method name="CreateWindow"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="b" direction="in" /> \
|
||||
<arg type="b" direction="in" /> \
|
||||
</method> \
|
||||
<method name="WaitWindows" /> \
|
||||
<method name="DestroyWindows" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const PerfHelperIface = <interface name="org.gnome.Shell.PerfHelper">
|
||||
<method name="CreateWindow">
|
||||
<arg type="i" direction="in" />
|
||||
<arg type="i" direction="in" />
|
||||
<arg type="b" direction="in" />
|
||||
<arg type="b" direction="in" />
|
||||
</method>
|
||||
<method name="WaitWindows" />
|
||||
<method name="DestroyWindows" />
|
||||
</interface>;
|
||||
|
||||
var PerfHelperProxy = Gio.DBusProxy.makeProxyWrapper(PerfHelperIface);
|
||||
function PerfHelper() {
|
||||
|
717
js/ui/search.js
717
js/ui/search.js
@ -1,706 +1,105 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Atk = imports.gi.Atk;
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const DND = imports.ui.dnd;
|
||||
const IconGrid = imports.ui.iconGrid;
|
||||
const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
const RemoteSearch = imports.ui.remoteSearch;
|
||||
const Separator = imports.ui.separator;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers';
|
||||
|
||||
const MAX_LIST_SEARCH_RESULTS_ROWS = 3;
|
||||
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
|
||||
|
||||
const SearchSystem = new Lang.Class({
|
||||
Name: 'SearchSystem',
|
||||
|
||||
_init: function() {
|
||||
this._providers = [];
|
||||
|
||||
this._registerProvider(new AppDisplay.AppSearchProvider());
|
||||
|
||||
this._searchSettings = new Gio.Settings({ schema: SEARCH_PROVIDERS_SCHEMA });
|
||||
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
|
||||
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
|
||||
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
|
||||
|
||||
this._reloadRemoteProviders();
|
||||
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
this._remoteProviders = [];
|
||||
this.reset();
|
||||
},
|
||||
|
||||
addProvider: function(provider) {
|
||||
registerProvider: function (provider) {
|
||||
provider.searchSystem = this;
|
||||
this._providers.push(provider);
|
||||
this.emit('providers-changed');
|
||||
|
||||
if (provider.isRemoteProvider)
|
||||
this._remoteProviders.push(provider);
|
||||
},
|
||||
|
||||
_reloadRemoteProviders: function() {
|
||||
let remoteProviders = this._providers.filter(function(provider) {
|
||||
return provider.isRemoteProvider;
|
||||
});
|
||||
remoteProviders.forEach(Lang.bind(this, function(provider) {
|
||||
this._unregisterProvider(provider);
|
||||
}));
|
||||
|
||||
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, function(providers) {
|
||||
providers.forEach(Lang.bind(this, this._registerProvider));
|
||||
}));
|
||||
|
||||
this.emit('providers-changed');
|
||||
},
|
||||
|
||||
_registerProvider: function (provider) {
|
||||
this._providers.push(provider);
|
||||
},
|
||||
|
||||
_unregisterProvider: function (provider) {
|
||||
unregisterProvider: function (provider) {
|
||||
let index = this._providers.indexOf(provider);
|
||||
if (index == -1)
|
||||
return;
|
||||
provider.searchSystem = null;
|
||||
this._providers.splice(index, 1);
|
||||
|
||||
let remoteIndex = this._remoteProviders.indexOf(provider);
|
||||
if (remoteIndex != -1)
|
||||
this._remoteProviders.splice(remoteIndex, 1);
|
||||
},
|
||||
|
||||
getProviders: function() {
|
||||
return this._providers;
|
||||
},
|
||||
|
||||
getRemoteProviders: function() {
|
||||
return this._remoteProviders;
|
||||
},
|
||||
|
||||
getTerms: function() {
|
||||
return this._terms;
|
||||
return this._previousTerms;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this._terms = [];
|
||||
this._results = {};
|
||||
this._previousTerms = [];
|
||||
this._previousResults = [];
|
||||
},
|
||||
|
||||
_gotResults: function(results, provider) {
|
||||
this._results[provider.id] = results;
|
||||
this.emit('search-updated', provider, results);
|
||||
setResults: function(provider, results) {
|
||||
let i = this._providers.indexOf(provider);
|
||||
if (i == -1)
|
||||
return;
|
||||
|
||||
this._previousResults[i] = [provider, results];
|
||||
this.emit('search-updated', this._previousResults[i]);
|
||||
},
|
||||
|
||||
setTerms: function(terms) {
|
||||
this._cancellable.cancel();
|
||||
this._cancellable.reset();
|
||||
|
||||
let previousResults = this._results;
|
||||
let previousTerms = this._terms;
|
||||
this.reset();
|
||||
|
||||
updateSearchResults: function(terms) {
|
||||
if (!terms)
|
||||
return;
|
||||
|
||||
let searchString = terms.join(' ');
|
||||
let previousSearchString = previousTerms.join(' ');
|
||||
let previousSearchString = this._previousTerms.join(' ');
|
||||
if (searchString == previousSearchString)
|
||||
return;
|
||||
|
||||
let isSubSearch = false;
|
||||
if (previousTerms.length > 0)
|
||||
if (this._previousTerms.length > 0)
|
||||
isSubSearch = searchString.indexOf(previousSearchString) == 0;
|
||||
|
||||
this._terms = terms;
|
||||
let previousResultsArr = this._previousResults;
|
||||
|
||||
this._providers.forEach(Lang.bind(this, function(provider) {
|
||||
let previousProviderResults = previousResults[provider.id];
|
||||
if (isSubSearch && previousProviderResults)
|
||||
provider.getSubsearchResultSet(previousProviderResults, terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
|
||||
else
|
||||
provider.getInitialResultSet(terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
|
||||
}));
|
||||
let results = [];
|
||||
this._previousTerms = terms;
|
||||
this._previousResults = results;
|
||||
|
||||
if (isSubSearch) {
|
||||
for (let i = 0; i < this._providers.length; i++) {
|
||||
let [provider, previousResults] = previousResultsArr[i];
|
||||
try {
|
||||
results.push([provider, []]);
|
||||
provider.getSubsearchResultSet(previousResults, terms);
|
||||
} catch (error) {
|
||||
log('A ' + error.name + ' has occured in ' + provider.id + ': ' + error.message);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < this._providers.length; i++) {
|
||||
let provider = this._providers[i];
|
||||
try {
|
||||
results.push([provider, []]);
|
||||
provider.getInitialResultSet(terms);
|
||||
} catch (error) {
|
||||
log('A ' + error.name + ' has occured in ' + provider.id + ': ' + error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(SearchSystem.prototype);
|
||||
|
||||
const MaxWidthBin = new Lang.Class({
|
||||
Name: 'MaxWidthBin',
|
||||
Extends: St.Bin,
|
||||
|
||||
vfunc_allocate: function(box, flags) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let maxWidth = themeNode.get_max_width();
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let adjustedBox = box;
|
||||
|
||||
if (availWidth > maxWidth) {
|
||||
let excessWidth = availWidth - maxWidth;
|
||||
adjustedBox.x1 += Math.floor(excessWidth / 2);
|
||||
adjustedBox.x2 -= Math.floor(excessWidth / 2);
|
||||
}
|
||||
|
||||
this.parent(adjustedBox, flags);
|
||||
}
|
||||
});
|
||||
|
||||
const SearchResult = new Lang.Class({
|
||||
Name: 'SearchResult',
|
||||
|
||||
_init: function(provider, metaInfo) {
|
||||
this.provider = provider;
|
||||
this.metaInfo = metaInfo;
|
||||
|
||||
this.actor = new St.Button({ reactive: true,
|
||||
can_focus: true,
|
||||
track_hover: true,
|
||||
x_align: St.Align.START,
|
||||
y_fill: true });
|
||||
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('clicked', Lang.bind(this, this.activate));
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this.emit('activate', this.metaInfo.id);
|
||||
},
|
||||
|
||||
setSelected: function(selected) {
|
||||
if (selected)
|
||||
this.actor.add_style_pseudo_class('selected');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('selected');
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(SearchResult.prototype);
|
||||
|
||||
const ListSearchResult = new Lang.Class({
|
||||
Name: 'ListSearchResult',
|
||||
Extends: SearchResult,
|
||||
|
||||
ICON_SIZE: 64,
|
||||
|
||||
_init: function(provider, metaInfo) {
|
||||
this.parent(provider, metaInfo);
|
||||
|
||||
this.actor.style_class = 'list-search-result';
|
||||
this.actor.x_fill = true;
|
||||
|
||||
let content = new St.BoxLayout({ style_class: 'list-search-result-content',
|
||||
vertical: false });
|
||||
this.actor.set_child(content);
|
||||
|
||||
// An icon for, or thumbnail of, content
|
||||
let icon = this.metaInfo['createIcon'](this.ICON_SIZE);
|
||||
if (icon) {
|
||||
content.add(icon);
|
||||
}
|
||||
|
||||
let details = new St.BoxLayout({ vertical: true });
|
||||
content.add(details, { x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.MIDDLE });
|
||||
|
||||
let title = new St.Label({ style_class: 'list-search-result-title',
|
||||
text: this.metaInfo['name'] })
|
||||
details.add(title, { x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
this.actor.label_actor = title;
|
||||
|
||||
if (this.metaInfo['description']) {
|
||||
let description = new St.Label({ style_class: 'list-search-result-description' });
|
||||
description.clutter_text.set_markup(this.metaInfo['description']);
|
||||
details.add(description, { x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.END });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const GridSearchResult = new Lang.Class({
|
||||
Name: 'GridSearchResult',
|
||||
Extends: SearchResult,
|
||||
|
||||
_init: function(provider, metaInfo) {
|
||||
this.parent(provider, metaInfo);
|
||||
|
||||
this.actor.style_class = 'grid-search-result';
|
||||
|
||||
let content = provider.createResultObject(metaInfo);
|
||||
let dragSource = null;
|
||||
|
||||
if (content == null) {
|
||||
let actor = new St.Bin();
|
||||
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
||||
{ createIcon: this.metaInfo['createIcon'] });
|
||||
actor.set_child(icon.actor);
|
||||
actor.label_actor = icon.label;
|
||||
dragSource = icon.icon;
|
||||
content = { actor: actor, icon: icon };
|
||||
} else {
|
||||
if (content._delegate && content._delegate.getDragActorSource)
|
||||
dragSource = content._delegate.getDragActorSource();
|
||||
}
|
||||
|
||||
this.actor.set_child(content.actor);
|
||||
this.actor.label_actor = content.actor.label_actor;
|
||||
this.icon = content.icon;
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
draggable.connect('drag-begin',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.beginItemDrag(this);
|
||||
}));
|
||||
draggable.connect('drag-cancelled',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.cancelledItemDrag(this);
|
||||
}));
|
||||
draggable.connect('drag-end',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.endItemDrag(this);
|
||||
}));
|
||||
|
||||
if (!dragSource)
|
||||
// not exactly right, but alignment problems are hard to notice
|
||||
dragSource = content;
|
||||
this._dragActorSource = dragSource;
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this._dragActorSource;
|
||||
},
|
||||
|
||||
getDragActor: function() {
|
||||
return this.metaInfo['createIcon'](Main.overview.dashIconSize);
|
||||
},
|
||||
|
||||
shellWorkspaceLaunch: function(params) {
|
||||
if (this.provider.dragActivateResult)
|
||||
this.provider.dragActivateResult(this.metaInfo.id, params);
|
||||
else
|
||||
this.provider.activateResult(this.metaInfo.id, this.terms);
|
||||
}
|
||||
});
|
||||
|
||||
const SearchResultsBase = new Lang.Class({
|
||||
Name: 'SearchResultsBase',
|
||||
|
||||
_init: function(provider) {
|
||||
this.provider = provider;
|
||||
|
||||
this._terms = [];
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'search-section',
|
||||
vertical: true });
|
||||
|
||||
this._resultDisplayBin = new St.Bin({ x_fill: true,
|
||||
y_fill: true });
|
||||
this.actor.add(this._resultDisplayBin, { expand: true });
|
||||
|
||||
let separator = new Separator.HorizontalSeparator({ style_class: 'search-section-separator' });
|
||||
this.actor.add(separator.actor);
|
||||
|
||||
this._resultDisplays = {};
|
||||
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.actor.destroy();
|
||||
this._terms = [];
|
||||
},
|
||||
|
||||
_clearResultDisplay: function() {
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
this._resultDisplays = {};
|
||||
this._clearResultDisplay();
|
||||
this.actor.hide();
|
||||
},
|
||||
|
||||
_keyFocusIn: function(actor) {
|
||||
this.emit('key-focus-in', actor);
|
||||
},
|
||||
|
||||
_activateResult: function(result, id) {
|
||||
this.provider.activateResult(id, this._terms);
|
||||
Main.overview.toggle();
|
||||
},
|
||||
|
||||
_setMoreIconVisible: function(visible) {
|
||||
},
|
||||
|
||||
_ensureResultActors: function(results, callback) {
|
||||
let metasNeeded = results.filter(Lang.bind(this, function(resultId) {
|
||||
return this._resultDisplays[resultId] === undefined;
|
||||
}));
|
||||
|
||||
if (metasNeeded.length === 0) {
|
||||
callback();
|
||||
} else {
|
||||
this._cancellable.cancel();
|
||||
this._cancellable.reset();
|
||||
|
||||
this.provider.getResultMetas(metasNeeded, Lang.bind(this, function(metas) {
|
||||
metasNeeded.forEach(Lang.bind(this, function(resultId, i) {
|
||||
let meta = metas[i];
|
||||
let display = this._createResultDisplay(meta);
|
||||
display.connect('activate', Lang.bind(this, this._activateResult));
|
||||
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._resultDisplays[resultId] = display;
|
||||
}));
|
||||
callback();
|
||||
}), this._cancellable);
|
||||
}
|
||||
},
|
||||
|
||||
updateSearch: function(providerResults, terms, callback) {
|
||||
this._terms = terms;
|
||||
|
||||
if (providerResults.length == 0) {
|
||||
this._clearResultDisplay();
|
||||
this.actor.hide();
|
||||
callback();
|
||||
} else {
|
||||
let maxResults = this._getMaxDisplayedResults();
|
||||
let results = this.provider.filterResults(providerResults, maxResults);
|
||||
let hasMoreResults = results.length < providerResults.length;
|
||||
|
||||
this._ensureResultActors(results, Lang.bind(this, function() {
|
||||
this._clearResultDisplay();
|
||||
|
||||
// To avoid CSS transitions causing flickering when
|
||||
// the first search result stays the same, we hide the
|
||||
// content while filling in the results.
|
||||
this.actor.hide();
|
||||
this._clearResultDisplay();
|
||||
results.forEach(Lang.bind(this, function(resultId) {
|
||||
this._addItem(this._resultDisplays[resultId]);
|
||||
}));
|
||||
this._setMoreIconVisible(hasMoreResults && this.provider.canLaunchSearch);
|
||||
this.actor.show();
|
||||
callback();
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const ListSearchResults = new Lang.Class({
|
||||
Name: 'ListSearchResults',
|
||||
Extends: SearchResultsBase,
|
||||
|
||||
_init: function(provider) {
|
||||
this.parent(provider);
|
||||
|
||||
this._container = new St.BoxLayout({ style_class: 'search-section-content' });
|
||||
this.providerIcon = new ProviderIcon(provider);
|
||||
this.providerIcon.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this.providerIcon.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
provider.launchSearch(this._terms);
|
||||
Main.overview.toggle();
|
||||
}));
|
||||
|
||||
this._container.add(this.providerIcon, { x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
|
||||
this._content = new St.BoxLayout({ style_class: 'list-search-results',
|
||||
vertical: true });
|
||||
this._container.add(this._content, { expand: true });
|
||||
|
||||
this._resultDisplayBin.set_child(this._container);
|
||||
},
|
||||
|
||||
_setMoreIconVisible: function(visible) {
|
||||
this.providerIcon.moreIcon.visible = true;
|
||||
},
|
||||
|
||||
_getMaxDisplayedResults: function() {
|
||||
return MAX_LIST_SEARCH_RESULTS_ROWS;
|
||||
},
|
||||
|
||||
_clearResultDisplay: function () {
|
||||
this._content.remove_all_children();
|
||||
},
|
||||
|
||||
_createResultDisplay: function(meta) {
|
||||
return new ListSearchResult(this.provider, meta);
|
||||
},
|
||||
|
||||
_addItem: function(display) {
|
||||
this._content.add_actor(display.actor);
|
||||
},
|
||||
|
||||
getFirstResult: function() {
|
||||
if (this._content.get_n_children() > 0)
|
||||
return this._content.get_child_at_index(0)._delegate;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ListSearchResults.prototype);
|
||||
|
||||
const GridSearchResults = new Lang.Class({
|
||||
Name: 'GridSearchResults',
|
||||
Extends: SearchResultsBase,
|
||||
|
||||
_init: function(provider) {
|
||||
this.parent(provider);
|
||||
|
||||
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
|
||||
xAlign: St.Align.START });
|
||||
this._bin = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||
this._bin.set_child(this._grid.actor);
|
||||
|
||||
this._resultDisplayBin.set_child(this._bin);
|
||||
},
|
||||
|
||||
_getMaxDisplayedResults: function() {
|
||||
return this._grid.columnsForWidth(this._bin.width) * this._grid.getRowLimit();
|
||||
},
|
||||
|
||||
_renderResults: function(metas) {
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
let display = new GridSearchResult(this.provider, metas[i]);
|
||||
display.connect('activate', Lang.bind(this, this._activateResult));
|
||||
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._grid.addItem(display);
|
||||
}
|
||||
},
|
||||
|
||||
_clearResultDisplay: function () {
|
||||
this._grid.removeAll();
|
||||
},
|
||||
|
||||
_createResultDisplay: function(meta) {
|
||||
return new GridSearchResult(this.provider, meta);
|
||||
},
|
||||
|
||||
_addItem: function(display) {
|
||||
this._grid.addItem(display);
|
||||
},
|
||||
|
||||
getFirstResult: function() {
|
||||
if (this._grid.visibleItemsCount() > 0)
|
||||
return this._grid.getItemAtIndex(0)._delegate;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(GridSearchResults.prototype);
|
||||
|
||||
const SearchResults = new Lang.Class({
|
||||
Name: 'SearchResults',
|
||||
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ name: 'searchResults',
|
||||
vertical: true });
|
||||
|
||||
this._content = new St.BoxLayout({ name: 'searchResultsContent',
|
||||
vertical: true });
|
||||
this._contentBin = new MaxWidthBin({ name: 'searchResultsBin',
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
child: this._content });
|
||||
|
||||
let scrollChild = new St.BoxLayout();
|
||||
scrollChild.add(this._contentBin, { expand: true });
|
||||
|
||||
this._scrollView = new St.ScrollView({ x_fill: true,
|
||||
y_fill: false,
|
||||
overlay_scrollbars: true,
|
||||
style_class: 'search-display vfade' });
|
||||
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||
this._scrollView.add_actor(scrollChild);
|
||||
let action = new Clutter.PanAction({ interpolate: true });
|
||||
action.connect('pan', Lang.bind(this, this._onPan));
|
||||
this._scrollView.add_action(action);
|
||||
|
||||
this.actor.add(this._scrollView, { x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
|
||||
this._statusText = new St.Label({ style_class: 'search-statustext' });
|
||||
this._statusBin = new St.Bin({ x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this._content.add(this._statusBin, { expand: true });
|
||||
this._statusBin.add_actor(this._statusText);
|
||||
|
||||
this._highlightDefault = false;
|
||||
this._defaultResult = null;
|
||||
|
||||
this._searchSystem = new SearchSystem();
|
||||
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
|
||||
this._searchSystem.connect('providers-changed', Lang.bind(this, this._updateProviderDisplays));
|
||||
this._updateProviderDisplays();
|
||||
},
|
||||
|
||||
_onPan: function(action) {
|
||||
let [dist, dx, dy] = action.get_motion_delta(0);
|
||||
let adjustment = this._scrollView.vscroll.adjustment;
|
||||
adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
|
||||
return false;
|
||||
},
|
||||
|
||||
_keyFocusIn: function(provider, actor) {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
|
||||
},
|
||||
|
||||
_ensureProviderDisplay: function(provider) {
|
||||
if (provider.display)
|
||||
return;
|
||||
|
||||
let providerDisplay;
|
||||
if (provider.appInfo)
|
||||
providerDisplay = new ListSearchResults(provider);
|
||||
else
|
||||
providerDisplay = new GridSearchResults(provider);
|
||||
|
||||
providerDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._content.add(providerDisplay.actor);
|
||||
provider.display = providerDisplay;
|
||||
},
|
||||
|
||||
_updateProviderDisplays: function() {
|
||||
this._searchSystem.getProviders().forEach(Lang.bind(this, this._ensureProviderDisplay));
|
||||
},
|
||||
|
||||
_clearDisplay: function() {
|
||||
this._searchSystem.getProviders().forEach(function(provider) {
|
||||
provider.display.clear();
|
||||
});
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this._searchSystem.reset();
|
||||
this._statusBin.hide();
|
||||
this._clearDisplay();
|
||||
this._defaultResult = null;
|
||||
},
|
||||
|
||||
startingSearch: function() {
|
||||
this.reset();
|
||||
this._statusText.set_text(_("Searching…"));
|
||||
this._statusBin.show();
|
||||
},
|
||||
|
||||
setTerms: function(terms) {
|
||||
this._searchSystem.setTerms(terms);
|
||||
},
|
||||
|
||||
_maybeSetInitialSelection: function() {
|
||||
let newDefaultResult = null;
|
||||
|
||||
let providers = this._searchSystem.getProviders();
|
||||
for (let i = 0; i < providers.length; i++) {
|
||||
let provider = providers[i];
|
||||
let display = provider.display;
|
||||
|
||||
if (!display.actor.visible)
|
||||
continue;
|
||||
|
||||
let firstResult = display.getFirstResult();
|
||||
if (firstResult) {
|
||||
newDefaultResult = firstResult;
|
||||
break; // select this one!
|
||||
}
|
||||
}
|
||||
|
||||
if (newDefaultResult != this._defaultResult) {
|
||||
if (this._defaultResult)
|
||||
this._defaultResult.setSelected(false);
|
||||
if (newDefaultResult)
|
||||
newDefaultResult.setSelected(this._highlightDefault);
|
||||
|
||||
this._defaultResult = newDefaultResult;
|
||||
}
|
||||
},
|
||||
|
||||
_updateStatusText: function () {
|
||||
let haveResults = this._searchSystem.getProviders().some(function(provider) {
|
||||
let display = provider.display;
|
||||
return (display.getFirstResult() != null);
|
||||
});
|
||||
|
||||
if (!haveResults) {
|
||||
this._statusText.set_text(_("No results."));
|
||||
this._statusBin.show();
|
||||
} else {
|
||||
this._statusBin.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_updateResults: function(searchSystem, provider, results) {
|
||||
let terms = searchSystem.getTerms();
|
||||
let display = provider.display;
|
||||
|
||||
display.updateSearch(results, terms, Lang.bind(this, function() {
|
||||
this._maybeSetInitialSelection();
|
||||
this._updateStatusText();
|
||||
}));
|
||||
},
|
||||
|
||||
activateDefault: function() {
|
||||
if (this._defaultResult)
|
||||
this._defaultResult.activate();
|
||||
},
|
||||
|
||||
highlightDefault: function(highlight) {
|
||||
this._highlightDefault = highlight;
|
||||
if (this._defaultResult)
|
||||
this._defaultResult.setSelected(highlight);
|
||||
},
|
||||
|
||||
navigateFocus: function(direction) {
|
||||
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
|
||||
if (direction == Gtk.DirectionType.TAB_BACKWARD ||
|
||||
direction == (rtl ? Gtk.DirectionType.RIGHT
|
||||
: Gtk.DirectionType.LEFT) ||
|
||||
direction == Gtk.DirectionType.UP) {
|
||||
this.actor.navigate_focus(null, direction, false);
|
||||
return;
|
||||
}
|
||||
|
||||
let from = this._defaultResult ? this._defaultResult.actor : null;
|
||||
this.actor.navigate_focus(from, direction, false);
|
||||
}
|
||||
});
|
||||
|
||||
const ProviderIcon = new Lang.Class({
|
||||
Name: 'ProviderIcon',
|
||||
Extends: St.Button,
|
||||
|
||||
PROVIDER_ICON_SIZE: 48,
|
||||
|
||||
_init: function(provider) {
|
||||
this.provider = provider;
|
||||
this.parent({ style_class: 'search-provider-icon',
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
accessible_name: provider.appInfo.get_name(),
|
||||
track_hover: true });
|
||||
|
||||
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
this.set_child(this._content);
|
||||
|
||||
let rtl = (this.get_text_direction() == Clutter.TextDirection.RTL);
|
||||
|
||||
this.moreIcon = new St.Widget({ style_class: 'search-provider-icon-more',
|
||||
visible: false,
|
||||
x_align: rtl ? Clutter.ActorAlign.START : Clutter.ActorAlign.END,
|
||||
y_align: Clutter.ActorAlign.END,
|
||||
x_expand: true,
|
||||
y_expand: true });
|
||||
|
||||
let icon = new St.Icon({ icon_size: this.PROVIDER_ICON_SIZE,
|
||||
gicon: provider.appInfo.get_icon() });
|
||||
this._content.add_actor(icon);
|
||||
this._content.add_actor(this.moreIcon);
|
||||
}
|
||||
});
|
||||
|
567
js/ui/searchDisplay.js
Normal file
567
js/ui/searchDisplay.js
Normal file
@ -0,0 +1,567 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Atk = imports.gi.Atk;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const IconGrid = imports.ui.iconGrid;
|
||||
const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
const Separator = imports.ui.separator;
|
||||
const Search = imports.ui.search;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const MAX_LIST_SEARCH_RESULTS_ROWS = 3;
|
||||
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
|
||||
|
||||
const MaxWidthBin = new Lang.Class({
|
||||
Name: 'MaxWidthBin',
|
||||
Extends: St.Bin,
|
||||
|
||||
vfunc_allocate: function(box, flags) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let maxWidth = themeNode.get_max_width();
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let adjustedBox = box;
|
||||
|
||||
if (availWidth > maxWidth) {
|
||||
let excessWidth = availWidth - maxWidth;
|
||||
adjustedBox.x1 += Math.floor(excessWidth / 2);
|
||||
adjustedBox.x2 -= Math.floor(excessWidth / 2);
|
||||
}
|
||||
|
||||
this.parent(adjustedBox, flags);
|
||||
}
|
||||
});
|
||||
|
||||
const SearchResult = new Lang.Class({
|
||||
Name: 'SearchResult',
|
||||
|
||||
_init: function(provider, metaInfo, terms) {
|
||||
this.provider = provider;
|
||||
this.metaInfo = metaInfo;
|
||||
this.terms = terms;
|
||||
|
||||
this.actor = new St.Button({ reactive: true,
|
||||
can_focus: true,
|
||||
track_hover: true,
|
||||
x_align: St.Align.START,
|
||||
y_fill: true });
|
||||
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('clicked', Lang.bind(this, this.activate));
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
this.provider.activateResult(this.metaInfo.id, this.terms);
|
||||
Main.overview.toggle();
|
||||
},
|
||||
|
||||
setSelected: function(selected) {
|
||||
if (selected)
|
||||
this.actor.add_style_pseudo_class('selected');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('selected');
|
||||
}
|
||||
});
|
||||
|
||||
const ListSearchResult = new Lang.Class({
|
||||
Name: 'ListSearchResult',
|
||||
Extends: SearchResult,
|
||||
|
||||
ICON_SIZE: 64,
|
||||
|
||||
_init: function(provider, metaInfo, terms) {
|
||||
this.parent(provider, metaInfo, terms);
|
||||
|
||||
this.actor.style_class = 'list-search-result';
|
||||
this.actor.x_fill = true;
|
||||
|
||||
let content = new St.BoxLayout({ style_class: 'list-search-result-content',
|
||||
vertical: false });
|
||||
this.actor.set_child(content);
|
||||
|
||||
// An icon for, or thumbnail of, content
|
||||
let icon = this.metaInfo['createIcon'](this.ICON_SIZE);
|
||||
if (icon) {
|
||||
content.add(icon);
|
||||
}
|
||||
|
||||
let details = new St.BoxLayout({ vertical: true });
|
||||
content.add(details, { x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.MIDDLE });
|
||||
|
||||
let title = new St.Label({ style_class: 'list-search-result-title',
|
||||
text: this.metaInfo['name'] })
|
||||
details.add(title, { x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
this.actor.label_actor = title;
|
||||
|
||||
if (this.metaInfo['description']) {
|
||||
let description = new St.Label({ style_class: 'list-search-result-description' });
|
||||
description.clutter_text.set_markup(this.metaInfo['description']);
|
||||
details.add(description, { x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.END });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const GridSearchResult = new Lang.Class({
|
||||
Name: 'GridSearchResult',
|
||||
Extends: SearchResult,
|
||||
|
||||
_init: function(provider, metaInfo, terms) {
|
||||
this.parent(provider, metaInfo, terms);
|
||||
|
||||
this.actor.style_class = 'grid-search-result';
|
||||
|
||||
let content = provider.createResultObject(metaInfo, terms);
|
||||
let dragSource = null;
|
||||
|
||||
if (content == null) {
|
||||
let actor = new St.Bin();
|
||||
let icon = new IconGrid.BaseIcon(this.metaInfo['name'],
|
||||
{ createIcon: this.metaInfo['createIcon'] });
|
||||
actor.set_child(icon.actor);
|
||||
actor.label_actor = icon.label;
|
||||
dragSource = icon.icon;
|
||||
content = { actor: actor, icon: icon };
|
||||
} else {
|
||||
if (content._delegate && content._delegate.getDragActorSource)
|
||||
dragSource = content._delegate.getDragActorSource();
|
||||
}
|
||||
|
||||
this.actor.set_child(content.actor);
|
||||
this.actor.label_actor = content.actor.label_actor;
|
||||
this.icon = content.icon;
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
draggable.connect('drag-begin',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.beginItemDrag(this);
|
||||
}));
|
||||
draggable.connect('drag-cancelled',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.cancelledItemDrag(this);
|
||||
}));
|
||||
draggable.connect('drag-end',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.endItemDrag(this);
|
||||
}));
|
||||
|
||||
if (!dragSource)
|
||||
// not exactly right, but alignment problems are hard to notice
|
||||
dragSource = content;
|
||||
this._dragActorSource = dragSource;
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this._dragActorSource;
|
||||
},
|
||||
|
||||
getDragActor: function() {
|
||||
return this.metaInfo['createIcon'](Main.overview.dashIconSize);
|
||||
},
|
||||
|
||||
shellWorkspaceLaunch: function(params) {
|
||||
if (this.provider.dragActivateResult)
|
||||
this.provider.dragActivateResult(this.metaInfo.id, params);
|
||||
else
|
||||
this.provider.activateResult(this.metaInfo.id, this.terms);
|
||||
}
|
||||
});
|
||||
|
||||
const SearchResultsBase = new Lang.Class({
|
||||
Name: 'SearchResultsBase',
|
||||
|
||||
_init: function(provider) {
|
||||
this.provider = provider;
|
||||
|
||||
this._terms = [];
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'search-section',
|
||||
vertical: true });
|
||||
|
||||
this._resultDisplayBin = new St.Bin({ x_fill: true,
|
||||
y_fill: true });
|
||||
this.actor.add(this._resultDisplayBin, { expand: true });
|
||||
|
||||
let separator = new Separator.HorizontalSeparator({ style_class: 'search-section-separator' });
|
||||
this.actor.add(separator.actor);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.actor.destroy();
|
||||
this._terms = [];
|
||||
},
|
||||
|
||||
_clearResultDisplay: function() {
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
this._clearResultDisplay();
|
||||
this.actor.hide();
|
||||
},
|
||||
|
||||
_keyFocusIn: function(actor) {
|
||||
this.emit('key-focus-in', actor);
|
||||
},
|
||||
|
||||
_setMoreIconVisible: function(visible) {
|
||||
},
|
||||
|
||||
updateSearch: function(providerResults, terms, callback) {
|
||||
this._terms = terms;
|
||||
|
||||
if (providerResults.length == 0) {
|
||||
this._clearResultDisplay();
|
||||
this.actor.hide();
|
||||
callback();
|
||||
} else {
|
||||
let maxResults = this._getMaxDisplayedResults();
|
||||
let results = this.provider.filterResults(providerResults, maxResults);
|
||||
let hasMoreResults = results.length < providerResults.length;
|
||||
|
||||
this.provider.getResultMetas(results, Lang.bind(this, function(metas) {
|
||||
this.clear();
|
||||
|
||||
// To avoid CSS transitions causing flickering when
|
||||
// the first search result stays the same, we hide the
|
||||
// content while filling in the results.
|
||||
this.actor.hide();
|
||||
this._clearResultDisplay();
|
||||
this._renderResults(metas);
|
||||
this._setMoreIconVisible(hasMoreResults && this.provider.canLaunchSearch);
|
||||
this.actor.show();
|
||||
callback();
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const ListSearchResults = new Lang.Class({
|
||||
Name: 'ListSearchResults',
|
||||
Extends: SearchResultsBase,
|
||||
|
||||
_init: function(provider) {
|
||||
this.parent(provider);
|
||||
|
||||
this._container = new St.BoxLayout({ style_class: 'search-section-content' });
|
||||
this.providerIcon = new ProviderIcon(provider);
|
||||
this.providerIcon.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this.providerIcon.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
provider.launchSearch(this._terms);
|
||||
Main.overview.toggle();
|
||||
}));
|
||||
|
||||
this._container.add(this.providerIcon, { x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
|
||||
this._content = new St.BoxLayout({ style_class: 'list-search-results',
|
||||
vertical: true });
|
||||
this._container.add(this._content, { expand: true });
|
||||
|
||||
this._resultDisplayBin.set_child(this._container);
|
||||
},
|
||||
|
||||
_setMoreIconVisible: function(visible) {
|
||||
this.providerIcon.moreIcon.visible = true;
|
||||
},
|
||||
|
||||
_getMaxDisplayedResults: function() {
|
||||
return MAX_LIST_SEARCH_RESULTS_ROWS;
|
||||
},
|
||||
|
||||
_renderResults: function(metas) {
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
let display = new ListSearchResult(this.provider, metas[i], this._terms);
|
||||
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._content.add_actor(display.actor);
|
||||
}
|
||||
},
|
||||
|
||||
_clearResultDisplay: function () {
|
||||
this._content.destroy_all_children();
|
||||
},
|
||||
|
||||
getFirstResult: function() {
|
||||
if (this._content.get_n_children() > 0)
|
||||
return this._content.get_child_at_index(0)._delegate;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ListSearchResults.prototype);
|
||||
|
||||
const GridSearchResults = new Lang.Class({
|
||||
Name: 'GridSearchResults',
|
||||
Extends: SearchResultsBase,
|
||||
|
||||
_init: function(provider) {
|
||||
this.parent(provider);
|
||||
|
||||
this._grid = new IconGrid.IconGrid({ rowLimit: MAX_GRID_SEARCH_RESULTS_ROWS,
|
||||
xAlign: St.Align.START });
|
||||
this._bin = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||
this._bin.set_child(this._grid.actor);
|
||||
|
||||
this._resultDisplayBin.set_child(this._bin);
|
||||
},
|
||||
|
||||
_getMaxDisplayedResults: function() {
|
||||
return this._grid.columnsForWidth(this._bin.width) * this._grid.getRowLimit();
|
||||
},
|
||||
|
||||
_renderResults: function(metas) {
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
let display = new GridSearchResult(this.provider, metas[i], this._terms);
|
||||
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._grid.addItem(display);
|
||||
}
|
||||
},
|
||||
|
||||
_clearResultDisplay: function () {
|
||||
this._grid.removeAll();
|
||||
},
|
||||
|
||||
getFirstResult: function() {
|
||||
if (this._grid.visibleItemsCount() > 0)
|
||||
return this._grid.getItemAtIndex(0)._delegate;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(GridSearchResults.prototype);
|
||||
|
||||
const SearchResults = new Lang.Class({
|
||||
Name: 'SearchResults',
|
||||
|
||||
_init: function(searchSystem) {
|
||||
this._searchSystem = searchSystem;
|
||||
this._searchSystem.connect('search-updated', Lang.bind(this, this._updateResults));
|
||||
|
||||
this.actor = new St.BoxLayout({ name: 'searchResults',
|
||||
vertical: true });
|
||||
|
||||
this._content = new St.BoxLayout({ name: 'searchResultsContent',
|
||||
vertical: true });
|
||||
this._contentBin = new MaxWidthBin({ name: 'searchResultsBin',
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
child: this._content });
|
||||
|
||||
let scrollChild = new St.BoxLayout();
|
||||
scrollChild.add(this._contentBin, { expand: true });
|
||||
|
||||
this._scrollView = new St.ScrollView({ x_fill: true,
|
||||
y_fill: false,
|
||||
overlay_scrollbars: true,
|
||||
style_class: 'search-display vfade' });
|
||||
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||
this._scrollView.add_actor(scrollChild);
|
||||
let action = new Clutter.PanAction({ interpolate: true });
|
||||
action.connect('pan', Lang.bind(this, this._onPan));
|
||||
this._scrollView.add_action(action);
|
||||
|
||||
this.actor.add(this._scrollView, { x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
|
||||
this._statusText = new St.Label({ style_class: 'search-statustext' });
|
||||
this._statusBin = new St.Bin({ x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this._content.add(this._statusBin, { expand: true });
|
||||
this._statusBin.add_actor(this._statusText);
|
||||
this._providers = this._searchSystem.getProviders();
|
||||
this._providerDisplays = {};
|
||||
for (let i = 0; i < this._providers.length; i++) {
|
||||
this.createProviderDisplay(this._providers[i]);
|
||||
}
|
||||
|
||||
this._highlightDefault = false;
|
||||
this._defaultResult = null;
|
||||
},
|
||||
|
||||
_onPan: function(action) {
|
||||
let [dist, dx, dy] = action.get_motion_delta(0);
|
||||
let adjustment = this._scrollView.vscroll.adjustment;
|
||||
adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
|
||||
return false;
|
||||
},
|
||||
|
||||
_keyFocusIn: function(provider, actor) {
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, actor);
|
||||
},
|
||||
|
||||
createProviderDisplay: function(provider) {
|
||||
let providerDisplay = null;
|
||||
|
||||
if (provider.appInfo) {
|
||||
providerDisplay = new ListSearchResults(provider);
|
||||
} else {
|
||||
providerDisplay = new GridSearchResults(provider);
|
||||
}
|
||||
|
||||
providerDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||
this._providerDisplays[provider.id] = providerDisplay;
|
||||
this._content.add(providerDisplay.actor);
|
||||
},
|
||||
|
||||
destroyProviderDisplay: function(provider) {
|
||||
this._providerDisplays[provider.id].destroy();
|
||||
delete this._providerDisplays[provider.id];
|
||||
},
|
||||
|
||||
_clearDisplay: function() {
|
||||
for (let i = 0; i < this._providers.length; i++) {
|
||||
let provider = this._providers[i];
|
||||
let providerDisplay = this._providerDisplays[provider.id];
|
||||
providerDisplay.clear();
|
||||
}
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this._searchSystem.reset();
|
||||
this._statusBin.hide();
|
||||
this._clearDisplay();
|
||||
this._defaultResult = null;
|
||||
},
|
||||
|
||||
startingSearch: function() {
|
||||
this.reset();
|
||||
this._statusText.set_text(_("Searching…"));
|
||||
this._statusBin.show();
|
||||
},
|
||||
|
||||
_maybeSetInitialSelection: function() {
|
||||
let newDefaultResult = null;
|
||||
|
||||
for (let i = 0; i < this._providers.length; i++) {
|
||||
let provider = this._providers[i];
|
||||
let display = this._providerDisplays[provider.id];
|
||||
|
||||
if (!display.actor.visible)
|
||||
continue;
|
||||
|
||||
let firstResult = display.getFirstResult();
|
||||
if (firstResult) {
|
||||
newDefaultResult = firstResult;
|
||||
break; // select this one!
|
||||
}
|
||||
}
|
||||
|
||||
if (newDefaultResult != this._defaultResult) {
|
||||
if (this._defaultResult)
|
||||
this._defaultResult.setSelected(false);
|
||||
if (newDefaultResult)
|
||||
newDefaultResult.setSelected(this._highlightDefault);
|
||||
|
||||
this._defaultResult = newDefaultResult;
|
||||
}
|
||||
},
|
||||
|
||||
_updateStatusText: function () {
|
||||
let haveResults = false;
|
||||
|
||||
for (let i = 0; i < this._providers.length; i++) {
|
||||
let provider = this._providers[i];
|
||||
let display = this._providerDisplays[provider.id];
|
||||
if (display.getFirstResult()) {
|
||||
haveResults = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!haveResults) {
|
||||
this._statusText.set_text(_("No results."));
|
||||
this._statusBin.show();
|
||||
} else {
|
||||
this._statusBin.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_updateResults: function(searchSystem, results) {
|
||||
let terms = searchSystem.getTerms();
|
||||
let [provider, providerResults] = results;
|
||||
let display = this._providerDisplays[provider.id];
|
||||
|
||||
display.updateSearch(providerResults, terms, Lang.bind(this, function() {
|
||||
this._maybeSetInitialSelection();
|
||||
this._updateStatusText();
|
||||
}));
|
||||
},
|
||||
|
||||
activateDefault: function() {
|
||||
if (this._defaultResult)
|
||||
this._defaultResult.activate();
|
||||
},
|
||||
|
||||
highlightDefault: function(highlight) {
|
||||
this._highlightDefault = highlight;
|
||||
if (this._defaultResult)
|
||||
this._defaultResult.setSelected(highlight);
|
||||
},
|
||||
|
||||
navigateFocus: function(direction) {
|
||||
let rtl = this.actor.get_text_direction() == Clutter.TextDirection.RTL;
|
||||
if (direction == Gtk.DirectionType.TAB_BACKWARD ||
|
||||
direction == (rtl ? Gtk.DirectionType.RIGHT
|
||||
: Gtk.DirectionType.LEFT) ||
|
||||
direction == Gtk.DirectionType.UP) {
|
||||
this.actor.navigate_focus(null, direction, false);
|
||||
return;
|
||||
}
|
||||
|
||||
let from = this._defaultResult ? this._defaultResult.actor : null;
|
||||
this.actor.navigate_focus(from, direction, false);
|
||||
}
|
||||
});
|
||||
|
||||
const ProviderIcon = new Lang.Class({
|
||||
Name: 'ProviderIcon',
|
||||
Extends: St.Button,
|
||||
|
||||
PROVIDER_ICON_SIZE: 48,
|
||||
|
||||
_init: function(provider) {
|
||||
this.provider = provider;
|
||||
this.parent({ style_class: 'search-provider-icon',
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
accessible_name: provider.appInfo.get_name(),
|
||||
track_hover: true });
|
||||
|
||||
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
this.set_child(this._content);
|
||||
|
||||
let rtl = (this.get_text_direction() == Clutter.TextDirection.RTL);
|
||||
|
||||
this.moreIcon = new St.Widget({ style_class: 'search-provider-icon-more',
|
||||
visible: false,
|
||||
x_align: rtl ? Clutter.ActorAlign.START : Clutter.ActorAlign.END,
|
||||
y_align: Clutter.ActorAlign.END,
|
||||
x_expand: true,
|
||||
y_expand: true });
|
||||
|
||||
let icon = new St.Icon({ icon_size: this.PROVIDER_ICON_SIZE,
|
||||
gicon: provider.appInfo.get_icon() });
|
||||
this._content.add_actor(icon);
|
||||
this._content.add_actor(this.moreIcon);
|
||||
}
|
||||
});
|
@ -102,12 +102,19 @@ const _modes = {
|
||||
}
|
||||
};
|
||||
|
||||
function _loadMode(file, info) {
|
||||
function _getModes(modesLoadedCallback) {
|
||||
FileUtils.collectFromDatadirsAsync('modes',
|
||||
{ processFile: _loadMode,
|
||||
loadedCallback: modesLoadedCallback,
|
||||
data: _modes });
|
||||
}
|
||||
|
||||
function _loadMode(file, info, loadedData) {
|
||||
let name = info.get_name();
|
||||
let suffix = name.indexOf('.json');
|
||||
let modeName = suffix == -1 ? name : name.slice(name, suffix);
|
||||
|
||||
if (_modes.hasOwnProperty(modeName))
|
||||
if (loadedData.hasOwnProperty(modeName))
|
||||
return;
|
||||
|
||||
let fileContent, success, tag, newMode;
|
||||
@ -118,23 +125,18 @@ function _loadMode(file, info) {
|
||||
return;
|
||||
}
|
||||
|
||||
_modes[modeName] = {};
|
||||
loadedData[modeName] = {};
|
||||
let propBlacklist = ['unlockDialog'];
|
||||
for (let prop in loadedData[DEFAULT_MODE]) {
|
||||
if (newMode[prop] !== undefined &&
|
||||
propBlacklist.indexOf(prop) == -1)
|
||||
loadedData[modeName][prop] = newMode[prop];
|
||||
loadedData[modeName][prop]= newMode[prop];
|
||||
}
|
||||
_modes[modeName]['isPrimary'] = true;
|
||||
}
|
||||
|
||||
function _getModes() {
|
||||
FileUtils.collectFromDatadirs('modes', false, _loadMode);
|
||||
loadedData[modeName]['isPrimary'] = true;
|
||||
}
|
||||
|
||||
function listModes() {
|
||||
let modes = _getModes();
|
||||
modes.forEach(function() {
|
||||
_getModes(function(modes) {
|
||||
let names = Object.getOwnPropertyNames(modes);
|
||||
for (let i = 0; i < names.length; i++)
|
||||
if (_modes[names[i]].isPrimary)
|
||||
@ -147,12 +149,17 @@ function listModes() {
|
||||
const SessionMode = new Lang.Class({
|
||||
Name: 'SessionMode',
|
||||
|
||||
_init: function() {
|
||||
let isPrimary = (_modes[global.session_mode] &&
|
||||
_modes[global.session_mode].isPrimary);
|
||||
let mode = isPrimary ? global.session_mode : 'user';
|
||||
this._modeStack = [mode];
|
||||
this._sync();
|
||||
init: function() {
|
||||
_getModes(Lang.bind(this, function(modes) {
|
||||
this._modes = modes;
|
||||
let primary = modes[global.session_mode] &&
|
||||
modes[global.session_mode].isPrimary;
|
||||
let mode = primary ? global.session_mode : 'user';
|
||||
this._modeStack = [mode];
|
||||
this._sync();
|
||||
|
||||
this.emit('sessions-loaded');
|
||||
}));
|
||||
},
|
||||
|
||||
pushMode: function(mode) {
|
||||
@ -179,13 +186,13 @@ const SessionMode = new Lang.Class({
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
let params = _modes[this.currentMode];
|
||||
let params = this._modes[this.currentMode];
|
||||
let defaults;
|
||||
if (params.parentMode)
|
||||
defaults = Params.parse(_modes[params.parentMode],
|
||||
_modes[DEFAULT_MODE]);
|
||||
defaults = Params.parse(this._modes[params.parentMode],
|
||||
this._modes[DEFAULT_MODE]);
|
||||
else
|
||||
defaults = _modes[DEFAULT_MODE];
|
||||
defaults = this._modes[DEFAULT_MODE];
|
||||
params = Params.parse(params, defaults);
|
||||
|
||||
// A simplified version of Lang.copyProperties, handles
|
||||
|
@ -15,63 +15,59 @@ const Main = imports.ui.main;
|
||||
const Screenshot = imports.ui.screenshot;
|
||||
const ViewSelector = imports.ui.viewSelector;
|
||||
|
||||
const GnomeShellIface = '<node> \
|
||||
<interface name="org.gnome.Shell"> \
|
||||
<method name="Eval"> \
|
||||
<arg type="s" direction="in" name="script" /> \
|
||||
<arg type="b" direction="out" name="success" /> \
|
||||
<arg type="s" direction="out" name="result" /> \
|
||||
</method> \
|
||||
<method name="FocusSearch"/> \
|
||||
<method name="ShowOSD"> \
|
||||
<arg type="a{sv}" direction="in" name="params"/> \
|
||||
</method> \
|
||||
<method name="FocusApp"> \
|
||||
<arg type="s" direction="in" name="id"/> \
|
||||
</method> \
|
||||
<method name="ShowApplications" /> \
|
||||
<method name="GrabAccelerator"> \
|
||||
<arg type="s" direction="in" name="accelerator"/> \
|
||||
<arg type="u" direction="in" name="flags"/> \
|
||||
<arg type="u" direction="out" name="action"/> \
|
||||
</method> \
|
||||
<method name="GrabAccelerators"> \
|
||||
<arg type="a(su)" direction="in" name="accelerators"/> \
|
||||
<arg type="au" direction="out" name="actions"/> \
|
||||
</method> \
|
||||
<method name="UngrabAccelerator"> \
|
||||
<arg type="u" direction="in" name="action"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
</method> \
|
||||
<signal name="AcceleratorActivated"> \
|
||||
<arg name="action" type="u" /> \
|
||||
<arg name="deviceid" type="u" /> \
|
||||
<arg name="timestamp" type="u" /> \
|
||||
</signal> \
|
||||
<property name="Mode" type="s" access="read" /> \
|
||||
<property name="OverviewActive" type="b" access="readwrite" /> \
|
||||
<property name="ShellVersion" type="s" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const GnomeShellIface = <interface name="org.gnome.Shell">
|
||||
<method name="Eval">
|
||||
<arg type="s" direction="in" name="script" />
|
||||
<arg type="b" direction="out" name="success" />
|
||||
<arg type="s" direction="out" name="result" />
|
||||
</method>
|
||||
<method name="FocusSearch"/>
|
||||
<method name="ShowOSD">
|
||||
<arg type="a{sv}" direction="in" name="params"/>
|
||||
</method>
|
||||
<method name="FocusApp">
|
||||
<arg type="s" direction="in" name="id"/>
|
||||
</method>
|
||||
<method name="ShowApplications" />
|
||||
<method name="GrabAccelerator">
|
||||
<arg type="s" direction="in" name="accelerator"/>
|
||||
<arg type="u" direction="in" name="flags"/>
|
||||
<arg type="u" direction="out" name="action"/>
|
||||
</method>
|
||||
<method name="GrabAccelerators">
|
||||
<arg type="a(su)" direction="in" name="accelerators"/>
|
||||
<arg type="au" direction="out" name="actions"/>
|
||||
</method>
|
||||
<method name="UngrabAccelerator">
|
||||
<arg type="u" direction="in" name="action"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
</method>
|
||||
<signal name="AcceleratorActivated">
|
||||
<arg name="action" type="u" />
|
||||
<arg name="deviceid" type="u" />
|
||||
<arg name="timestamp" type="u" />
|
||||
</signal>
|
||||
<property name="Mode" type="s" access="read" />
|
||||
<property name="OverviewActive" type="b" access="readwrite" />
|
||||
<property name="ShellVersion" type="s" access="read" />
|
||||
</interface>;
|
||||
|
||||
const ScreenSaverIface = '<node> \
|
||||
<interface name="org.gnome.ScreenSaver"> \
|
||||
<method name="Lock"> \
|
||||
</method> \
|
||||
<method name="GetActive"> \
|
||||
<arg name="active" direction="out" type="b" /> \
|
||||
</method> \
|
||||
<method name="SetActive"> \
|
||||
<arg name="value" direction="in" type="b" /> \
|
||||
</method> \
|
||||
<method name="GetActiveTime"> \
|
||||
<arg name="value" direction="out" type="u" /> \
|
||||
</method> \
|
||||
<signal name="ActiveChanged"> \
|
||||
<arg name="new_value" type="b" /> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const ScreenSaverIface = <interface name="org.gnome.ScreenSaver">
|
||||
<method name="Lock">
|
||||
</method>
|
||||
<method name="GetActive">
|
||||
<arg name="active" direction="out" type="b" />
|
||||
</method>
|
||||
<method name="SetActive">
|
||||
<arg name="value" direction="in" type="b" />
|
||||
</method>
|
||||
<method name="GetActiveTime">
|
||||
<arg name="value" direction="out" type="u" />
|
||||
</method>
|
||||
<signal name="ActiveChanged">
|
||||
<arg name="new_value" type="b" />
|
||||
</signal>
|
||||
</interface>;
|
||||
|
||||
const GnomeShell = new Lang.Class({
|
||||
Name: 'GnomeShellDBus',
|
||||
@ -119,7 +115,7 @@ const GnomeShell = new Lang.Class({
|
||||
returnValue = '';
|
||||
success = true;
|
||||
} catch (e) {
|
||||
returnValue = '' + e;
|
||||
returnValue = JSON.stringify(e);
|
||||
success = false;
|
||||
}
|
||||
return [success, returnValue];
|
||||
@ -250,43 +246,41 @@ const GnomeShell = new Lang.Class({
|
||||
ShellVersion: Config.PACKAGE_VERSION
|
||||
});
|
||||
|
||||
const GnomeShellExtensionsIface = '<node> \
|
||||
<interface name="org.gnome.Shell.Extensions"> \
|
||||
<method name="ListExtensions"> \
|
||||
<arg type="a{sa{sv}}" direction="out" name="extensions" /> \
|
||||
</method> \
|
||||
<method name="GetExtensionInfo"> \
|
||||
<arg type="s" direction="in" name="extension" /> \
|
||||
<arg type="a{sv}" direction="out" name="info" /> \
|
||||
</method> \
|
||||
<method name="GetExtensionErrors"> \
|
||||
<arg type="s" direction="in" name="extension" /> \
|
||||
<arg type="as" direction="out" name="errors" /> \
|
||||
</method> \
|
||||
<signal name="ExtensionStatusChanged"> \
|
||||
<arg type="s" name="uuid"/> \
|
||||
<arg type="i" name="state"/> \
|
||||
<arg type="s" name="error"/> \
|
||||
</signal> \
|
||||
<method name="InstallRemoteExtension"> \
|
||||
<arg type="s" direction="in" name="uuid"/> \
|
||||
<arg type="s" direction="out" name="result"/> \
|
||||
</method> \
|
||||
<method name="UninstallExtension"> \
|
||||
<arg type="s" direction="in" name="uuid"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
</method> \
|
||||
<method name="LaunchExtensionPrefs"> \
|
||||
<arg type="s" direction="in" name="uuid"/> \
|
||||
</method> \
|
||||
<method name="ReloadExtension"> \
|
||||
<arg type="s" direction="in" name="uuid"/> \
|
||||
</method> \
|
||||
<method name="CheckForUpdates"> \
|
||||
</method> \
|
||||
<property name="ShellVersion" type="s" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const GnomeShellExtensionsIface = <interface name="org.gnome.Shell.Extensions">
|
||||
<method name="ListExtensions">
|
||||
<arg type="a{sa{sv}}" direction="out" name="extensions" />
|
||||
</method>
|
||||
<method name="GetExtensionInfo">
|
||||
<arg type="s" direction="in" name="extension" />
|
||||
<arg type="a{sv}" direction="out" name="info" />
|
||||
</method>
|
||||
<method name="GetExtensionErrors">
|
||||
<arg type="s" direction="in" name="extension" />
|
||||
<arg type="as" direction="out" name="errors" />
|
||||
</method>
|
||||
<signal name="ExtensionStatusChanged">
|
||||
<arg type="s" name="uuid"/>
|
||||
<arg type="i" name="state"/>
|
||||
<arg type="s" name="error"/>
|
||||
</signal>
|
||||
<method name="InstallRemoteExtension">
|
||||
<arg type="s" direction="in" name="uuid"/>
|
||||
<arg type="s" direction="out" name="result"/>
|
||||
</method>
|
||||
<method name="UninstallExtension">
|
||||
<arg type="s" direction="in" name="uuid"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
</method>
|
||||
<method name="LaunchExtensionPrefs">
|
||||
<arg type="s" direction="in" name="uuid"/>
|
||||
</method>
|
||||
<method name="ReloadExtension">
|
||||
<arg type="s" direction="in" name="uuid"/>
|
||||
</method>
|
||||
<method name="CheckForUpdates">
|
||||
</method>
|
||||
<property name="ShellVersion" type="s" access="read" />
|
||||
</interface>;
|
||||
|
||||
const GnomeShellExtensions = new Lang.Class({
|
||||
Name: 'GnomeShellExtensionsDBus',
|
||||
|
@ -521,38 +521,36 @@ const ShellProcessesDialog = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(ShellProcessesDialog.prototype);
|
||||
|
||||
const GnomeShellMountOpIface = '<node> \
|
||||
<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> \
|
||||
</node>';
|
||||
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,
|
||||
|
@ -105,8 +105,8 @@ const AuthNotification = new Lang.Class({
|
||||
this._devicePath = device_path;
|
||||
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
|
||||
|
||||
this.addAction('allow', _("Allow"));
|
||||
this.addAction('deny', _("Deny"));
|
||||
this.addButton('allow', _("Allow"));
|
||||
this.addButton('deny', _("Deny"));
|
||||
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
if (action == 'allow')
|
||||
@ -133,9 +133,9 @@ const AuthServiceNotification = new Lang.Class({
|
||||
this._devicePath = device_path;
|
||||
this.addBody(_("Device %s wants access to the service '%s'").format(long_name, uuid));
|
||||
|
||||
this.addAction('always-grant', _("Always grant access"));
|
||||
this.addAction('grant', _("Grant this time only"));
|
||||
this.addAction('reject', _("Reject"));
|
||||
this.addButton('always-grant', _("Always grant access"));
|
||||
this.addButton('grant', _("Grant this time only"));
|
||||
this.addButton('reject', _("Reject"));
|
||||
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
switch (action) {
|
||||
@ -172,8 +172,8 @@ const ConfirmNotification = new Lang.Class({
|
||||
this.addBody(_("Please confirm whether the Passkey '%06d' matches the one on the device.").format(pin));
|
||||
|
||||
/* Translators: this is the verb, not the noun */
|
||||
this.addAction('matches', _("Matches"));
|
||||
this.addAction('does-not-match', _("Does not match"));
|
||||
this.addButton('matches', _("Matches"));
|
||||
this.addButton('does-not-match', _("Does not match"));
|
||||
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
if (action == 'matches')
|
||||
@ -207,46 +207,45 @@ const PinNotification = new Lang.Class({
|
||||
let key = event.get_key_symbol();
|
||||
if (key == Clutter.KEY_Return) {
|
||||
if (this._canActivateOkButton())
|
||||
this._ok();
|
||||
this.emit('action-invoked', 'ok');
|
||||
return true;
|
||||
} else if (key == Clutter.KEY_Escape) {
|
||||
this._cancel();
|
||||
this.emit('action-invoked', 'cancel');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
this.addActor(this._entry);
|
||||
|
||||
let okButton = this.addAction(_("OK"), Lang.bind(this, this._ok));
|
||||
this.addAction(_("Cancel"), Lang.bind(this, this._cancel));
|
||||
this.addButton('ok', _("OK"));
|
||||
this.addButton('cancel', _("Cancel"));
|
||||
|
||||
okButton.reactive = this._canActivateOkButton();
|
||||
this._entry.clutter_text.connect('text-changed', Lang.bind(this, function() {
|
||||
okButton.reactive = this._canActivateOkButton();
|
||||
}));
|
||||
},
|
||||
this.setButtonSensitive('ok', this._canActivateOkButton());
|
||||
this._entry.clutter_text.connect('text-changed', Lang.bind(this,
|
||||
function() {
|
||||
this.setButtonSensitive('ok', this._canActivateOkButton());
|
||||
}));
|
||||
|
||||
_ok: function() {
|
||||
if (this._numeric) {
|
||||
let num = parseInt(this._entry.text, 10);
|
||||
if (isNaN(num)) {
|
||||
// user reply was empty, or was invalid
|
||||
// cancel the operation
|
||||
num = -1;
|
||||
this.connect('action-invoked', Lang.bind(this, function(self, action) {
|
||||
if (action == 'ok') {
|
||||
if (this._numeric) {
|
||||
let num = parseInt(this._entry.text);
|
||||
if (isNaN(num)) {
|
||||
// user reply was empty, or was invalid
|
||||
// cancel the operation
|
||||
num = -1;
|
||||
}
|
||||
this._applet.agent_reply_passkey(this._devicePath, num);
|
||||
} else
|
||||
this._applet.agent_reply_pincode(this._devicePath, this._entry.text);
|
||||
} else {
|
||||
if (this._numeric)
|
||||
this._applet.agent_reply_passkey(this._devicePath, -1);
|
||||
else
|
||||
this._applet.agent_reply_pincode(this._devicePath, null);
|
||||
}
|
||||
this._applet.agent_reply_passkey(this._devicePath, num);
|
||||
} else {
|
||||
this._applet.agent_reply_pincode(this._devicePath, this._entry.text);
|
||||
}
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_cancel: function() {
|
||||
if (this._numeric)
|
||||
this._applet.agent_reply_passkey(this._devicePath, -1);
|
||||
else
|
||||
this._applet.agent_reply_pincode(this._devicePath, null);
|
||||
this.destroy();
|
||||
this.destroy();
|
||||
}));
|
||||
},
|
||||
|
||||
_canActivateOkButton: function() {
|
||||
|
@ -11,11 +11,9 @@ const Slider = imports.ui.slider;
|
||||
const BUS_NAME = 'org.gnome.SettingsDaemon.Power';
|
||||
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
|
||||
|
||||
const BrightnessInterface = '<node> \
|
||||
<interface name="org.gnome.SettingsDaemon.Power.Screen"> \
|
||||
<property name="Brightness" type="i" access="readwrite"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const BrightnessInterface = <interface name="org.gnome.SettingsDaemon.Power.Screen">
|
||||
<property name='Brightness' type='i' access='readwrite'/>
|
||||
</interface>;
|
||||
|
||||
const BrightnessProxy = Gio.DBusProxy.makeProxyWrapper(BrightnessInterface);
|
||||
|
||||
|
@ -41,13 +41,11 @@ const MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms
|
||||
const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard';
|
||||
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard';
|
||||
|
||||
const KeyboardManagerInterface = '<node> \
|
||||
<interface name="org.gnome.SettingsDaemon.Keyboard"> \
|
||||
<method name="SetInputSource"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const KeyboardManagerInterface = <interface name="org.gnome.SettingsDaemon.Keyboard">
|
||||
<method name="SetInputSource">
|
||||
<arg type="u" direction="in" />
|
||||
</method>
|
||||
</interface>;
|
||||
|
||||
const KeyboardManagerProxy = Gio.DBusProxy.makeProxyWrapper(KeyboardManagerInterface);
|
||||
|
||||
|
@ -549,30 +549,33 @@ const NMWirelessDialogItem = new Lang.Class({
|
||||
this._network = network;
|
||||
this._ap = network.accessPoints[0];
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'nm-dialog-item',
|
||||
can_focus: true,
|
||||
reactive: true });
|
||||
this.actor = new St.Button({ style_class: 'nm-dialog-item',
|
||||
can_focus: true,
|
||||
x_fill: true });
|
||||
this.actor.connect('key-focus-in', Lang.bind(this, function() {
|
||||
this.emit('selected');
|
||||
}));
|
||||
let action = new Clutter.ClickAction();
|
||||
action.connect('clicked', Lang.bind(this, function() {
|
||||
this.actor.connect('clicked', Lang.bind(this, function() {
|
||||
this.actor.grab_key_focus();
|
||||
}));
|
||||
this.actor.add_action(action);
|
||||
|
||||
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
||||
|
||||
this._content = new St.BoxLayout({ style_class: 'nm-dialog-item-box' });
|
||||
this.actor.set_child(this._content);
|
||||
|
||||
let title = ssidToLabel(this._ap.get_ssid());
|
||||
this._label = new St.Label({ text: title });
|
||||
|
||||
this.actor.label_actor = this._label;
|
||||
this.actor.add(this._label, { x_align: St.Align.START });
|
||||
this._content.add(this._label, { x_align: St.Align.START });
|
||||
|
||||
this._selectedIcon = new St.Icon({ style_class: 'nm-dialog-icon',
|
||||
icon_name: 'object-select-symbolic' });
|
||||
this.actor.add(this._selectedIcon);
|
||||
this._content.add(this._selectedIcon);
|
||||
|
||||
this._icons = new St.BoxLayout({ style_class: 'nm-dialog-icons' });
|
||||
this.actor.add(this._icons, { expand: true, x_fill: false, x_align: St.Align.END });
|
||||
this._content.add(this._icons, { expand: true, x_fill: false, x_align: St.Align.END });
|
||||
|
||||
this._secureIcon = new St.Icon({ style_class: 'nm-dialog-icon' });
|
||||
if (this._ap._secType != NMAccessPointSecurity.NONE)
|
||||
@ -603,6 +606,16 @@ const NMWirelessDialogItem = new Lang.Class({
|
||||
return 'network-workgroup-symbolic';
|
||||
else
|
||||
return 'network-wireless-signal-' + signalToIcon(this._ap.strength) + '-symbolic';
|
||||
},
|
||||
|
||||
_onKeyPressEvent: function(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return
|
||||
|| symbol == Clutter.KEY_KP_Enter) {
|
||||
this.emit('connect');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(NMWirelessDialogItem.prototype);
|
||||
@ -955,13 +968,13 @@ const NMWirelessDialog = new Lang.Class({
|
||||
|
||||
_selectNetwork: function(network) {
|
||||
if (this._selectedNetwork)
|
||||
this._selectedNetwork.item.actor.remove_style_pseudo_class('selected');
|
||||
this._selectedNetwork.item.actor.checked = false;
|
||||
|
||||
this._selectedNetwork = network;
|
||||
this._updateSensitivity();
|
||||
|
||||
if (this._selectedNetwork)
|
||||
this._selectedNetwork.item.actor.add_style_pseudo_class('selected');
|
||||
this._selectedNetwork.item.actor.checked = true;
|
||||
},
|
||||
|
||||
_createNetworkItem: function(network) {
|
||||
@ -971,6 +984,9 @@ const NMWirelessDialog = new Lang.Class({
|
||||
Util.ensureActorVisibleInScrollView(this._scrollView, network.item.actor);
|
||||
this._selectNetwork(network);
|
||||
}));
|
||||
network.item.connect('connect', Lang.bind(this, function() {
|
||||
this._connect();
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -8,22 +8,20 @@ const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
const BUS_NAME = 'org.freedesktop.UPower';
|
||||
const OBJECT_PATH = '/org/freedesktop/UPower/devices/DisplayDevice';
|
||||
const BUS_NAME = 'org.gnome.SettingsDaemon.Power';
|
||||
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Power';
|
||||
|
||||
const DisplayDeviceInterface = '<node> \
|
||||
<interface name="org.freedesktop.UPower.Device"> \
|
||||
<property name="Type" type="u" access="read"/> \
|
||||
<property name="State" type="u" access="read"/> \
|
||||
<property name="Percentage" type="d" access="read"/> \
|
||||
<property name="TimeToEmpty" type="x" access="read"/> \
|
||||
<property name="TimeToFull" type="x" access="read"/> \
|
||||
<property name="IsPresent" type="b" access="read"/> \
|
||||
<property name="IconName" type="s" access="read"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const PowerManagerInterface = <interface name="org.gnome.SettingsDaemon.Power">
|
||||
<method name="GetDevices">
|
||||
<arg type="a(susdut)" direction="out" />
|
||||
</method>
|
||||
<method name="GetPrimaryDevice">
|
||||
<arg type="(susdut)" direction="out" />
|
||||
</method>
|
||||
<property name="Icon" type="s" access="read" />
|
||||
</interface>;
|
||||
|
||||
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface);
|
||||
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(PowerManagerInterface);
|
||||
|
||||
const Indicator = new Lang.Class({
|
||||
Name: 'PowerIndicator',
|
||||
@ -34,7 +32,7 @@ const Indicator = new Lang.Class({
|
||||
|
||||
this._indicator = this._addIndicator();
|
||||
|
||||
this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH,
|
||||
this._proxy = new PowerManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
|
||||
Lang.bind(this, function(proxy, error) {
|
||||
if (error) {
|
||||
log(error.message);
|
||||
@ -45,7 +43,7 @@ const Indicator = new Lang.Class({
|
||||
this._sync();
|
||||
}));
|
||||
|
||||
this._item = new PopupMenu.PopupSubMenuMenuItem("", true);
|
||||
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Battery"), true);
|
||||
this._item.menu.addSettingsAction(_("Power Settings"), 'gnome-power-panel.desktop');
|
||||
this.menu.addMenuItem(this._item);
|
||||
|
||||
@ -58,18 +56,11 @@ const Indicator = new Lang.Class({
|
||||
this.menu.setSensitive(sensitive);
|
||||
},
|
||||
|
||||
_getStatus: function() {
|
||||
let seconds = 0;
|
||||
_statusForDevice: function(device) {
|
||||
let [device_id, device_type, icon, percentage, state, seconds] = device;
|
||||
|
||||
if (this._proxy.State == UPower.DeviceState.FULLY_CHARGED)
|
||||
if (state == UPower.DeviceState.FULLY_CHARGED)
|
||||
return _("Fully Charged");
|
||||
else if (this._proxy.State == UPower.DeviceState.CHARGING)
|
||||
seconds = this._proxy.TimeToFull;
|
||||
else if (this._proxy.State == UPower.DeviceState.DISCHARGING)
|
||||
seconds = this._proxy.TimeToEmpty;
|
||||
// state is one of PENDING_CHARGING, PENDING_DISCHARGING
|
||||
else
|
||||
return _("Estimating…");
|
||||
|
||||
let time = Math.round(seconds / 60);
|
||||
if (time == 0) {
|
||||
@ -81,43 +72,44 @@ const Indicator = new Lang.Class({
|
||||
let minutes = time % 60;
|
||||
let hours = Math.floor(time / 60);
|
||||
|
||||
if (this._proxy.State == UPower.DeviceState.DISCHARGING) {
|
||||
if (state == UPower.DeviceState.DISCHARGING) {
|
||||
// Translators: this is <hours>:<minutes> Remaining (<percentage>)
|
||||
return _("%d\u2236%02d Remaining (%d%%)").format(hours, minutes, this._proxy.Percentage);
|
||||
return _("%d\u2236%02d Remaining (%d%%)").format(hours, minutes, percentage);
|
||||
}
|
||||
|
||||
if (this._proxy.State == UPower.DeviceState.CHARGING) {
|
||||
if (state == UPower.DeviceState.CHARGING) {
|
||||
// Translators: this is <hours>:<minutes> Until Full (<percentage>)
|
||||
return _("%d\u2236%02d Until Full (%d%%)").format(hours, minutes, this._proxy.Percentage);
|
||||
return _("%d\u2236%02d Until Full (%d%%)").format(hours, minutes, percentage);
|
||||
}
|
||||
|
||||
return null;
|
||||
// state is one of PENDING_CHARGING, PENDING_DISCHARGING
|
||||
return _("Estimating…");
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
// Do we have batteries or a UPS?
|
||||
let visible = this._proxy.IsPresent;
|
||||
if (visible) {
|
||||
this._item.actor.show();
|
||||
} else {
|
||||
// If there's no battery, then we use the power icon.
|
||||
this._item.actor.hide();
|
||||
this._indicator.icon_name = 'system-shutdown-symbolic';
|
||||
return;
|
||||
function isBattery(result) {
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
let [device] = result;
|
||||
let [, deviceType] = device;
|
||||
return (deviceType == UPower.DeviceKind.BATTERY);
|
||||
}
|
||||
|
||||
// The icons
|
||||
let icon = this._proxy.IconName;
|
||||
this._indicator.icon_name = icon;
|
||||
this._item.icon.icon_name = icon;
|
||||
|
||||
// The status label
|
||||
this._item.status.text = this._getStatus();
|
||||
|
||||
// The sub-menu heading
|
||||
if (this._proxy.Type == UPower.DeviceKind.UPS)
|
||||
this._item.label.text = _("UPS");
|
||||
else
|
||||
this._item.label.text = _("Battery");
|
||||
this._proxy.GetPrimaryDeviceRemote(Lang.bind(this, function(result, error) {
|
||||
if (isBattery(result)) {
|
||||
let [device] = result;
|
||||
let [,, icon] = device;
|
||||
let gicon = Gio.icon_new_for_string(icon);
|
||||
this._indicator.gicon = gicon;
|
||||
this._item.icon.gicon = gicon;
|
||||
this._item.status.text = this._statusForDevice(device);
|
||||
this._item.actor.show();
|
||||
} else {
|
||||
// If there's no battery, then we use the power icon.
|
||||
this._indicator.icon_name = 'system-shutdown-symbolic';
|
||||
this._item.actor.hide();
|
||||
}
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
@ -9,11 +9,9 @@ const PopupMenu = imports.ui.popupMenu;
|
||||
const BUS_NAME = 'org.gnome.SettingsDaemon.Rfkill';
|
||||
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Rfkill';
|
||||
|
||||
const RfkillManagerInterface = '<node> \
|
||||
<interface name="org.gnome.SettingsDaemon.Rfkill"> \
|
||||
<property name="AirplaneMode" type="b" access="readwrite" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
const RfkillManagerInterface = <interface name="org.gnome.SettingsDaemon.Rfkill">
|
||||
<property name="AirplaneMode" type="b" access="readwrite" />
|
||||
</interface>;
|
||||
|
||||
const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface);
|
||||
|
||||
|
@ -11,8 +11,29 @@ const Signals = imports.signals;
|
||||
const Tweener = imports.tweener.tweener;
|
||||
|
||||
// This is a wrapper around imports.tweener.tweener that adds a bit of
|
||||
// Clutter integration. If the tweening target is a Clutter.Actor, then
|
||||
// the tweenings will automatically be removed if the actor is destroyed.
|
||||
// Clutter integration and some additional callbacks:
|
||||
//
|
||||
// 1. If the tweening target is a Clutter.Actor, then the tweenings
|
||||
// will automatically be removed if the actor is destroyed
|
||||
//
|
||||
// 2. If target._delegate.onAnimationStart() exists, it will be
|
||||
// called when the target starts being animated.
|
||||
//
|
||||
// 3. If target._delegate.onAnimationComplete() exists, it will be
|
||||
// called once the target is no longer being animated.
|
||||
//
|
||||
// The onAnimationStart() and onAnimationComplete() callbacks differ
|
||||
// from the tweener onStart and onComplete parameters, in that (1)
|
||||
// they track whether or not the target has *any* tweens attached to
|
||||
// it, as opposed to be called for *each* tween, and (2)
|
||||
// onAnimationComplete() is always called when the object stops being
|
||||
// animated, regardless of whether it stopped normally or abnormally.
|
||||
//
|
||||
// onAnimationComplete() is called at idle time, which means that if a
|
||||
// tween completes and then another is added before returning to the
|
||||
// main loop, the complete callback will not be called (until the new
|
||||
// tween finishes).
|
||||
|
||||
|
||||
// ActionScript Tweener methods that imports.tweener.tweener doesn't
|
||||
// currently implement: getTweens, getVersion, registerTransition,
|
||||
@ -56,6 +77,7 @@ function _wrapTweening(target, tweeningParameters) {
|
||||
if (!Gtk.Settings.get_default().gtk_enable_animations)
|
||||
tweeningParameters['time'] = 0.000001;
|
||||
|
||||
_addHandler(target, tweeningParameters, 'onStart', _tweenStarted);
|
||||
_addHandler(target, tweeningParameters, 'onComplete', _tweenCompleted);
|
||||
}
|
||||
|
||||
@ -63,7 +85,7 @@ function _getTweenState(target) {
|
||||
// If we were paranoid, we could keep a plist mapping targets to
|
||||
// states... but we're not that paranoid.
|
||||
if (!target.__ShellTweenerState)
|
||||
target.__ShellTweenerState = {};
|
||||
_resetTweenState(target);
|
||||
return target.__ShellTweenerState;
|
||||
}
|
||||
|
||||
@ -73,6 +95,8 @@ function _resetTweenState(target) {
|
||||
if (state) {
|
||||
if (state.destroyedId)
|
||||
state.actor.disconnect(state.destroyedId);
|
||||
if (state.idleCompletedId)
|
||||
Mainloop.source_remove(state.idleCompletedId);
|
||||
}
|
||||
|
||||
target.__ShellTweenerState = {};
|
||||
@ -98,9 +122,32 @@ function _actorDestroyed(target) {
|
||||
Tweener.removeTweens(target);
|
||||
}
|
||||
|
||||
function _tweenStarted(target) {
|
||||
let state = _getTweenState(target);
|
||||
let delegate = target._delegate;
|
||||
|
||||
if (!state.running && delegate && delegate.onAnimationStart)
|
||||
delegate.onAnimationStart();
|
||||
state.running = true;
|
||||
}
|
||||
|
||||
function _tweenCompleted(target) {
|
||||
if (!isTweening(target))
|
||||
let state = _getTweenState(target);
|
||||
|
||||
if (!state.idleCompletedId)
|
||||
state.idleCompletedId = Mainloop.idle_add(Lang.bind(null, _idleCompleted, target));
|
||||
}
|
||||
|
||||
function _idleCompleted(target) {
|
||||
let state = _getTweenState(target);
|
||||
let delegate = target._delegate;
|
||||
|
||||
if (!isTweening(target)) {
|
||||
_resetTweenState(target);
|
||||
if (delegate && delegate.onAnimationComplete)
|
||||
delegate.onAnimationComplete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getTweenCount(scope) {
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
//
|
||||
// A widget showing the user avatar and name
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const AccountsService = imports.gi.AccountsService;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
@ -57,83 +56,6 @@ const Avatar = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const UserWidgetLabel = new Lang.Class({
|
||||
Name: 'UserWidgetLabel',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init: function(user) {
|
||||
this.parent({ layout_manager: new Clutter.BinLayout() });
|
||||
|
||||
this._user = user;
|
||||
|
||||
this._realNameLabel = new St.Label({ style_class: 'user-widget-label',
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
this.add_child(this._realNameLabel);
|
||||
|
||||
this._userNameLabel = new St.Label({ style_class: 'user-widget-label',
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
this.add_child(this._userNameLabel);
|
||||
|
||||
this._currentLabel = null;
|
||||
|
||||
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUser));
|
||||
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUser));
|
||||
this._updateUser();
|
||||
},
|
||||
|
||||
vfunc_destroy: function() {
|
||||
if (this._userLoadedId != 0) {
|
||||
this._user.disconnect(this._userLoadedId);
|
||||
this._userLoadedId = 0;
|
||||
}
|
||||
|
||||
if (this._userChangedId != 0) {
|
||||
this._user.disconnect(this._userChangedId);
|
||||
this._userChangedId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
vfunc_allocate: function(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
|
||||
let [minRealNameWidth, minRealNameHeight,
|
||||
natRealNameWidth, natRealNameHeight] = this._realNameLabel.get_preferred_size();
|
||||
|
||||
let [minUserNameWidth, minUserNameHeight,
|
||||
natUserNameWidth, natUserNameHeight] = this._userNameLabel.get_preferred_size();
|
||||
|
||||
if (natRealNameWidth <= availWidth)
|
||||
this._currentLabel = this._realNameLabel;
|
||||
else
|
||||
this._currentLabel = this._userNameLabel;
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = 0;
|
||||
childBox.y1 = 0;
|
||||
childBox.x2 = availWidth;
|
||||
childBox.y2 = availHeight;
|
||||
|
||||
this._currentLabel.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
vfunc_paint: function() {
|
||||
this._currentLabel.paint();
|
||||
},
|
||||
|
||||
_updateUser: function() {
|
||||
if (this._user.is_loaded) {
|
||||
this._realNameLabel.text = this._user.get_real_name();
|
||||
this._userNameLabel.text = this._user.get_user_name();
|
||||
} else {
|
||||
this._realNameLabel.text = '';
|
||||
this._userNameLabel.text = '';
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const UserWidget = new Lang.Class({
|
||||
Name: 'UserWidget',
|
||||
|
||||
@ -145,14 +67,22 @@ const UserWidget = new Lang.Class({
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this._avatar = new Avatar(user);
|
||||
this.actor.add_child(this._avatar.actor);
|
||||
this.actor.add(this._avatar.actor,
|
||||
{ x_fill: true, y_fill: true });
|
||||
|
||||
this._label = new UserWidgetLabel(user);
|
||||
this.actor.add_child(this._label);
|
||||
this._label = new St.Label({ style_class: 'user-widget-label' });
|
||||
this.actor.add(this._label,
|
||||
{ expand: true,
|
||||
x_fill: true,
|
||||
y_fill: false,
|
||||
y_align: St.Align.MIDDLE });
|
||||
|
||||
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUser));
|
||||
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUser));
|
||||
this._updateUser();
|
||||
this._userLoadedId = this._user.connect('notify::is-loaded',
|
||||
Lang.bind(this, this._updateUser));
|
||||
this._userChangedId = this._user.connect('changed',
|
||||
Lang.bind(this, this._updateUser));
|
||||
if (this._user.is_loaded)
|
||||
this._updateUser();
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
@ -168,6 +98,11 @@ const UserWidget = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateUser: function() {
|
||||
if (this._user.is_loaded)
|
||||
this._label.text = this._user.get_real_name();
|
||||
else
|
||||
this._label.text = '';
|
||||
|
||||
this._avatar.update();
|
||||
}
|
||||
});
|
||||
|
@ -14,9 +14,12 @@ const AppDisplay = imports.ui.appDisplay;
|
||||
const Main = imports.ui.main;
|
||||
const OverviewControls = imports.ui.overviewControls;
|
||||
const Params = imports.misc.params;
|
||||
const RemoteSearch = imports.ui.remoteSearch;
|
||||
const Search = imports.ui.search;
|
||||
const SearchDisplay = imports.ui.searchDisplay;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Wanda = imports.ui.wanda;
|
||||
const WorkspacesView = imports.ui.workspacesView;
|
||||
|
||||
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
|
||||
@ -63,6 +66,8 @@ const ViewSelector = new Lang.Class({
|
||||
this._searchActive = false;
|
||||
this._searchTimeoutId = 0;
|
||||
|
||||
this._searchSystem = new Search.SearchSystem();
|
||||
|
||||
this._entry = searchEntry;
|
||||
ShellEntry.addContextMenu(this._entry);
|
||||
|
||||
@ -98,11 +103,24 @@ const ViewSelector = new Lang.Class({
|
||||
this._appsPage = this._addPage(this.appDisplay.actor,
|
||||
_("Applications"), 'view-grid-symbolic');
|
||||
|
||||
this._searchResults = new Search.SearchResults();
|
||||
this._searchResults = new SearchDisplay.SearchResults(this._searchSystem);
|
||||
this._searchPage = this._addPage(this._searchResults.actor,
|
||||
_("Search"), 'edit-find-symbolic',
|
||||
{ a11yFocus: this._entry });
|
||||
|
||||
this._searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
|
||||
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
|
||||
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
|
||||
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
|
||||
|
||||
// Default search providers
|
||||
// Wanda comes obviously first
|
||||
this.addSearchProvider(new Wanda.WandaSearchProvider());
|
||||
this.addSearchProvider(new AppDisplay.AppSearchProvider());
|
||||
|
||||
// Load remote search providers provided by applications
|
||||
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
|
||||
|
||||
// Since the entry isn't inside the results container we install this
|
||||
// dummy widget as the last results container child so that we can
|
||||
// include the entry in the keynav tab path
|
||||
@ -468,10 +486,45 @@ const ViewSelector = new Lang.Class({
|
||||
|
||||
let terms = getTermsForSearchString(this._entry.get_text());
|
||||
|
||||
this._searchResults.setTerms(terms);
|
||||
this._searchSystem.updateSearchResults(terms);
|
||||
this._showPage(this._searchPage);
|
||||
},
|
||||
|
||||
_shouldUseSearchProvider: function(provider) {
|
||||
// the disable-external GSetting only affects remote providers
|
||||
if (!provider.isRemoteProvider)
|
||||
return true;
|
||||
|
||||
if (this._searchSettings.get_boolean('disable-external'))
|
||||
return false;
|
||||
|
||||
let appId = provider.appInfo.get_id();
|
||||
let disable = this._searchSettings.get_strv('disabled');
|
||||
return disable.indexOf(appId) == -1;
|
||||
},
|
||||
|
||||
_reloadRemoteProviders: function() {
|
||||
// removeSearchProvider() modifies the provider list we iterate on,
|
||||
// so make a copy first
|
||||
let remoteProviders = this._searchSystem.getRemoteProviders().slice(0);
|
||||
|
||||
remoteProviders.forEach(Lang.bind(this, this.removeSearchProvider));
|
||||
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
|
||||
},
|
||||
|
||||
addSearchProvider: function(provider) {
|
||||
if (!this._shouldUseSearchProvider(provider))
|
||||
return;
|
||||
|
||||
this._searchSystem.registerProvider(provider);
|
||||
this._searchResults.createProviderDisplay(provider);
|
||||
},
|
||||
|
||||
removeSearchProvider: function(provider) {
|
||||
this._searchSystem.unregisterProvider(provider);
|
||||
this._searchResults.destroyProviderDisplay(provider);
|
||||
},
|
||||
|
||||
getActivePage: function() {
|
||||
if (this._activePage == this._workspacesPage)
|
||||
return ViewPage.WINDOWS;
|
||||
|
160
js/ui/wanda.js
Normal file
160
js/ui/wanda.js
Normal file
@ -0,0 +1,160 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const IconGrid = imports.ui.iconGrid;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const Panel = imports.ui.panel;
|
||||
|
||||
const FISH_NAME = 'wanda';
|
||||
const FISH_FILENAME = 'wanda.png';
|
||||
const FISH_SPEED = 300;
|
||||
const FISH_COMMAND = 'fortune';
|
||||
// The size of an individual frame in the animation
|
||||
const FISH_HEIGHT = 22;
|
||||
const FISH_WIDTH = 36;
|
||||
|
||||
const FISH_GROUP = 'Fish Animation';
|
||||
|
||||
const MAGIC_FISH_KEY = 'free the fish';
|
||||
|
||||
const WandaIcon = new Lang.Class({
|
||||
Name: 'WandaIcon',
|
||||
Extends: IconGrid.BaseIcon,
|
||||
|
||||
_init : function(fish, label, params) {
|
||||
this.parent(label, params);
|
||||
|
||||
this._fish = fish;
|
||||
this._imageFile = GLib.build_filenamev([global.datadir, fish + '.png']);
|
||||
|
||||
this._imgHeight = FISH_HEIGHT;
|
||||
this._imgWidth = FISH_WIDTH;
|
||||
},
|
||||
|
||||
createIcon: function(iconSize) {
|
||||
this._animations = new Panel.Animation(this._imageFile, this._imgWidth, this._imgHeight, FISH_SPEED);
|
||||
this._animations.play();
|
||||
return this._animations.actor;
|
||||
},
|
||||
|
||||
_createIconTexture: function(size) {
|
||||
if (size == this.iconSize)
|
||||
return;
|
||||
|
||||
this.parent(size);
|
||||
}
|
||||
});
|
||||
|
||||
const WandaIconBin = new Lang.Class({
|
||||
Name: 'WandaIconBin',
|
||||
|
||||
_init: function(fish, label, params) {
|
||||
this.actor = new St.Bin({ reactive: true,
|
||||
track_hover: true });
|
||||
this.icon = new WandaIcon(fish, label, params);
|
||||
|
||||
this.actor.child = this.icon.actor;
|
||||
this.actor.label_actor = this.icon.label;
|
||||
},
|
||||
});
|
||||
|
||||
const FortuneDialog = new Lang.Class({
|
||||
Name: 'FortuneDialog',
|
||||
|
||||
_init: function(name, command) {
|
||||
let text;
|
||||
|
||||
try {
|
||||
let [res, stdout, stderr, status] = GLib.spawn_command_line_sync(command);
|
||||
text = String.fromCharCode.apply(null, stdout);
|
||||
} catch(e) {
|
||||
text = _("Sorry, no wisdom for you today:\n%s").format(e.message);
|
||||
}
|
||||
|
||||
this._title = new St.Label({ style_class: 'prompt-dialog-headline',
|
||||
text: _("%s the Oracle says").format(name) });
|
||||
this._label = new St.Label({ style_class: 'prompt-dialog-description',
|
||||
text: text });
|
||||
this._label.clutter_text.line_wrap = true;
|
||||
|
||||
this._box = new St.BoxLayout({ vertical: true,
|
||||
style_class: 'prompt-dialog' // this is just to force a reasonable width
|
||||
});
|
||||
this._box.add(this._title, { align: St.Align.MIDDLE });
|
||||
this._box.add(this._label, { expand: true });
|
||||
|
||||
this._button = new St.Button({ button_mask: St.ButtonMask.ONE,
|
||||
style_class: 'modal-dialog',
|
||||
reactive: true });
|
||||
this._button.connect('clicked', Lang.bind(this, this.destroy));
|
||||
this._button.child = this._box;
|
||||
|
||||
this._bin = new St.Bin({ x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.MIDDLE });
|
||||
this._bin.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||
this._bin.add_actor(this._button);
|
||||
|
||||
Main.layoutManager.addChrome(this._bin);
|
||||
|
||||
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 10, Lang.bind(this, this.destroy));
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this._bin.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
function capitalize(str) {
|
||||
return str[0].toUpperCase() + str.substring(1, str.length);
|
||||
}
|
||||
|
||||
const WandaSearchProvider = new Lang.Class({
|
||||
Name: 'WandaSearchProvider',
|
||||
|
||||
_init: function() {
|
||||
this.id = 'wanda';
|
||||
},
|
||||
|
||||
getResultMetas: function(fish, callback) {
|
||||
callback([{ 'id': fish[0], // there may be many fish in the sea, but
|
||||
// only one which speaks the truth!
|
||||
'name': capitalize(fish[0]),
|
||||
'createIcon': function(iconSize) {
|
||||
return new St.Icon({ gicon: Gio.icon_new_for_string('face-smile'),
|
||||
icon_size: iconSize });
|
||||
}
|
||||
}]);
|
||||
},
|
||||
|
||||
filterResults: function(results) {
|
||||
return results;
|
||||
},
|
||||
|
||||
getInitialResultSet: function(terms) {
|
||||
if (terms.join(' ') == MAGIC_FISH_KEY) {
|
||||
this.searchSystem.setResults(this, [ FISH_NAME ]);
|
||||
} else {
|
||||
this.searchSystem.setResults(this, []);
|
||||
}
|
||||
},
|
||||
|
||||
getSubsearchResultSet: function(previousResults, terms) {
|
||||
this.getInitialResultSet(terms);
|
||||
},
|
||||
|
||||
activateResult: function(fish) {
|
||||
if (this._dialog)
|
||||
this._dialog.destroy();
|
||||
this._dialog = new FortuneDialog(capitalize(fish), FISH_COMMAND);
|
||||
},
|
||||
|
||||
createResultObject: function (resultMeta, terms) {
|
||||
return new WandaIconBin(resultMeta.id, resultMeta.name);
|
||||
}
|
||||
});
|
@ -39,9 +39,6 @@ const WindowAttentionHandler = new Lang.Class({
|
||||
let [title, banner] = this._getTitleAndBanner(app, window);
|
||||
|
||||
let notification = new MessageTray.Notification(source, title, banner);
|
||||
notification.connect('clicked', function() {
|
||||
source.open();
|
||||
});
|
||||
notification.setForFeedback(true);
|
||||
|
||||
source.notify(notification);
|
||||
@ -82,7 +79,7 @@ const Source = new Lang.Class({
|
||||
return this._app.create_icon_texture(size);
|
||||
},
|
||||
|
||||
open: function() {
|
||||
open : function(notification) {
|
||||
Main.activateWindow(this._window);
|
||||
this.destroy();
|
||||
}
|
||||
|
@ -10,14 +10,19 @@ const St = imports.gi.St;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
const Panel = imports.ui.panel;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const FOCUS_ANIMATION_TIME = 0.15;
|
||||
|
||||
const WINDOW_DND_SIZE = 256;
|
||||
|
||||
const WINDOW_CLONE_MAXIMUM_SCALE = 0.7;
|
||||
|
||||
const LIGHTBOX_FADE_TIME = 0.1;
|
||||
const CLOSE_BUTTON_FADE_TIME = 0.1;
|
||||
|
||||
const DRAGGING_WINDOW_OPACITY = 100;
|
||||
@ -887,19 +892,6 @@ function padArea(area, padding) {
|
||||
};
|
||||
}
|
||||
|
||||
function rectEqual(one, two) {
|
||||
if (one == two)
|
||||
return true;
|
||||
|
||||
if (!one || !two)
|
||||
return false;
|
||||
|
||||
return (one.x == two.x &&
|
||||
one.y == two.y &&
|
||||
one.width == two.width &&
|
||||
one.height == two.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @metaWorkspace: a #Meta.Workspace, or null
|
||||
*/
|
||||
@ -975,17 +967,11 @@ const Workspace = new Lang.Class({
|
||||
},
|
||||
|
||||
setFullGeometry: function(geom) {
|
||||
if (rectEqual(this._fullGeometry, geom))
|
||||
return;
|
||||
|
||||
this._fullGeometry = geom;
|
||||
this._recalculateWindowPositions(WindowPositionFlags.NONE);
|
||||
},
|
||||
|
||||
setActualGeometry: function(geom) {
|
||||
if (rectEqual(this._actualGeometry, geom))
|
||||
return;
|
||||
|
||||
this._actualGeometry = geom;
|
||||
|
||||
if (this._actualGeometryLater)
|
||||
@ -1208,7 +1194,6 @@ const Workspace = new Lang.Class({
|
||||
}
|
||||
|
||||
this._recalculateWindowPositions(WindowPositionFlags.ANIMATE);
|
||||
this._repositionWindowsId = 0;
|
||||
return false;
|
||||
},
|
||||
|
||||
@ -1464,17 +1449,17 @@ const Workspace = new Lang.Class({
|
||||
clone.connect('selected',
|
||||
Lang.bind(this, this._onCloneSelected));
|
||||
clone.connect('drag-begin',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.beginWindowDrag(clone);
|
||||
Lang.bind(this, function(clone) {
|
||||
Main.overview.beginWindowDrag();
|
||||
overlay.hide();
|
||||
}));
|
||||
clone.connect('drag-cancelled',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.cancelledWindowDrag(clone);
|
||||
Lang.bind(this, function(clone) {
|
||||
Main.overview.cancelledWindowDrag();
|
||||
}));
|
||||
clone.connect('drag-end',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.endWindowDrag(clone);
|
||||
Lang.bind(this, function(clone) {
|
||||
Main.overview.endWindowDrag();
|
||||
overlay.show();
|
||||
}));
|
||||
clone.connect('size-changed',
|
||||
@ -1636,7 +1621,9 @@ const Workspace = new Lang.Class({
|
||||
metaWindow.move_to_monitor(this.monitorIndex);
|
||||
|
||||
let index = this.metaWorkspace ? this.metaWorkspace.index() : global.screen.get_active_workspace_index();
|
||||
metaWindow.change_workspace_by_index(index, false);
|
||||
metaWindow.change_workspace_by_index(index,
|
||||
false, // don't create workspace
|
||||
time);
|
||||
return true;
|
||||
} else if (source.shellWorkspaceLaunch) {
|
||||
source.shellWorkspaceLaunch({ workspace: this.metaWorkspace ? this.metaWorkspace.index() : -1,
|
||||
|
@ -438,16 +438,16 @@ const WorkspaceThumbnail = new Lang.Class({
|
||||
this.activate(time);
|
||||
}));
|
||||
clone.connect('drag-begin',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.beginWindowDrag(clone);
|
||||
Lang.bind(this, function(clone) {
|
||||
Main.overview.beginWindowDrag();
|
||||
}));
|
||||
clone.connect('drag-cancelled',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.cancelledWindowDrag(clone);
|
||||
Lang.bind(this, function(clone) {
|
||||
Main.overview.cancelledWindowDrag();
|
||||
}));
|
||||
clone.connect('drag-end',
|
||||
Lang.bind(this, function() {
|
||||
Main.overview.endWindowDrag(clone);
|
||||
Lang.bind(this, function(clone) {
|
||||
Main.overview.endWindowDrag();
|
||||
}));
|
||||
this._contents.add_actor(clone.actor);
|
||||
|
||||
@ -507,7 +507,9 @@ const WorkspaceThumbnail = new Lang.Class({
|
||||
if (metaWindow.get_monitor() != this.monitorIndex)
|
||||
metaWindow.move_to_monitor(this.monitorIndex);
|
||||
|
||||
metaWindow.change_workspace_by_index(this.metaWorkspace.index(), false);
|
||||
metaWindow.change_workspace_by_index(this.metaWorkspace.index(),
|
||||
false, // don't create workspace
|
||||
time);
|
||||
return true;
|
||||
} else if (source.shellWorkspaceLaunch) {
|
||||
source.shellWorkspaceLaunch({ workspace: this.metaWorkspace ? this.metaWorkspace.index() : -1,
|
||||
@ -737,12 +739,14 @@ const ThumbnailsBox = new Lang.Class({
|
||||
|
||||
// ... move them down one.
|
||||
windows.forEach(function(win) {
|
||||
win.meta_window.change_workspace_by_index(win.get_workspace() + 1, true);
|
||||
win.meta_window.change_workspace_by_index(win.get_workspace() + 1,
|
||||
true, time);
|
||||
});
|
||||
|
||||
if (isWindow)
|
||||
// ... and bam, a workspace, good as new.
|
||||
source.metaWindow.change_workspace_by_index(newWorkspaceIndex, true);
|
||||
source.metaWindow.change_workspace_by_index(newWorkspaceIndex,
|
||||
true, time);
|
||||
else if (source.shellWorkspaceLaunch) {
|
||||
source.shellWorkspaceLaunch({ workspace: newWorkspaceIndex,
|
||||
timestamp: time });
|
||||
|
@ -23,92 +23,75 @@ const MAX_WORKSPACES = 16;
|
||||
|
||||
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
|
||||
|
||||
const WorkspacesViewBase = new Lang.Class({
|
||||
Name: 'WorkspacesViewBase',
|
||||
function rectEqual(one, two) {
|
||||
if (one == two)
|
||||
return true;
|
||||
|
||||
_init: function(monitorIndex) {
|
||||
if (!one || !two)
|
||||
return false;
|
||||
|
||||
return (one.x == two.x &&
|
||||
one.y == two.y &&
|
||||
one.width == two.width &&
|
||||
one.height == two.height);
|
||||
}
|
||||
|
||||
const WorkspacesView = new Lang.Class({
|
||||
Name: 'WorkspacesView',
|
||||
|
||||
_init: function(workspaces) {
|
||||
this.actor = new St.Widget({ style_class: 'workspaces-view',
|
||||
reactive: true });
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
// The actor itself isn't a drop target, so we don't want to pick on its area
|
||||
this.actor.set_size(0, 0);
|
||||
|
||||
this._monitorIndex = monitorIndex;
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this.actor.connect('style-changed', Lang.bind(this,
|
||||
function() {
|
||||
let node = this.actor.get_theme_node();
|
||||
this._spacing = node.get_length('spacing');
|
||||
this._updateWorkspaceActors(false);
|
||||
}));
|
||||
|
||||
this._fullGeometry = null;
|
||||
this._actualGeometry = null;
|
||||
|
||||
this._inDrag = false;
|
||||
this._windowDragBeginId = Main.overview.connect('window-drag-begin', Lang.bind(this, this._dragBegin));
|
||||
this._windowDragEndId = Main.overview.connect('window-drag-end', Lang.bind(this, this._dragEnd));
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this._dragEnd();
|
||||
|
||||
if (this._windowDragBeginId > 0) {
|
||||
Main.overview.disconnect(this._windowDragBeginId);
|
||||
this._windowDragBeginId = 0;
|
||||
}
|
||||
if (this._windowDragEndId > 0) {
|
||||
Main.overview.disconnect(this._windowDragEndId);
|
||||
this._windowDragEndId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_dragBegin: function(overview, clone) {
|
||||
this._inDrag = true;
|
||||
this._setReservedSlot(clone);
|
||||
},
|
||||
|
||||
_dragEnd: function() {
|
||||
this._inDrag = false;
|
||||
this._setReservedSlot(null);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
setFullGeometry: function(geom) {
|
||||
this._fullGeometry = geom;
|
||||
this._syncGeometry();
|
||||
},
|
||||
|
||||
setActualGeometry: function(geom) {
|
||||
this._actualGeometry = geom;
|
||||
this._syncGeometry();
|
||||
},
|
||||
});
|
||||
|
||||
const WorkspacesView = new Lang.Class({
|
||||
Name: 'WorkspacesView',
|
||||
Extends: WorkspacesViewBase,
|
||||
|
||||
_init: function(monitorIndex) {
|
||||
this.parent(monitorIndex);
|
||||
|
||||
this._spacing = 0;
|
||||
this._animating = false; // tweening
|
||||
this._scrolling = false; // swipe-scrolling
|
||||
this._animatingScroll = false; // programatically updating the adjustment
|
||||
this._inDrag = false; // dragging a window
|
||||
|
||||
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
|
||||
this._updateExtraWorkspacesId =
|
||||
this._settings.connect('changed::workspaces-only-on-primary',
|
||||
Lang.bind(this, this._updateExtraWorkspaces));
|
||||
|
||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||
this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
|
||||
lower: 0,
|
||||
page_increment: 1,
|
||||
page_size: 1,
|
||||
step_increment: 0,
|
||||
upper: 0 });
|
||||
this.scrollAdjustment.connect('notify::value',
|
||||
Lang.bind(this, this._onScroll));
|
||||
this._workspaces = workspaces;
|
||||
|
||||
this._workspaces = [];
|
||||
this._updateWorkspaces();
|
||||
this._updateWorkspacesId = global.screen.connect('notify::n-workspaces', Lang.bind(this, this._updateWorkspaces));
|
||||
// Add workspace actors
|
||||
for (let w = 0; w < global.screen.n_workspaces; w++)
|
||||
this.actor.add_actor(this._workspaces[w].actor);
|
||||
this._workspaces[activeWorkspaceIndex].actor.raise_top();
|
||||
|
||||
this._extraWorkspaces = [];
|
||||
this._updateExtraWorkspaces();
|
||||
|
||||
// Position/scale the desktop windows and their children after the
|
||||
// workspaces have been created. This cannot be done first because
|
||||
// window movement depends on the Workspaces object being accessible
|
||||
// as an Overview member.
|
||||
this._overviewShowingId =
|
||||
Main.overview.connect('showing',
|
||||
Lang.bind(this, function() {
|
||||
for (let w = 0; w < this._workspaces.length; w++)
|
||||
this._workspaces[w].zoomToOverview();
|
||||
for (let w = 0; w < this._extraWorkspaces.length; w++)
|
||||
this._extraWorkspaces[w].zoomToOverview();
|
||||
}));
|
||||
this._overviewShownId =
|
||||
Main.overview.connect('shown',
|
||||
Lang.bind(this, function() {
|
||||
@ -116,21 +99,72 @@ const WorkspacesView = new Lang.Class({
|
||||
this._fullGeometry.width, this._fullGeometry.height);
|
||||
}));
|
||||
|
||||
this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
|
||||
lower: 0,
|
||||
page_increment: 1,
|
||||
page_size: 1,
|
||||
step_increment: 0,
|
||||
upper: this._workspaces.length });
|
||||
this.scrollAdjustment.connect('notify::value',
|
||||
Lang.bind(this, this._onScroll));
|
||||
|
||||
this._switchWorkspaceNotifyId =
|
||||
global.window_manager.connect('switch-workspace',
|
||||
Lang.bind(this, this._activeWorkspaceChanged));
|
||||
|
||||
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
||||
Lang.bind(this, this._dragBegin));
|
||||
this._itemDragEndId = Main.overview.connect('item-drag-end',
|
||||
Lang.bind(this, this._dragEnd));
|
||||
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
|
||||
Lang.bind(this, this._dragBegin));
|
||||
this._windowDragEndId = Main.overview.connect('window-drag-end',
|
||||
Lang.bind(this, this._dragEnd));
|
||||
},
|
||||
|
||||
_setReservedSlot: function(clone) {
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setReservedSlot(clone);
|
||||
_updateExtraWorkspaces: function() {
|
||||
this._destroyExtraWorkspaces();
|
||||
|
||||
if (!this._settings.get_boolean('workspaces-only-on-primary'))
|
||||
return;
|
||||
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
if (i == Main.layoutManager.primaryIndex)
|
||||
continue;
|
||||
|
||||
let ws = new Workspace.Workspace(null, i);
|
||||
ws.setFullGeometry(monitors[i]);
|
||||
ws.setActualGeometry(monitors[i]);
|
||||
Main.layoutManager.overviewGroup.add_actor(ws.actor);
|
||||
this._extraWorkspaces.push(ws);
|
||||
}
|
||||
},
|
||||
|
||||
_syncGeometry: function() {
|
||||
_destroyExtraWorkspaces: function() {
|
||||
for (let m = 0; m < this._extraWorkspaces.length; m++)
|
||||
this._extraWorkspaces[m].destroy();
|
||||
this._extraWorkspaces = [];
|
||||
},
|
||||
|
||||
setFullGeometry: function(geom) {
|
||||
if (rectEqual(this._fullGeometry, geom))
|
||||
return;
|
||||
|
||||
this._fullGeometry = geom;
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setFullGeometry(this._fullGeometry);
|
||||
this._workspaces[i].setFullGeometry(geom);
|
||||
},
|
||||
|
||||
setActualGeometry: function(geom) {
|
||||
if (rectEqual(this._actualGeometry, geom))
|
||||
return;
|
||||
|
||||
this._actualGeometry = geom;
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setActualGeometry(this._actualGeometry);
|
||||
this._workspaces[i].setActualGeometry(geom);
|
||||
},
|
||||
|
||||
getActiveWorkspace: function() {
|
||||
@ -138,22 +172,29 @@ const WorkspacesView = new Lang.Class({
|
||||
return this._workspaces[active];
|
||||
},
|
||||
|
||||
zoomToOverview: function() {
|
||||
for (let w = 0; w < this._workspaces.length; w++)
|
||||
this._workspaces[w].zoomToOverview();
|
||||
this._updateWorkspaceActors(false);
|
||||
},
|
||||
hide: function() {
|
||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||
let activeWorkspace = this._workspaces[activeWorkspaceIndex];
|
||||
|
||||
activeWorkspace.actor.raise_top();
|
||||
|
||||
zoomFromOverview: function() {
|
||||
this.actor.remove_clip();
|
||||
|
||||
for (let w = 0; w < this._workspaces.length; w++)
|
||||
this._workspaces[w].zoomFromOverview();
|
||||
for (let w = 0; w < this._extraWorkspaces.length; w++)
|
||||
this._extraWorkspaces[w].zoomFromOverview();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.actor.destroy();
|
||||
},
|
||||
|
||||
syncStacking: function(stackIndices) {
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].syncStacking(stackIndices);
|
||||
for (let i = 0; i < this._extraWorkspaces.length; i++)
|
||||
this._extraWorkspaces[i].syncStacking(stackIndices);
|
||||
},
|
||||
|
||||
_scrollToActive: function() {
|
||||
@ -175,7 +216,7 @@ const WorkspacesView = new Lang.Class({
|
||||
|
||||
Tweener.removeTweens(workspace.actor);
|
||||
|
||||
let y = (w - active) * this._fullGeometry.height;
|
||||
let y = (w - active) * (this._fullGeometry.height + this._spacing);
|
||||
|
||||
if (showAnimation) {
|
||||
let params = { y: y,
|
||||
@ -235,31 +276,25 @@ const WorkspacesView = new Lang.Class({
|
||||
});
|
||||
},
|
||||
|
||||
_updateWorkspaces: function() {
|
||||
let oldNumWorkspaces = this._workspaces.length;
|
||||
let newNumWorkspaces = global.screen.n_workspaces;
|
||||
updateWorkspaces: function(oldNumWorkspaces, newNumWorkspaces) {
|
||||
let active = global.screen.get_active_workspace_index();
|
||||
|
||||
this.scrollAdjustment.upper = newNumWorkspaces;
|
||||
Tweener.addTween(this.scrollAdjustment,
|
||||
{ upper: newNumWorkspaces,
|
||||
time: WORKSPACE_SWITCH_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
|
||||
if (newNumWorkspaces > oldNumWorkspaces) {
|
||||
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
|
||||
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
||||
let workspace = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
|
||||
this._workspaces.push(workspace);
|
||||
this.actor.add_actor(workspace.actor);
|
||||
this._workspaces[w].setFullGeometry(this._fullGeometry);
|
||||
if (this._actualGeometry)
|
||||
this._workspaces[w].setActualGeometry(this._actualGeometry);
|
||||
this.actor.add_actor(this._workspaces[w].actor);
|
||||
}
|
||||
|
||||
if (this._fullGeometry)
|
||||
this._updateWorkspaceActors(false);
|
||||
} else if (newNumWorkspaces < oldNumWorkspaces) {
|
||||
let nRemoved = (newNumWorkspaces - oldNumWorkspaces);
|
||||
let removed = this._workspaces.splice(oldNumWorkspaces, nRemoved);
|
||||
removed.forEach(function(workspace) {
|
||||
workspace.destroy();
|
||||
});
|
||||
this._updateWorkspaceActors(false);
|
||||
}
|
||||
|
||||
this._syncGeometry();
|
||||
},
|
||||
|
||||
_activeWorkspaceChanged: function(wm, from, to, direction) {
|
||||
@ -270,12 +305,70 @@ const WorkspacesView = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this.parent();
|
||||
|
||||
this._destroyExtraWorkspaces();
|
||||
this.scrollAdjustment.run_dispose();
|
||||
Main.overview.disconnect(this._overviewShowingId);
|
||||
Main.overview.disconnect(this._overviewShownId);
|
||||
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
||||
global.screen.disconnect(this._updateWorkspacesId);
|
||||
this._settings.disconnect(this._updateExtraWorkspacesId);
|
||||
|
||||
if (this._inDrag)
|
||||
this._dragEnd();
|
||||
|
||||
if (this._itemDragBeginId > 0) {
|
||||
Main.overview.disconnect(this._itemDragBeginId);
|
||||
this._itemDragBeginId = 0;
|
||||
}
|
||||
if (this._itemDragEndId > 0) {
|
||||
Main.overview.disconnect(this._itemDragEndId);
|
||||
this._itemDragEndId = 0;
|
||||
}
|
||||
if (this._windowDragBeginId > 0) {
|
||||
Main.overview.disconnect(this._windowDragBeginId);
|
||||
this._windowDragBeginId = 0;
|
||||
}
|
||||
if (this._windowDragEndId > 0) {
|
||||
Main.overview.disconnect(this._windowDragEndId);
|
||||
this._windowDragEndId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_dragBegin: function() {
|
||||
if (this._scrolling)
|
||||
return;
|
||||
|
||||
this._inDrag = true;
|
||||
this._firstDragMotion = true;
|
||||
|
||||
this._dragMonitor = {
|
||||
dragMotion: Lang.bind(this, this._onDragMotion)
|
||||
};
|
||||
DND.addDragMonitor(this._dragMonitor);
|
||||
},
|
||||
|
||||
_onDragMotion: function(dragEvent) {
|
||||
if (Main.overview.animationInProgress)
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
|
||||
if (this._firstDragMotion) {
|
||||
this._firstDragMotion = false;
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
|
||||
for (let i = 0; i < this._extraWorkspaces.length; i++)
|
||||
this._extraWorkspaces[i].setReservedSlot(dragEvent.dragActor._delegate);
|
||||
}
|
||||
|
||||
return DND.DragMotionResult.CONTINUE;
|
||||
},
|
||||
|
||||
_dragEnd: function() {
|
||||
DND.removeDragMonitor(this._dragMonitor);
|
||||
this._inDrag = false;
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++)
|
||||
this._workspaces[i].setReservedSlot(null);
|
||||
for (let i = 0; i < this._extraWorkspaces.length; i++)
|
||||
this._extraWorkspaces[i].setReservedSlot(null);
|
||||
},
|
||||
|
||||
startSwipeScroll: function() {
|
||||
@ -334,42 +427,6 @@ const WorkspacesView = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(WorkspacesView.prototype);
|
||||
|
||||
const ExtraWorkspaceView = new Lang.Class({
|
||||
Name: 'ExtraWorkspaceView',
|
||||
Extends: WorkspacesViewBase,
|
||||
|
||||
_init: function(monitorIndex) {
|
||||
this.parent(monitorIndex);
|
||||
this._workspace = new Workspace.Workspace(null, monitorIndex);
|
||||
this.actor.add_actor(this._workspace.actor);
|
||||
},
|
||||
|
||||
_setReservedSlot: function(clone) {
|
||||
this._workspace.setReservedSlot(clone);
|
||||
},
|
||||
|
||||
_syncGeometry: function() {
|
||||
this._workspace.setFullGeometry(this._fullGeometry);
|
||||
this._workspace.setActualGeometry(this._actualGeometry);
|
||||
},
|
||||
|
||||
zoomToOverview: function() {
|
||||
this._workspace.zoomToOverview();
|
||||
},
|
||||
|
||||
zoomFromOverview: function() {
|
||||
this._workspace.zoomFromOverview();
|
||||
},
|
||||
|
||||
syncStacking: function(stackIndices) {
|
||||
this._workspace.syncStacking(stackIndices);
|
||||
},
|
||||
|
||||
startSwipeScroll: function() {
|
||||
},
|
||||
endSwipeScroll: function() {
|
||||
},
|
||||
});
|
||||
|
||||
const WorkspacesDisplay = new Lang.Class({
|
||||
Name: 'WorkspacesDisplay',
|
||||
@ -414,6 +471,7 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
this._primaryIndex = Main.layoutManager.primaryIndex;
|
||||
|
||||
this._workspacesViews = [];
|
||||
this._workspaces = [];
|
||||
this._primaryScrollAdjustment = null;
|
||||
|
||||
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
|
||||
@ -422,6 +480,9 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
this._workspacesOnlyOnPrimaryChanged));
|
||||
this._workspacesOnlyOnPrimaryChanged();
|
||||
|
||||
global.screen.connect('notify::n-workspaces',
|
||||
Lang.bind(this, this._workspacesChanged));
|
||||
|
||||
this._switchWorkspaceNotifyId = 0;
|
||||
|
||||
this._notifyOpacityId = 0;
|
||||
@ -439,8 +500,6 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
|
||||
show: function() {
|
||||
this._updateWorkspacesViews();
|
||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||
this._workspacesViews[i].zoomToOverview();
|
||||
|
||||
this._restackedNotifyId =
|
||||
Main.overview.connect('windows-restacked',
|
||||
@ -450,8 +509,9 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
},
|
||||
|
||||
zoomFromOverview: function() {
|
||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||
this._workspacesViews[i].zoomFromOverview();
|
||||
for (let i = 0; i < this._workspacesViews.length; i++) {
|
||||
this._workspacesViews[i].hide();
|
||||
}
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
@ -483,38 +543,46 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
this._workspacesViews[i].destroy();
|
||||
|
||||
this._workspacesViews = [];
|
||||
this._workspaces = [];
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let view;
|
||||
if (this._workspacesOnlyOnPrimary && i != this._primaryIndex)
|
||||
view = new ExtraWorkspaceView(i);
|
||||
else
|
||||
view = new WorkspacesView(i);
|
||||
continue; // we are only interested in the primary monitor
|
||||
|
||||
let monitorWorkspaces = [];
|
||||
for (let w = 0; w < global.screen.n_workspaces; w++) {
|
||||
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
||||
monitorWorkspaces.push(new Workspace.Workspace(metaWorkspace, i));
|
||||
}
|
||||
|
||||
this._workspaces.push(monitorWorkspaces);
|
||||
|
||||
let view = new WorkspacesView(monitorWorkspaces);
|
||||
view.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
||||
if (i == this._primaryIndex) {
|
||||
if (this._workspacesOnlyOnPrimary || i == this._primaryIndex) {
|
||||
this._scrollAdjustment = view.scrollAdjustment;
|
||||
this._scrollAdjustment.connect('notify::value',
|
||||
Lang.bind(this, this._scrollValueChanged));
|
||||
}
|
||||
|
||||
this._workspacesViews.push(view);
|
||||
Main.layoutManager.overviewGroup.add_actor(view.actor);
|
||||
}
|
||||
|
||||
this._updateWorkspacesFullGeometry();
|
||||
this._updateWorkspacesActualGeometry();
|
||||
|
||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||
Main.layoutManager.overviewGroup.add_actor(this._workspacesViews[i].actor);
|
||||
},
|
||||
|
||||
_scrollValueChanged: function() {
|
||||
if (this._workspacesOnlyOnPrimary)
|
||||
return;
|
||||
|
||||
for (let i = 0; i < this._workspacesViews.length; i++) {
|
||||
if (i == this._primaryIndex)
|
||||
continue;
|
||||
|
||||
let adjustment = this._workspacesViews[i].scrollAdjustment;
|
||||
if (!adjustment)
|
||||
continue;
|
||||
|
||||
// the adjustments work in terms of workspaces, so the
|
||||
// values map directly
|
||||
adjustment.value = this._scrollAdjustment.value;
|
||||
@ -524,7 +592,10 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
_getPrimaryView: function() {
|
||||
if (!this._workspacesViews.length)
|
||||
return null;
|
||||
return this._workspacesViews[this._primaryIndex];
|
||||
if (this._workspacesOnlyOnPrimary)
|
||||
return this._workspacesViews[0];
|
||||
else
|
||||
return this._workspacesViews[this._primaryIndex];
|
||||
},
|
||||
|
||||
activeWorkspaceHasMaximizedWindows: function() {
|
||||
@ -570,9 +641,15 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
return;
|
||||
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
let m = 0;
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let geometry = (i == this._primaryIndex) ? this._fullGeometry : monitors[i];
|
||||
this._workspacesViews[i].setFullGeometry(geometry);
|
||||
if (i == this._primaryIndex) {
|
||||
this._workspacesViews[m].setFullGeometry(this._fullGeometry);
|
||||
m++;
|
||||
} else if (!this._workspacesOnlyOnPrimary) {
|
||||
this._workspacesViews[m].setFullGeometry(monitors[i]);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -583,12 +660,18 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
let [x, y] = this.actor.get_transformed_position();
|
||||
let width = this.actor.allocation.x2 - this.actor.allocation.x1;
|
||||
let height = this.actor.allocation.y2 - this.actor.allocation.y1;
|
||||
let primaryGeometry = { x: x, y: y, width: width, height: height };
|
||||
let geometry = { x: x, y: y, width: width, height: height };
|
||||
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
let m = 0;
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let geometry = (i == this._primaryIndex) ? primaryGeometry : monitors[i];
|
||||
this._workspacesViews[i].setActualGeometry(geometry);
|
||||
if (i == this._primaryIndex) {
|
||||
this._workspacesViews[m].setActualGeometry(geometry);
|
||||
m++;
|
||||
} else if (!this._workspacesOnlyOnPrimary) {
|
||||
this._workspacesViews[m].setActualGeometry(monitors[i]);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -597,6 +680,60 @@ const WorkspacesDisplay = new Lang.Class({
|
||||
this._workspacesViews[i].syncStacking(stackIndices);
|
||||
},
|
||||
|
||||
_workspacesChanged: function() {
|
||||
if (!this._workspacesViews.length)
|
||||
return;
|
||||
|
||||
let oldNumWorkspaces = this._workspaces[0].length;
|
||||
let newNumWorkspaces = global.screen.n_workspaces;
|
||||
let active = global.screen.get_active_workspace_index();
|
||||
|
||||
let lostWorkspaces = [];
|
||||
if (newNumWorkspaces > oldNumWorkspaces) {
|
||||
let monitors = Main.layoutManager.monitors;
|
||||
let m = 0;
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
if (this._workspacesOnlyOnPrimary &&
|
||||
i != this._primaryIndex)
|
||||
continue;
|
||||
|
||||
// Assume workspaces are only added at the end
|
||||
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
|
||||
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
||||
this._workspaces[m][w] =
|
||||
new Workspace.Workspace(metaWorkspace, i);
|
||||
}
|
||||
m++;
|
||||
}
|
||||
} else {
|
||||
// Assume workspaces are only removed sequentially
|
||||
// (e.g. 2,3,4 - not 2,4,7)
|
||||
let removedIndex;
|
||||
let removedNum = oldNumWorkspaces - newNumWorkspaces;
|
||||
for (let w = 0; w < oldNumWorkspaces; w++) {
|
||||
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
||||
if (this._workspaces[0][w].metaWorkspace != metaWorkspace) {
|
||||
removedIndex = w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._workspaces.length; i++) {
|
||||
lostWorkspaces = this._workspaces[i].splice(removedIndex,
|
||||
removedNum);
|
||||
|
||||
for (let l = 0; l < lostWorkspaces.length; l++) {
|
||||
lostWorkspaces[l].disconnectAll();
|
||||
lostWorkspaces[l].destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._workspacesViews.length; i++)
|
||||
this._workspacesViews[i].updateWorkspaces(oldNumWorkspaces,
|
||||
newNumWorkspaces);
|
||||
},
|
||||
|
||||
_onScrollEvent: function(actor, event) {
|
||||
if (!this.actor.mapped)
|
||||
return false;
|
||||
|
@ -38,7 +38,7 @@ js/ui/panel.js
|
||||
js/ui/popupMenu.js
|
||||
js/ui/runDialog.js
|
||||
js/ui/screenShield.js
|
||||
js/ui/search.js
|
||||
js/ui/searchDisplay.js
|
||||
js/ui/shellEntry.js
|
||||
js/ui/shellMountOperation.js
|
||||
js/ui/status/accessibility.js
|
||||
@ -52,6 +52,7 @@ js/ui/status/system.js
|
||||
js/ui/status/volume.js
|
||||
js/ui/unlockDialog.js
|
||||
js/ui/viewSelector.js
|
||||
js/ui/wanda.js
|
||||
js/ui/windowAttentionHandler.js
|
||||
js/ui/windowManager.js
|
||||
src/calendar-server/evolution-calendar.desktop.in.in
|
||||
|
320
po/be.po
320
po/be.po
@ -5,7 +5,7 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell.master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-10-02 17:58+0000\n"
|
||||
"POT-Creation-Date: 2013-10-15 18:32+0000\n"
|
||||
"PO-Revision-Date: 2012-10-16 12:05+0300\n"
|
||||
"Last-Translator: Kasia Bondarava <kasia.bondarava@gmail.com>\n"
|
||||
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
|
||||
@ -273,23 +273,23 @@ msgstr ""
|
||||
"Абярыце пашырэнне, каб настроіць графу з выплыўным спісам, якая знаходзіцца "
|
||||
"вышэй."
|
||||
|
||||
#: ../js/gdm/authPrompt.js:145 ../js/ui/components/networkAgent.js:136
|
||||
#: ../js/gdm/authPrompt.js:146 ../js/ui/components/networkAgent.js:136
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:351
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:222 ../js/ui/status/network.js:692
|
||||
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:739
|
||||
msgid "Cancel"
|
||||
msgstr "Скасаваць"
|
||||
|
||||
#: ../js/gdm/authPrompt.js:167 ../js/gdm/authPrompt.js:215
|
||||
#: ../js/gdm/authPrompt.js:168 ../js/gdm/authPrompt.js:216
|
||||
msgid "Next"
|
||||
msgstr "Далей"
|
||||
|
||||
#: ../js/gdm/authPrompt.js:211 ../js/ui/shellMountOperation.js:403
|
||||
#: ../js/gdm/authPrompt.js:212 ../js/ui/shellMountOperation.js:403
|
||||
#: ../js/ui/unlockDialog.js:59
|
||||
msgid "Unlock"
|
||||
msgstr "Разблакіраваць"
|
||||
|
||||
#: ../js/gdm/authPrompt.js:213
|
||||
#: ../js/gdm/authPrompt.js:214
|
||||
msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Увайсці"
|
||||
@ -316,23 +316,23 @@ msgstr "Імя карыстальніка: "
|
||||
msgid "Login Window"
|
||||
msgstr "Акно ўваходу"
|
||||
|
||||
#: ../js/gdm/util.js:306
|
||||
#: ../js/gdm/util.js:321
|
||||
msgid "Authentication error"
|
||||
msgstr "Памылка ідэнтыфікацыі"
|
||||
|
||||
#: ../js/gdm/util.js:436
|
||||
#: ../js/gdm/util.js:451
|
||||
msgid "(or swipe finger)"
|
||||
msgstr "(або правядзіце пальцам)"
|
||||
|
||||
#: ../js/misc/util.js:98
|
||||
#: ../js/misc/util.js:115
|
||||
msgid "Command not found"
|
||||
msgstr "Загад не знойдзены"
|
||||
|
||||
#: ../js/misc/util.js:131
|
||||
#: ../js/misc/util.js:148
|
||||
msgid "Could not parse command:"
|
||||
msgstr "Не ўдалося разабраць загад:"
|
||||
|
||||
#: ../js/misc/util.js:139
|
||||
#: ../js/misc/util.js:156
|
||||
#, javascript-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Не ўдалося выканаць \"%s\":"
|
||||
@ -349,15 +349,15 @@ msgstr "Часта"
|
||||
msgid "All"
|
||||
msgstr "Усе"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1514
|
||||
#: ../js/ui/appDisplay.js:1523
|
||||
msgid "New Window"
|
||||
msgstr "Новае акно"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1517 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:1526 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Выдаліць са спіса ўпадабанага"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1518
|
||||
#: ../js/ui/appDisplay.js:1527
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Дадаць у спіс упадабанага"
|
||||
|
||||
@ -371,7 +371,7 @@ msgstr "%s дададзены ў ваш спіс упадабанага."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s выдалены з вашага спіса ўпадабанага."
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/panel.js:808
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/panel.js:806
|
||||
#: ../js/ui/status/system.js:325
|
||||
msgid "Settings"
|
||||
msgstr "Настройкі"
|
||||
@ -562,16 +562,16 @@ msgstr "Адкрыць у %s"
|
||||
msgid "Eject"
|
||||
msgstr "Выняць"
|
||||
|
||||
#: ../js/ui/components/keyring.js:91 ../js/ui/components/polkitAgent.js:280
|
||||
#: ../js/ui/components/keyring.js:89 ../js/ui/components/polkitAgent.js:280
|
||||
msgid "Password:"
|
||||
msgstr "Пароль:"
|
||||
|
||||
#: ../js/ui/components/keyring.js:110
|
||||
#: ../js/ui/components/keyring.js:108
|
||||
msgid "Type again:"
|
||||
msgstr "Паўтарыце пароль:"
|
||||
|
||||
#: ../js/ui/components/networkAgent.js:131 ../js/ui/status/network.js:112
|
||||
#: ../js/ui/status/network.js:275 ../js/ui/status/network.js:695
|
||||
#: ../js/ui/components/networkAgent.js:131 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:295 ../js/ui/status/network.js:742
|
||||
msgid "Connect"
|
||||
msgstr "Злучыць"
|
||||
|
||||
@ -667,60 +667,60 @@ msgstr "Ідэнтыфікаваць"
|
||||
msgid "Sorry, that didn't work. Please try again."
|
||||
msgstr "На жаль, ідэнтыфікацыя не адбылася. Паўтарыце спробу."
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:238
|
||||
#: ../js/ui/components/telepathyClient.js:237
|
||||
msgid "Invitation"
|
||||
msgstr "Запрашэнне"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:298
|
||||
#: ../js/ui/components/telepathyClient.js:297
|
||||
msgid "Call"
|
||||
msgstr "Званок"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:314
|
||||
#: ../js/ui/components/telepathyClient.js:313
|
||||
msgid "File Transfer"
|
||||
msgstr "Перадача файла"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:418
|
||||
#: ../js/ui/components/telepathyClient.js:417
|
||||
msgid "Chat"
|
||||
msgstr "Чат"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Unmute"
|
||||
msgstr "Вярнуць гук"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Mute"
|
||||
msgstr "Абязгучыць"
|
||||
|
||||
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"*/
|
||||
#: ../js/ui/components/telepathyClient.js:942
|
||||
#: ../js/ui/components/telepathyClient.js:941
|
||||
msgid "<b>Yesterday</b>, <b>%H:%M</b>"
|
||||
msgstr "<b>Учора</b>, <b>%H:%M</b>"
|
||||
|
||||
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30*/
|
||||
#: ../js/ui/components/telepathyClient.js:948
|
||||
#: ../js/ui/components/telepathyClient.js:947
|
||||
msgid "<b>%A</b>, <b>%H:%M</b>"
|
||||
msgstr "<b>%A</b>, <b>%H:%M</b>"
|
||||
|
||||
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"*/
|
||||
#: ../js/ui/components/telepathyClient.js:953
|
||||
#: ../js/ui/components/telepathyClient.js:952
|
||||
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
|
||||
msgstr "<b>%d</b> <b>%B</b>, <b>%H:%M</b>"
|
||||
|
||||
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"*/
|
||||
#: ../js/ui/components/telepathyClient.js:957
|
||||
#: ../js/ui/components/telepathyClient.js:956
|
||||
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
|
||||
msgstr "<b>%d</b> <b>%B</b> <b>%Y</b>, <b>%H:%M</b> "
|
||||
|
||||
#. Translators: this is the other person changing their old IM name to their new
|
||||
#. IM name. */
|
||||
#: ../js/ui/components/telepathyClient.js:986
|
||||
#: ../js/ui/components/telepathyClient.js:985
|
||||
#, javascript-format
|
||||
msgid "%s is now known as %s"
|
||||
msgstr "%s змяніў імя на %s"
|
||||
|
||||
#. translators: argument is a room name like
|
||||
#. * room@jabber.org for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1089
|
||||
#: ../js/ui/components/telepathyClient.js:1088
|
||||
#, javascript-format
|
||||
msgid "Invitation to %s"
|
||||
msgstr "Запрашэнне ў %s"
|
||||
@ -728,38 +728,38 @@ msgstr "Запрашэнне ў %s"
|
||||
#. 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
|
||||
#. * for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1097
|
||||
#: ../js/ui/components/telepathyClient.js:1096
|
||||
#, javascript-format
|
||||
msgid "%s is inviting you to join %s"
|
||||
msgstr "Удзельнік %s запрашае вас далучыцца да %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1140
|
||||
#: ../js/ui/components/telepathyClient.js:1180
|
||||
#: ../js/ui/components/telepathyClient.js:1243
|
||||
#: ../js/ui/components/telepathyClient.js:1098
|
||||
#: ../js/ui/components/telepathyClient.js:1139
|
||||
#: ../js/ui/components/telepathyClient.js:1179
|
||||
#: ../js/ui/components/telepathyClient.js:1242
|
||||
msgid "Decline"
|
||||
msgstr "Адмовіцца"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1100
|
||||
#: ../js/ui/components/telepathyClient.js:1181
|
||||
#: ../js/ui/components/telepathyClient.js:1244
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1180
|
||||
#: ../js/ui/components/telepathyClient.js:1243
|
||||
msgid "Accept"
|
||||
msgstr "Прыняць"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1130
|
||||
#: ../js/ui/components/telepathyClient.js:1129
|
||||
#, javascript-format
|
||||
msgid "Video call from %s"
|
||||
msgstr "Відэазванок ад %s"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1133
|
||||
#: ../js/ui/components/telepathyClient.js:1132
|
||||
#, javascript-format
|
||||
msgid "Call from %s"
|
||||
msgstr "Званок ад %s"
|
||||
|
||||
#. translators: this is a button label (verb), not a noun */
|
||||
#: ../js/ui/components/telepathyClient.js:1142
|
||||
#: ../js/ui/components/telepathyClient.js:1141
|
||||
msgid "Answer"
|
||||
msgstr "Адказаць"
|
||||
|
||||
@ -768,108 +768,108 @@ msgstr "Адказаць"
|
||||
#. * file name. The string will be something
|
||||
#. * like: "Alice is sending you test.ogg"
|
||||
#. */
|
||||
#: ../js/ui/components/telepathyClient.js:1174
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
#, javascript-format
|
||||
msgid "%s is sending you %s"
|
||||
msgstr "%s пасылае вам %s"
|
||||
|
||||
#. To translators: The parameter is the contact's alias */
|
||||
#: ../js/ui/components/telepathyClient.js:1209
|
||||
#: ../js/ui/components/telepathyClient.js:1208
|
||||
#, javascript-format
|
||||
msgid "%s would like permission to see when you are online"
|
||||
msgstr "%s просіць дазволу на прагляд вашага сеткавага стану"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1301
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
msgid "Network error"
|
||||
msgstr "Сеткавая памылка"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1303
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
msgid "Authentication failed"
|
||||
msgstr "Няўдалая ідэнтыфікацыя"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1305
|
||||
#: ../js/ui/components/telepathyClient.js:1304
|
||||
msgid "Encryption error"
|
||||
msgstr "Памылка шыфравання"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1307
|
||||
#: ../js/ui/components/telepathyClient.js:1306
|
||||
msgid "Certificate not provided"
|
||||
msgstr "Сертыфікат не пададзены"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1309
|
||||
#: ../js/ui/components/telepathyClient.js:1308
|
||||
msgid "Certificate untrusted"
|
||||
msgstr "Сертыфікат не заслугоўвае даверу"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1311
|
||||
#: ../js/ui/components/telepathyClient.js:1310
|
||||
msgid "Certificate expired"
|
||||
msgstr "Сертыфікат састарэў"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1313
|
||||
#: ../js/ui/components/telepathyClient.js:1312
|
||||
msgid "Certificate not activated"
|
||||
msgstr "Сертыфікат не актывізаваны"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1315
|
||||
#: ../js/ui/components/telepathyClient.js:1314
|
||||
msgid "Certificate hostname mismatch"
|
||||
msgstr "Назва камп'ютара ў сертыфікаце не адпавядае патрэбнай"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1317
|
||||
#: ../js/ui/components/telepathyClient.js:1316
|
||||
msgid "Certificate fingerprint mismatch"
|
||||
msgstr "Адбітак сертыфіката не адпавядае патрэбнаму"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1319
|
||||
#: ../js/ui/components/telepathyClient.js:1318
|
||||
msgid "Certificate self-signed"
|
||||
msgstr "Сертыфікат уласнаручна падпісаны"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1321
|
||||
#: ../js/ui/components/telepathyClient.js:1320
|
||||
msgid "Status is set to offline"
|
||||
msgstr "Уключаны рэжым па-за сеткай"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1323
|
||||
#: ../js/ui/components/telepathyClient.js:1322
|
||||
msgid "Encryption is not available"
|
||||
msgstr "Шыфраванне недаступнае"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1325
|
||||
#: ../js/ui/components/telepathyClient.js:1324
|
||||
msgid "Certificate is invalid"
|
||||
msgstr "Хібны сертыфікат"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1327
|
||||
#: ../js/ui/components/telepathyClient.js:1326
|
||||
msgid "Connection has been refused"
|
||||
msgstr "Адмоўлена ў злучэнні"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1329
|
||||
#: ../js/ui/components/telepathyClient.js:1328
|
||||
msgid "Connection can't be established"
|
||||
msgstr "Не ўдалося ўсталяваць злучэнне"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1331
|
||||
#: ../js/ui/components/telepathyClient.js:1330
|
||||
msgid "Connection has been lost"
|
||||
msgstr "Злучэнне страчана"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1333
|
||||
#: ../js/ui/components/telepathyClient.js:1332
|
||||
msgid "This account is already connected to the server"
|
||||
msgstr "Гэты конт ужо злучаны з серверам"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1335
|
||||
#: ../js/ui/components/telepathyClient.js:1334
|
||||
msgid ""
|
||||
"Connection has been replaced by a new connection using the same resource"
|
||||
msgstr "Злучэнне заменена новым для таго ж самага рэсурсу"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1337
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
msgid "The account already exists on the server"
|
||||
msgstr "Такі конт ужо існуе на серверы"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1339
|
||||
#: ../js/ui/components/telepathyClient.js:1338
|
||||
msgid "Server is currently too busy to handle the connection"
|
||||
msgstr "Сервер надта заняты і не можа абслужыць гэта злучэнне"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1341
|
||||
#: ../js/ui/components/telepathyClient.js:1340
|
||||
msgid "Certificate has been revoked"
|
||||
msgstr "Сертыфікат быў адкліканы"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1343
|
||||
#: ../js/ui/components/telepathyClient.js:1342
|
||||
msgid ""
|
||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||
msgstr "Для сертыфіката выкарыстаны слабы або небяспечны алгарытм шыфравання"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1345
|
||||
#: ../js/ui/components/telepathyClient.js:1344
|
||||
msgid ""
|
||||
"The length of the server certificate, or the depth of the server certificate "
|
||||
"chain, exceed the limits imposed by the cryptography library"
|
||||
@ -877,22 +877,22 @@ msgstr ""
|
||||
"Даўжыня сертыфіката сервера або глыбіня яго ланцуга перавышае абмежаванне, "
|
||||
"выстаўленае крыптаграфічнай бібліятэкай"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1347
|
||||
#: ../js/ui/components/telepathyClient.js:1346
|
||||
msgid "Internal error"
|
||||
msgstr "Унутраная памылка"
|
||||
|
||||
#. translators: argument is the account name, like
|
||||
#. * name@jabber.org for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1357
|
||||
#: ../js/ui/components/telepathyClient.js:1356
|
||||
#, javascript-format
|
||||
msgid "Unable to connect to %s"
|
||||
msgstr "Не ўдалося злучыцца з %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1362
|
||||
#: ../js/ui/components/telepathyClient.js:1361
|
||||
msgid "View account"
|
||||
msgstr "Праглядзець конт"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1401
|
||||
#: ../js/ui/components/telepathyClient.js:1400
|
||||
msgid "Unknown reason"
|
||||
msgstr "Невядомая прычына"
|
||||
|
||||
@ -1072,9 +1072,12 @@ msgstr "Паказваць памылкі"
|
||||
msgid "Enabled"
|
||||
msgstr "Уключана"
|
||||
|
||||
#. Translators: this is for a network device that cannot be activated
|
||||
#. because it's disabled by rfkill (airplane mode) */
|
||||
#. translators:
|
||||
#. * The device has been disabled
|
||||
#: ../js/ui/lookingGlass.js:765 ../src/gvc/gvc-mixer-control.c:1830
|
||||
#: ../js/ui/lookingGlass.js:765 ../js/ui/status/network.js:472
|
||||
#: ../src/gvc/gvc-mixer-control.c:1830
|
||||
msgid "Disabled"
|
||||
msgstr "Выключана"
|
||||
|
||||
@ -1098,44 +1101,48 @@ msgstr "Паглядзець выточны код"
|
||||
msgid "Web Page"
|
||||
msgstr "Сеціўная старонка"
|
||||
|
||||
#: ../js/ui/messageTray.js:1222
|
||||
#: ../js/ui/messageTray.js:1347
|
||||
msgid "Open"
|
||||
msgstr "Адкрыць"
|
||||
|
||||
#: ../js/ui/messageTray.js:1229
|
||||
#: ../js/ui/messageTray.js:1354
|
||||
msgid "Remove"
|
||||
msgstr "Выдаліць"
|
||||
|
||||
#: ../js/ui/messageTray.js:1513
|
||||
#: ../js/ui/messageTray.js:1657
|
||||
msgid "Notifications"
|
||||
msgstr "Апавяшчэнні"
|
||||
|
||||
#: ../js/ui/messageTray.js:1664
|
||||
msgid "Clear Messages"
|
||||
msgstr "Ачысціць спіс апавяшчэнняў"
|
||||
|
||||
#: ../js/ui/messageTray.js:1540
|
||||
#: ../js/ui/messageTray.js:1683
|
||||
msgid "Notification Settings"
|
||||
msgstr "Настройкі апавяшчэння"
|
||||
|
||||
#: ../js/ui/messageTray.js:1559
|
||||
#: ../js/ui/messageTray.js:1736
|
||||
msgid "Tray Menu"
|
||||
msgstr "Меню трэя"
|
||||
|
||||
#: ../js/ui/messageTray.js:1775
|
||||
#: ../js/ui/messageTray.js:1952
|
||||
msgid "No Messages"
|
||||
msgstr "Апавяшчэнні адсутнічаюць"
|
||||
|
||||
#: ../js/ui/messageTray.js:1813
|
||||
#: ../js/ui/messageTray.js:1990
|
||||
msgid "Message Tray"
|
||||
msgstr "Абшар апавяшчэнняў"
|
||||
|
||||
#: ../js/ui/messageTray.js:2788
|
||||
#: ../js/ui/messageTray.js:2965
|
||||
msgid "System Information"
|
||||
msgstr "Сістэмная інфармацыя"
|
||||
|
||||
#: ../js/ui/notificationDaemon.js:629 ../src/shell-app.c:396
|
||||
#: ../js/ui/notificationDaemon.js:510 ../src/shell-app.c:396
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Невядомая"
|
||||
|
||||
#: ../js/ui/overviewControls.js:491 ../js/ui/screenShield.js:152
|
||||
#: ../js/ui/overviewControls.js:488 ../js/ui/screenShield.js:153
|
||||
#, javascript-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
@ -1159,21 +1166,21 @@ msgstr "Агляд"
|
||||
msgid "Type to search…"
|
||||
msgstr "Увядзіце тэкст для пошуку..."
|
||||
|
||||
#: ../js/ui/panel.js:518
|
||||
#: ../js/ui/panel.js:516
|
||||
msgid "Quit"
|
||||
msgstr "Выйсці"
|
||||
|
||||
#. Translators: If there is no suitable word for "Activities"
|
||||
#. in your language, you can use the word for "Overview". */
|
||||
#: ../js/ui/panel.js:570
|
||||
#: ../js/ui/panel.js:568
|
||||
msgid "Activities"
|
||||
msgstr "Заняткі"
|
||||
|
||||
#: ../js/ui/panel.js:904
|
||||
#: ../js/ui/panel.js:900
|
||||
msgid "Top Bar"
|
||||
msgstr "Верхняя панэль"
|
||||
|
||||
#: ../js/ui/popupMenu.js:233
|
||||
#: ../js/ui/popupMenu.js:260
|
||||
msgid "toggle-switch-us"
|
||||
msgstr "toggle-switch-intl"
|
||||
|
||||
@ -1187,11 +1194,11 @@ msgstr "Закрыць"
|
||||
|
||||
#. Translators: This is a time format for a date in
|
||||
#. long format */
|
||||
#: ../js/ui/screenShield.js:88
|
||||
#: ../js/ui/screenShield.js:89
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %d %B"
|
||||
|
||||
#: ../js/ui/screenShield.js:154
|
||||
#: ../js/ui/screenShield.js:155
|
||||
#, javascript-format
|
||||
msgid "%d new notification"
|
||||
msgid_plural "%d new notifications"
|
||||
@ -1199,19 +1206,19 @@ msgstr[0] "%d новае апавяшчэнне"
|
||||
msgstr[1] "%d новыя апавяшчэнні"
|
||||
msgstr[2] "%d новых апавяшчэнняў"
|
||||
|
||||
#: ../js/ui/screenShield.js:477 ../js/ui/status/system.js:333
|
||||
#: ../js/ui/screenShield.js:478 ../js/ui/status/system.js:333
|
||||
msgid "Lock"
|
||||
msgstr "Заблакіраваць"
|
||||
|
||||
#: ../js/ui/screenShield.js:704
|
||||
#: ../js/ui/screenShield.js:712
|
||||
msgid "GNOME needs to lock the screen"
|
||||
msgstr "GNOME патрабуе блакіравання экрана"
|
||||
|
||||
#: ../js/ui/screenShield.js:831 ../js/ui/screenShield.js:1297
|
||||
#: ../js/ui/screenShield.js:839 ../js/ui/screenShield.js:1305
|
||||
msgid "Unable to lock"
|
||||
msgstr "Не ўдалося заблакіраваць"
|
||||
|
||||
#: ../js/ui/screenShield.js:832 ../js/ui/screenShield.js:1298
|
||||
#: ../js/ui/screenShield.js:840 ../js/ui/screenShield.js:1306
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Блакіраванне стрымана праграмай"
|
||||
|
||||
@ -1251,62 +1258,62 @@ msgstr "Запомніць пароль"
|
||||
msgid "Accessibility"
|
||||
msgstr "Даступнасць"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:58
|
||||
#: ../js/ui/status/accessibility.js:56
|
||||
msgid "Zoom"
|
||||
msgstr "Маштабаванне"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:65
|
||||
#: ../js/ui/status/accessibility.js:63
|
||||
msgid "Screen Reader"
|
||||
msgstr "Чытальнік з экрана"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:69
|
||||
#: ../js/ui/status/accessibility.js:67
|
||||
msgid "Screen Keyboard"
|
||||
msgstr "Экранная клавіятура"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:73
|
||||
#: ../js/ui/status/accessibility.js:71
|
||||
msgid "Visual Alerts"
|
||||
msgstr "Візуальныя сігналы"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:76
|
||||
#: ../js/ui/status/accessibility.js:74
|
||||
msgid "Sticky Keys"
|
||||
msgstr "Грузкія клавішы"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:79
|
||||
#: ../js/ui/status/accessibility.js:77
|
||||
msgid "Slow Keys"
|
||||
msgstr "Марудныя клавішы"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:82
|
||||
#: ../js/ui/status/accessibility.js:80
|
||||
msgid "Bounce Keys"
|
||||
msgstr "Рыкашэтныя клавішы"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:85
|
||||
#: ../js/ui/status/accessibility.js:83
|
||||
msgid "Mouse Keys"
|
||||
msgstr "Мышыныя клавішы"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:144
|
||||
#: ../js/ui/status/accessibility.js:142
|
||||
msgid "High Contrast"
|
||||
msgstr "Высокая кантраснасць"
|
||||
|
||||
#: ../js/ui/status/accessibility.js:193
|
||||
#: ../js/ui/status/accessibility.js:191
|
||||
msgid "Large Text"
|
||||
msgstr "Буйны тэкст"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:28 ../js/ui/status/bluetooth.js:63
|
||||
#: ../js/ui/status/bluetooth.js:100 ../js/ui/status/bluetooth.js:128
|
||||
#: ../js/ui/status/bluetooth.js:164 ../js/ui/status/bluetooth.js:195
|
||||
#: ../js/ui/status/bluetooth.js:27 ../js/ui/status/bluetooth.js:62
|
||||
#: ../js/ui/status/bluetooth.js:99 ../js/ui/status/bluetooth.js:127
|
||||
#: ../js/ui/status/bluetooth.js:163 ../js/ui/status/bluetooth.js:194
|
||||
msgid "Bluetooth"
|
||||
msgstr "Bluetooth"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:30 ../js/ui/status/network.js:112
|
||||
#: ../js/ui/status/network.js:1040 ../js/ui/status/rfkill.js:46
|
||||
#: ../js/ui/status/bluetooth.js:29 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:1099 ../js/ui/status/rfkill.js:46
|
||||
msgid "Turn Off"
|
||||
msgstr "Выключыць"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:33
|
||||
#: ../js/ui/status/bluetooth.js:32
|
||||
msgid "Bluetooth Settings"
|
||||
msgstr "Настройкі Bluetooth"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:58
|
||||
#: ../js/ui/status/bluetooth.js:57
|
||||
#, javascript-format
|
||||
msgid "%d Connected Device"
|
||||
msgid_plural "%d Connected Devices"
|
||||
@ -1314,73 +1321,73 @@ msgstr[0] "%d злучанае прыстасаванне"
|
||||
msgstr[1] "%d злучаныя прыстасаванні"
|
||||
msgstr[2] "%d злучаных прыстасаванняў"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:101 ../js/ui/status/bluetooth.js:129
|
||||
#: ../js/ui/status/bluetooth.js:100 ../js/ui/status/bluetooth.js:128
|
||||
#, javascript-format
|
||||
msgid "Authorization request from %s"
|
||||
msgstr "Запыт на ўпаўнаважанне ад %s"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:107 ../js/ui/status/bluetooth.js:172
|
||||
#: ../js/ui/status/bluetooth.js:203
|
||||
#: ../js/ui/status/bluetooth.js:106 ../js/ui/status/bluetooth.js:171
|
||||
#: ../js/ui/status/bluetooth.js:202
|
||||
#, javascript-format
|
||||
msgid "Device %s wants to pair with this computer"
|
||||
msgstr "Прыстасаванне %s хоча спарыцца з гэтым камп'ютарам"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:109
|
||||
#: ../js/ui/status/bluetooth.js:108
|
||||
msgid "Allow"
|
||||
msgstr "Дазволіць"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:110
|
||||
#: ../js/ui/status/bluetooth.js:109
|
||||
msgid "Deny"
|
||||
msgstr "Адмовіць"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:135
|
||||
#: ../js/ui/status/bluetooth.js:134
|
||||
#, javascript-format
|
||||
msgid "Device %s wants access to the service '%s'"
|
||||
msgstr "Прыстасаванне %s хоча даступіцца да паслугі \"%s\""
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:137
|
||||
#: ../js/ui/status/bluetooth.js:136
|
||||
msgid "Always grant access"
|
||||
msgstr "Заўсёды даваць дазвол"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:138
|
||||
#: ../js/ui/status/bluetooth.js:137
|
||||
msgid "Grant this time only"
|
||||
msgstr "Даць дазвол аднойчы"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:139
|
||||
#: ../js/ui/status/bluetooth.js:138
|
||||
msgid "Reject"
|
||||
msgstr "Адмовіць"
|
||||
|
||||
#. Translators: argument is the device short name */
|
||||
#: ../js/ui/status/bluetooth.js:166
|
||||
#: ../js/ui/status/bluetooth.js:165
|
||||
#, javascript-format
|
||||
msgid "Pairing confirmation for %s"
|
||||
msgstr "Пацвярджэнне спарвання з %s"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:173
|
||||
#: ../js/ui/status/bluetooth.js:172
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Please confirm whether the Passkey '%06d' matches the one on the device."
|
||||
msgstr "Праверце, ці супадае пароль \"%06d\" з нумарам на прыстасаванні."
|
||||
|
||||
#. Translators: this is the verb, not the noun */
|
||||
#: ../js/ui/status/bluetooth.js:176
|
||||
#: ../js/ui/status/bluetooth.js:175
|
||||
msgid "Matches"
|
||||
msgstr "Супадае"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:177
|
||||
#: ../js/ui/status/bluetooth.js:176
|
||||
msgid "Does not match"
|
||||
msgstr "Не супадае"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:196
|
||||
#: ../js/ui/status/bluetooth.js:195
|
||||
#, javascript-format
|
||||
msgid "Pairing request for %s"
|
||||
msgstr "Запыт на спарванне з %s"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:204
|
||||
#: ../js/ui/status/bluetooth.js:203
|
||||
msgid "Please enter the PIN mentioned on the device."
|
||||
msgstr "Увядзіце PIN, які паказвае прыстасаванне."
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:221
|
||||
#: ../js/ui/status/bluetooth.js:220
|
||||
msgid "OK"
|
||||
msgstr "Добра"
|
||||
|
||||
@ -1388,87 +1395,99 @@ msgstr "Добра"
|
||||
msgid "Brightness"
|
||||
msgstr "Яркасць"
|
||||
|
||||
#: ../js/ui/status/network.js:72
|
||||
#: ../js/ui/status/network.js:71
|
||||
msgid "<unknown>"
|
||||
msgstr "<невядома>"
|
||||
|
||||
#: ../js/ui/status/network.js:203 ../js/ui/status/network.js:1055
|
||||
#: ../js/ui/status/network.js:222 ../js/ui/status/network.js:379
|
||||
#: ../js/ui/status/network.js:1120
|
||||
msgid "Off"
|
||||
msgstr "Выключана"
|
||||
|
||||
#: ../js/ui/status/network.js:276 ../js/ui/status/network.js:961
|
||||
#: ../js/ui/status/rfkill.js:49
|
||||
msgid "Network Settings"
|
||||
msgstr "Сеткавыя настройкі"
|
||||
|
||||
#. Translators: this is for network devices that are physically present but are not
|
||||
#. under NetworkManager's control (and thus cannot be used in the menu) */
|
||||
#: ../js/ui/status/network.js:364
|
||||
#: ../js/ui/status/network.js:385
|
||||
msgid "unmanaged"
|
||||
msgstr "непадкантрольна"
|
||||
|
||||
#: ../js/ui/status/network.js:366
|
||||
#: ../js/ui/status/network.js:387
|
||||
msgid "disconnecting..."
|
||||
msgstr "адлучэнне..."
|
||||
|
||||
#: ../js/ui/status/network.js:372 ../js/ui/status/network.js:1106
|
||||
#: ../js/ui/status/network.js:393 ../js/ui/status/network.js:1174
|
||||
msgid "connecting..."
|
||||
msgstr "усталяванне злучэння..."
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password */
|
||||
#: ../js/ui/status/network.js:375 ../js/ui/status/network.js:1109
|
||||
#: ../js/ui/status/network.js:396 ../js/ui/status/network.js:1177
|
||||
msgid "authentication required"
|
||||
msgstr "патрэбная ідэнтыфікацыя"
|
||||
|
||||
#. Translators: this is for devices that require some kind of firmware or kernel
|
||||
#. module, which is missing */
|
||||
#: ../js/ui/status/network.js:383
|
||||
#: ../js/ui/status/network.js:404
|
||||
msgid "firmware missing"
|
||||
msgstr "няма апаратнага апраграмавання"
|
||||
|
||||
#. Translators: this is for a network device that cannot be activated (for example it
|
||||
#. is disabled by rfkill, or it has no coverage */
|
||||
#: ../js/ui/status/network.js:387
|
||||
#: ../js/ui/status/network.js:408
|
||||
msgid "unavailable"
|
||||
msgstr "недаступна"
|
||||
|
||||
#: ../js/ui/status/network.js:389 ../js/ui/status/network.js:1111
|
||||
#: ../js/ui/status/network.js:410 ../js/ui/status/network.js:1179
|
||||
msgid "connection failed"
|
||||
msgstr "не ўдалося злучыцца"
|
||||
|
||||
#: ../js/ui/status/network.js:660
|
||||
#: ../js/ui/status/network.js:426 ../js/ui/status/network.js:512
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "Настройкі шырокапалоснай мабільнай сеткі"
|
||||
|
||||
#: ../js/ui/status/network.js:468 ../js/ui/status/network.js:1118
|
||||
msgid "Hardware Disabled"
|
||||
msgstr "Апаратура выключана"
|
||||
|
||||
#: ../js/ui/status/network.js:707
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Сеткі Wi-Fi"
|
||||
|
||||
#: ../js/ui/status/network.js:662
|
||||
#: ../js/ui/status/network.js:709
|
||||
msgid "Select a network"
|
||||
msgstr "Выберыце сетку"
|
||||
|
||||
#: ../js/ui/status/network.js:686
|
||||
#: ../js/ui/status/network.js:733
|
||||
msgid "No Networks"
|
||||
msgstr "Няма сетак"
|
||||
|
||||
#: ../js/ui/status/network.js:955
|
||||
#: ../js/ui/status/network.js:1005
|
||||
msgid "Select Network"
|
||||
msgstr "Выбраць сетку"
|
||||
|
||||
#: ../js/ui/status/network.js:1040
|
||||
#: ../js/ui/status/network.js:1011
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Настройкі Wi-Fi"
|
||||
|
||||
#: ../js/ui/status/network.js:1099
|
||||
msgid "Turn On"
|
||||
msgstr "Уключыць"
|
||||
|
||||
#: ../js/ui/status/network.js:1174
|
||||
#: ../js/ui/status/network.js:1122
|
||||
msgid "Not Connected"
|
||||
msgstr "Няма злучэння"
|
||||
|
||||
#: ../js/ui/status/network.js:1242
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: ../js/ui/status/network.js:1314
|
||||
#: ../js/ui/status/network.js:1382
|
||||
msgid "Network Manager"
|
||||
msgstr "Сеткавы кіраўнік"
|
||||
|
||||
#: ../js/ui/status/network.js:1353
|
||||
#: ../js/ui/status/network.js:1421
|
||||
msgid "Connection failed"
|
||||
msgstr "Не ўдалося злучыцца"
|
||||
|
||||
#: ../js/ui/status/network.js:1354
|
||||
#: ../js/ui/status/network.js:1422
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Не ўдалося ўключыць сеткавае злучэнне"
|
||||
|
||||
@ -1506,6 +1525,10 @@ msgstr "Рэжым самалёта"
|
||||
msgid "On"
|
||||
msgstr "Укл."
|
||||
|
||||
#: ../js/ui/status/rfkill.js:49
|
||||
msgid "Network Settings"
|
||||
msgstr "Сеткавыя настройкі"
|
||||
|
||||
#: ../js/ui/status/system.js:305
|
||||
msgid "Switch User"
|
||||
msgstr "Перамяніць карыстальніка"
|
||||
@ -1656,4 +1679,3 @@ msgstr "Пароль не можа быць пустым"
|
||||
#: ../src/shell-polkit-authentication-agent.c:343
|
||||
msgid "Authentication dialog was dismissed by the user"
|
||||
msgstr "Карыстальнік праігнараваў дыялогавае акенца ідэнтыфікацыі"
|
||||
|
||||
|
352
po/nb.po
352
po/nb.po
@ -6,10 +6,10 @@
|
||||
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell 3.11.x\n"
|
||||
"Project-Id-Version: gnome-shell 3.10.x\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-11-03 16:01+0100\n"
|
||||
"PO-Revision-Date: 2013-11-03 16:03+0100\n"
|
||||
"POT-Creation-Date: 2013-10-20 13:05+0200\n"
|
||||
"PO-Revision-Date: 2013-10-26 15:17+0200\n"
|
||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
||||
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
||||
"Language: \n"
|
||||
@ -52,7 +52,6 @@ msgid "Window management and application launching"
|
||||
msgstr "Vindushåndtering og oppstart av programmer"
|
||||
|
||||
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
||||
#: ../js/extensionPrefs/main.js:155
|
||||
msgid "GNOME Shell Extension Preferences"
|
||||
msgstr "Brukervalg for GNOME Shell utvidelser"
|
||||
|
||||
@ -252,23 +251,14 @@ msgstr "Arbeidsområder vises kun på hovedskjerm"
|
||||
msgid "Delay focus changes in mouse mode until the pointer stops moving"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/extensionPrefs/main.js:127
|
||||
#, javascript-format
|
||||
msgid "There was an error loading the preferences dialog for %s:"
|
||||
msgstr "Det oppsto en feil ved lasting av brukervalgdialog for %s:"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:167
|
||||
msgid "Extension"
|
||||
msgstr "Utvidelse"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:191
|
||||
#: ../js/extensionPrefs/main.js:189
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
|
||||
|
||||
#: ../js/gdm/authPrompt.js:146 ../js/ui/components/networkAgent.js:136
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:357
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:351
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:726
|
||||
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:739
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
@ -286,25 +276,25 @@ msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Logg inn"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:272
|
||||
#: ../js/gdm/loginDialog.js:294
|
||||
msgid "Choose Session"
|
||||
msgstr "Velg økt"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:432
|
||||
#: ../js/gdm/loginDialog.js:454
|
||||
msgid "Not listed?"
|
||||
msgstr "Ikke listet?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:600
|
||||
#: ../js/gdm/loginDialog.js:622
|
||||
#, javascript-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(f.eks. bruker eller %s)"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:605 ../js/ui/components/networkAgent.js:259
|
||||
#: ../js/gdm/loginDialog.js:627 ../js/ui/components/networkAgent.js:259
|
||||
#: ../js/ui/components/networkAgent.js:277
|
||||
msgid "Username: "
|
||||
msgstr "Brukernavn: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:869
|
||||
#: ../js/gdm/loginDialog.js:891
|
||||
msgid "Login Window"
|
||||
msgstr "Innloggingsvindu"
|
||||
|
||||
@ -333,23 +323,23 @@ msgstr "Kjøring av «%s» feilet:"
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "Ofte brukte programmer vil vises her"
|
||||
|
||||
#: ../js/ui/appDisplay.js:715
|
||||
#: ../js/ui/appDisplay.js:712
|
||||
msgid "Frequent"
|
||||
msgstr "Ofte"
|
||||
|
||||
#: ../js/ui/appDisplay.js:722
|
||||
#: ../js/ui/appDisplay.js:719
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1526
|
||||
#: ../js/ui/appDisplay.js:1523
|
||||
msgid "New Window"
|
||||
msgstr "Nytt vindu"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1529 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:1526 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Fjern fra favoritter"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1530
|
||||
#: ../js/ui/appDisplay.js:1527
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Legg til i favoritter"
|
||||
|
||||
@ -364,7 +354,7 @@ msgid "%s has been removed from your favorites."
|
||||
msgstr "%s ble fjernet fra dine favoritter."
|
||||
|
||||
#: ../js/ui/backgroundMenu.js:19 ../js/ui/panel.js:806
|
||||
#: ../js/ui/status/system.js:334
|
||||
#: ../js/ui/status/system.js:325
|
||||
msgid "Settings"
|
||||
msgstr "Innstillinger"
|
||||
|
||||
@ -488,48 +478,48 @@ msgctxt "list saturday"
|
||||
msgid "S"
|
||||
msgstr "Lø"
|
||||
|
||||
#: ../js/ui/calendar.js:391
|
||||
#: ../js/ui/calendar.js:389
|
||||
msgid "calendar:MY"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/calendar.js:449
|
||||
#: ../js/ui/calendar.js:447
|
||||
msgid "Previous month"
|
||||
msgstr "Forrige måned"
|
||||
|
||||
#: ../js/ui/calendar.js:459
|
||||
#: ../js/ui/calendar.js:457
|
||||
msgid "Next month"
|
||||
msgstr "Neste måned"
|
||||
|
||||
#. Translators: Text to show if there are no events */
|
||||
#: ../js/ui/calendar.js:755
|
||||
#: ../js/ui/calendar.js:753
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "Ingenting planlagt"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year */
|
||||
#: ../js/ui/calendar.js:773
|
||||
#: ../js/ui/calendar.js:771
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A %B %d"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year */
|
||||
#: ../js/ui/calendar.js:776
|
||||
#: ../js/ui/calendar.js:774
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%A %B %d, %Y"
|
||||
|
||||
#: ../js/ui/calendar.js:787
|
||||
#: ../js/ui/calendar.js:785
|
||||
msgid "Today"
|
||||
msgstr "I dag"
|
||||
|
||||
#: ../js/ui/calendar.js:791
|
||||
#: ../js/ui/calendar.js:789
|
||||
msgid "Tomorrow"
|
||||
msgstr "I morgen"
|
||||
|
||||
#: ../js/ui/calendar.js:802
|
||||
#: ../js/ui/calendar.js:800
|
||||
msgid "This week"
|
||||
msgstr "Denne uken"
|
||||
|
||||
#: ../js/ui/calendar.js:810
|
||||
#: ../js/ui/calendar.js:808
|
||||
msgid "Next week"
|
||||
msgstr "Neste uke"
|
||||
|
||||
@ -541,16 +531,16 @@ msgstr "Ekstern stasjon koblet til"
|
||||
msgid "External drive disconnected"
|
||||
msgstr "Ekstern stasjon koblet fra"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:296
|
||||
#: ../js/ui/components/autorunManager.js:294
|
||||
msgid "Removable Devices"
|
||||
msgstr "Avtagbare enheter"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:596
|
||||
#: ../js/ui/components/autorunManager.js:594
|
||||
#, javascript-format
|
||||
msgid "Open with %s"
|
||||
msgstr "Åpne med %s"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:622
|
||||
#: ../js/ui/components/autorunManager.js:620
|
||||
msgid "Eject"
|
||||
msgstr "Løs ut"
|
||||
|
||||
@ -563,7 +553,7 @@ msgid "Type again:"
|
||||
msgstr "Skriv på nytt:"
|
||||
|
||||
#: ../js/ui/components/networkAgent.js:131 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:295 ../js/ui/status/network.js:729
|
||||
#: ../js/ui/status/network.js:295 ../js/ui/status/network.js:742
|
||||
msgid "Connect"
|
||||
msgstr "Koble til"
|
||||
|
||||
@ -673,11 +663,11 @@ msgstr "Filoverføring"
|
||||
msgid "Chat"
|
||||
msgstr "Prat"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Unmute"
|
||||
msgstr "Fjern demping"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Mute"
|
||||
msgstr "Demp"
|
||||
|
||||
@ -724,32 +714,32 @@ msgid "%s is inviting you to join %s"
|
||||
msgstr "%s inviterer deg til å bli med i %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1098
|
||||
#: ../js/ui/components/telepathyClient.js:1133
|
||||
#: ../js/ui/components/telepathyClient.js:1167
|
||||
#: ../js/ui/components/telepathyClient.js:1224
|
||||
#: ../js/ui/components/telepathyClient.js:1139
|
||||
#: ../js/ui/components/telepathyClient.js:1179
|
||||
#: ../js/ui/components/telepathyClient.js:1242
|
||||
msgid "Decline"
|
||||
msgstr "Avslå"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1104
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
#: ../js/ui/components/telepathyClient.js:1229
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1180
|
||||
#: ../js/ui/components/telepathyClient.js:1243
|
||||
msgid "Accept"
|
||||
msgstr "Godta"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1123
|
||||
#: ../js/ui/components/telepathyClient.js:1129
|
||||
#, javascript-format
|
||||
msgid "Video call from %s"
|
||||
msgstr "Videosamtale fra %s"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1126
|
||||
#: ../js/ui/components/telepathyClient.js:1132
|
||||
#, javascript-format
|
||||
msgid "Call from %s"
|
||||
msgstr "Samtale fra %s"
|
||||
|
||||
#. translators: this is a button label (verb), not a noun */
|
||||
#: ../js/ui/components/telepathyClient.js:1140
|
||||
#: ../js/ui/components/telepathyClient.js:1141
|
||||
msgid "Answer"
|
||||
msgstr "Svar"
|
||||
|
||||
@ -758,110 +748,110 @@ msgstr "Svar"
|
||||
#. * file name. The string will be something
|
||||
#. * like: "Alice is sending you test.ogg"
|
||||
#. */
|
||||
#: ../js/ui/components/telepathyClient.js:1161
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
#, javascript-format
|
||||
msgid "%s is sending you %s"
|
||||
msgstr "%s sender deg %s"
|
||||
|
||||
#. To translators: The parameter is the contact's alias */
|
||||
#: ../js/ui/components/telepathyClient.js:1190
|
||||
#: ../js/ui/components/telepathyClient.js:1208
|
||||
#, javascript-format
|
||||
msgid "%s would like permission to see when you are online"
|
||||
msgstr "%s vil ha rettigheter til å se når du er tilkoblet"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1275
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
msgid "Network error"
|
||||
msgstr "Nettverksfeil"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1277
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
msgid "Authentication failed"
|
||||
msgstr "Autentisering feilet"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1279
|
||||
#: ../js/ui/components/telepathyClient.js:1304
|
||||
msgid "Encryption error"
|
||||
msgstr "Feil ved kryptering"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1281
|
||||
#: ../js/ui/components/telepathyClient.js:1306
|
||||
msgid "Certificate not provided"
|
||||
msgstr "Sertifikat ikke oppgitt"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1283
|
||||
#: ../js/ui/components/telepathyClient.js:1308
|
||||
msgid "Certificate untrusted"
|
||||
msgstr "Stoler ikke på sertifikatet"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1285
|
||||
#: ../js/ui/components/telepathyClient.js:1310
|
||||
msgid "Certificate expired"
|
||||
msgstr "Sertifikatet er utløpt"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1287
|
||||
#: ../js/ui/components/telepathyClient.js:1312
|
||||
msgid "Certificate not activated"
|
||||
msgstr "Sertifikatet er ikke aktivert"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1289
|
||||
#: ../js/ui/components/telepathyClient.js:1314
|
||||
msgid "Certificate hostname mismatch"
|
||||
msgstr "Feil vertsnavn for sertifikat"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1291
|
||||
#: ../js/ui/components/telepathyClient.js:1316
|
||||
msgid "Certificate fingerprint mismatch"
|
||||
msgstr "Feil fingeravtrykk for sertifikat"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1293
|
||||
#: ../js/ui/components/telepathyClient.js:1318
|
||||
msgid "Certificate self-signed"
|
||||
msgstr "Sertifikatet er selvsignert"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1295
|
||||
#: ../js/ui/components/telepathyClient.js:1320
|
||||
msgid "Status is set to offline"
|
||||
msgstr "Status er satt til frakoblet"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1297
|
||||
#: ../js/ui/components/telepathyClient.js:1322
|
||||
msgid "Encryption is not available"
|
||||
msgstr "Kryptering er ikke tilgjengelig"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1299
|
||||
#: ../js/ui/components/telepathyClient.js:1324
|
||||
msgid "Certificate is invalid"
|
||||
msgstr "Sertifikatet er ugyldig"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1301
|
||||
#: ../js/ui/components/telepathyClient.js:1326
|
||||
msgid "Connection has been refused"
|
||||
msgstr "Tilkobling ble nektet"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1303
|
||||
#: ../js/ui/components/telepathyClient.js:1328
|
||||
msgid "Connection can't be established"
|
||||
msgstr "Tilkobling kan ikke etableres"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1305
|
||||
#: ../js/ui/components/telepathyClient.js:1330
|
||||
msgid "Connection has been lost"
|
||||
msgstr "Tilkobling tapt"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1307
|
||||
#: ../js/ui/components/telepathyClient.js:1332
|
||||
msgid "This account is already connected to the server"
|
||||
msgstr "Denne kontoen er allerede koblet til tjeneren"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1309
|
||||
#: ../js/ui/components/telepathyClient.js:1334
|
||||
msgid ""
|
||||
"Connection has been replaced by a new connection using the same resource"
|
||||
msgstr ""
|
||||
"Tilkoblingen har blitt erstattet av en ny tilkobling som bruker samme ressurs"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1311
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
msgid "The account already exists on the server"
|
||||
msgstr "Kontoen eksisterer allerede på tjeneren"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1313
|
||||
#: ../js/ui/components/telepathyClient.js:1338
|
||||
msgid "Server is currently too busy to handle the connection"
|
||||
msgstr "Tjener er for opptatt til å håndtere tilkoblingen"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1315
|
||||
#: ../js/ui/components/telepathyClient.js:1340
|
||||
msgid "Certificate has been revoked"
|
||||
msgstr "Sertifikatet er tilbaketrukket"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1317
|
||||
#: ../js/ui/components/telepathyClient.js:1342
|
||||
msgid ""
|
||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||
msgstr ""
|
||||
"Sertifikatet bruker en usikker sifferalgoritme eller er krytografisk svakt"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1319
|
||||
#: ../js/ui/components/telepathyClient.js:1344
|
||||
msgid ""
|
||||
"The length of the server certificate, or the depth of the server certificate "
|
||||
"chain, exceed the limits imposed by the cryptography library"
|
||||
@ -869,26 +859,26 @@ msgstr ""
|
||||
"Lengden eller dybden på tjenersertifikatet oversteg grensen som er satt i "
|
||||
"kryptografibiblioteket"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1321
|
||||
#: ../js/ui/components/telepathyClient.js:1346
|
||||
msgid "Internal error"
|
||||
msgstr "Intern feil"
|
||||
|
||||
#. translators: argument is the account name, like
|
||||
#. * name@jabber.org for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1331
|
||||
#: ../js/ui/components/telepathyClient.js:1356
|
||||
#, javascript-format
|
||||
msgid "Unable to connect to %s"
|
||||
msgstr "Kan ikke koble til %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
#: ../js/ui/components/telepathyClient.js:1361
|
||||
msgid "View account"
|
||||
msgstr "Vis konto"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1368
|
||||
#: ../js/ui/components/telepathyClient.js:1400
|
||||
msgid "Unknown reason"
|
||||
msgstr "Ukjent årsak"
|
||||
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:95
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:100
|
||||
msgid "Windows"
|
||||
msgstr "Vinduer"
|
||||
|
||||
@ -919,76 +909,76 @@ msgstr "Innstillinger for dato og klokkeslett"
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%a %e %B, %Y"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:64
|
||||
#: ../js/ui/endSessionDialog.js:62
|
||||
#, javascript-format
|
||||
msgctxt "title"
|
||||
msgid "Log Out %s"
|
||||
msgstr "Logg ut %s"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:65
|
||||
#: ../js/ui/endSessionDialog.js:63
|
||||
msgctxt "title"
|
||||
msgid "Log Out"
|
||||
msgstr "Logg ut"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:67
|
||||
#: ../js/ui/endSessionDialog.js:65
|
||||
#, javascript-format
|
||||
msgid "%s will be logged out automatically in %d second."
|
||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||
msgstr[0] "%s vil bli logget ut automatisk om %d sekund."
|
||||
msgstr[1] "%s vil bli logget ut automatisk om %d sekunder."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:72
|
||||
#: ../js/ui/endSessionDialog.js:70
|
||||
#, javascript-format
|
||||
msgid "You will be logged out automatically in %d second."
|
||||
msgid_plural "You will be logged out automatically in %d seconds."
|
||||
msgstr[0] "Du vil bli logget ut automatisk om %d sekund."
|
||||
msgstr[1] "Du vil bli logget ut automatisk om %d sekunder."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:77
|
||||
#: ../js/ui/endSessionDialog.js:75
|
||||
msgctxt "button"
|
||||
msgid "Log Out"
|
||||
msgstr "Logg ut"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:83
|
||||
#: ../js/ui/endSessionDialog.js:81
|
||||
msgctxt "title"
|
||||
msgid "Power Off"
|
||||
msgstr "Slå av"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:85
|
||||
#: ../js/ui/endSessionDialog.js:83
|
||||
#, javascript-format
|
||||
msgid "The system will power off automatically in %d second."
|
||||
msgid_plural "The system will power off automatically in %d seconds."
|
||||
msgstr[0] "Systemet vil slås av automatisk om %d sekund."
|
||||
msgstr[1] "Systemet vil slås av automatisk om %d sekunder."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:106
|
||||
#: ../js/ui/endSessionDialog.js:88 ../js/ui/endSessionDialog.js:104
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Start på nytt"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:92
|
||||
#: ../js/ui/endSessionDialog.js:90
|
||||
msgctxt "button"
|
||||
msgid "Power Off"
|
||||
msgstr "Slå av"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:99
|
||||
#: ../js/ui/endSessionDialog.js:97
|
||||
msgctxt "title"
|
||||
msgid "Restart"
|
||||
msgstr "Start på nytt"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:101
|
||||
#: ../js/ui/endSessionDialog.js:99
|
||||
#, javascript-format
|
||||
msgid "The system will restart automatically in %d second."
|
||||
msgid_plural "The system will restart automatically in %d seconds."
|
||||
msgstr[0] "Systemet vil starte på nytt automatisk om %d sekund."
|
||||
msgstr[1] "Systemet vil starte på nytt automatisk om %d sekunder."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:114
|
||||
#: ../js/ui/endSessionDialog.js:112
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Updates"
|
||||
msgstr "Start på nytt og installer oppdateringer"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:116
|
||||
#: ../js/ui/endSessionDialog.js:114
|
||||
#, javascript-format
|
||||
msgid "The system will automatically restart and install updates in %d second."
|
||||
msgid_plural ""
|
||||
@ -1000,27 +990,27 @@ msgstr[1] ""
|
||||
"Systemet vil starte på nytt og installere oppdateringer automatisk om %d "
|
||||
"sekunder."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:121
|
||||
#: ../js/ui/endSessionDialog.js:119
|
||||
msgctxt "button"
|
||||
msgid "Restart & Install"
|
||||
msgstr "Start på nytt og installer"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:275
|
||||
#: ../js/ui/endSessionDialog.js:271
|
||||
msgid "Some applications are busy or have unsaved work."
|
||||
msgstr "Noen programmer er opptatt eller har arbeid som ikke er lagret."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:282
|
||||
#: ../js/ui/endSessionDialog.js:277
|
||||
msgid "Other users are logged in."
|
||||
msgstr "Andre brukere er logget inn."
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login */
|
||||
#: ../js/ui/endSessionDialog.js:485
|
||||
#: ../js/ui/endSessionDialog.js:479
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (ekstern)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console */
|
||||
#: ../js/ui/endSessionDialog.js:488
|
||||
#: ../js/ui/endSessionDialog.js:482
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (konsoll)"
|
||||
@ -1034,29 +1024,29 @@ msgstr "Installer"
|
||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||
msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
|
||||
|
||||
#: ../js/ui/keyboard.js:621 ../js/ui/status/keyboard.js:335
|
||||
#: ../js/ui/keyboard.js:619
|
||||
msgid "Keyboard"
|
||||
msgstr "Tastatur"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:640
|
||||
#: ../js/ui/lookingGlass.js:689
|
||||
msgid "No extensions installed"
|
||||
msgstr "Ingen utvidelser installert"
|
||||
|
||||
#. Translators: argument is an extension UUID. */
|
||||
#: ../js/ui/lookingGlass.js:694
|
||||
#: ../js/ui/lookingGlass.js:743
|
||||
#, javascript-format
|
||||
msgid "%s has not emitted any errors."
|
||||
msgstr "%s har ikke avgitt noen feil."
|
||||
|
||||
#: ../js/ui/lookingGlass.js:700
|
||||
#: ../js/ui/lookingGlass.js:749
|
||||
msgid "Hide Errors"
|
||||
msgstr "Skjul feil"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:704 ../js/ui/lookingGlass.js:764
|
||||
#: ../js/ui/lookingGlass.js:753 ../js/ui/lookingGlass.js:813
|
||||
msgid "Show Errors"
|
||||
msgstr "Vis feil"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:713
|
||||
#: ../js/ui/lookingGlass.js:762
|
||||
msgid "Enabled"
|
||||
msgstr "Aktivert"
|
||||
|
||||
@ -1064,73 +1054,73 @@ msgstr "Aktivert"
|
||||
#. because it's disabled by rfkill (airplane mode) */
|
||||
#. translators:
|
||||
#. * The device has been disabled
|
||||
#: ../js/ui/lookingGlass.js:716 ../js/ui/status/network.js:472
|
||||
#: ../js/ui/lookingGlass.js:765 ../js/ui/status/network.js:472
|
||||
#: ../src/gvc/gvc-mixer-control.c:1830
|
||||
msgid "Disabled"
|
||||
msgstr "Deaktivert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:718
|
||||
#: ../js/ui/lookingGlass.js:767
|
||||
msgid "Error"
|
||||
msgstr "Feil"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:720
|
||||
#: ../js/ui/lookingGlass.js:769
|
||||
msgid "Out of date"
|
||||
msgstr "Utdatert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:722
|
||||
#: ../js/ui/lookingGlass.js:771
|
||||
msgid "Downloading"
|
||||
msgstr "Laster ned"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:746
|
||||
#: ../js/ui/lookingGlass.js:795
|
||||
msgid "View Source"
|
||||
msgstr "Vis kildekode"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:755
|
||||
#: ../js/ui/lookingGlass.js:804
|
||||
msgid "Web Page"
|
||||
msgstr "Nettside"
|
||||
|
||||
#: ../js/ui/messageTray.js:1310
|
||||
#: ../js/ui/messageTray.js:1347
|
||||
msgid "Open"
|
||||
msgstr "Åpne"
|
||||
|
||||
#: ../js/ui/messageTray.js:1317
|
||||
#: ../js/ui/messageTray.js:1354
|
||||
msgid "Remove"
|
||||
msgstr "Fjern"
|
||||
|
||||
#: ../js/ui/messageTray.js:1618
|
||||
#: ../js/ui/messageTray.js:1657
|
||||
msgid "Notifications"
|
||||
msgstr "Varslinger"
|
||||
|
||||
#: ../js/ui/messageTray.js:1625
|
||||
#: ../js/ui/messageTray.js:1664
|
||||
msgid "Clear Messages"
|
||||
msgstr "Tøm meldinger"
|
||||
|
||||
#: ../js/ui/messageTray.js:1644
|
||||
#: ../js/ui/messageTray.js:1683
|
||||
msgid "Notification Settings"
|
||||
msgstr "Innstillinger for varsling"
|
||||
|
||||
#: ../js/ui/messageTray.js:1697
|
||||
#: ../js/ui/messageTray.js:1736
|
||||
msgid "Tray Menu"
|
||||
msgstr "Meny for varslingsområde"
|
||||
|
||||
#: ../js/ui/messageTray.js:1913
|
||||
#: ../js/ui/messageTray.js:1952
|
||||
msgid "No Messages"
|
||||
msgstr "Ingen meldinger"
|
||||
|
||||
#: ../js/ui/messageTray.js:1951
|
||||
#: ../js/ui/messageTray.js:1990
|
||||
msgid "Message Tray"
|
||||
msgstr "Meldingstrau"
|
||||
|
||||
#: ../js/ui/messageTray.js:2929
|
||||
#: ../js/ui/messageTray.js:2965
|
||||
msgid "System Information"
|
||||
msgstr "Systeminformasjon"
|
||||
|
||||
#: ../js/ui/notificationDaemon.js:539 ../src/shell-app.c:396
|
||||
#: ../js/ui/notificationDaemon.js:510 ../src/shell-app.c:396
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Ukjent"
|
||||
|
||||
#: ../js/ui/overviewControls.js:486 ../js/ui/screenShield.js:153
|
||||
#: ../js/ui/overviewControls.js:488 ../js/ui/screenShield.js:153
|
||||
#, javascript-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
@ -1141,7 +1131,7 @@ msgstr[1] "%d nye meldinger"
|
||||
msgid "Undo"
|
||||
msgstr "Angre"
|
||||
|
||||
#: ../js/ui/overview.js:125
|
||||
#: ../js/ui/overview.js:127
|
||||
msgid "Overview"
|
||||
msgstr "Oversikt"
|
||||
|
||||
@ -1149,7 +1139,7 @@ msgstr "Oversikt"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters. */
|
||||
#: ../js/ui/overview.js:256
|
||||
#: ../js/ui/overview.js:258
|
||||
msgid "Type to search…"
|
||||
msgstr "Skriv for å søke …"
|
||||
|
||||
@ -1192,7 +1182,7 @@ msgid_plural "%d new notifications"
|
||||
msgstr[0] "%d ny varsling"
|
||||
msgstr[1] "%d nye varslinger"
|
||||
|
||||
#: ../js/ui/screenShield.js:478 ../js/ui/status/system.js:342
|
||||
#: ../js/ui/screenShield.js:478 ../js/ui/status/system.js:333
|
||||
msgid "Lock"
|
||||
msgstr "Lås"
|
||||
|
||||
@ -1208,11 +1198,11 @@ msgstr "Kan ikke låse"
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Låsing ble stoppet av et program"
|
||||
|
||||
#: ../js/ui/search.js:592
|
||||
#: ../js/ui/searchDisplay.js:448
|
||||
msgid "Searching…"
|
||||
msgstr "Søker …"
|
||||
|
||||
#: ../js/ui/search.js:635
|
||||
#: ../js/ui/searchDisplay.js:492
|
||||
msgid "No results."
|
||||
msgstr "Ingen resultater."
|
||||
|
||||
@ -1291,7 +1281,7 @@ msgid "Bluetooth"
|
||||
msgstr "Bluetooth"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:29 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:1083 ../js/ui/status/rfkill.js:48
|
||||
#: ../js/ui/status/network.js:1099 ../js/ui/status/rfkill.js:46
|
||||
msgid "Turn Off"
|
||||
msgstr "Slå av"
|
||||
|
||||
@ -1376,20 +1366,16 @@ msgstr "Vennligst oppgi PIN som oppgitt på enheten."
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
|
||||
#: ../js/ui/status/brightness.js:44
|
||||
#: ../js/ui/status/brightness.js:42
|
||||
msgid "Brightness"
|
||||
msgstr "Lysstyrke"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:403
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "Vis tastaturutforming"
|
||||
|
||||
#: ../js/ui/status/network.js:71
|
||||
msgid "<unknown>"
|
||||
msgstr "<ukjent>"
|
||||
|
||||
#: ../js/ui/status/network.js:222 ../js/ui/status/network.js:379
|
||||
#: ../js/ui/status/network.js:1104
|
||||
#: ../js/ui/status/network.js:1120
|
||||
msgid "Off"
|
||||
msgstr "Av"
|
||||
|
||||
@ -1403,12 +1389,12 @@ msgstr "ikke håndtert"
|
||||
msgid "disconnecting..."
|
||||
msgstr "kobler fra …"
|
||||
|
||||
#: ../js/ui/status/network.js:393 ../js/ui/status/network.js:1158
|
||||
#: ../js/ui/status/network.js:393 ../js/ui/status/network.js:1174
|
||||
msgid "connecting..."
|
||||
msgstr "kobler til …"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password */
|
||||
#: ../js/ui/status/network.js:396 ../js/ui/status/network.js:1161
|
||||
#: ../js/ui/status/network.js:396 ../js/ui/status/network.js:1177
|
||||
msgid "authentication required"
|
||||
msgstr "autentisering kreves"
|
||||
|
||||
@ -1424,7 +1410,7 @@ msgstr "fastvare mangler"
|
||||
msgid "unavailable"
|
||||
msgstr "ikke tilgjengelig"
|
||||
|
||||
#: ../js/ui/status/network.js:410 ../js/ui/status/network.js:1163
|
||||
#: ../js/ui/status/network.js:410 ../js/ui/status/network.js:1179
|
||||
msgid "connection failed"
|
||||
msgstr "tilkobling feilet"
|
||||
|
||||
@ -1432,113 +1418,109 @@ msgstr "tilkobling feilet"
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "Innstillinger for mobilt bredbånd"
|
||||
|
||||
#: ../js/ui/status/network.js:468 ../js/ui/status/network.js:1102
|
||||
#: ../js/ui/status/network.js:468 ../js/ui/status/network.js:1118
|
||||
msgid "Hardware Disabled"
|
||||
msgstr "Maskinvare slått av"
|
||||
|
||||
#: ../js/ui/status/network.js:694
|
||||
#: ../js/ui/status/network.js:707
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Wi-Fi nettverk"
|
||||
|
||||
#: ../js/ui/status/network.js:696
|
||||
#: ../js/ui/status/network.js:709
|
||||
msgid "Select a network"
|
||||
msgstr "Velg et nettverk"
|
||||
|
||||
#: ../js/ui/status/network.js:720
|
||||
#: ../js/ui/status/network.js:733
|
||||
msgid "No Networks"
|
||||
msgstr "Ingen nettverk"
|
||||
|
||||
#: ../js/ui/status/network.js:989
|
||||
#: ../js/ui/status/network.js:1005
|
||||
msgid "Select Network"
|
||||
msgstr "Velg nettverk"
|
||||
|
||||
#: ../js/ui/status/network.js:995
|
||||
#: ../js/ui/status/network.js:1011
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Innstillinger"
|
||||
|
||||
#: ../js/ui/status/network.js:1083
|
||||
#: ../js/ui/status/network.js:1099
|
||||
msgid "Turn On"
|
||||
msgstr "Slå på"
|
||||
|
||||
#: ../js/ui/status/network.js:1106
|
||||
#: ../js/ui/status/network.js:1122
|
||||
msgid "Not Connected"
|
||||
msgstr "Ikke koblet til"
|
||||
|
||||
#: ../js/ui/status/network.js:1226
|
||||
#: ../js/ui/status/network.js:1242
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: ../js/ui/status/network.js:1366
|
||||
#: ../js/ui/status/network.js:1382
|
||||
msgid "Network Manager"
|
||||
msgstr "Nettverkshåndtering"
|
||||
|
||||
#: ../js/ui/status/network.js:1405
|
||||
#: ../js/ui/status/network.js:1421
|
||||
msgid "Connection failed"
|
||||
msgstr "Tilkobling feilet"
|
||||
|
||||
#: ../js/ui/status/network.js:1406
|
||||
#: ../js/ui/status/network.js:1422
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Aktivering av nettverkstilkobling feilet"
|
||||
|
||||
#: ../js/ui/status/power.js:49
|
||||
#: ../js/ui/status/power.js:46
|
||||
msgid "Battery"
|
||||
msgstr "Batteri"
|
||||
|
||||
#: ../js/ui/status/power.js:47
|
||||
msgid "Power Settings"
|
||||
msgstr "Innstillinger for strøm"
|
||||
|
||||
#: ../js/ui/status/power.js:65
|
||||
#: ../js/ui/status/power.js:63
|
||||
msgid "Fully Charged"
|
||||
msgstr "Fullt oppladet"
|
||||
|
||||
#: ../js/ui/status/power.js:72 ../js/ui/status/power.js:78
|
||||
#: ../js/ui/status/power.js:69 ../js/ui/status/power.js:86
|
||||
msgid "Estimating…"
|
||||
msgstr "Estimerer …"
|
||||
|
||||
#: ../js/ui/status/power.js:86
|
||||
#: ../js/ui/status/power.js:77
|
||||
#, javascript-format
|
||||
msgid "%d∶%02d Remaining (%d%%)"
|
||||
msgstr "%d:%02d gjenstår (%d%%)"
|
||||
|
||||
#: ../js/ui/status/power.js:91
|
||||
#: ../js/ui/status/power.js:82
|
||||
#, javascript-format
|
||||
msgid "%d∶%02d Until Full (%d%%)"
|
||||
msgstr "%d:%02d til batteriet er fullt (%d%%)"
|
||||
|
||||
#: ../js/ui/status/power.js:119
|
||||
msgid "UPS"
|
||||
msgstr "UPS"
|
||||
|
||||
#: ../js/ui/status/power.js:121
|
||||
msgid "Battery"
|
||||
msgstr "Batteri"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:45
|
||||
#: ../js/ui/status/rfkill.js:43
|
||||
msgid "Airplane Mode"
|
||||
msgstr "Flymodus"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:47
|
||||
#: ../js/ui/status/rfkill.js:45
|
||||
msgid "On"
|
||||
msgstr "På"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:51
|
||||
#: ../js/ui/status/rfkill.js:49
|
||||
msgid "Network Settings"
|
||||
msgstr "Innstillinger for nettverk"
|
||||
|
||||
#: ../js/ui/status/system.js:314
|
||||
#: ../js/ui/status/system.js:305
|
||||
msgid "Switch User"
|
||||
msgstr "Bytt bruker"
|
||||
|
||||
#: ../js/ui/status/system.js:319
|
||||
#: ../js/ui/status/system.js:310
|
||||
msgid "Log Out"
|
||||
msgstr "Logg ut"
|
||||
|
||||
#: ../js/ui/status/system.js:338
|
||||
#: ../js/ui/status/system.js:329
|
||||
msgid "Orientation Lock"
|
||||
msgstr "Lås for orientering"
|
||||
|
||||
#: ../js/ui/status/system.js:346
|
||||
#: ../js/ui/status/system.js:337
|
||||
msgid "Suspend"
|
||||
msgstr "Hvilemodus"
|
||||
|
||||
#: ../js/ui/status/system.js:349
|
||||
#: ../js/ui/status/system.js:340
|
||||
msgid "Power Off"
|
||||
msgstr "Slå av"
|
||||
|
||||
@ -1562,14 +1544,28 @@ msgstr "Logg inn som en annen bruker"
|
||||
msgid "Unlock Window"
|
||||
msgstr "Lås opp vindu"
|
||||
|
||||
#: ../js/ui/viewSelector.js:99
|
||||
#: ../js/ui/viewSelector.js:104
|
||||
msgid "Applications"
|
||||
msgstr "Programmer"
|
||||
|
||||
#: ../js/ui/viewSelector.js:103
|
||||
#: ../js/ui/viewSelector.js:108
|
||||
msgid "Search"
|
||||
msgstr "Søk"
|
||||
|
||||
#: ../js/ui/wanda.js:77
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
"Beklager, ingen visdom til deg i dag:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:81
|
||||
#, javascript-format
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "Orakelet sier %s"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:19
|
||||
#, javascript-format
|
||||
msgid "'%s' is ready"
|
||||
@ -1623,23 +1619,23 @@ msgstr[1] "%u innganger"
|
||||
msgid "System Sounds"
|
||||
msgstr "Systemlyder"
|
||||
|
||||
#: ../src/main.c:351
|
||||
#: ../src/main.c:353
|
||||
msgid "Print version"
|
||||
msgstr "Skriv ut versjon"
|
||||
|
||||
#: ../src/main.c:357
|
||||
#: ../src/main.c:359
|
||||
msgid "Mode used by GDM for login screen"
|
||||
msgstr "Modus som brukes av GDM for innloggingsskjermen"
|
||||
|
||||
#: ../src/main.c:363
|
||||
#: ../src/main.c:365
|
||||
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
|
||||
msgstr "Bruk spesifikt modus, f.eks «gdm» for innloggingsskjerm"
|
||||
|
||||
#: ../src/main.c:369
|
||||
#: ../src/main.c:371
|
||||
msgid "List possible modes"
|
||||
msgstr "Vis mulige modi"
|
||||
|
||||
#: ../src/shell-app.c:639
|
||||
#: ../src/shell-app.c:644
|
||||
#, c-format
|
||||
msgid "Failed to launch '%s'"
|
||||
msgstr "Klarte ikke å starte «%s»"
|
||||
|
346
po/ru.po
346
po/ru.po
@ -16,8 +16,8 @@ msgstr ""
|
||||
"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"
|
||||
"POT-Creation-Date: 2013-11-01 12:08+0000\n"
|
||||
"PO-Revision-Date: 2013-11-01 23:32+0400\n"
|
||||
"POT-Creation-Date: 2013-11-01 12:09+0000\n"
|
||||
"PO-Revision-Date: 2013-11-01 23:30+0400\n"
|
||||
"Last-Translator: Yuri Myasoedov <ymyasoedov@yandex.ru>\n"
|
||||
"Language-Team: Russian <gnome-cyr@gnome.org>\n"
|
||||
"Language: ru\n"
|
||||
@ -62,7 +62,6 @@ msgid "Window management and application launching"
|
||||
msgstr "Управление окнами и запуск приложений"
|
||||
|
||||
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
||||
#: ../js/extensionPrefs/main.js:155
|
||||
msgid "GNOME Shell Extension Preferences"
|
||||
msgstr "Параметры расширений GNOME Shell"
|
||||
|
||||
@ -277,23 +276,14 @@ msgstr "Рабочие места только на основном монит
|
||||
msgid "Delay focus changes in mouse mode until the pointer stops moving"
|
||||
msgstr "Задержка изменения фокуса в режиме мыши после остановки указателя"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:127
|
||||
#, javascript-format
|
||||
msgid "There was an error loading the preferences dialog for %s:"
|
||||
msgstr "Ошибка загрузки диалога параметров для %s:"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:167
|
||||
msgid "Extension"
|
||||
msgstr "Расширение"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:191
|
||||
#: ../js/extensionPrefs/main.js:189
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "Выберите расширение из выпадающего списка."
|
||||
|
||||
#: ../js/gdm/authPrompt.js:146 ../js/ui/components/networkAgent.js:136
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:357
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:351
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:726
|
||||
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:739
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
|
||||
@ -311,25 +301,25 @@ msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "Войти"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:272
|
||||
#: ../js/gdm/loginDialog.js:294
|
||||
msgid "Choose Session"
|
||||
msgstr "Выбрать сеанс"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:432
|
||||
#: ../js/gdm/loginDialog.js:454
|
||||
msgid "Not listed?"
|
||||
msgstr "Нет в списке?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:600
|
||||
#: ../js/gdm/loginDialog.js:622
|
||||
#, javascript-format
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(например, пользователь или %s)"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:605 ../js/ui/components/networkAgent.js:259
|
||||
#: ../js/gdm/loginDialog.js:627 ../js/ui/components/networkAgent.js:259
|
||||
#: ../js/ui/components/networkAgent.js:277
|
||||
msgid "Username: "
|
||||
msgstr "Имя пользователя: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:869
|
||||
#: ../js/gdm/loginDialog.js:891
|
||||
msgid "Login Window"
|
||||
msgstr "Окно входа в систему"
|
||||
|
||||
@ -358,23 +348,23 @@ msgstr "Не удалось выполнить «%s»:"
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "Здесь появляются часто используемые приложения"
|
||||
|
||||
#: ../js/ui/appDisplay.js:716
|
||||
#: ../js/ui/appDisplay.js:712
|
||||
msgid "Frequent"
|
||||
msgstr "Популярные"
|
||||
|
||||
#: ../js/ui/appDisplay.js:723
|
||||
#: ../js/ui/appDisplay.js:719
|
||||
msgid "All"
|
||||
msgstr "Все"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1528
|
||||
#: ../js/ui/appDisplay.js:1523
|
||||
msgid "New Window"
|
||||
msgstr "Новое окно"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1531 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:1526 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Удалить из избранного"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1532
|
||||
#: ../js/ui/appDisplay.js:1527
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Добавить в избранное"
|
||||
|
||||
@ -513,48 +503,48 @@ msgctxt "list saturday"
|
||||
msgid "S"
|
||||
msgstr "Сб"
|
||||
|
||||
#: ../js/ui/calendar.js:391
|
||||
#: ../js/ui/calendar.js:389
|
||||
msgid "calendar:MY"
|
||||
msgstr "calendar:MY"
|
||||
|
||||
#: ../js/ui/calendar.js:449
|
||||
#: ../js/ui/calendar.js:447
|
||||
msgid "Previous month"
|
||||
msgstr "Предыдущий месяц"
|
||||
|
||||
#: ../js/ui/calendar.js:459
|
||||
#: ../js/ui/calendar.js:457
|
||||
msgid "Next month"
|
||||
msgstr "Следующий месяц"
|
||||
|
||||
#. Translators: Text to show if there are no events */
|
||||
#: ../js/ui/calendar.js:755
|
||||
#: ../js/ui/calendar.js:753
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "Нет событий"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year */
|
||||
#: ../js/ui/calendar.js:773
|
||||
#: ../js/ui/calendar.js:771
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %B %d"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year */
|
||||
#: ../js/ui/calendar.js:776
|
||||
#: ../js/ui/calendar.js:774
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%A, %B %d, %Y"
|
||||
|
||||
#: ../js/ui/calendar.js:787
|
||||
#: ../js/ui/calendar.js:785
|
||||
msgid "Today"
|
||||
msgstr "Сегодня"
|
||||
|
||||
#: ../js/ui/calendar.js:791
|
||||
#: ../js/ui/calendar.js:789
|
||||
msgid "Tomorrow"
|
||||
msgstr "Завтра"
|
||||
|
||||
#: ../js/ui/calendar.js:802
|
||||
#: ../js/ui/calendar.js:800
|
||||
msgid "This week"
|
||||
msgstr "Эта неделя"
|
||||
|
||||
#: ../js/ui/calendar.js:810
|
||||
#: ../js/ui/calendar.js:808
|
||||
msgid "Next week"
|
||||
msgstr "Следующая неделя"
|
||||
|
||||
@ -566,16 +556,16 @@ msgstr "Внешний диск подключён"
|
||||
msgid "External drive disconnected"
|
||||
msgstr "Внешний диск отключён"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:296
|
||||
#: ../js/ui/components/autorunManager.js:294
|
||||
msgid "Removable Devices"
|
||||
msgstr "Съёмные устройства"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:596
|
||||
#: ../js/ui/components/autorunManager.js:594
|
||||
#, javascript-format
|
||||
msgid "Open with %s"
|
||||
msgstr "Открыть с помощью %s"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:622
|
||||
#: ../js/ui/components/autorunManager.js:620
|
||||
msgid "Eject"
|
||||
msgstr "Извлечь"
|
||||
|
||||
@ -588,7 +578,7 @@ msgid "Type again:"
|
||||
msgstr "Введите ещё раз:"
|
||||
|
||||
#: ../js/ui/components/networkAgent.js:131 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:295 ../js/ui/status/network.js:729
|
||||
#: ../js/ui/status/network.js:295 ../js/ui/status/network.js:742
|
||||
msgid "Connect"
|
||||
msgstr "Соединиться"
|
||||
|
||||
@ -697,11 +687,11 @@ msgstr "Передача файлов"
|
||||
msgid "Chat"
|
||||
msgstr "Чат"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Unmute"
|
||||
msgstr "Восстановить громкость"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Mute"
|
||||
msgstr "Приглушить звук"
|
||||
|
||||
@ -748,32 +738,32 @@ msgid "%s is inviting you to join %s"
|
||||
msgstr "%s приглашает вас присоединиться к %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1098
|
||||
#: ../js/ui/components/telepathyClient.js:1133
|
||||
#: ../js/ui/components/telepathyClient.js:1167
|
||||
#: ../js/ui/components/telepathyClient.js:1224
|
||||
#: ../js/ui/components/telepathyClient.js:1139
|
||||
#: ../js/ui/components/telepathyClient.js:1179
|
||||
#: ../js/ui/components/telepathyClient.js:1242
|
||||
msgid "Decline"
|
||||
msgstr "Отказаться"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1104
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
#: ../js/ui/components/telepathyClient.js:1229
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1180
|
||||
#: ../js/ui/components/telepathyClient.js:1243
|
||||
msgid "Accept"
|
||||
msgstr "Принять"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1123
|
||||
#: ../js/ui/components/telepathyClient.js:1129
|
||||
#, javascript-format
|
||||
msgid "Video call from %s"
|
||||
msgstr "Вас вызывает %s по видео"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1126
|
||||
#: ../js/ui/components/telepathyClient.js:1132
|
||||
#, javascript-format
|
||||
msgid "Call from %s"
|
||||
msgstr "Вас вызывает %s"
|
||||
|
||||
#. translators: this is a button label (verb), not a noun */
|
||||
#: ../js/ui/components/telepathyClient.js:1140
|
||||
#: ../js/ui/components/telepathyClient.js:1141
|
||||
msgid "Answer"
|
||||
msgstr "Ответить"
|
||||
|
||||
@ -782,111 +772,111 @@ msgstr "Ответить"
|
||||
#. * file name. The string will be something
|
||||
#. * like: "Alice is sending you test.ogg"
|
||||
#. */
|
||||
#: ../js/ui/components/telepathyClient.js:1161
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
#, javascript-format
|
||||
msgid "%s is sending you %s"
|
||||
msgstr "%s отправляет вам %s"
|
||||
|
||||
#. To translators: The parameter is the contact's alias */
|
||||
#: ../js/ui/components/telepathyClient.js:1190
|
||||
#: ../js/ui/components/telepathyClient.js:1208
|
||||
#, javascript-format
|
||||
msgid "%s would like permission to see when you are online"
|
||||
msgstr "%s хотел бы получить разрешение видеть, когда вы в сети"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1275
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
msgid "Network error"
|
||||
msgstr "Ошибка сети"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1277
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
msgid "Authentication failed"
|
||||
msgstr "Ошибка аутентификации"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1279
|
||||
#: ../js/ui/components/telepathyClient.js:1304
|
||||
msgid "Encryption error"
|
||||
msgstr "Ошибка шифрования"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1281
|
||||
#: ../js/ui/components/telepathyClient.js:1306
|
||||
msgid "Certificate not provided"
|
||||
msgstr "Сертификат не предоставляется"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1283
|
||||
#: ../js/ui/components/telepathyClient.js:1308
|
||||
msgid "Certificate untrusted"
|
||||
msgstr "Недоверенный сертификат"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1285
|
||||
#: ../js/ui/components/telepathyClient.js:1310
|
||||
msgid "Certificate expired"
|
||||
msgstr "Срок действия сертификата истёк"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1287
|
||||
#: ../js/ui/components/telepathyClient.js:1312
|
||||
msgid "Certificate not activated"
|
||||
msgstr "Сертификат не активирован"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1289
|
||||
#: ../js/ui/components/telepathyClient.js:1314
|
||||
msgid "Certificate hostname mismatch"
|
||||
msgstr "Имя узла сертификата не совпадает"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1291
|
||||
#: ../js/ui/components/telepathyClient.js:1316
|
||||
msgid "Certificate fingerprint mismatch"
|
||||
msgstr "Отпечаток сертификата не совпадает"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1293
|
||||
#: ../js/ui/components/telepathyClient.js:1318
|
||||
msgid "Certificate self-signed"
|
||||
msgstr "Самоподписанный сертификат"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1295
|
||||
#: ../js/ui/components/telepathyClient.js:1320
|
||||
msgid "Status is set to offline"
|
||||
msgstr "Установлен статус «не в сети»"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1297
|
||||
#: ../js/ui/components/telepathyClient.js:1322
|
||||
msgid "Encryption is not available"
|
||||
msgstr "Шифрование недоступно"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1299
|
||||
#: ../js/ui/components/telepathyClient.js:1324
|
||||
msgid "Certificate is invalid"
|
||||
msgstr "Недействительный сертификат"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1301
|
||||
#: ../js/ui/components/telepathyClient.js:1326
|
||||
msgid "Connection has been refused"
|
||||
msgstr "В соединении отказано"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1303
|
||||
#: ../js/ui/components/telepathyClient.js:1328
|
||||
msgid "Connection can't be established"
|
||||
msgstr "Соединение не может быть установлено"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1305
|
||||
#: ../js/ui/components/telepathyClient.js:1330
|
||||
msgid "Connection has been lost"
|
||||
msgstr "Соединение потеряно"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1307
|
||||
#: ../js/ui/components/telepathyClient.js:1332
|
||||
msgid "This account is already connected to the server"
|
||||
msgstr "Эта учётная запись уже подключена к серверу"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1309
|
||||
#: ../js/ui/components/telepathyClient.js:1334
|
||||
msgid ""
|
||||
"Connection has been replaced by a new connection using the same resource"
|
||||
msgstr "Соединение было заменено новым, используя тот же источник"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1311
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
msgid "The account already exists on the server"
|
||||
msgstr "Учётная запись уже существует на сервере"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1313
|
||||
#: ../js/ui/components/telepathyClient.js:1338
|
||||
msgid "Server is currently too busy to handle the connection"
|
||||
msgstr ""
|
||||
"Сервер в настоящее время сильно перегружен, чтобы обработать соединение"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1315
|
||||
#: ../js/ui/components/telepathyClient.js:1340
|
||||
msgid "Certificate has been revoked"
|
||||
msgstr "Сертификат аннулирован"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1317
|
||||
#: ../js/ui/components/telepathyClient.js:1342
|
||||
msgid ""
|
||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||
msgstr ""
|
||||
"Сертификат использует небезопасный алгоритм шифрования или он "
|
||||
"криптографически нестоек"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1319
|
||||
#: ../js/ui/components/telepathyClient.js:1344
|
||||
msgid ""
|
||||
"The length of the server certificate, or the depth of the server certificate "
|
||||
"chain, exceed the limits imposed by the cryptography library"
|
||||
@ -894,26 +884,26 @@ msgstr ""
|
||||
"Длина сертификата сервера, или глубина цепочки сертификатов сервера, "
|
||||
"превышает пределы, установленные библиотекой криптографии"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1321
|
||||
#: ../js/ui/components/telepathyClient.js:1346
|
||||
msgid "Internal error"
|
||||
msgstr "Внутренняя ошибка"
|
||||
|
||||
#. translators: argument is the account name, like
|
||||
#. * name@jabber.org for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1331
|
||||
#: ../js/ui/components/telepathyClient.js:1356
|
||||
#, javascript-format
|
||||
msgid "Unable to connect to %s"
|
||||
msgstr "Не удалось подключиться к %s"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
#: ../js/ui/components/telepathyClient.js:1361
|
||||
msgid "View account"
|
||||
msgstr "Показать учётную запись"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1368
|
||||
#: ../js/ui/components/telepathyClient.js:1400
|
||||
msgid "Unknown reason"
|
||||
msgstr "Неизвестная причина"
|
||||
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:95
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:100
|
||||
msgid "Windows"
|
||||
msgstr "Окна"
|
||||
|
||||
@ -944,18 +934,18 @@ msgstr "Настроить дату и время"
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%A, %e %B, %Y"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:64
|
||||
#: ../js/ui/endSessionDialog.js:62
|
||||
#, javascript-format
|
||||
msgctxt "title"
|
||||
msgid "Log Out %s"
|
||||
msgstr "Завершение сеанса пользователя %s"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:65
|
||||
#: ../js/ui/endSessionDialog.js:63
|
||||
msgctxt "title"
|
||||
msgid "Log Out"
|
||||
msgstr "Завершение сеанса"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:67
|
||||
#: ../js/ui/endSessionDialog.js:65
|
||||
#, javascript-format
|
||||
msgid "%s will be logged out automatically in %d second."
|
||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||
@ -965,7 +955,7 @@ msgstr[1] ""
|
||||
"Сеанс пользователя %s будет автоматически завершён через %d секунды."
|
||||
msgstr[2] "Сеанс пользователя %s будет автоматически завершён через %d секунд."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:72
|
||||
#: ../js/ui/endSessionDialog.js:70
|
||||
#, javascript-format
|
||||
msgid "You will be logged out automatically in %d second."
|
||||
msgid_plural "You will be logged out automatically in %d seconds."
|
||||
@ -973,17 +963,17 @@ msgstr[0] "Сеанс будет автоматически завершён ч
|
||||
msgstr[1] "Сеанс будет автоматически завершён через %d секунды."
|
||||
msgstr[2] "Сеанс будет автоматически завершён через %d секунд."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:77
|
||||
#: ../js/ui/endSessionDialog.js:75
|
||||
msgctxt "button"
|
||||
msgid "Log Out"
|
||||
msgstr "Завершить сеанс"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:83
|
||||
#: ../js/ui/endSessionDialog.js:81
|
||||
msgctxt "title"
|
||||
msgid "Power Off"
|
||||
msgstr "Выключение"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:85
|
||||
#: ../js/ui/endSessionDialog.js:83
|
||||
#, javascript-format
|
||||
msgid "The system will power off automatically in %d second."
|
||||
msgid_plural "The system will power off automatically in %d seconds."
|
||||
@ -991,22 +981,22 @@ msgstr[0] "Система будет автоматически выключен
|
||||
msgstr[1] "Система будет автоматически выключена через %d секунды."
|
||||
msgstr[2] "Система будет автоматически выключена через %d секунд."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:106
|
||||
#: ../js/ui/endSessionDialog.js:88 ../js/ui/endSessionDialog.js:104
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапустить"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:92
|
||||
#: ../js/ui/endSessionDialog.js:90
|
||||
msgctxt "button"
|
||||
msgid "Power Off"
|
||||
msgstr "Выключить"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:99
|
||||
#: ../js/ui/endSessionDialog.js:97
|
||||
msgctxt "title"
|
||||
msgid "Restart"
|
||||
msgstr "Перезапуск"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:101
|
||||
#: ../js/ui/endSessionDialog.js:99
|
||||
#, javascript-format
|
||||
msgid "The system will restart automatically in %d second."
|
||||
msgid_plural "The system will restart automatically in %d seconds."
|
||||
@ -1014,12 +1004,12 @@ msgstr[0] "Система будет автоматически перезапу
|
||||
msgstr[1] "Система будет автоматически перезапущена через %d секунды."
|
||||
msgstr[2] "Система будет автоматически перезапущена через %d секунд."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:114
|
||||
#: ../js/ui/endSessionDialog.js:112
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Updates"
|
||||
msgstr "Перезапуск и установка обновлений"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:116
|
||||
#: ../js/ui/endSessionDialog.js:114
|
||||
#, javascript-format
|
||||
msgid "The system will automatically restart and install updates in %d second."
|
||||
msgid_plural ""
|
||||
@ -1031,27 +1021,27 @@ msgstr[1] ""
|
||||
msgstr[2] ""
|
||||
"Система автоматически перезапустится и установит обновления через %d секунд."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:121
|
||||
#: ../js/ui/endSessionDialog.js:119
|
||||
msgctxt "button"
|
||||
msgid "Restart & Install"
|
||||
msgstr "Перезапустить и установить"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:275
|
||||
#: ../js/ui/endSessionDialog.js:271
|
||||
msgid "Some applications are busy or have unsaved work."
|
||||
msgstr "Некоторые приложения заняты или результаты их работы не сохранены."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:282
|
||||
#: ../js/ui/endSessionDialog.js:277
|
||||
msgid "Other users are logged in."
|
||||
msgstr "В системе имеются открытые сеансы других пользователей."
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login */
|
||||
#: ../js/ui/endSessionDialog.js:485
|
||||
#: ../js/ui/endSessionDialog.js:479
|
||||
#, javascript-format
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (удалённый)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console */
|
||||
#: ../js/ui/endSessionDialog.js:488
|
||||
#: ../js/ui/endSessionDialog.js:482
|
||||
#, javascript-format
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (консоль)"
|
||||
@ -1065,29 +1055,29 @@ msgstr "Установить"
|
||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||
msgstr "Загрузить и установить расширение «%s» с extensions.gnome.org?"
|
||||
|
||||
#: ../js/ui/keyboard.js:621 ../js/ui/status/keyboard.js:335
|
||||
#: ../js/ui/keyboard.js:619
|
||||
msgid "Keyboard"
|
||||
msgstr "Клавиатура"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:640
|
||||
#: ../js/ui/lookingGlass.js:689
|
||||
msgid "No extensions installed"
|
||||
msgstr "Расширения не установлены"
|
||||
|
||||
#. Translators: argument is an extension UUID. */
|
||||
#: ../js/ui/lookingGlass.js:694
|
||||
#: ../js/ui/lookingGlass.js:743
|
||||
#, javascript-format
|
||||
msgid "%s has not emitted any errors."
|
||||
msgstr "%s не сообщал о каких-либо ошибках."
|
||||
|
||||
#: ../js/ui/lookingGlass.js:700
|
||||
#: ../js/ui/lookingGlass.js:749
|
||||
msgid "Hide Errors"
|
||||
msgstr "Скрыть ошибки"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:704 ../js/ui/lookingGlass.js:764
|
||||
#: ../js/ui/lookingGlass.js:753 ../js/ui/lookingGlass.js:813
|
||||
msgid "Show Errors"
|
||||
msgstr "Показать ошибки"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:713
|
||||
#: ../js/ui/lookingGlass.js:762
|
||||
msgid "Enabled"
|
||||
msgstr "Включено"
|
||||
|
||||
@ -1095,73 +1085,73 @@ msgstr "Включено"
|
||||
#. because it's disabled by rfkill (airplane mode) */
|
||||
#. translators:
|
||||
#. * The device has been disabled
|
||||
#: ../js/ui/lookingGlass.js:716 ../js/ui/status/network.js:472
|
||||
#: ../js/ui/lookingGlass.js:765 ../js/ui/status/network.js:472
|
||||
#: ../src/gvc/gvc-mixer-control.c:1830
|
||||
msgid "Disabled"
|
||||
msgstr "Выключено"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:718
|
||||
#: ../js/ui/lookingGlass.js:767
|
||||
msgid "Error"
|
||||
msgstr "Ошибка"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:720
|
||||
#: ../js/ui/lookingGlass.js:769
|
||||
msgid "Out of date"
|
||||
msgstr "Устарело"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:722
|
||||
#: ../js/ui/lookingGlass.js:771
|
||||
msgid "Downloading"
|
||||
msgstr "Загрузка"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:746
|
||||
#: ../js/ui/lookingGlass.js:795
|
||||
msgid "View Source"
|
||||
msgstr "Показать код"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:755
|
||||
#: ../js/ui/lookingGlass.js:804
|
||||
msgid "Web Page"
|
||||
msgstr "Веб-страница"
|
||||
|
||||
#: ../js/ui/messageTray.js:1310
|
||||
#: ../js/ui/messageTray.js:1347
|
||||
msgid "Open"
|
||||
msgstr "Открыть"
|
||||
|
||||
#: ../js/ui/messageTray.js:1317
|
||||
#: ../js/ui/messageTray.js:1354
|
||||
msgid "Remove"
|
||||
msgstr "Удалить"
|
||||
|
||||
#: ../js/ui/messageTray.js:1618
|
||||
#: ../js/ui/messageTray.js:1657
|
||||
msgid "Notifications"
|
||||
msgstr "Уведомления"
|
||||
|
||||
#: ../js/ui/messageTray.js:1625
|
||||
#: ../js/ui/messageTray.js:1664
|
||||
msgid "Clear Messages"
|
||||
msgstr "Очистить список сообщений"
|
||||
|
||||
#: ../js/ui/messageTray.js:1644
|
||||
#: ../js/ui/messageTray.js:1683
|
||||
msgid "Notification Settings"
|
||||
msgstr "Параметры уведомлений"
|
||||
|
||||
#: ../js/ui/messageTray.js:1697
|
||||
#: ../js/ui/messageTray.js:1736
|
||||
msgid "Tray Menu"
|
||||
msgstr "Меню панели"
|
||||
|
||||
#: ../js/ui/messageTray.js:1913
|
||||
#: ../js/ui/messageTray.js:1952
|
||||
msgid "No Messages"
|
||||
msgstr "Нет сообщений"
|
||||
|
||||
#: ../js/ui/messageTray.js:1951
|
||||
#: ../js/ui/messageTray.js:1990
|
||||
msgid "Message Tray"
|
||||
msgstr "Панель сообщений"
|
||||
|
||||
#: ../js/ui/messageTray.js:2929
|
||||
#: ../js/ui/messageTray.js:2965
|
||||
msgid "System Information"
|
||||
msgstr "Системная информация"
|
||||
|
||||
#: ../js/ui/notificationDaemon.js:539 ../src/shell-app.c:396
|
||||
#: ../js/ui/notificationDaemon.js:510 ../src/shell-app.c:396
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "Неизвестно"
|
||||
|
||||
#: ../js/ui/overviewControls.js:486 ../js/ui/screenShield.js:153
|
||||
#: ../js/ui/overviewControls.js:488 ../js/ui/screenShield.js:153
|
||||
#, javascript-format
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
@ -1173,7 +1163,7 @@ msgstr[2] "%d новых сообщений"
|
||||
msgid "Undo"
|
||||
msgstr "Отменить"
|
||||
|
||||
#: ../js/ui/overview.js:125
|
||||
#: ../js/ui/overview.js:127
|
||||
msgid "Overview"
|
||||
msgstr "Обзор"
|
||||
|
||||
@ -1181,7 +1171,7 @@ msgstr "Обзор"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters. */
|
||||
#: ../js/ui/overview.js:256
|
||||
#: ../js/ui/overview.js:258
|
||||
msgid "Type to search…"
|
||||
msgstr "Найти…"
|
||||
|
||||
@ -1241,11 +1231,11 @@ msgstr "Не удалось заблокировать"
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "Блокировке помешало приложение"
|
||||
|
||||
#: ../js/ui/search.js:607
|
||||
#: ../js/ui/searchDisplay.js:448
|
||||
msgid "Searching…"
|
||||
msgstr "Поиск…"
|
||||
|
||||
#: ../js/ui/search.js:650
|
||||
#: ../js/ui/searchDisplay.js:492
|
||||
msgid "No results."
|
||||
msgstr "Нет результатов."
|
||||
|
||||
@ -1324,7 +1314,7 @@ msgid "Bluetooth"
|
||||
msgstr "Bluetooth"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:29 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:1083 ../js/ui/status/rfkill.js:48
|
||||
#: ../js/ui/status/network.js:1099 ../js/ui/status/rfkill.js:46
|
||||
msgid "Turn Off"
|
||||
msgstr "Выключить"
|
||||
|
||||
@ -1410,20 +1400,16 @@ msgstr "Введите PIN-код указанный на устройстве."
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
|
||||
#: ../js/ui/status/brightness.js:44
|
||||
#: ../js/ui/status/brightness.js:42
|
||||
msgid "Brightness"
|
||||
msgstr "Яркость"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:403
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "Показать раскладку клавиатуры"
|
||||
|
||||
#: ../js/ui/status/network.js:71
|
||||
msgid "<unknown>"
|
||||
msgstr "<неизвестно>"
|
||||
|
||||
#: ../js/ui/status/network.js:222 ../js/ui/status/network.js:379
|
||||
#: ../js/ui/status/network.js:1104
|
||||
#: ../js/ui/status/network.js:1120
|
||||
msgid "Off"
|
||||
msgstr "Выключена"
|
||||
|
||||
@ -1437,12 +1423,12 @@ msgstr "не управляется"
|
||||
msgid "disconnecting..."
|
||||
msgstr "отключение…"
|
||||
|
||||
#: ../js/ui/status/network.js:393 ../js/ui/status/network.js:1158
|
||||
#: ../js/ui/status/network.js:393 ../js/ui/status/network.js:1174
|
||||
msgid "connecting..."
|
||||
msgstr "подключение…"
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password */
|
||||
#: ../js/ui/status/network.js:396 ../js/ui/status/network.js:1161
|
||||
#: ../js/ui/status/network.js:396 ../js/ui/status/network.js:1177
|
||||
msgid "authentication required"
|
||||
msgstr "требуется подтверждение подлинности"
|
||||
|
||||
@ -1458,7 +1444,7 @@ msgstr "отсутствует прошивка"
|
||||
msgid "unavailable"
|
||||
msgstr "недоступное"
|
||||
|
||||
#: ../js/ui/status/network.js:410 ../js/ui/status/network.js:1163
|
||||
#: ../js/ui/status/network.js:410 ../js/ui/status/network.js:1179
|
||||
msgid "connection failed"
|
||||
msgstr "сбой подключения"
|
||||
|
||||
@ -1466,93 +1452,89 @@ msgstr "сбой подключения"
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "Параметры широкополосной мобильной связи"
|
||||
|
||||
#: ../js/ui/status/network.js:468 ../js/ui/status/network.js:1102
|
||||
#: ../js/ui/status/network.js:468 ../js/ui/status/network.js:1118
|
||||
msgid "Hardware Disabled"
|
||||
msgstr "Оборудование выключено"
|
||||
|
||||
#: ../js/ui/status/network.js:694
|
||||
#: ../js/ui/status/network.js:707
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Сети Wi-Fi"
|
||||
|
||||
#: ../js/ui/status/network.js:696
|
||||
#: ../js/ui/status/network.js:709
|
||||
msgid "Select a network"
|
||||
msgstr "Выберите сеть"
|
||||
|
||||
#: ../js/ui/status/network.js:720
|
||||
#: ../js/ui/status/network.js:733
|
||||
msgid "No Networks"
|
||||
msgstr "Сети отсутствуют"
|
||||
|
||||
#: ../js/ui/status/network.js:989
|
||||
#: ../js/ui/status/network.js:1005
|
||||
msgid "Select Network"
|
||||
msgstr "Выбрать сеть"
|
||||
|
||||
#: ../js/ui/status/network.js:995
|
||||
#: ../js/ui/status/network.js:1011
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Параметры Wi-Fi"
|
||||
|
||||
#: ../js/ui/status/network.js:1083
|
||||
#: ../js/ui/status/network.js:1099
|
||||
msgid "Turn On"
|
||||
msgstr "Включить"
|
||||
|
||||
#: ../js/ui/status/network.js:1106
|
||||
#: ../js/ui/status/network.js:1122
|
||||
msgid "Not Connected"
|
||||
msgstr "Не подключено"
|
||||
|
||||
#: ../js/ui/status/network.js:1226
|
||||
#: ../js/ui/status/network.js:1242
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: ../js/ui/status/network.js:1366
|
||||
#: ../js/ui/status/network.js:1382
|
||||
msgid "Network Manager"
|
||||
msgstr "Диспетчер сети"
|
||||
|
||||
#: ../js/ui/status/network.js:1405
|
||||
#: ../js/ui/status/network.js:1421
|
||||
msgid "Connection failed"
|
||||
msgstr "Сбой подключения"
|
||||
|
||||
#: ../js/ui/status/network.js:1406
|
||||
#: ../js/ui/status/network.js:1422
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "Не удалось активировать сетевое подключение"
|
||||
|
||||
#: ../js/ui/status/power.js:49
|
||||
#: ../js/ui/status/power.js:46
|
||||
msgid "Battery"
|
||||
msgstr "Батарея"
|
||||
|
||||
#: ../js/ui/status/power.js:47
|
||||
msgid "Power Settings"
|
||||
msgstr "Параметры электропитания"
|
||||
|
||||
#: ../js/ui/status/power.js:65
|
||||
#: ../js/ui/status/power.js:63
|
||||
msgid "Fully Charged"
|
||||
msgstr "Полностью заряжена"
|
||||
|
||||
#: ../js/ui/status/power.js:72 ../js/ui/status/power.js:78
|
||||
#: ../js/ui/status/power.js:69 ../js/ui/status/power.js:86
|
||||
msgid "Estimating…"
|
||||
msgstr "Выполняется подсчёт…"
|
||||
|
||||
#: ../js/ui/status/power.js:86
|
||||
#: ../js/ui/status/power.js:77
|
||||
#, javascript-format
|
||||
msgid "%d∶%02d Remaining (%d%%)"
|
||||
msgstr "Осталось %d∶%02d (%d%%)"
|
||||
|
||||
#: ../js/ui/status/power.js:91
|
||||
#: ../js/ui/status/power.js:82
|
||||
#, javascript-format
|
||||
msgid "%d∶%02d Until Full (%d%%)"
|
||||
msgstr "До полного заряда %d∶%02d (%d%%)"
|
||||
|
||||
#: ../js/ui/status/power.js:119
|
||||
msgid "UPS"
|
||||
msgstr "ИБП"
|
||||
|
||||
#: ../js/ui/status/power.js:121
|
||||
msgid "Battery"
|
||||
msgstr "Батарея"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:45
|
||||
#: ../js/ui/status/rfkill.js:43
|
||||
msgid "Airplane Mode"
|
||||
msgstr "Режим перелёта"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:47
|
||||
#: ../js/ui/status/rfkill.js:45
|
||||
msgid "On"
|
||||
msgstr "Включено"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:51
|
||||
#: ../js/ui/status/rfkill.js:49
|
||||
msgid "Network Settings"
|
||||
msgstr "Настроить сеть"
|
||||
|
||||
@ -1596,14 +1578,28 @@ msgstr "Войти от имени другого пользователя"
|
||||
msgid "Unlock Window"
|
||||
msgstr "Разблокировать окно"
|
||||
|
||||
#: ../js/ui/viewSelector.js:99
|
||||
#: ../js/ui/viewSelector.js:104
|
||||
msgid "Applications"
|
||||
msgstr "Приложения"
|
||||
|
||||
#: ../js/ui/viewSelector.js:103
|
||||
#: ../js/ui/viewSelector.js:108
|
||||
msgid "Search"
|
||||
msgstr "Поиск"
|
||||
|
||||
#: ../js/ui/wanda.js:77
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
"Извините, на сегодня нет никаких советов:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:81
|
||||
#, javascript-format
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "Оракул говорит: «%s»"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:19
|
||||
#, javascript-format
|
||||
msgid "'%s' is ready"
|
||||
@ -1660,24 +1656,24 @@ msgstr[2] "%u входов"
|
||||
msgid "System Sounds"
|
||||
msgstr "Системные звуки"
|
||||
|
||||
#: ../src/main.c:351
|
||||
#: ../src/main.c:353
|
||||
msgid "Print version"
|
||||
msgstr "Показать номер версии"
|
||||
|
||||
#: ../src/main.c:357
|
||||
#: ../src/main.c:359
|
||||
msgid "Mode used by GDM for login screen"
|
||||
msgstr "Режим, используемый GDM для окна входа в систему"
|
||||
|
||||
#: ../src/main.c:363
|
||||
#: ../src/main.c:365
|
||||
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
|
||||
msgstr ""
|
||||
"Использовать для экрана входа в систему определённый режим, например «gdm»"
|
||||
|
||||
#: ../src/main.c:369
|
||||
#: ../src/main.c:371
|
||||
msgid "List possible modes"
|
||||
msgstr "Список возможных режимов"
|
||||
|
||||
#: ../src/shell-app.c:639
|
||||
#: ../src/shell-app.c:644
|
||||
#, c-format
|
||||
msgid "Failed to launch '%s'"
|
||||
msgstr "Не удалось запустить «%s»"
|
||||
@ -1693,13 +1689,3 @@ msgstr "Пароль не может быть пустым"
|
||||
#: ../src/shell-polkit-authentication-agent.c:343
|
||||
msgid "Authentication dialog was dismissed by the user"
|
||||
msgstr "Аутентификация отклонена пользователем"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Sorry, no wisdom for you today:\n"
|
||||
#~ "%s"
|
||||
#~ msgstr ""
|
||||
#~ "Извините, на сегодня нет никаких советов:\n"
|
||||
#~ "%s"
|
||||
|
||||
#~ msgid "%s the Oracle says"
|
||||
#~ msgstr "Оракул говорит: «%s»"
|
||||
|
363
po/ta.po
363
po/ta.po
@ -9,8 +9,8 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-11-03 00:53+0000\n"
|
||||
"PO-Revision-Date: 2013-11-11 14:44+0530\n"
|
||||
"POT-Creation-Date: 2013-11-01 19:31+0000\n"
|
||||
"PO-Revision-Date: 2013-11-11 15:02+0530\n"
|
||||
"Last-Translator: Shantha kumar <shkumar@redhat.com>\n"
|
||||
"Language-Team: American English <>\n"
|
||||
"Language: ta\n"
|
||||
@ -54,7 +54,6 @@ msgid "Window management and application launching"
|
||||
msgstr "சாளர மேலாண்மை மற்றும் பயன்பாடு துவக்கம்"
|
||||
|
||||
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
||||
#: ../js/extensionPrefs/main.js:155
|
||||
msgid "GNOME Shell Extension Preferences"
|
||||
msgstr "க்னோம் ஷெல் நீட்சி விருப்பங்கள்"
|
||||
|
||||
@ -269,22 +268,14 @@ msgid "Delay focus changes in mouse mode until the pointer stops moving"
|
||||
msgstr ""
|
||||
"சொடுக்கி பயன்முறையில் கவனப் பகுதி மாற்றங்களை சுட்டி நகர்வது நிற்கும் வரை தாமதப்படுத்தவும்"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:127
|
||||
msgid "There was an error loading the preferences dialog for %s:"
|
||||
msgstr "%s க்கு விருப்பங்கள் உரையாடலை ஏற்றுகையில் பிழை நேர்ந்தது:"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:167
|
||||
msgid "Extension"
|
||||
msgstr "நீட்சி"
|
||||
|
||||
#: ../js/extensionPrefs/main.js:191
|
||||
#: ../js/extensionPrefs/main.js:189
|
||||
msgid "Select an extension to configure using the combobox above."
|
||||
msgstr "மேலுள்ள கூட்டுப்பெட்டியை பயன்படுத்தி வடிவமைக்க ஒரு நீட்சியை தேர்ந்தெடுக்கவும்"
|
||||
|
||||
#: ../js/gdm/authPrompt.js:146 ../js/ui/components/networkAgent.js:136
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:357
|
||||
#: ../js/ui/components/polkitAgent.js:161 ../js/ui/endSessionDialog.js:351
|
||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:726
|
||||
#: ../js/ui/status/bluetooth.js:221 ../js/ui/status/network.js:739
|
||||
msgid "Cancel"
|
||||
msgstr "ரத்துசெய்க"
|
||||
|
||||
@ -302,25 +293,25 @@ msgctxt "button"
|
||||
msgid "Sign In"
|
||||
msgstr "உள்நுழை"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:272
|
||||
#: ../js/gdm/loginDialog.js:294
|
||||
#| msgid "Switch Session"
|
||||
msgid "Choose Session"
|
||||
msgstr "அமர்வைத் தேர்வு செய்யவும்"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:432
|
||||
#: ../js/gdm/loginDialog.js:454
|
||||
msgid "Not listed?"
|
||||
msgstr "பட்டியலில் இல்லை?"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:600
|
||||
#: ../js/gdm/loginDialog.js:622
|
||||
msgid "(e.g., user or %s)"
|
||||
msgstr "(எ.கா., பயனர் அல்லது %s)"
|
||||
|
||||
#: ../js/gdm/loginDialog.js:605 ../js/ui/components/networkAgent.js:259
|
||||
#: ../js/gdm/loginDialog.js:627 ../js/ui/components/networkAgent.js:259
|
||||
#: ../js/ui/components/networkAgent.js:277
|
||||
msgid "Username: "
|
||||
msgstr "பயனர்பெயர்: "
|
||||
|
||||
#: ../js/gdm/loginDialog.js:869
|
||||
#: ../js/gdm/loginDialog.js:891
|
||||
msgid "Login Window"
|
||||
msgstr "உள்புகு சாளரம்"
|
||||
|
||||
@ -348,23 +339,23 @@ msgstr "'%s' ஐ நிறைவேற்றுதல் தோல்வி அ
|
||||
msgid "Frequently used applications will appear here"
|
||||
msgstr "அதிகம் பயன்படுத்தும் பயன்பாடுகள் இங்கு காண்பிக்கப்படும்"
|
||||
|
||||
#: ../js/ui/appDisplay.js:715
|
||||
#: ../js/ui/appDisplay.js:712
|
||||
msgid "Frequent"
|
||||
msgstr "அடிக்கடி"
|
||||
|
||||
#: ../js/ui/appDisplay.js:722
|
||||
#: ../js/ui/appDisplay.js:719
|
||||
msgid "All"
|
||||
msgstr "எல்லா"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1526
|
||||
#: ../js/ui/appDisplay.js:1523
|
||||
msgid "New Window"
|
||||
msgstr "புதிய சாளரம்"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1529 ../js/ui/dash.js:284
|
||||
#: ../js/ui/appDisplay.js:1526 ../js/ui/dash.js:284
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "விருப்பத்தில் இருந்து நீக்கு"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1530
|
||||
#: ../js/ui/appDisplay.js:1527
|
||||
msgid "Add to Favorites"
|
||||
msgstr "விருப்பங்களுக்கு சேர்"
|
||||
|
||||
@ -501,48 +492,48 @@ msgctxt "list saturday"
|
||||
msgid "S"
|
||||
msgstr "ச"
|
||||
|
||||
#: ../js/ui/calendar.js:391
|
||||
#: ../js/ui/calendar.js:389
|
||||
msgid "calendar:MY"
|
||||
msgstr "நாள்காட்டி:MY"
|
||||
|
||||
#: ../js/ui/calendar.js:449
|
||||
#: ../js/ui/calendar.js:447
|
||||
msgid "Previous month"
|
||||
msgstr "முந்தைய மாதம்"
|
||||
|
||||
#: ../js/ui/calendar.js:459
|
||||
#: ../js/ui/calendar.js:457
|
||||
msgid "Next month"
|
||||
msgstr "அடுத்த மாதம்"
|
||||
|
||||
#. Translators: Text to show if there are no events */
|
||||
#: ../js/ui/calendar.js:755
|
||||
#: ../js/ui/calendar.js:753
|
||||
msgid "Nothing Scheduled"
|
||||
msgstr "திட்டம் எதுவுமில்லை"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on current year */
|
||||
#: ../js/ui/calendar.js:773
|
||||
#: ../js/ui/calendar.js:771
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d"
|
||||
msgstr "%A, %B %d"
|
||||
|
||||
#. Translators: Shown on calendar heading when selected day occurs on different year */
|
||||
#: ../js/ui/calendar.js:776
|
||||
#: ../js/ui/calendar.js:774
|
||||
msgctxt "calendar heading"
|
||||
msgid "%A, %B %d, %Y"
|
||||
msgstr "%A, %B %d, %Y"
|
||||
|
||||
#: ../js/ui/calendar.js:787
|
||||
#: ../js/ui/calendar.js:785
|
||||
msgid "Today"
|
||||
msgstr "இன்று"
|
||||
|
||||
#: ../js/ui/calendar.js:791
|
||||
#: ../js/ui/calendar.js:789
|
||||
msgid "Tomorrow"
|
||||
msgstr "நாளை"
|
||||
|
||||
#: ../js/ui/calendar.js:802
|
||||
#: ../js/ui/calendar.js:800
|
||||
msgid "This week"
|
||||
msgstr "இந்த வாரம்"
|
||||
|
||||
#: ../js/ui/calendar.js:810
|
||||
#: ../js/ui/calendar.js:808
|
||||
msgid "Next week"
|
||||
msgstr "அடுத்த வாரம்"
|
||||
|
||||
@ -554,15 +545,15 @@ msgstr "வெளிப்புற இயக்கி இணைக்கப்
|
||||
msgid "External drive disconnected"
|
||||
msgstr "வெளிப்புற இயக்கி இணைப்பு நீக்கப்பட்டது"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:296
|
||||
#: ../js/ui/components/autorunManager.js:294
|
||||
msgid "Removable Devices"
|
||||
msgstr "நீக்கப்படக்கூடிய சாதனங்கள் "
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:596
|
||||
#: ../js/ui/components/autorunManager.js:594
|
||||
msgid "Open with %s"
|
||||
msgstr "%s ஆல் திற"
|
||||
|
||||
#: ../js/ui/components/autorunManager.js:622
|
||||
#: ../js/ui/components/autorunManager.js:620
|
||||
msgid "Eject"
|
||||
msgstr "வெளியேற்று"
|
||||
|
||||
@ -575,7 +566,7 @@ msgid "Type again:"
|
||||
msgstr "மீண்டும் உள்ளிடவும்:"
|
||||
|
||||
#: ../js/ui/components/networkAgent.js:131 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:295 ../js/ui/status/network.js:729
|
||||
#: ../js/ui/status/network.js:295 ../js/ui/status/network.js:742
|
||||
msgid "Connect"
|
||||
msgstr "இணை"
|
||||
|
||||
@ -681,11 +672,11 @@ msgstr "கோப்பு பறிமாற்றம் "
|
||||
msgid "Chat"
|
||||
msgstr "அரட்டை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Unmute"
|
||||
msgstr "ஒலி நிறுத்தம் நீக்கு"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:480
|
||||
#: ../js/ui/components/telepathyClient.js:479
|
||||
msgid "Mute"
|
||||
msgstr "ஒலி நிறுத்தம்"
|
||||
|
||||
@ -729,30 +720,30 @@ msgid "%s is inviting you to join %s"
|
||||
msgstr "%s உங்களை %s உடன் சேர அழைக்கிறார்."
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1098
|
||||
#: ../js/ui/components/telepathyClient.js:1133
|
||||
#: ../js/ui/components/telepathyClient.js:1167
|
||||
#: ../js/ui/components/telepathyClient.js:1224
|
||||
#: ../js/ui/components/telepathyClient.js:1139
|
||||
#: ../js/ui/components/telepathyClient.js:1179
|
||||
#: ../js/ui/components/telepathyClient.js:1242
|
||||
msgid "Decline"
|
||||
msgstr "நிராகரி"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1104
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
#: ../js/ui/components/telepathyClient.js:1229
|
||||
#: ../js/ui/components/telepathyClient.js:1099
|
||||
#: ../js/ui/components/telepathyClient.js:1180
|
||||
#: ../js/ui/components/telepathyClient.js:1243
|
||||
msgid "Accept"
|
||||
msgstr "ஏற்றுக்கொள்"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1123
|
||||
#: ../js/ui/components/telepathyClient.js:1129
|
||||
msgid "Video call from %s"
|
||||
msgstr "%s இடமிருந்து விடியோ அழைப்பு"
|
||||
|
||||
#. translators: argument is a contact name like Alice for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1126
|
||||
#: ../js/ui/components/telepathyClient.js:1132
|
||||
msgid "Call from %s"
|
||||
msgstr "%s இடமிருந்து அழைப்பு"
|
||||
|
||||
#. translators: this is a button label (verb), not a noun */
|
||||
#: ../js/ui/components/telepathyClient.js:1140
|
||||
#: ../js/ui/components/telepathyClient.js:1141
|
||||
msgid "Answer"
|
||||
msgstr "பதிலளி"
|
||||
|
||||
@ -761,108 +752,108 @@ msgstr "பதிலளி"
|
||||
#. * file name. The string will be something
|
||||
#. * like: "Alice is sending you test.ogg"
|
||||
#. */
|
||||
#: ../js/ui/components/telepathyClient.js:1161
|
||||
#: ../js/ui/components/telepathyClient.js:1173
|
||||
msgid "%s is sending you %s"
|
||||
msgstr "%s உங்களுக்கு %s அனுப்புகிறார்"
|
||||
|
||||
#. To translators: The parameter is the contact's alias */
|
||||
#: ../js/ui/components/telepathyClient.js:1190
|
||||
#: ../js/ui/components/telepathyClient.js:1208
|
||||
msgid "%s would like permission to see when you are online"
|
||||
msgstr "%s நீங்கள் இணைப்பில் இருக்கும் போது காண அனுமதி வேண்டுகிறார். "
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1275
|
||||
#: ../js/ui/components/telepathyClient.js:1300
|
||||
msgid "Network error"
|
||||
msgstr "வலையமைப்பு பிழை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1277
|
||||
#: ../js/ui/components/telepathyClient.js:1302
|
||||
msgid "Authentication failed"
|
||||
msgstr "உறுதி செய்தல் தோல்வி"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1279
|
||||
#: ../js/ui/components/telepathyClient.js:1304
|
||||
msgid "Encryption error"
|
||||
msgstr "மறையாக்க பிழை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1281
|
||||
#: ../js/ui/components/telepathyClient.js:1306
|
||||
msgid "Certificate not provided"
|
||||
msgstr "சான்றிதழ் தரப்படவில்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1283
|
||||
#: ../js/ui/components/telepathyClient.js:1308
|
||||
msgid "Certificate untrusted"
|
||||
msgstr "சான்றிதழில் நம்பக தன்மை இல்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1285
|
||||
#: ../js/ui/components/telepathyClient.js:1310
|
||||
msgid "Certificate expired"
|
||||
msgstr "சான்றிதழ் காலாவதியானது"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1287
|
||||
#: ../js/ui/components/telepathyClient.js:1312
|
||||
msgid "Certificate not activated"
|
||||
msgstr "சான்றிதழ் செயல்படுத்தப்படவில்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1289
|
||||
#: ../js/ui/components/telepathyClient.js:1314
|
||||
msgid "Certificate hostname mismatch"
|
||||
msgstr "சான்றிதழ் புரவலன் பெயர் ஒத்திசையவில்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1291
|
||||
#: ../js/ui/components/telepathyClient.js:1316
|
||||
msgid "Certificate fingerprint mismatch"
|
||||
msgstr "சான்றிதழ் அடையாளம் ஒத்திசையவில்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1293
|
||||
#: ../js/ui/components/telepathyClient.js:1318
|
||||
msgid "Certificate self-signed"
|
||||
msgstr "சான்றிதழ் தானே கையெழுத்திட்டது"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1295
|
||||
#: ../js/ui/components/telepathyClient.js:1320
|
||||
msgid "Status is set to offline"
|
||||
msgstr "நிலை இப்போது இணைப்பு விலகி "
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1297
|
||||
#: ../js/ui/components/telepathyClient.js:1322
|
||||
msgid "Encryption is not available"
|
||||
msgstr "குறீயீட்டுமுறை கிடைப்பில் இல்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1299
|
||||
#: ../js/ui/components/telepathyClient.js:1324
|
||||
msgid "Certificate is invalid"
|
||||
msgstr "சான்றிதழ் செல்லுபடியாகாது"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1301
|
||||
#: ../js/ui/components/telepathyClient.js:1326
|
||||
msgid "Connection has been refused"
|
||||
msgstr "இணைப்பு மறுக்கப்பட்டது"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1303
|
||||
#: ../js/ui/components/telepathyClient.js:1328
|
||||
msgid "Connection can't be established"
|
||||
msgstr "இணைக்க முடியவில்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1305
|
||||
#: ../js/ui/components/telepathyClient.js:1330
|
||||
msgid "Connection has been lost"
|
||||
msgstr "இணைப்பு அற்றுப்போயிற்று"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1307
|
||||
#: ../js/ui/components/telepathyClient.js:1332
|
||||
msgid "This account is already connected to the server"
|
||||
msgstr "இந்த கணக்கு ஏற்கனவே சேவையகத்துக்கு இணைக்கப்பட்டது"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1309
|
||||
#: ../js/ui/components/telepathyClient.js:1334
|
||||
msgid ""
|
||||
"Connection has been replaced by a new connection using the same resource"
|
||||
msgstr "இணைப்பு அதே முலத்துடன் புதிய இணைப்பால் மாற்றப்பட்டது."
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1311
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
msgid "The account already exists on the server"
|
||||
msgstr "இந்த கணக்கு ஏற்கனவே சேவையகத்தில் உள்ளது"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1313
|
||||
#: ../js/ui/components/telepathyClient.js:1338
|
||||
msgid "Server is currently too busy to handle the connection"
|
||||
msgstr "இணைப்பை கையாள சேவையகம் இப்போது மிகவும் வேலை பளுவில் உள்ளது."
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1315
|
||||
#: ../js/ui/components/telepathyClient.js:1340
|
||||
msgid "Certificate has been revoked"
|
||||
msgstr "சான்றிதழ் ரத்து செய்யப்பட்டது"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1317
|
||||
#: ../js/ui/components/telepathyClient.js:1342
|
||||
msgid ""
|
||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||
msgstr ""
|
||||
"சான்றிதழ் பாதுகாப்பில்லாத சைபர் அல்கோரிதத்தை பயன்படுத்துகிறது. இது மறையாக்கத்தில் "
|
||||
"பலகீனமானது."
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1319
|
||||
#: ../js/ui/components/telepathyClient.js:1344
|
||||
msgid ""
|
||||
"The length of the server certificate, or the depth of the server certificate "
|
||||
"chain, exceed the limits imposed by the cryptography library"
|
||||
@ -870,25 +861,25 @@ msgstr ""
|
||||
"சேவயகத்தின் சான்றிதழின் நீளம் அல்லது சங்கிலியின் ஆழம் மறையாக்க நூலகம் வரயறுத்த மதிப்பை "
|
||||
"தாண்டியது."
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1321
|
||||
#: ../js/ui/components/telepathyClient.js:1346
|
||||
msgid "Internal error"
|
||||
msgstr "உள்ளார்ந்த பிழை"
|
||||
|
||||
#. translators: argument is the account name, like
|
||||
#. * name@jabber.org for example. */
|
||||
#: ../js/ui/components/telepathyClient.js:1331
|
||||
#: ../js/ui/components/telepathyClient.js:1356
|
||||
msgid "Unable to connect to %s"
|
||||
msgstr "%s க்கு இணைக்க முடியவில்லை"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1336
|
||||
#: ../js/ui/components/telepathyClient.js:1361
|
||||
msgid "View account"
|
||||
msgstr "கணக்கை காட்டவும்"
|
||||
|
||||
#: ../js/ui/components/telepathyClient.js:1368
|
||||
#: ../js/ui/components/telepathyClient.js:1400
|
||||
msgid "Unknown reason"
|
||||
msgstr "தெரியாத காரணம்"
|
||||
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:95
|
||||
#: ../js/ui/ctrlAltTab.js:29 ../js/ui/viewSelector.js:100
|
||||
msgid "Windows"
|
||||
msgstr "சாளரங்கள்"
|
||||
|
||||
@ -919,72 +910,72 @@ msgstr "தேதி நேரம் அமைப்புகள்"
|
||||
msgid "%A %B %e, %Y"
|
||||
msgstr "%A %B %e, %Y"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:64
|
||||
#: ../js/ui/endSessionDialog.js:62
|
||||
msgctxt "title"
|
||||
msgid "Log Out %s"
|
||||
msgstr "%s யிலிருந்து வெளியேறு"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:65
|
||||
#: ../js/ui/endSessionDialog.js:63
|
||||
msgctxt "title"
|
||||
msgid "Log Out"
|
||||
msgstr "வெளியேறு"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:67
|
||||
#: ../js/ui/endSessionDialog.js:65
|
||||
msgid "%s will be logged out automatically in %d second."
|
||||
msgid_plural "%s will be logged out automatically in %d seconds."
|
||||
msgstr[0] "%s தானியங்கியாக %d வினாடியில் வெளியேறும்"
|
||||
msgstr[1] "%s தானியங்கியாக %d வினாடிகளில் வெளியேறும்"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:72
|
||||
#: ../js/ui/endSessionDialog.js:70
|
||||
msgid "You will be logged out automatically in %d second."
|
||||
msgid_plural "You will be logged out automatically in %d seconds."
|
||||
msgstr[0] "நீங்கள் தானியங்கியாக %d வினாடியில் வெளியேற்றப்படுவீர்கள் "
|
||||
msgstr[1] "நீங்கள் தானியங்கியாக %d வினாடிகளில் வெளியேற்றப்படுவீர்கள் "
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:77
|
||||
#: ../js/ui/endSessionDialog.js:75
|
||||
msgctxt "button"
|
||||
msgid "Log Out"
|
||||
msgstr "வெளியேறு"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:83
|
||||
#: ../js/ui/endSessionDialog.js:81
|
||||
msgctxt "title"
|
||||
msgid "Power Off"
|
||||
msgstr "மின்சக்தி நிறுத்தம்"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:85
|
||||
#: ../js/ui/endSessionDialog.js:83
|
||||
msgid "The system will power off automatically in %d second."
|
||||
msgid_plural "The system will power off automatically in %d seconds."
|
||||
msgstr[0] "கணினி தானியங்கியாக %d வினாடியில் மின் நிறுத்தப்படும்"
|
||||
msgstr[1] "கணினி தானியங்கியாக %d வினாடிகளில் மின் நிறுத்தப்படும்"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:90 ../js/ui/endSessionDialog.js:106
|
||||
#: ../js/ui/endSessionDialog.js:88 ../js/ui/endSessionDialog.js:104
|
||||
msgctxt "button"
|
||||
msgid "Restart"
|
||||
msgstr "மறு துவக்கம்"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:92
|
||||
#: ../js/ui/endSessionDialog.js:90
|
||||
msgctxt "button"
|
||||
msgid "Power Off"
|
||||
msgstr "மின்சக்தி நிறுத்தம்"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:99
|
||||
#: ../js/ui/endSessionDialog.js:97
|
||||
msgctxt "title"
|
||||
msgid "Restart"
|
||||
msgstr "மறு துவக்கம்"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:101
|
||||
#: ../js/ui/endSessionDialog.js:99
|
||||
msgid "The system will restart automatically in %d second."
|
||||
msgid_plural "The system will restart automatically in %d seconds."
|
||||
msgstr[0] "கணினி தானியங்கியாக %d வினாடியில் மீள் துவக்கம் செய்யப்படும்."
|
||||
msgstr[1] "கணினி தானியங்கியாக %d வினாடிகளில் மீள் துவக்கம் செய்யப்படும்."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:114
|
||||
#: ../js/ui/endSessionDialog.js:112
|
||||
#| msgid "Install Updates & Restart"
|
||||
msgctxt "title"
|
||||
msgid "Restart & Install Updates"
|
||||
msgstr "மறுதுவக்கி புதுப்பிப்புகளை நிறுவு"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:116
|
||||
#: ../js/ui/endSessionDialog.js:114
|
||||
#| msgid "The system will restart automatically in %d second."
|
||||
#| msgid_plural "The system will restart automatically in %d seconds."
|
||||
msgid "The system will automatically restart and install updates in %d second."
|
||||
@ -993,26 +984,26 @@ msgid_plural ""
|
||||
msgstr[0] "%d வினாடியில் கணினி தானாகவே மறுதுவக்கமாகி புதுப்பிப்புகளை நிறுவும்."
|
||||
msgstr[1] "%d வினாடிகளில் கணினி தானாகவே மறுதுவக்கமாகி புதுப்பிப்புகளை நிறுவும்."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:121
|
||||
#: ../js/ui/endSessionDialog.js:119
|
||||
msgctxt "button"
|
||||
msgid "Restart & Install"
|
||||
msgstr "மறுதுவக்கி நிறுவு"
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:275
|
||||
#: ../js/ui/endSessionDialog.js:271
|
||||
msgid "Some applications are busy or have unsaved work."
|
||||
msgstr "சில பயன்பாடுகள் பணிமிகுதியாக உள்ளன அல்லது சேமிக்கப்படாத பணியைக் கொண்டுள்ளன."
|
||||
|
||||
#: ../js/ui/endSessionDialog.js:282
|
||||
#: ../js/ui/endSessionDialog.js:277
|
||||
msgid "Other users are logged in."
|
||||
msgstr "மற்ற பயனர்கள் புகுபதிவு செய்துள்ளனர்."
|
||||
|
||||
#. Translators: Remote here refers to a remote session, like a ssh login */
|
||||
#: ../js/ui/endSessionDialog.js:485
|
||||
#: ../js/ui/endSessionDialog.js:479
|
||||
msgid "%s (remote)"
|
||||
msgstr "%s (தொலைநிலை)"
|
||||
|
||||
#. Translators: Console here refers to a tty like a VT console */
|
||||
#: ../js/ui/endSessionDialog.js:488
|
||||
#: ../js/ui/endSessionDialog.js:482
|
||||
msgid "%s (console)"
|
||||
msgstr "%s (கன்சோல்)"
|
||||
|
||||
@ -1024,28 +1015,28 @@ msgstr "நிறுவு"
|
||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||
msgstr "'%s' ஐ எக்ஸ்டென்ஷன்ஸ்.க்னோம்.ஆர்க். இலிருந்து தரவிறக்கி நிறுவவா?"
|
||||
|
||||
#: ../js/ui/keyboard.js:621 ../js/ui/status/keyboard.js:335
|
||||
#: ../js/ui/keyboard.js:619
|
||||
msgid "Keyboard"
|
||||
msgstr "விசைப்பலகை"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:640
|
||||
#: ../js/ui/lookingGlass.js:689
|
||||
msgid "No extensions installed"
|
||||
msgstr "நீட்சிகள் ஏதும் நிறுவப்படவில்லை"
|
||||
|
||||
#. Translators: argument is an extension UUID. */
|
||||
#: ../js/ui/lookingGlass.js:694
|
||||
#: ../js/ui/lookingGlass.js:743
|
||||
msgid "%s has not emitted any errors."
|
||||
msgstr "%s எந்த பிழையையும் வெளியிடவில்லை"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:700
|
||||
#: ../js/ui/lookingGlass.js:749
|
||||
msgid "Hide Errors"
|
||||
msgstr "பிழைகளை மறை"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:704 ../js/ui/lookingGlass.js:764
|
||||
#: ../js/ui/lookingGlass.js:753 ../js/ui/lookingGlass.js:813
|
||||
msgid "Show Errors"
|
||||
msgstr "பிழைகளை காட்டுக"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:713
|
||||
#: ../js/ui/lookingGlass.js:762
|
||||
msgid "Enabled"
|
||||
msgstr "செயலாக்கப்பட்டது"
|
||||
|
||||
@ -1053,73 +1044,73 @@ msgstr "செயலாக்கப்பட்டது"
|
||||
#. because it's disabled by rfkill (airplane mode) */
|
||||
#. translators:
|
||||
#. * The device has been disabled
|
||||
#: ../js/ui/lookingGlass.js:716 ../js/ui/status/network.js:472
|
||||
#: ../js/ui/lookingGlass.js:765 ../js/ui/status/network.js:472
|
||||
#: ../src/gvc/gvc-mixer-control.c:1830
|
||||
msgid "Disabled"
|
||||
msgstr "செயல்நீக்கப்பட்டது"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:718
|
||||
#: ../js/ui/lookingGlass.js:767
|
||||
msgid "Error"
|
||||
msgstr "பிழை"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:720
|
||||
#: ../js/ui/lookingGlass.js:769
|
||||
msgid "Out of date"
|
||||
msgstr "காலாவதியானது"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:722
|
||||
#: ../js/ui/lookingGlass.js:771
|
||||
msgid "Downloading"
|
||||
msgstr "பதிவிறக்குகிறது"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:746
|
||||
#: ../js/ui/lookingGlass.js:795
|
||||
msgid "View Source"
|
||||
msgstr "மூலத்தை பார்க்க"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:755
|
||||
#: ../js/ui/lookingGlass.js:804
|
||||
msgid "Web Page"
|
||||
msgstr "இணைய பக்கம்"
|
||||
|
||||
#: ../js/ui/messageTray.js:1310
|
||||
#: ../js/ui/messageTray.js:1347
|
||||
msgid "Open"
|
||||
msgstr "திற"
|
||||
|
||||
#: ../js/ui/messageTray.js:1317
|
||||
#: ../js/ui/messageTray.js:1354
|
||||
msgid "Remove"
|
||||
msgstr "நீக்கு"
|
||||
|
||||
#: ../js/ui/messageTray.js:1618
|
||||
#: ../js/ui/messageTray.js:1657
|
||||
msgid "Notifications"
|
||||
msgstr "அறிவிப்புகள்"
|
||||
|
||||
#: ../js/ui/messageTray.js:1625
|
||||
#: ../js/ui/messageTray.js:1664
|
||||
msgid "Clear Messages"
|
||||
msgstr "செய்திகளை அழி"
|
||||
|
||||
#: ../js/ui/messageTray.js:1644
|
||||
#: ../js/ui/messageTray.js:1683
|
||||
msgid "Notification Settings"
|
||||
msgstr "அறிவிப்பு அமைப்புகள்"
|
||||
|
||||
#: ../js/ui/messageTray.js:1697
|
||||
#: ../js/ui/messageTray.js:1736
|
||||
msgid "Tray Menu"
|
||||
msgstr "ட்ரே மெனு"
|
||||
|
||||
#: ../js/ui/messageTray.js:1913
|
||||
#: ../js/ui/messageTray.js:1952
|
||||
msgid "No Messages"
|
||||
msgstr "செய்திகள் இல்லை"
|
||||
|
||||
#: ../js/ui/messageTray.js:1951
|
||||
#: ../js/ui/messageTray.js:1990
|
||||
msgid "Message Tray"
|
||||
msgstr "அறிவிப்பு பலகம்"
|
||||
|
||||
#: ../js/ui/messageTray.js:2929
|
||||
#: ../js/ui/messageTray.js:2965
|
||||
msgid "System Information"
|
||||
msgstr "கணினி தகவல்கள்"
|
||||
|
||||
#: ../js/ui/notificationDaemon.js:539 ../src/shell-app.c:396
|
||||
#: ../js/ui/notificationDaemon.js:510 ../src/shell-app.c:396
|
||||
msgctxt "program"
|
||||
msgid "Unknown"
|
||||
msgstr "தெரியாத"
|
||||
|
||||
#: ../js/ui/overviewControls.js:486 ../js/ui/screenShield.js:153
|
||||
#: ../js/ui/overviewControls.js:488 ../js/ui/screenShield.js:153
|
||||
msgid "%d new message"
|
||||
msgid_plural "%d new messages"
|
||||
msgstr[0] "%d புதிய செய்தி"
|
||||
@ -1129,7 +1120,7 @@ msgstr[1] "%d புதிய செய்திகள்"
|
||||
msgid "Undo"
|
||||
msgstr "மறை"
|
||||
|
||||
#: ../js/ui/overview.js:125
|
||||
#: ../js/ui/overview.js:127
|
||||
msgid "Overview"
|
||||
msgstr "மேலோட்டம்"
|
||||
|
||||
@ -1137,7 +1128,7 @@ msgstr "மேலோட்டம்"
|
||||
#. in the search entry when no search is
|
||||
#. active; it should not exceed ~30
|
||||
#. characters. */
|
||||
#: ../js/ui/overview.js:256
|
||||
#: ../js/ui/overview.js:258
|
||||
msgid "Type to search…"
|
||||
msgstr "தேட தட்டச்சு செய்யவும்..."
|
||||
|
||||
@ -1195,11 +1186,11 @@ msgstr "பூட்ட முடியவில்லை"
|
||||
msgid "Lock was blocked by an application"
|
||||
msgstr "ஒரு பயன்பாடு பூட்டுதலை முடக்கியுள்ளது"
|
||||
|
||||
#: ../js/ui/search.js:592
|
||||
#: ../js/ui/searchDisplay.js:448
|
||||
msgid "Searching…"
|
||||
msgstr "தேடுகிறது..."
|
||||
|
||||
#: ../js/ui/search.js:635
|
||||
#: ../js/ui/searchDisplay.js:492
|
||||
msgid "No results."
|
||||
msgstr "விடைகள் இல்லை."
|
||||
|
||||
@ -1278,7 +1269,7 @@ msgid "Bluetooth"
|
||||
msgstr "ப்ளூடூத்"
|
||||
|
||||
#: ../js/ui/status/bluetooth.js:29 ../js/ui/status/network.js:132
|
||||
#: ../js/ui/status/network.js:1083 ../js/ui/status/rfkill.js:48
|
||||
#: ../js/ui/status/network.js:1099 ../js/ui/status/rfkill.js:46
|
||||
msgid "Turn Off"
|
||||
msgstr "அணை"
|
||||
|
||||
@ -1360,20 +1351,16 @@ msgstr "சாதனத்தின் சொல்லும் பின் ஐ
|
||||
msgid "OK"
|
||||
msgstr "சரி"
|
||||
|
||||
#: ../js/ui/status/brightness.js:44
|
||||
#: ../js/ui/status/brightness.js:42
|
||||
msgid "Brightness"
|
||||
msgstr "ஒளிர்வு"
|
||||
|
||||
#: ../js/ui/status/keyboard.js:403
|
||||
msgid "Show Keyboard Layout"
|
||||
msgstr "விசைப்பலகை இடவமைவை காட்டுக"
|
||||
|
||||
#: ../js/ui/status/network.js:71
|
||||
msgid "<unknown>"
|
||||
msgstr "<தெரியாத>"
|
||||
|
||||
#: ../js/ui/status/network.js:222 ../js/ui/status/network.js:379
|
||||
#: ../js/ui/status/network.js:1104
|
||||
#: ../js/ui/status/network.js:1120
|
||||
#| msgid "Offline"
|
||||
msgid "Off"
|
||||
msgstr "ஆஃப்"
|
||||
@ -1388,12 +1375,12 @@ msgstr "மேலாண்மை இல்லாத"
|
||||
msgid "disconnecting..."
|
||||
msgstr "துண்டிக்கப்படுகிறது......"
|
||||
|
||||
#: ../js/ui/status/network.js:393 ../js/ui/status/network.js:1158
|
||||
#: ../js/ui/status/network.js:393 ../js/ui/status/network.js:1174
|
||||
msgid "connecting..."
|
||||
msgstr "இணைக்கிறது..."
|
||||
|
||||
#. Translators: this is for network connections that require some kind of key or password */
|
||||
#: ../js/ui/status/network.js:396 ../js/ui/status/network.js:1161
|
||||
#: ../js/ui/status/network.js:396 ../js/ui/status/network.js:1177
|
||||
msgid "authentication required"
|
||||
msgstr "உறுதிப்படுத்துதல் தேவை"
|
||||
|
||||
@ -1409,7 +1396,7 @@ msgstr "தள நிரல் காணவில்லை"
|
||||
msgid "unavailable"
|
||||
msgstr "செயலாக்க முடியாதவை"
|
||||
|
||||
#: ../js/ui/status/network.js:410 ../js/ui/status/network.js:1163
|
||||
#: ../js/ui/status/network.js:410 ../js/ui/status/network.js:1179
|
||||
msgid "connection failed"
|
||||
msgstr "இணைப்பு தோல்வி அடைந்தது"
|
||||
|
||||
@ -1418,99 +1405,95 @@ msgstr "இணைப்பு தோல்வி அடைந்தது"
|
||||
msgid "Mobile Broadband Settings"
|
||||
msgstr "மொபைல் பிராட்பேன்ட் அமைவுகள்"
|
||||
|
||||
#: ../js/ui/status/network.js:468 ../js/ui/status/network.js:1102
|
||||
#: ../js/ui/status/network.js:468 ../js/ui/status/network.js:1118
|
||||
#| msgid "hardware disabled"
|
||||
msgid "Hardware Disabled"
|
||||
msgstr "வன்பொருள் முடக்கப்பட்டது"
|
||||
|
||||
#: ../js/ui/status/network.js:694
|
||||
#: ../js/ui/status/network.js:707
|
||||
#| msgid "Network"
|
||||
msgid "Wi-Fi Networks"
|
||||
msgstr "Wi-Fi பிணையங்கள்"
|
||||
|
||||
#: ../js/ui/status/network.js:696
|
||||
#: ../js/ui/status/network.js:709
|
||||
#| msgid "Enable networking"
|
||||
msgid "Select a network"
|
||||
msgstr "ஒரு பிணையத்தைத் தேர்ந்தெடுக்கவும்"
|
||||
|
||||
#: ../js/ui/status/network.js:720
|
||||
#: ../js/ui/status/network.js:733
|
||||
#| msgid "Network"
|
||||
msgid "No Networks"
|
||||
msgstr "பிணையங்கள் இல்லை"
|
||||
|
||||
#: ../js/ui/status/network.js:989
|
||||
#: ../js/ui/status/network.js:1005
|
||||
#| msgid "Network"
|
||||
msgid "Select Network"
|
||||
msgstr "பிணையத்தைத் தேர்ந்தெடுக்கவும்"
|
||||
|
||||
#: ../js/ui/status/network.js:995
|
||||
#: ../js/ui/status/network.js:1011
|
||||
#| msgid "Settings"
|
||||
msgid "Wi-Fi Settings"
|
||||
msgstr "Wi-Fi அமைவுகள்"
|
||||
|
||||
#: ../js/ui/status/network.js:1083
|
||||
#: ../js/ui/status/network.js:1099
|
||||
msgid "Turn On"
|
||||
msgstr "இயக்கு"
|
||||
|
||||
#: ../js/ui/status/network.js:1106
|
||||
#: ../js/ui/status/network.js:1122
|
||||
#| msgid "Connect"
|
||||
msgid "Not Connected"
|
||||
msgstr "இணைக்கப்படவில்லை"
|
||||
|
||||
#: ../js/ui/status/network.js:1226
|
||||
#: ../js/ui/status/network.js:1242
|
||||
msgid "VPN"
|
||||
msgstr "VPN"
|
||||
|
||||
#: ../js/ui/status/network.js:1366
|
||||
#: ../js/ui/status/network.js:1382
|
||||
msgid "Network Manager"
|
||||
msgstr "வலைப்பின்னல் மேலாளர்"
|
||||
|
||||
#: ../js/ui/status/network.js:1405
|
||||
#: ../js/ui/status/network.js:1421
|
||||
msgid "Connection failed"
|
||||
msgstr "இணைப்பு தோல்வியுற்றது"
|
||||
|
||||
#: ../js/ui/status/network.js:1406
|
||||
#: ../js/ui/status/network.js:1422
|
||||
msgid "Activation of network connection failed"
|
||||
msgstr "வலைப்பின்னல் இணைப்பு செயலாக்கம் தோல்வி அடைந்தது"
|
||||
|
||||
#: ../js/ui/status/power.js:49
|
||||
msgid "Power Settings"
|
||||
msgstr "மின்சக்தி அமைப்புகள்"
|
||||
|
||||
#: ../js/ui/status/power.js:65
|
||||
msgid "Fully Charged"
|
||||
msgstr "முழுதும் சார்ஜ் ஆகியுள்ளது"
|
||||
|
||||
#: ../js/ui/status/power.js:72 ../js/ui/status/power.js:78
|
||||
msgid "Estimating…"
|
||||
msgstr "கணிக்கிறது…"
|
||||
|
||||
#: ../js/ui/status/power.js:86
|
||||
msgid "%d∶%02d Remaining (%d%%)"
|
||||
msgstr "%d∶%02d மீதமுள்ளது (%d%%)"
|
||||
|
||||
#: ../js/ui/status/power.js:91
|
||||
msgid "%d∶%02d Until Full (%d%%)"
|
||||
msgstr "%d∶%02d நிரம்ப உள்ளது (%d%%)"
|
||||
|
||||
#: ../js/ui/status/power.js:119
|
||||
msgid "UPS"
|
||||
msgstr "யூபிஎஸ்"
|
||||
|
||||
#: ../js/ui/status/power.js:121
|
||||
#: ../js/ui/status/power.js:46
|
||||
msgid "Battery"
|
||||
msgstr "மின்கலம்"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:45
|
||||
#: ../js/ui/status/power.js:47
|
||||
msgid "Power Settings"
|
||||
msgstr "மின்சக்தி அமைப்புகள்"
|
||||
|
||||
#: ../js/ui/status/power.js:63
|
||||
msgid "Fully Charged"
|
||||
msgstr "முழுதும் சார்ஜ் ஆகியுள்ளது"
|
||||
|
||||
#: ../js/ui/status/power.js:69 ../js/ui/status/power.js:86
|
||||
msgid "Estimating…"
|
||||
msgstr "கணிக்கிறது…"
|
||||
|
||||
#: ../js/ui/status/power.js:77
|
||||
msgid "%d∶%02d Remaining (%d%%)"
|
||||
msgstr "%d∶%02d மீதமுள்ளது (%d%%)"
|
||||
|
||||
#: ../js/ui/status/power.js:82
|
||||
msgid "%d∶%02d Until Full (%d%%)"
|
||||
msgstr "%d∶%02d நிரம்ப உள்ளது (%d%%)"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:43
|
||||
msgid "Airplane Mode"
|
||||
msgstr "விமானப் பயன்முறை"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:47
|
||||
#: ../js/ui/status/rfkill.js:45
|
||||
#| msgid "Open"
|
||||
msgid "On"
|
||||
msgstr "ஆன்"
|
||||
|
||||
#: ../js/ui/status/rfkill.js:51
|
||||
#: ../js/ui/status/rfkill.js:49
|
||||
msgid "Network Settings"
|
||||
msgstr "வலைப்பின்னல் அமைப்புகள்"
|
||||
|
||||
@ -1554,14 +1537,26 @@ msgstr "வேறு பயனராக உள்நுழைக"
|
||||
msgid "Unlock Window"
|
||||
msgstr "சாளர பூட்டு திறக்கவும்"
|
||||
|
||||
#: ../js/ui/viewSelector.js:99
|
||||
#: ../js/ui/viewSelector.js:104
|
||||
msgid "Applications"
|
||||
msgstr "பயன்பாடுகள்"
|
||||
|
||||
#: ../js/ui/viewSelector.js:103
|
||||
#: ../js/ui/viewSelector.js:108
|
||||
msgid "Search"
|
||||
msgstr "தேடு"
|
||||
|
||||
#: ../js/ui/wanda.js:77
|
||||
msgid ""
|
||||
"Sorry, no wisdom for you today:\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
"மன்னிக்க இன்றூ உங்களுக்கு பொன்மொழி இல்லை:\n"
|
||||
"%s"
|
||||
|
||||
#: ../js/ui/wanda.js:81
|
||||
msgid "%s the Oracle says"
|
||||
msgstr "%s அசரீரி சொல்லுகிறது"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:19
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' தயாராக உள்ளது"
|
||||
@ -1614,23 +1609,23 @@ msgstr[1] "%u உள்ளீடுகள்"
|
||||
msgid "System Sounds"
|
||||
msgstr "கணினி ஒலிகள்"
|
||||
|
||||
#: ../src/main.c:351
|
||||
#: ../src/main.c:353
|
||||
msgid "Print version"
|
||||
msgstr "அச்சுப் பதிப்பு"
|
||||
|
||||
#: ../src/main.c:357
|
||||
#: ../src/main.c:359
|
||||
msgid "Mode used by GDM for login screen"
|
||||
msgstr "ஜிடிஎம் உள்நுழைவு திரைக்கு பயன்படுத்தும் பாங்கு"
|
||||
|
||||
#: ../src/main.c:363
|
||||
#: ../src/main.c:365
|
||||
msgid "Use a specific mode, e.g. \"gdm\" for login screen"
|
||||
msgstr "உள்நுழைவு திரைக்கு குறிப்பிட்ட பாங்கை, எ.கா. \"gdm\" பயன்படுத்துக"
|
||||
|
||||
#: ../src/main.c:369
|
||||
#: ../src/main.c:371
|
||||
msgid "List possible modes"
|
||||
msgstr "இயன்ற பாங்குகளின் பட்டியல்"
|
||||
|
||||
#: ../src/shell-app.c:639
|
||||
#: ../src/shell-app.c:644
|
||||
#, c-format
|
||||
msgid "Failed to launch '%s'"
|
||||
msgstr "'%s' ஐ துவக்க முடியவில்லை"
|
||||
@ -1734,3 +1729,9 @@ msgstr "பயனர் உறுதிப்படுத்தல் உரை
|
||||
#~ "ஸ்க்ரீன்காஸ்ட் இல் பதிவாவனக்கான கோப்புப்பெயர் தனித்தன்மை வாய்ந்தது. இது நடப்பு தேதியை "
|
||||
#~ "அடிப்படையாக கொண்டது; இந்த பின்னொட்டை பயன்படுத்தும். பதிவதை வேறு கொள்கலத்தின் ஒழுங்கில் "
|
||||
#~ "மாற்றுகையில் இதையும் மாற்ற வேண்டும்."
|
||||
|
||||
#~ msgid "There was an error loading the preferences dialog for %s:"
|
||||
#~ msgstr "%s க்கு விருப்பங்கள் உரையாடலை ஏற்றுகையில் பிழை நேர்ந்தது:"
|
||||
|
||||
#~ msgid "Extension"
|
||||
#~ msgstr "நீட்சி"
|
||||
|
555
po/zh_CN.po
555
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
@ -156,10 +156,8 @@ libst_1_0_la_SOURCES = \
|
||||
$(st_source_private_h) \
|
||||
$(st_source_private_c) \
|
||||
$(st_source_h) \
|
||||
$(NULL)
|
||||
nodist_libst_1_0_la_SOURCES = \
|
||||
$(st_built_sources) \
|
||||
st.h \
|
||||
$(st_built_sources) \
|
||||
$(NULL)
|
||||
libst_1_0_la_CPPFLAGS = $(st_cflags)
|
||||
libst_1_0_la_LDFLAGS = $(LDADD)
|
||||
|
@ -4,6 +4,8 @@ tray_cflags = \
|
||||
$(TRAY_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
BUILT_SOURCES += $(tray_built_sources)
|
||||
|
||||
# please, keep this sorted alphabetically
|
||||
tray_source = \
|
||||
tray/na-tray-child.c \
|
||||
@ -17,6 +19,7 @@ noinst_LTLIBRARIES += libtray.la
|
||||
libtray_la_LIBADD = $(TRAY_LIBS)
|
||||
libtray_la_SOURCES = \
|
||||
$(tray_source) \
|
||||
$(tray_built_sources) \
|
||||
$(NULL)
|
||||
libtray_la_CPPFLAGS = $(tray_cflags)
|
||||
libtray_la_LDFLAGS = $(LDADD)
|
||||
|
@ -75,7 +75,8 @@ gnome_shell_cflags = \
|
||||
-DDATADIR=\"$(datadir)\" \
|
||||
-DGNOME_SHELL_LIBEXECDIR=\"$(libexecdir)\" \
|
||||
-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
|
||||
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\"
|
||||
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DJSDIR=\"$(pkgdatadir)/js\"
|
||||
|
||||
privlibdir = $(pkglibdir)
|
||||
privlib_LTLIBRARIES = libgnome-shell-js.la libgnome-shell-menu.la libgnome-shell.la
|
||||
@ -151,6 +152,7 @@ libgnome_shell_base_la_SOURCES = \
|
||||
$(NULL)
|
||||
|
||||
libgnome_shell_sources = \
|
||||
$(shell_built_sources) \
|
||||
$(shell_public_headers_h) \
|
||||
shell-app-private.h \
|
||||
shell-app-system-private.h \
|
||||
@ -171,17 +173,10 @@ libgnome_shell_sources = \
|
||||
shell-wm.c \
|
||||
$(NULL)
|
||||
|
||||
libgnome_shell_built_sources = \
|
||||
$(shell_built_sources) \
|
||||
$(top_builddir)/js/js-resources.c \
|
||||
$(top_builddir)/js/js-resources.h \
|
||||
$(NULL)
|
||||
|
||||
libgnome_shell_la_SOURCES = $(libgnome_shell_sources)
|
||||
nodist_libgnome_shell_la_SOURCES = $(libgnome_shell_built_sources)
|
||||
|
||||
libgnome_shell_la_gir_sources = \
|
||||
$(filter-out %-private.h $(shell_private_sources), $(shell_public_headers_h) $(libgnome_shell_base_la_SOURCES) $(libgnome_shell_sources) $(libgnome_shell_built_sources))
|
||||
$(filter-out %-private.h $(shell_private_sources), $(shell_public_headers_h) $(libgnome_shell_base_la_SOURCES) $(libgnome_shell_sources))
|
||||
|
||||
gnome_shell_SOURCES = main.c
|
||||
gnome_shell_CPPFLAGS = \
|
||||
@ -196,7 +191,6 @@ gnome_shell_DEPENDENCIES = libgnome-shell.la
|
||||
|
||||
if HAVE_MUTTER_WAYLAND
|
||||
libgnome_shell_wayland_la_SOURCES = $(libgnome_shell_sources)
|
||||
nodist_libgnome_shell_wayland_la_SOURCES = $(libgnome_shell_built_sources)
|
||||
|
||||
gnome_shell_wayland_SOURCES = main.c
|
||||
gnome_shell_wayland_CPPFLAGS = \
|
||||
@ -213,7 +207,7 @@ endif HAVE_MUTTER_WAYLAND
|
||||
|
||||
libgnome_shell_js_la_SOURCES = \
|
||||
shell-js.h \
|
||||
shell-js.cpp \
|
||||
shell-js.c \
|
||||
$(NULL)
|
||||
|
||||
libgnome_shell_js_la_LIBADD = \
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "shell-perf-log.h"
|
||||
#include "st.h"
|
||||
|
||||
#include <jsapi.h>
|
||||
|
||||
extern GType gnome_shell_plugin_get_type (void);
|
||||
|
||||
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
|
||||
|
@ -12,9 +12,9 @@ G_BEGIN_DECLS
|
||||
|
||||
ShellApp* _shell_app_new_for_window (MetaWindow *window);
|
||||
|
||||
ShellApp* _shell_app_new (GDesktopAppInfo *info);
|
||||
ShellApp* _shell_app_new (GMenuTreeEntry *entry);
|
||||
|
||||
void _shell_app_set_app_info (ShellApp *app, GDesktopAppInfo *info);
|
||||
void _shell_app_set_entry (ShellApp *app, GMenuTreeEntry *entry);
|
||||
|
||||
void _shell_app_handle_startup_sequence (ShellApp *app, SnStartupSequence *sequence);
|
||||
|
||||
|
@ -38,12 +38,18 @@ enum {
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
struct _ShellAppSystemPrivate {
|
||||
GMenuTree *apps_tree;
|
||||
|
||||
GHashTable *running_apps;
|
||||
GHashTable *visible_id_to_app;
|
||||
GHashTable *id_to_app;
|
||||
GHashTable *startup_wm_class_to_id;
|
||||
GHashTable *startup_wm_class_to_app;
|
||||
|
||||
GSList *known_vendor_prefixes;
|
||||
};
|
||||
|
||||
static void shell_app_system_finalize (GObject *object);
|
||||
static void on_apps_tree_changed_cb (GMenuTree *tree, gpointer user_data);
|
||||
|
||||
G_DEFINE_TYPE(ShellAppSystem, shell_app_system, G_TYPE_OBJECT);
|
||||
|
||||
@ -71,45 +77,10 @@ static void shell_app_system_class_init(ShellAppSystemClass *klass)
|
||||
g_type_class_add_private (gobject_class, sizeof (ShellAppSystemPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
scan_startup_wm_class_to_id (ShellAppSystem *self)
|
||||
{
|
||||
ShellAppSystemPrivate *priv = self->priv;
|
||||
GList *apps, *l;
|
||||
|
||||
g_hash_table_remove_all (priv->startup_wm_class_to_id);
|
||||
|
||||
apps = g_app_info_get_all ();
|
||||
for (l = apps; l != NULL; l = l->next)
|
||||
{
|
||||
GAppInfo *info = l->data;
|
||||
const char *startup_wm_class, *id;
|
||||
|
||||
id = g_app_info_get_id (info);
|
||||
startup_wm_class = g_desktop_app_info_get_startup_wm_class (G_DESKTOP_APP_INFO (info));
|
||||
if (startup_wm_class != NULL)
|
||||
g_hash_table_insert (priv->startup_wm_class_to_id, (char *) startup_wm_class, (char *) id);
|
||||
}
|
||||
|
||||
g_list_free_full (apps, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
installed_changed (GAppInfoMonitor *monitor,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShellAppSystem *self = user_data;
|
||||
|
||||
scan_startup_wm_class_to_id (self);
|
||||
|
||||
g_signal_emit (self, signals[INSTALLED_CHANGED], 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_app_system_init (ShellAppSystem *self)
|
||||
{
|
||||
ShellAppSystemPrivate *priv;
|
||||
GAppInfoMonitor *monitor;
|
||||
|
||||
self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
SHELL_TYPE_APP_SYSTEM,
|
||||
@ -120,11 +91,19 @@ shell_app_system_init (ShellAppSystem *self)
|
||||
NULL,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
priv->startup_wm_class_to_id = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
/* 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);
|
||||
|
||||
monitor = g_app_info_monitor_get ();
|
||||
g_signal_connect (monitor, "changed", G_CALLBACK (installed_changed), self);
|
||||
installed_changed (monitor, self);
|
||||
priv->startup_wm_class_to_app = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
/* We want to track NoDisplay apps, so we add INCLUDE_NODISPLAY. We'll
|
||||
* filter NoDisplay apps out when showing them to the user. */
|
||||
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);
|
||||
|
||||
on_apps_tree_changed_cb (priv->apps_tree, self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -133,13 +112,313 @@ shell_app_system_finalize (GObject *object)
|
||||
ShellAppSystem *self = SHELL_APP_SYSTEM (object);
|
||||
ShellAppSystemPrivate *priv = self->priv;
|
||||
|
||||
g_object_unref (priv->apps_tree);
|
||||
|
||||
g_hash_table_destroy (priv->running_apps);
|
||||
g_hash_table_destroy (priv->id_to_app);
|
||||
g_hash_table_destroy (priv->startup_wm_class_to_id);
|
||||
g_hash_table_destroy (priv->visible_id_to_app);
|
||||
g_hash_table_destroy (priv->startup_wm_class_to_app);
|
||||
|
||||
g_slist_free_full (priv->known_vendor_prefixes, g_free);
|
||||
priv->known_vendor_prefixes = NULL;
|
||||
|
||||
G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_prefix_for_entry (GMenuTreeEntry *entry)
|
||||
{
|
||||
char *prefix = NULL, *file_prefix = NULL;
|
||||
const char *id;
|
||||
GFile *file;
|
||||
char *name;
|
||||
int i = 0;
|
||||
|
||||
id = gmenu_tree_entry_get_desktop_file_id (entry);
|
||||
file = g_file_new_for_path (gmenu_tree_entry_get_desktop_file_path (entry));
|
||||
name = g_file_get_basename (file);
|
||||
|
||||
if (!name)
|
||||
{
|
||||
g_object_unref (file);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; vendor_prefixes[i]; i++)
|
||||
{
|
||||
if (g_str_has_prefix (name, vendor_prefixes[i]))
|
||||
{
|
||||
file_prefix = g_strdup (vendor_prefixes[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (strcmp (name, id) != 0)
|
||||
{
|
||||
char *t;
|
||||
char *pname;
|
||||
GFile *parent = g_file_get_parent (file);
|
||||
|
||||
if (!parent)
|
||||
{
|
||||
g_warn_if_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
pname = g_file_get_basename (parent);
|
||||
if (!pname)
|
||||
{
|
||||
g_object_unref (parent);
|
||||
break;
|
||||
}
|
||||
if (!g_strstr_len (id, -1, pname))
|
||||
{
|
||||
/* handle <LegacyDir prefix="..."> */
|
||||
char *t;
|
||||
size_t name_len = strlen (name);
|
||||
size_t id_len = strlen (id);
|
||||
char *t_id = g_strdup (id);
|
||||
|
||||
t_id[id_len - name_len] = '\0';
|
||||
t = g_strdup(t_id);
|
||||
g_free (prefix);
|
||||
g_free (t_id);
|
||||
g_free (name);
|
||||
name = g_strdup (id);
|
||||
prefix = t;
|
||||
|
||||
g_object_unref (file);
|
||||
file = parent;
|
||||
g_free (pname);
|
||||
g_free (file_prefix);
|
||||
file_prefix = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
t = g_strconcat (pname, "-", name, NULL);
|
||||
g_free (name);
|
||||
name = t;
|
||||
|
||||
t = g_strconcat (pname, "-", prefix, NULL);
|
||||
g_free (prefix);
|
||||
prefix = t;
|
||||
|
||||
g_object_unref (file);
|
||||
file = parent;
|
||||
g_free (pname);
|
||||
}
|
||||
|
||||
if (file)
|
||||
g_object_unref (file);
|
||||
|
||||
if (strcmp (name, id) == 0)
|
||||
{
|
||||
g_free (name);
|
||||
if (file_prefix && !prefix)
|
||||
return file_prefix;
|
||||
if (file_prefix)
|
||||
{
|
||||
char *t = g_strconcat (prefix, "-", file_prefix, NULL);
|
||||
g_free (prefix);
|
||||
g_free (file_prefix);
|
||||
prefix = t;
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
g_free (prefix);
|
||||
g_free (file_prefix);
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
get_flattened_entries_recurse (GMenuTreeDirectory *dir,
|
||||
GHashTable *entry_set)
|
||||
{
|
||||
GMenuTreeIter *iter = gmenu_tree_directory_iter (dir);
|
||||
GMenuTreeItemType next_type;
|
||||
|
||||
while ((next_type = gmenu_tree_iter_next (iter)) != GMENU_TREE_ITEM_INVALID)
|
||||
{
|
||||
gpointer item = NULL;
|
||||
|
||||
switch (next_type)
|
||||
{
|
||||
case GMENU_TREE_ITEM_ENTRY:
|
||||
{
|
||||
GMenuTreeEntry *entry;
|
||||
item = entry = gmenu_tree_iter_get_entry (iter);
|
||||
/* Key is owned by entry */
|
||||
g_hash_table_replace (entry_set,
|
||||
(char*)gmenu_tree_entry_get_desktop_file_id (entry),
|
||||
gmenu_tree_item_ref (entry));
|
||||
}
|
||||
break;
|
||||
case GMENU_TREE_ITEM_DIRECTORY:
|
||||
{
|
||||
item = gmenu_tree_iter_get_directory (iter);
|
||||
get_flattened_entries_recurse ((GMenuTreeDirectory*)item, entry_set);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (item != NULL)
|
||||
gmenu_tree_item_unref (item);
|
||||
}
|
||||
|
||||
gmenu_tree_iter_unref (iter);
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
get_flattened_entries_from_tree (GMenuTree *tree)
|
||||
{
|
||||
GHashTable *table;
|
||||
GMenuTreeDirectory *root;
|
||||
|
||||
table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) NULL,
|
||||
(GDestroyNotify) gmenu_tree_item_unref);
|
||||
|
||||
root = gmenu_tree_get_root_directory (tree);
|
||||
|
||||
if (root != NULL)
|
||||
get_flattened_entries_recurse (root, table);
|
||||
|
||||
gmenu_tree_item_unref (root);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
static void
|
||||
on_apps_tree_changed_cb (GMenuTree *tree,
|
||||
gpointer user_data)
|
||||
{
|
||||
ShellAppSystem *self = SHELL_APP_SYSTEM (user_data);
|
||||
GError *error = NULL;
|
||||
GHashTable *new_apps;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_assert (tree == self->priv->apps_tree);
|
||||
|
||||
g_hash_table_remove_all (self->priv->visible_id_to_app);
|
||||
g_slist_free_full (self->priv->known_vendor_prefixes, g_free);
|
||||
self->priv->known_vendor_prefixes = NULL;
|
||||
|
||||
if (!gmenu_tree_load_sync (self->priv->apps_tree, &error))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Failed to load apps: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to load apps");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
new_apps = get_flattened_entries_from_tree (self->priv->apps_tree);
|
||||
g_hash_table_iter_init (&iter, new_apps);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
const char *id = key;
|
||||
GMenuTreeEntry *entry = value;
|
||||
GMenuTreeEntry *old_entry;
|
||||
char *prefix;
|
||||
ShellApp *app;
|
||||
GDesktopAppInfo *info;
|
||||
const char *startup_wm_class;
|
||||
|
||||
prefix = get_prefix_for_entry (entry);
|
||||
|
||||
if (prefix != NULL
|
||||
&& !g_slist_find_custom (self->priv->known_vendor_prefixes, prefix,
|
||||
(GCompareFunc)g_strcmp0))
|
||||
self->priv->known_vendor_prefixes = g_slist_append (self->priv->known_vendor_prefixes,
|
||||
prefix);
|
||||
else
|
||||
g_free (prefix);
|
||||
|
||||
app = g_hash_table_lookup (self->priv->id_to_app, id);
|
||||
if (app != NULL)
|
||||
{
|
||||
/* We hold a reference to the original entry temporarily,
|
||||
* because otherwise the hash table would be referencing
|
||||
* potentially free'd memory until we replace it below with
|
||||
* the new data.
|
||||
*/
|
||||
old_entry = shell_app_get_tree_entry (app);
|
||||
gmenu_tree_item_ref (old_entry);
|
||||
_shell_app_set_entry (app, entry);
|
||||
g_object_ref (app); /* Extra ref, removed in _replace below */
|
||||
}
|
||||
else
|
||||
{
|
||||
old_entry = NULL;
|
||||
app = _shell_app_new (entry);
|
||||
}
|
||||
/* Note that "id" is owned by app->entry. Since we're always
|
||||
* setting a new entry, even if the app already exists in the
|
||||
* hash table we need to replace the key so that the new id
|
||||
* string is pointed to.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
GDesktopAppInfo *old_info;
|
||||
const gchar *old_startup_wm_class;
|
||||
|
||||
old_info = gmenu_tree_entry_get_app_info (old_entry);
|
||||
old_startup_wm_class = g_desktop_app_info_get_startup_wm_class (old_info);
|
||||
|
||||
if (old_startup_wm_class)
|
||||
g_hash_table_remove (self->priv->startup_wm_class_to_app, old_startup_wm_class);
|
||||
}
|
||||
|
||||
info = gmenu_tree_entry_get_app_info (entry);
|
||||
startup_wm_class = g_desktop_app_info_get_startup_wm_class (info);
|
||||
if (startup_wm_class)
|
||||
g_hash_table_replace (self->priv->startup_wm_class_to_app,
|
||||
(char*)startup_wm_class, g_object_ref (app));
|
||||
|
||||
if (old_entry)
|
||||
gmenu_tree_item_unref (old_entry);
|
||||
}
|
||||
/* Now iterate over the apps again; we need to unreference any apps
|
||||
* which have been removed. The JS code may still be holding a
|
||||
* reference; that's fine.
|
||||
*/
|
||||
g_hash_table_iter_init (&iter, self->priv->id_to_app);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
const char *id = key;
|
||||
|
||||
if (!g_hash_table_lookup (new_apps, id))
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
|
||||
g_hash_table_destroy (new_apps);
|
||||
|
||||
g_signal_emit (self, signals[INSTALLED_CHANGED], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_get_tree:
|
||||
*
|
||||
* Return Value: (transfer none): The #GMenuTree for apps
|
||||
*/
|
||||
GMenuTree *
|
||||
shell_app_system_get_tree (ShellAppSystem *self)
|
||||
{
|
||||
return self->priv->apps_tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_get_default:
|
||||
*
|
||||
@ -167,21 +446,61 @@ ShellApp *
|
||||
shell_app_system_lookup_app (ShellAppSystem *self,
|
||||
const char *id)
|
||||
{
|
||||
ShellAppSystemPrivate *priv = self->priv;
|
||||
return g_hash_table_lookup (self->priv->id_to_app, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_lookup_app_by_tree_entry:
|
||||
* @system: a #ShellAppSystem
|
||||
* @entry: a #GMenuTreeEntry
|
||||
*
|
||||
* Find a #ShellApp corresponding to a #GMenuTreeEntry.
|
||||
*
|
||||
* Return value: (transfer none): The #ShellApp for @entry, or %NULL if none
|
||||
*/
|
||||
ShellApp *
|
||||
shell_app_system_lookup_app_by_tree_entry (ShellAppSystem *self,
|
||||
GMenuTreeEntry *entry)
|
||||
{
|
||||
/* If we looked up directly in ->entry_to_app, we'd lose the
|
||||
* override of running apps. Thus, indirect through the id.
|
||||
*/
|
||||
return shell_app_system_lookup_app (self, gmenu_tree_entry_get_desktop_file_id (entry));
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_lookup_app_for_path:
|
||||
* @system: a #ShellAppSystem
|
||||
* @desktop_path: (type utf8): UTF-8 encoded absolute file name
|
||||
*
|
||||
* Find or create a #ShellApp corresponding to a given absolute file
|
||||
* name which must be in the standard paths (XDG_DATA_DIRS). For
|
||||
* files outside the datadirs, this function returns %NULL.
|
||||
*
|
||||
* Return value: (transfer none): The #ShellApp for id, or %NULL if none
|
||||
*/
|
||||
ShellApp *
|
||||
shell_app_system_lookup_app_for_path (ShellAppSystem *system,
|
||||
const char *desktop_path)
|
||||
{
|
||||
const char *basename;
|
||||
const char *app_path;
|
||||
ShellApp *app;
|
||||
GDesktopAppInfo *info;
|
||||
|
||||
app = g_hash_table_lookup (priv->id_to_app, id);
|
||||
if (app)
|
||||
return app;
|
||||
basename = g_strrstr (desktop_path, "/");
|
||||
if (basename)
|
||||
basename += 1;
|
||||
else
|
||||
basename = desktop_path;
|
||||
|
||||
info = g_desktop_app_info_new (id);
|
||||
if (!info)
|
||||
app = shell_app_system_lookup_app (system, basename);
|
||||
if (!app)
|
||||
return NULL;
|
||||
|
||||
app_path = g_desktop_app_info_get_filename (shell_app_get_app_info (app));
|
||||
if (strcmp (desktop_path, app_path) != 0)
|
||||
return NULL;
|
||||
|
||||
app = _shell_app_new (info);
|
||||
g_hash_table_insert (priv->id_to_app, (char *) shell_app_get_id (app), app);
|
||||
g_object_unref (info);
|
||||
return app;
|
||||
}
|
||||
|
||||
@ -201,15 +520,15 @@ shell_app_system_lookup_heuristic_basename (ShellAppSystem *system,
|
||||
const char *name)
|
||||
{
|
||||
ShellApp *result;
|
||||
const char *const *prefix;
|
||||
GSList *prefix;
|
||||
|
||||
result = shell_app_system_lookup_app (system, name);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
|
||||
for (prefix = vendor_prefixes; *prefix != NULL; prefix++)
|
||||
for (prefix = system->priv->known_vendor_prefixes; prefix; prefix = g_slist_next (prefix))
|
||||
{
|
||||
char *tmpid = g_strconcat (*prefix, name, NULL);
|
||||
char *tmpid = g_strconcat ((char*)prefix->data, name, NULL);
|
||||
result = shell_app_system_lookup_app (system, tmpid);
|
||||
g_free (tmpid);
|
||||
if (result != NULL)
|
||||
@ -284,16 +603,10 @@ ShellApp *
|
||||
shell_app_system_lookup_startup_wmclass (ShellAppSystem *system,
|
||||
const char *wmclass)
|
||||
{
|
||||
const char *id;
|
||||
|
||||
if (wmclass == NULL)
|
||||
return NULL;
|
||||
|
||||
id = g_hash_table_lookup (system->priv->startup_wm_class_to_id, wmclass);
|
||||
if (id == NULL)
|
||||
return NULL;
|
||||
|
||||
return shell_app_system_lookup_app (system, id);
|
||||
return g_hash_table_lookup (system->priv->startup_wm_class_to_app, wmclass);
|
||||
}
|
||||
|
||||
void
|
||||
@ -368,22 +681,13 @@ sort_and_concat_results (ShellAppSystem *system,
|
||||
GSList *prefix_matches,
|
||||
GSList *substring_matches)
|
||||
{
|
||||
GSList *matches = NULL;
|
||||
GSList *l;
|
||||
|
||||
prefix_matches = g_slist_sort_with_data (prefix_matches,
|
||||
compare_apps_by_usage,
|
||||
system);
|
||||
substring_matches = g_slist_sort_with_data (substring_matches,
|
||||
compare_apps_by_usage,
|
||||
system);
|
||||
|
||||
for (l = substring_matches; l != NULL; l = l->next)
|
||||
matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
|
||||
for (l = prefix_matches; l != NULL; l = l->next)
|
||||
matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
|
||||
|
||||
return g_slist_reverse (matches);
|
||||
return g_slist_concat (prefix_matches, substring_matches);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -430,6 +734,7 @@ search_tree (ShellAppSystem *self,
|
||||
g_slist_free_full (normalized_terms, g_free);
|
||||
|
||||
return sort_and_concat_results (self, prefix_results, substring_results);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -439,26 +744,26 @@ search_tree (ShellAppSystem *self,
|
||||
*
|
||||
* Search through applications for the given search terms.
|
||||
*
|
||||
* Returns: (transfer container) (element-type utf8): List of applications
|
||||
* Returns: (transfer container) (element-type ShellApp): List of applications
|
||||
*/
|
||||
GSList *
|
||||
shell_app_system_initial_search (ShellAppSystem *self,
|
||||
GSList *terms)
|
||||
{
|
||||
return search_tree (self, terms, self->priv->id_to_app);
|
||||
return search_tree (self, terms, self->priv->visible_id_to_app);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_subsearch:
|
||||
* @system: A #ShellAppSystem
|
||||
* @previous_results: (element-type utf8): List of previous results
|
||||
* @previous_results: (element-type ShellApp): List of previous results
|
||||
* @terms: (element-type utf8): List of terms, logical AND
|
||||
*
|
||||
* Search through a previous result set; for more information, see
|
||||
* js/ui/search.js. Note that returned strings are only valid until
|
||||
* a return to the main loop.
|
||||
*
|
||||
* Returns: (transfer container) (element-type utf8): List of application identifiers
|
||||
* Returns: (transfer container) (element-type ShellApp): List of application identifiers
|
||||
*/
|
||||
GSList *
|
||||
shell_app_system_subsearch (ShellAppSystem *system,
|
||||
@ -474,8 +779,8 @@ shell_app_system_subsearch (ShellAppSystem *system,
|
||||
|
||||
for (iter = previous_results; iter; iter = iter->next)
|
||||
{
|
||||
ShellApp *app = shell_app_system_lookup_app (system, iter->data);
|
||||
|
||||
ShellApp *app = iter->data;
|
||||
|
||||
_shell_app_do_match (app, normalized_terms,
|
||||
&prefix_results,
|
||||
&substring_results);
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <gio/gio.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <meta/window.h>
|
||||
#define GMENU_I_KNOW_THIS_IS_UNSTABLE
|
||||
#include <gmenu-tree.h>
|
||||
|
||||
#include "shell-app.h"
|
||||
|
||||
@ -37,8 +39,14 @@ struct _ShellAppSystemClass
|
||||
GType shell_app_system_get_type (void) G_GNUC_CONST;
|
||||
ShellAppSystem *shell_app_system_get_default (void);
|
||||
|
||||
GMenuTree *shell_app_system_get_tree (ShellAppSystem *system);
|
||||
|
||||
ShellApp *shell_app_system_lookup_app (ShellAppSystem *system,
|
||||
const char *id);
|
||||
ShellApp *shell_app_system_lookup_app_by_tree_entry (ShellAppSystem *system,
|
||||
GMenuTreeEntry *entry);
|
||||
ShellApp *shell_app_system_lookup_app_for_path (ShellAppSystem *system,
|
||||
const char *desktop_path);
|
||||
ShellApp *shell_app_system_lookup_heuristic_basename (ShellAppSystem *system,
|
||||
const char *id);
|
||||
|
||||
|
150
src/shell-app.c
150
src/shell-app.c
@ -17,12 +17,6 @@
|
||||
#include "st.h"
|
||||
#include "gtkactionmuxer.h"
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-journal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MATCH_NONE,
|
||||
MATCH_SUBSTRING, /* Not prefix, substring */
|
||||
@ -43,7 +37,7 @@ typedef struct {
|
||||
GSList *windows;
|
||||
|
||||
/* Whether or not we need to resort the windows; this is done on demand */
|
||||
guint window_sort_stale : 1;
|
||||
gboolean window_sort_stale : 1;
|
||||
|
||||
/* DBus property notification subscription */
|
||||
guint properties_changed_id : 1;
|
||||
@ -59,7 +53,7 @@ typedef struct {
|
||||
* SECTION:shell-app
|
||||
* @short_description: Object representing an application
|
||||
*
|
||||
* This object wraps a #GDesktopAppInfo, providing methods and signals
|
||||
* This object wraps a #GMenuTreeEntry, providing methods and signals
|
||||
* primarily useful for running applications.
|
||||
*/
|
||||
struct _ShellApp
|
||||
@ -70,7 +64,7 @@ struct _ShellApp
|
||||
|
||||
ShellAppState state;
|
||||
|
||||
GDesktopAppInfo *info; /* If NULL, this app is backed by one or more
|
||||
GMenuTreeEntry *entry; /* If NULL, this app is backed by one or more
|
||||
* MetaWindow. For purposes of app title
|
||||
* etc., we use the first window added,
|
||||
* because it's most likely to be what we
|
||||
@ -143,15 +137,15 @@ shell_app_get_property (GObject *gobject,
|
||||
const char *
|
||||
shell_app_get_id (ShellApp *app)
|
||||
{
|
||||
if (app->info)
|
||||
return g_app_info_get_id (G_APP_INFO (app->info));
|
||||
if (app->entry)
|
||||
return gmenu_tree_entry_get_desktop_file_id (app->entry);
|
||||
return app->window_id_string;
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
window_backed_app_get_window (ShellApp *app)
|
||||
{
|
||||
g_assert (app->info == NULL);
|
||||
g_assert (app->entry == NULL);
|
||||
g_assert (app->running_state);
|
||||
g_assert (app->running_state->windows);
|
||||
return app->running_state->windows->data;
|
||||
@ -200,10 +194,10 @@ shell_app_create_icon_texture (ShellApp *app,
|
||||
|
||||
ret = NULL;
|
||||
|
||||
if (app->info == NULL)
|
||||
if (app->entry == NULL)
|
||||
return window_backed_app_get_icon (app, size);
|
||||
|
||||
icon = g_app_info_get_icon (G_APP_INFO (app->info));
|
||||
icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry)));
|
||||
if (icon != NULL)
|
||||
ret = st_texture_cache_load_gicon (st_texture_cache_get_default (), NULL, icon, size);
|
||||
|
||||
@ -251,7 +245,7 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache,
|
||||
|
||||
info = NULL;
|
||||
|
||||
icon = g_app_info_get_icon (G_APP_INFO (app->info));
|
||||
icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry)));
|
||||
if (icon != NULL)
|
||||
{
|
||||
info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (),
|
||||
@ -353,7 +347,7 @@ shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection directio
|
||||
* property tracking bits, and this helps us visually distinguish
|
||||
* app-tracked from not.
|
||||
*/
|
||||
if (!app->info)
|
||||
if (!app->entry)
|
||||
return window_backed_app_get_icon (app, size);
|
||||
|
||||
/* Use icon: prefix so that we get evicted from the cache on
|
||||
@ -390,8 +384,8 @@ shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection directio
|
||||
const char *
|
||||
shell_app_get_name (ShellApp *app)
|
||||
{
|
||||
if (app->info)
|
||||
return g_app_info_get_name (G_APP_INFO (app->info));
|
||||
if (app->entry)
|
||||
return g_app_info_get_name (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry)));
|
||||
else
|
||||
{
|
||||
MetaWindow *window = window_backed_app_get_window (app);
|
||||
@ -407,8 +401,8 @@ shell_app_get_name (ShellApp *app)
|
||||
const char *
|
||||
shell_app_get_description (ShellApp *app)
|
||||
{
|
||||
if (app->info)
|
||||
return g_app_info_get_description (G_APP_INFO (app->info));
|
||||
if (app->entry)
|
||||
return g_app_info_get_description (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry)));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@ -423,7 +417,7 @@ shell_app_get_description (ShellApp *app)
|
||||
gboolean
|
||||
shell_app_is_window_backed (ShellApp *app)
|
||||
{
|
||||
return app->info == NULL;
|
||||
return app->entry == NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -639,7 +633,12 @@ shell_app_activate_full (ShellApp *app,
|
||||
case SHELL_APP_STATE_STOPPED:
|
||||
{
|
||||
GError *error = NULL;
|
||||
if (!shell_app_launch (app, timestamp, workspace, &error))
|
||||
if (!shell_app_launch (app,
|
||||
timestamp,
|
||||
NULL,
|
||||
workspace,
|
||||
NULL,
|
||||
&error))
|
||||
{
|
||||
char *msg;
|
||||
msg = g_strdup_printf (_("Failed to launch '%s'"), shell_app_get_name (app));
|
||||
@ -671,7 +670,7 @@ void
|
||||
shell_app_open_new_window (ShellApp *app,
|
||||
int workspace)
|
||||
{
|
||||
g_return_if_fail (app->info != NULL);
|
||||
g_return_if_fail (app->entry != NULL);
|
||||
|
||||
/* Here we just always launch the application again, even if we know
|
||||
* it was already running. For most applications this
|
||||
@ -681,7 +680,12 @@ shell_app_open_new_window (ShellApp *app,
|
||||
* as say Pidgin. Ideally, we have the application express to us
|
||||
* that it supports an explicit new-window action.
|
||||
*/
|
||||
shell_app_launch (app, 0, workspace, NULL);
|
||||
shell_app_launch (app,
|
||||
0,
|
||||
NULL,
|
||||
workspace,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -861,24 +865,25 @@ _shell_app_new_for_window (MetaWindow *window)
|
||||
}
|
||||
|
||||
ShellApp *
|
||||
_shell_app_new (GDesktopAppInfo *info)
|
||||
_shell_app_new (GMenuTreeEntry *info)
|
||||
{
|
||||
ShellApp *app;
|
||||
|
||||
app = g_object_new (SHELL_TYPE_APP, NULL);
|
||||
|
||||
_shell_app_set_app_info (app, info);
|
||||
_shell_app_set_entry (app, info);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
void
|
||||
_shell_app_set_app_info (ShellApp *app,
|
||||
GDesktopAppInfo *info)
|
||||
_shell_app_set_entry (ShellApp *app,
|
||||
GMenuTreeEntry *entry)
|
||||
{
|
||||
g_clear_object (&app->info);
|
||||
app->info = g_object_ref (info);
|
||||
|
||||
if (app->entry != NULL)
|
||||
gmenu_tree_item_unref (app->entry);
|
||||
app->entry = gmenu_tree_item_ref (entry);
|
||||
|
||||
if (app->name_collation_key != NULL)
|
||||
g_free (app->name_collation_key);
|
||||
app->name_collation_key = g_utf8_collate_key (shell_app_get_name (app), -1);
|
||||
@ -1167,50 +1172,40 @@ _gather_pid_callback (GDesktopAppInfo *gapp,
|
||||
app);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
/* This sets up the launched application to log to the journal
|
||||
* using its own identifier, instead of just "gnome-session".
|
||||
*/
|
||||
static void
|
||||
app_child_setup (gpointer user_data)
|
||||
{
|
||||
const char *appid = user_data;
|
||||
int res;
|
||||
int journalfd = sd_journal_stream_fd (appid, LOG_INFO, FALSE);
|
||||
if (journalfd >= 0)
|
||||
{
|
||||
do
|
||||
res = dup2 (journalfd, 1);
|
||||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
do
|
||||
res = dup2 (journalfd, 2);
|
||||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
(void) close (journalfd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* shell_app_launch:
|
||||
* @timestamp: Event timestamp, or 0 for current event timestamp
|
||||
* @uris: (element-type utf8): List of uris to pass to application
|
||||
* @workspace: Start on this workspace, or -1 for default
|
||||
* @startup_id: (out): Returned startup notification ID, or %NULL if none
|
||||
* @error: A #GError
|
||||
*/
|
||||
gboolean
|
||||
shell_app_launch (ShellApp *app,
|
||||
guint timestamp,
|
||||
GList *uris,
|
||||
int workspace,
|
||||
char **startup_id,
|
||||
GError **error)
|
||||
{
|
||||
GDesktopAppInfo *gapp;
|
||||
GdkAppLaunchContext *context;
|
||||
gboolean ret;
|
||||
ShellGlobal *global;
|
||||
MetaScreen *screen;
|
||||
GdkDisplay *gdisplay;
|
||||
|
||||
if (app->info == NULL)
|
||||
if (startup_id)
|
||||
*startup_id = NULL;
|
||||
|
||||
if (app->entry == NULL)
|
||||
{
|
||||
MetaWindow *window = window_backed_app_get_window (app);
|
||||
/* We can't pass URIs into a window; shouldn't hit this
|
||||
* code path. If we do, fix the caller to disallow it.
|
||||
*/
|
||||
g_return_val_if_fail (uris == NULL, TRUE);
|
||||
|
||||
meta_window_activate (window, timestamp);
|
||||
return TRUE;
|
||||
}
|
||||
@ -1229,14 +1224,11 @@ shell_app_launch (ShellApp *app,
|
||||
gdk_app_launch_context_set_timestamp (context, timestamp);
|
||||
gdk_app_launch_context_set_desktop (context, workspace);
|
||||
|
||||
ret = g_desktop_app_info_launch_uris_as_manager (app->info, NULL,
|
||||
gapp = gmenu_tree_entry_get_app_info (app->entry);
|
||||
ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris,
|
||||
G_APP_LAUNCH_CONTEXT (context),
|
||||
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
#ifdef HAVE_SYSTEMD
|
||||
app_child_setup, (gpointer)shell_app_get_id (app),
|
||||
#else
|
||||
NULL, NULL,
|
||||
#endif
|
||||
_gather_pid_callback, app,
|
||||
error);
|
||||
g_object_unref (context);
|
||||
@ -1253,7 +1245,21 @@ shell_app_launch (ShellApp *app,
|
||||
GDesktopAppInfo *
|
||||
shell_app_get_app_info (ShellApp *app)
|
||||
{
|
||||
return app->info;
|
||||
if (app->entry)
|
||||
return gmenu_tree_entry_get_app_info (app->entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_get_tree_entry:
|
||||
* @app: a #ShellApp
|
||||
*
|
||||
* Returns: (transfer none): The #GMenuTreeEntry for this app, or %NULL if backed by a window
|
||||
*/
|
||||
GMenuTreeEntry *
|
||||
shell_app_get_tree_entry (ShellApp *app)
|
||||
{
|
||||
return app->entry;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1368,22 +1374,24 @@ shell_app_init_search_data (ShellApp *app)
|
||||
const char *exec;
|
||||
const char * const *keywords;
|
||||
char *normalized_exec;
|
||||
GDesktopAppInfo *appinfo;
|
||||
|
||||
name = g_app_info_get_name (G_APP_INFO (app->info));
|
||||
appinfo = gmenu_tree_entry_get_app_info (app->entry);
|
||||
name = g_app_info_get_name (G_APP_INFO (appinfo));
|
||||
app->casefolded_name = shell_util_normalize_casefold_and_unaccent (name);
|
||||
|
||||
generic_name = g_desktop_app_info_get_generic_name (app->info);
|
||||
generic_name = g_desktop_app_info_get_generic_name (appinfo);
|
||||
if (generic_name)
|
||||
app->casefolded_generic_name = shell_util_normalize_casefold_and_unaccent (generic_name);
|
||||
else
|
||||
app->casefolded_generic_name = NULL;
|
||||
|
||||
exec = g_app_info_get_executable (G_APP_INFO (app->info));
|
||||
exec = g_app_info_get_executable (G_APP_INFO (appinfo));
|
||||
normalized_exec = shell_util_normalize_casefold_and_unaccent (exec);
|
||||
app->casefolded_exec = trim_exec_line (normalized_exec);
|
||||
g_free (normalized_exec);
|
||||
|
||||
keywords = g_desktop_app_info_get_keywords (app->info);
|
||||
keywords = g_desktop_app_info_get_keywords (appinfo);
|
||||
|
||||
if (keywords)
|
||||
{
|
||||
@ -1504,14 +1512,16 @@ _shell_app_do_match (ShellApp *app,
|
||||
GSList **substring_results)
|
||||
{
|
||||
ShellAppSearchMatch match;
|
||||
GAppInfo *appinfo;
|
||||
|
||||
g_assert (app != NULL);
|
||||
|
||||
/* Skip window-backed apps */
|
||||
if (app->info == NULL)
|
||||
appinfo = (GAppInfo*)shell_app_get_app_info (app);
|
||||
if (appinfo == NULL)
|
||||
return;
|
||||
/* Skip not-visible apps */
|
||||
if (!g_app_info_should_show (G_APP_INFO (app->info)))
|
||||
if (!g_app_info_should_show (appinfo))
|
||||
return;
|
||||
|
||||
match = _shell_app_match_search_terms (app, terms);
|
||||
@ -1540,7 +1550,11 @@ shell_app_dispose (GObject *object)
|
||||
{
|
||||
ShellApp *app = SHELL_APP (object);
|
||||
|
||||
g_clear_object (&app->info);
|
||||
if (app->entry)
|
||||
{
|
||||
gmenu_tree_item_unref (app->entry);
|
||||
app->entry = NULL;
|
||||
}
|
||||
|
||||
if (app->running_state)
|
||||
{
|
||||
|
@ -4,8 +4,9 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <meta/window.h>
|
||||
#define GMENU_I_KNOW_THIS_IS_UNSTABLE
|
||||
#include <gmenu-tree.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -38,6 +39,7 @@ GType shell_app_get_type (void) G_GNUC_CONST;
|
||||
|
||||
const char *shell_app_get_id (ShellApp *app);
|
||||
|
||||
GMenuTreeEntry *shell_app_get_tree_entry (ShellApp *app);
|
||||
GDesktopAppInfo *shell_app_get_app_info (ShellApp *app);
|
||||
|
||||
ClutterActor *shell_app_create_icon_texture (ShellApp *app, int size);
|
||||
@ -71,7 +73,9 @@ gboolean shell_app_is_on_workspace (ShellApp *app, MetaWorkspace *workspace);
|
||||
|
||||
gboolean shell_app_launch (ShellApp *app,
|
||||
guint timestamp,
|
||||
GList *uris,
|
||||
int workspace,
|
||||
char **startup_id,
|
||||
GError **error);
|
||||
|
||||
int shell_app_compare_by_name (ShellApp *app, ShellApp *other);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gjs/gjs-module.h>
|
||||
#include <girepository.h>
|
||||
#include <meta/display.h>
|
||||
#include <meta/util.h>
|
||||
@ -33,11 +34,6 @@
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include "shell-enum-types.h"
|
||||
#include "shell-global-private.h"
|
||||
#include "shell-perf-log.h"
|
||||
@ -84,11 +80,10 @@ struct _ShellGlobal {
|
||||
const char *datadir;
|
||||
const char *imagedir;
|
||||
const char *userdatadir;
|
||||
GFile *userdatadir_path;
|
||||
GFile *runtime_state_path;
|
||||
|
||||
StFocusManager *focus_manager;
|
||||
|
||||
GFile *runtime_state_path;
|
||||
|
||||
guint work_count;
|
||||
GSList *leisure_closures;
|
||||
guint leisure_function_id;
|
||||
@ -257,7 +252,6 @@ shell_global_init (ShellGlobal *global)
|
||||
/* Ensure config dir exists for later use */
|
||||
global->userdatadir = g_build_filename (g_get_user_data_dir (), "gnome-shell", NULL);
|
||||
g_mkdir_with_parents (global->userdatadir, 0700);
|
||||
global->userdatadir_path = g_file_new_for_path (global->userdatadir);
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
byteorder_string = "LE";
|
||||
@ -288,16 +282,9 @@ shell_global_init (ShellGlobal *global)
|
||||
NULL);
|
||||
ca_context_open (global->sound_context);
|
||||
|
||||
if (shell_js)
|
||||
{
|
||||
search_path = g_strsplit (shell_js, ":", -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
search_path = g_malloc0 (2 * sizeof (char *));
|
||||
search_path[0] = g_strdup ("resource:///org/gnome/shell");
|
||||
}
|
||||
|
||||
if (!shell_js)
|
||||
shell_js = JSDIR;
|
||||
search_path = g_strsplit (shell_js, ":", -1);
|
||||
global->js_context = g_object_new (GJS_TYPE_CONTEXT,
|
||||
"search-path", search_path,
|
||||
"js-version", "1.8",
|
||||
@ -319,7 +306,6 @@ shell_global_finalize (GObject *object)
|
||||
|
||||
the_object = NULL;
|
||||
|
||||
g_clear_object (&global->userdatadir_path);
|
||||
g_clear_object (&global->runtime_state_path);
|
||||
|
||||
G_OBJECT_CLASS(shell_global_parent_class)->finalize (object);
|
||||
@ -1114,30 +1100,20 @@ shell_global_reexec_self (ShellGlobal *global)
|
||||
char *buf_p;
|
||||
char *buf_end;
|
||||
GError *error = NULL;
|
||||
|
||||
#if defined __linux__
|
||||
|
||||
/* Linux specific (I think, anyways). */
|
||||
if (!g_file_get_contents ("/proc/self/cmdline", &buf, &len, &error))
|
||||
{
|
||||
g_warning ("failed to get /proc/self/cmdline: %s", error->message);
|
||||
return;
|
||||
}
|
||||
#elif defined __OpenBSD__
|
||||
int pid = getpid();
|
||||
int mib[] = { CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV };
|
||||
if (sysctl(mib, G_N_ELEMENTS (mib), &buf, &len, NULL, 0) == -1) {
|
||||
g_warning ("failed to get command line args: %d", errno);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
buf_end = buf+len;
|
||||
arr = g_ptr_array_new ();
|
||||
/* The cmdline file is NUL-separated */
|
||||
for (buf_p = buf; buf_p < buf_end; buf_p = buf_p + strlen (buf_p) + 1)
|
||||
g_ptr_array_add (arr, buf_p);
|
||||
|
||||
|
||||
g_ptr_array_add (arr, NULL);
|
||||
|
||||
/* Close all file descriptors other than stdin/stdout/stderr, otherwise
|
||||
@ -1163,6 +1139,44 @@ shell_global_on_gc (GjsContext *context,
|
||||
global->last_gc_end_time = g_get_monotonic_time ();
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_get_memory_info:
|
||||
* @global:
|
||||
* @meminfo: (out caller-allocates): Output location for memory information
|
||||
*
|
||||
* Load process-global data about memory usage.
|
||||
*/
|
||||
void
|
||||
shell_global_get_memory_info (ShellGlobal *global,
|
||||
ShellMemoryInfo *meminfo)
|
||||
{
|
||||
JSContext *context;
|
||||
gint64 now;
|
||||
|
||||
#ifdef HAVE_MALLINFO
|
||||
{
|
||||
struct mallinfo info = mallinfo ();
|
||||
meminfo->glibc_uordblks = info.uordblks;
|
||||
}
|
||||
#else
|
||||
meminfo->glibc_uordblks = 0;
|
||||
#endif
|
||||
|
||||
context = gjs_context_get_native_context (global->js_context);
|
||||
|
||||
meminfo->js_bytes = JS_GetGCParameter (JS_GetRuntime (context), JSGC_BYTES);
|
||||
|
||||
meminfo->gjs_boxed = (unsigned int) gjs_counter_boxed.value;
|
||||
meminfo->gjs_gobject = (unsigned int) gjs_counter_object.value;
|
||||
meminfo->gjs_function = (unsigned int) gjs_counter_function.value;
|
||||
meminfo->gjs_closure = (unsigned int) gjs_counter_closure.value;
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
|
||||
meminfo->last_gc_seconds_ago = (now - global->last_gc_end_time) / G_TIME_SPAN_SECOND;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* shell_global_notify_error:
|
||||
* @global: a #ShellGlobal
|
||||
@ -1732,14 +1746,31 @@ shell_global_get_session_mode (ShellGlobal *global)
|
||||
return global->session_mode;
|
||||
}
|
||||
|
||||
static void
|
||||
save_variant (GFile *dir,
|
||||
const char *property_name,
|
||||
GVariant *variant)
|
||||
static GFile *
|
||||
get_runtime_state_path (ShellGlobal *global,
|
||||
const char *property_name)
|
||||
{
|
||||
GFile *path = g_file_get_child (dir, property_name);
|
||||
return g_file_get_child (global->runtime_state_path, property_name);
|
||||
}
|
||||
|
||||
if (variant == NULL || g_variant_get_data (variant) == NULL)
|
||||
/**
|
||||
* shell_global_set_runtime_state:
|
||||
* @global: a #ShellGlobal
|
||||
* @property_name: Name of the property
|
||||
* @variant: (allow-none): A #GVariant, or %NULL to unset
|
||||
*
|
||||
* Change the value of serialized runtime state.
|
||||
*/
|
||||
void
|
||||
shell_global_set_runtime_state (ShellGlobal *global,
|
||||
const char *property_name,
|
||||
GVariant *variant)
|
||||
{
|
||||
GFile *path;
|
||||
|
||||
path = get_runtime_state_path (global, property_name);
|
||||
|
||||
if (variant == NULL)
|
||||
(void) g_file_delete (path, NULL, NULL);
|
||||
else
|
||||
{
|
||||
@ -1752,17 +1783,29 @@ save_variant (GFile *dir,
|
||||
g_object_unref (path);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
load_variant (GFile *dir,
|
||||
const char *property_type,
|
||||
const char *property_name)
|
||||
/**
|
||||
* shell_global_get_runtime_state:
|
||||
* @global: a #ShellGlobal
|
||||
* @property_type: Expected data type
|
||||
* @property_name: Name of the property
|
||||
*
|
||||
* The shell maintains "runtime" state which does not persist across
|
||||
* logout or reboot.
|
||||
*
|
||||
* Returns: (transfer floating): The value of a serialized property, or %NULL if none stored
|
||||
*/
|
||||
GVariant *
|
||||
shell_global_get_runtime_state (ShellGlobal *global,
|
||||
const char *property_type,
|
||||
const char *property_name)
|
||||
{
|
||||
GVariant *res = NULL;
|
||||
GMappedFile *mfile;
|
||||
GFile *path = g_file_get_child (dir, property_name);
|
||||
GFile *path;
|
||||
char *pathstr;
|
||||
GError *local_error = NULL;
|
||||
|
||||
path = get_runtime_state_path (global, property_name);
|
||||
pathstr = g_file_get_path (path);
|
||||
mfile = g_mapped_file_new (pathstr, FALSE, &local_error);
|
||||
if (!mfile)
|
||||
@ -1786,73 +1829,3 @@ load_variant (GFile *dir,
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_set_runtime_state:
|
||||
* @global: a #ShellGlobal
|
||||
* @property_name: Name of the property
|
||||
* @variant: (allow-none): A #GVariant, or %NULL to unset
|
||||
*
|
||||
* Change the value of serialized runtime state.
|
||||
*/
|
||||
void
|
||||
shell_global_set_runtime_state (ShellGlobal *global,
|
||||
const char *property_name,
|
||||
GVariant *variant)
|
||||
{
|
||||
save_variant (global->runtime_state_path, property_name, variant);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_get_runtime_state:
|
||||
* @global: a #ShellGlobal
|
||||
* @property_type: Expected data type
|
||||
* @property_name: Name of the property
|
||||
*
|
||||
* The shell maintains "runtime" state which does not persist across
|
||||
* logout or reboot.
|
||||
*
|
||||
* Returns: (transfer floating): The value of a serialized property, or %NULL if none stored
|
||||
*/
|
||||
GVariant *
|
||||
shell_global_get_runtime_state (ShellGlobal *global,
|
||||
const char *property_type,
|
||||
const char *property_name)
|
||||
{
|
||||
return load_variant (global->runtime_state_path, property_type, property_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_set_persistent_state:
|
||||
* @global: a #ShellGlobal
|
||||
* @property_name: Name of the property
|
||||
* @variant: (allow-none): A #GVariant, or %NULL to unset
|
||||
*
|
||||
* Change the value of serialized persistent state.
|
||||
*/
|
||||
void
|
||||
shell_global_set_persistent_state (ShellGlobal *global,
|
||||
const char *property_name,
|
||||
GVariant *variant)
|
||||
{
|
||||
save_variant (global->userdatadir_path, property_name, variant);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_get_persistent_state:
|
||||
* @global: a #ShellGlobal
|
||||
* @property_type: Expected data type
|
||||
* @property_name: Name of the property
|
||||
*
|
||||
* The shell maintains "persistent" state which will persist after
|
||||
* logout or reboot.
|
||||
*
|
||||
* Returns: (transfer none): The value of a serialized property, or %NULL if none stored
|
||||
*/
|
||||
GVariant *
|
||||
shell_global_get_persistent_state (ShellGlobal *global,
|
||||
const char *property_type,
|
||||
const char *property_name)
|
||||
{
|
||||
return load_variant (global->userdatadir_path, property_type, property_name);
|
||||
}
|
||||
|
@ -69,6 +69,10 @@ typedef struct {
|
||||
guint last_gc_seconds_ago;
|
||||
} ShellMemoryInfo;
|
||||
|
||||
void shell_global_get_memory_info (ShellGlobal *global,
|
||||
ShellMemoryInfo *meminfo);
|
||||
|
||||
|
||||
/* Run-at-leisure API */
|
||||
void shell_global_begin_work (ShellGlobal *global);
|
||||
void shell_global_end_work (ShellGlobal *global);
|
||||
@ -125,19 +129,13 @@ void shell_global_reexec_self (ShellGlobal *global);
|
||||
|
||||
const char * shell_global_get_session_mode (ShellGlobal *global);
|
||||
|
||||
void shell_global_set_runtime_state (ShellGlobal *global,
|
||||
const char *property_name,
|
||||
GVariant *variant);
|
||||
void shell_global_set_runtime_state (ShellGlobal *global,
|
||||
const char *property_name,
|
||||
GVariant *variant);
|
||||
GVariant * shell_global_get_runtime_state (ShellGlobal *global,
|
||||
const char *property_type,
|
||||
const char *property_name);
|
||||
|
||||
void shell_global_set_persistent_state (ShellGlobal *global,
|
||||
const char *property_name,
|
||||
GVariant *variant);
|
||||
GVariant * shell_global_get_persistent_state (ShellGlobal *global,
|
||||
const char *property_type,
|
||||
const char *property_name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -38,7 +38,7 @@ shell_js_add_extension_importer (const char *target_object_script,
|
||||
* we should only ever have one context, so this
|
||||
* should be alright. */
|
||||
contexts = gjs_context_get_all ();
|
||||
context = (JSContext*) gjs_context_get_native_context ((GjsContext*)contexts->data);
|
||||
context = gjs_context_get_native_context (contexts->data);
|
||||
g_list_free_full (contexts, g_object_unref);
|
||||
|
||||
JS_BeginRequest (context);
|
@ -844,7 +844,6 @@ ShellApp *
|
||||
shell_startup_sequence_get_app (ShellStartupSequence *sequence)
|
||||
{
|
||||
const char *appid;
|
||||
char *basename;
|
||||
ShellAppSystem *appsys;
|
||||
ShellApp *app;
|
||||
|
||||
@ -852,10 +851,8 @@ shell_startup_sequence_get_app (ShellStartupSequence *sequence)
|
||||
if (!appid)
|
||||
return NULL;
|
||||
|
||||
basename = g_path_get_basename (appid);
|
||||
appsys = shell_app_system_get_default ();
|
||||
app = shell_app_system_lookup_app (appsys, basename);
|
||||
g_free (basename);
|
||||
app = shell_app_system_lookup_app_for_path (appsys, appid);
|
||||
return app;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ struct _StAdjustmentPrivate
|
||||
{
|
||||
/* Do not sanity-check values while constructing,
|
||||
* not all properties may be set yet. */
|
||||
guint is_constructing : 1;
|
||||
gboolean is_constructing : 1;
|
||||
|
||||
gdouble lower;
|
||||
gdouble upper;
|
||||
|
@ -98,8 +98,8 @@ struct _StScrollViewPrivate
|
||||
|
||||
StScrollViewFade *fade_effect;
|
||||
|
||||
guint row_size_set : 1;
|
||||
guint column_size_set : 1;
|
||||
gboolean row_size_set : 1;
|
||||
gboolean column_size_set : 1;
|
||||
guint mouse_scroll : 1;
|
||||
guint overlay_scrollbars : 1;
|
||||
guint hscrollbar_visible : 1;
|
||||
|
@ -45,7 +45,10 @@
|
||||
#include "st-theme-node.h"
|
||||
#include "st-theme-private.h"
|
||||
|
||||
static void st_theme_constructed (GObject *object);
|
||||
static GObject *st_theme_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
GObjectConstructParam *construct_properties);
|
||||
|
||||
static void st_theme_finalize (GObject *object);
|
||||
static void st_theme_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -111,7 +114,7 @@ st_theme_class_init (StThemeClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = st_theme_constructed;
|
||||
object_class->constructor = st_theme_constructor;
|
||||
object_class->finalize = st_theme_finalize;
|
||||
object_class->set_property = st_theme_set_property;
|
||||
object_class->get_property = st_theme_get_property;
|
||||
@ -299,15 +302,21 @@ st_theme_get_custom_stylesheets (StTheme *theme)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
st_theme_constructed (GObject *object)
|
||||
static GObject *
|
||||
st_theme_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
GObjectConstructParam *construct_properties)
|
||||
{
|
||||
StTheme *theme = ST_THEME (object);
|
||||
GObject *object;
|
||||
StTheme *theme;
|
||||
CRStyleSheet *application_stylesheet;
|
||||
CRStyleSheet *theme_stylesheet;
|
||||
CRStyleSheet *default_stylesheet;
|
||||
|
||||
G_OBJECT_CLASS (st_theme_parent_class)->constructed (object);
|
||||
object = (*G_OBJECT_CLASS (st_theme_parent_class)->constructor) (type,
|
||||
n_construct_properties,
|
||||
construct_properties);
|
||||
theme = ST_THEME (object);
|
||||
|
||||
application_stylesheet = parse_stylesheet_nofail (theme->application_stylesheet);
|
||||
theme_stylesheet = parse_stylesheet_nofail (theme->theme_stylesheet);
|
||||
@ -323,6 +332,8 @@ st_theme_constructed (GObject *object)
|
||||
insert_stylesheet (theme, theme->application_stylesheet, application_stylesheet);
|
||||
insert_stylesheet (theme, theme->theme_stylesheet, theme_stylesheet);
|
||||
insert_stylesheet (theme, theme->default_stylesheet, default_stylesheet);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -59,12 +59,13 @@ struct _StWidgetPrivate
|
||||
|
||||
StThemeNodeTransition *transition_animation;
|
||||
|
||||
guint is_style_dirty : 1;
|
||||
guint draw_bg_color : 1;
|
||||
guint draw_border_internal : 1;
|
||||
guint track_hover : 1;
|
||||
guint hover : 1;
|
||||
guint can_focus : 1;
|
||||
gboolean is_stylable : 1;
|
||||
gboolean is_style_dirty : 1;
|
||||
gboolean draw_bg_color : 1;
|
||||
gboolean draw_border_internal : 1;
|
||||
gboolean track_hover : 1;
|
||||
gboolean hover : 1;
|
||||
gboolean can_focus : 1;
|
||||
|
||||
gulong texture_file_changed_id;
|
||||
|
||||
@ -104,6 +105,7 @@ enum
|
||||
PROP_PSEUDO_CLASS,
|
||||
PROP_STYLE_CLASS,
|
||||
PROP_STYLE,
|
||||
PROP_STYLABLE,
|
||||
PROP_TRACK_HOVER,
|
||||
PROP_HOVER,
|
||||
PROP_CAN_FOCUS,
|
||||
@ -162,6 +164,14 @@ st_widget_set_property (GObject *gobject,
|
||||
st_widget_set_style (actor, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_STYLABLE:
|
||||
if (actor->priv->is_stylable != g_value_get_boolean (value))
|
||||
{
|
||||
actor->priv->is_stylable = g_value_get_boolean (value);
|
||||
clutter_actor_queue_relayout ((ClutterActor *) gobject);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_TRACK_HOVER:
|
||||
st_widget_set_track_hover (actor, g_value_get_boolean (value));
|
||||
break;
|
||||
@ -219,6 +229,10 @@ st_widget_get_property (GObject *gobject,
|
||||
g_value_set_string (value, priv->inline_style);
|
||||
break;
|
||||
|
||||
case PROP_STYLABLE:
|
||||
g_value_set_boolean (value, priv->is_stylable);
|
||||
break;
|
||||
|
||||
case PROP_TRACK_HOVER:
|
||||
g_value_set_boolean (value, priv->track_hover);
|
||||
break;
|
||||
@ -324,8 +338,17 @@ st_widget_dispose (GObject *gobject)
|
||||
StWidget *actor = ST_WIDGET (gobject);
|
||||
StWidgetPrivate *priv = ST_WIDGET (actor)->priv;
|
||||
|
||||
g_clear_pointer (&priv->theme, g_object_unref);
|
||||
g_clear_pointer (&priv->theme_node, g_object_unref);
|
||||
if (priv->theme)
|
||||
{
|
||||
g_object_unref (priv->theme);
|
||||
priv->theme = NULL;
|
||||
}
|
||||
|
||||
if (priv->theme_node)
|
||||
{
|
||||
g_object_unref (priv->theme_node);
|
||||
priv->theme_node = NULL;
|
||||
}
|
||||
|
||||
st_widget_remove_transition (actor);
|
||||
|
||||
@ -335,7 +358,11 @@ st_widget_dispose (GObject *gobject)
|
||||
if (priv->accessible)
|
||||
priv->accessible = NULL;
|
||||
|
||||
g_clear_pointer (&priv->label_actor, g_object_unref);
|
||||
if (priv->label_actor)
|
||||
{
|
||||
g_object_unref (priv->label_actor);
|
||||
priv->label_actor = NULL;
|
||||
}
|
||||
|
||||
if (priv->texture_file_changed_id != 0)
|
||||
{
|
||||
@ -524,6 +551,12 @@ notify_children_of_style_change (ClutterActor *self)
|
||||
static void
|
||||
st_widget_real_style_changed (StWidget *self)
|
||||
{
|
||||
StWidgetPrivate *priv = ST_WIDGET (self)->priv;
|
||||
|
||||
/* application has request this widget is not stylable */
|
||||
if (!priv->is_stylable)
|
||||
return;
|
||||
|
||||
clutter_actor_queue_redraw ((ClutterActor *) self);
|
||||
notify_children_of_style_change ((ClutterActor *) self);
|
||||
}
|
||||
@ -909,6 +942,20 @@ st_widget_class_init (StWidgetClass *klass)
|
||||
ST_TYPE_THEME,
|
||||
ST_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* StWidget:stylable:
|
||||
*
|
||||
* Enable or disable styling of the widget
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("stylable",
|
||||
"Stylable",
|
||||
"Whether the table should be styled",
|
||||
TRUE,
|
||||
ST_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_STYLABLE,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* StWidget:track-hover:
|
||||
*
|
||||
@ -1499,6 +1546,7 @@ st_widget_init (StWidget *actor)
|
||||
int i;
|
||||
|
||||
actor->priv = priv = ST_WIDGET_GET_PRIVATE (actor);
|
||||
priv->is_stylable = TRUE;
|
||||
priv->transition_animation = NULL;
|
||||
priv->local_state_set = atk_state_set_new ();
|
||||
|
||||
|
Reference in New Issue
Block a user