Compare commits

..

3 Commits

Author SHA1 Message Date
d2052a885e NetworkMenu: use async initialization for libnm-glib objects
NMClient recently got more heavyweight, with a property holding supported
connections. As fully initializing a NMObject is a recursive operation
and requires multiple DBus calls, switch to async initalization for NMClient
and NMRemoteSettings.

https://bugzilla.gnome.org/show_bug.cgi?id=683288
2012-11-02 14:11:10 +01:00
afcc1b7b52 Try to do more async initialization
Synchronous calls in the main loop are a performance killer, especially
at login.
2012-11-02 14:11:10 +01:00
a6b4d68a1d Port to GDBus 2
The GDBus bindings in gjs have been updated to leverage metaclasses
and gobject inheritance, which should result in cleaner and more
maintainable code.
2012-11-02 14:11:10 +01:00
95 changed files with 3121 additions and 3824 deletions

1
.gitignore vendored
View File

@ -45,7 +45,6 @@ intltool-merge.in
intltool-update.in intltool-update.in
libtool libtool
m4/ m4/
man/gnome-shell.1
omf.make omf.make
po/*.gmo po/*.gmo
po/gnome-shell.pot po/gnome-shell.pot

View File

@ -1,11 +1,7 @@
# Point to our macro directory and pick up user flags from the environment # Point to our macro directory and pick up user flags from the environment
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
SUBDIRS = data js src browser-plugin tests po docs SUBDIRS = data js src browser-plugin tests po man docs
if ENABLE_MAN
SUBDIRS += man
endif
EXTRA_DIST = \ EXTRA_DIST = \
.project \ .project \
@ -25,4 +21,4 @@ distcheck-hook:
@echo "Checking disted files against files in git" @echo "Checking disted files against files in git"
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE) @$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-man DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc

67
NEWS
View File

@ -1,70 +1,3 @@
3.7.2.1
=======
* Revert 490206b to not depend on NMGTK-0.9.7, which hasn't been released yet
3.7.2
=====
* Enforce RTL in he for messages that might end up as LTR [Florian; #686630]
* gdm: Move logo into the panel [Florian; #685852]
* Hide notifications when closed button is clicked [Jasper, Florian; #682237]
* Tweak screenShield animations [Rui; #686745]
* Restore Fittsability of summary items in message tray [Florian; #686474]
* Save screencasts as recent item [Ray; #680647]
* overview: Resize window captions on content change [Giovanni, Alex; #620874]
* App search: Match GenericName too [Matthias; #687121]
* runDialog: Better match style of other modal dialogs [Florian, Allan; #687127]
* Improve the button insensitive style [Stéphane; #687110]
* network: Don't use a global switch for all VPN connections [Giovanni; #682929]
* appMenu: Update on icon theme changes [Florian; #687224]
* Show 'Log out' in more situations [Matthias; #686736]
* Add a setting to force the 'Log out' menuitem [Matthias; #686057]
* overview: Improve styling of search box [Stéphane; #686479]
* Implement 'disable-user-list' in login screen [Ray; #660660]
* Fix auto-scroll to bottom in chat notifications [Sjoerd; #686571]
* Show feedback notifications when user is busy [Stéphane; #662900]
* Disable login button when there is no input [Stéphane; #687112]
* Use non-linear overview shade for background [Giovanni, Pierre-Eric; #669798]
* Reduce blocking in compositor thread [Simon, Jasper; #687465]
* network: new country-specific type to gather providers [Aleksander; #687356]
* Update man page [Matthias; #680601]
* st-entry: Change the pointer cursor on enter/leave events [Thomas; #687130]
* screenShield: Blur and desaturate the background [Giovanni, Cosimo; #682536]
* Change height of chat notifications to have more context [Carlos; #665255]
* screenShield: Account for motion velocity when hiding [Giovanni; #682537]
* screenShield: hide the cursor while the lock screen is on [Giovanni; #682535]
* Support remote search provider settings [Cosimo; #687491]
* unlockDialog: Improve label of confirmation button [Stéphane; #687656]
* userMenu: Rename "System Settings" item to "Settings" [Elad; #687738]
* messageTray: Add keybinding to focus current notification [Stéphane; #652082]
* Remove shell-screen-grabber [Neil; #685915]
* main: Stop using Metacity's keybinding files [Florian; #687672]
* Bluetooth: Remove ObexFTP functionality [Bastien; #688160]
* a11y: Also set WM theme when HighContrast is switched on [Cosimo; #688256]
* network: Rework multiple NIC support [Giovanni; #677142]
* Rework keybindings to allow selective blocking/processing [Florian; #688202]
* recorder: Show indicator on primary monitor [Adel; #688470]
* recorder: Set frame duration to fix broken video headers [Adel; #688487]
* Misc. bugfixes and cleanups [Florian, Jasper, Giovanni, Matthew, Stéphane,
Allan, Daiki, Owen, Alejandro, Jean-François, Cosimo, Sebastian, Adel, Alban;
#686484, #686728, #686805, #686574, #686763, #682428, #687132, #685239,
#687189, #687226, #658091, #670687, #687457, #687242, #687287, #687020,
#686583, #661194, #687491, #657315, #687958, #683986, #688089, #687708,
#686530, #684810, #688181, #688475, #688557, #688507, #638351]
Contributors:
Elad Alfassa, Matthew Barnes, Alban Browaeys, Giovanni Campagna,
Cosimo Cecchi, Matthias Clasen, Allan Day, Stéphane Démurget,
Jean-François Fortin Tam, Adel Gadllah, Alex Hultman, Sebastian Keller,
Rui Matos, Simon McVittie, Aleksander Morgado, Florian Müllner,
Bastien Nocera, Pierre-Eric Pelloux-Prayer, Alejandro Piñeiro, Neil Roberts,
Sjoerd Simons, Carlos Soriano Sánchez, Jasper St. Pierre, Ray Strode,
Owen Taylor, Daiki Ueno, Thomas Wood
Translations:
Dušan Kazik [sk], Pavol Klačanský [sk], Piotr Drąg [pl], Yuri Myasoedov [ru],
Marek Černocký [cs], Kjartan Maraas [nb], Wolfgang Stöggl [de],
Yaron Shahrabani [he], Fran Diéguez [gl], Mattias Põldaru [et]
3.7.1 3.7.1
===== =====
* Add shortcut to open application view directly [Jeremy; #685738] * Add shortcut to open application view directly [Jeremy; #685738]

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.63) AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.7.2.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell]) AC_INIT([gnome-shell],[3.7.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c]) AC_CONFIG_SRCDIR([src/shell-global.c])
@ -36,8 +36,6 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
PKG_PROG_PKG_CONFIG([0.22]) PKG_PROG_PKG_CONFIG([0.22])
AC_PATH_PROG([XSLTPROC], [xsltproc])
GLIB_GSETTINGS GLIB_GSETTINGS
# Get a value to substitute into gnome-shell.in # Get a value to substitute into gnome-shell.in
@ -65,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.11.11 CLUTTER_MIN_VERSION=1.11.11
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1 GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.33.2 GJS_MIN_VERSION=1.33.2
MUTTER_MIN_VERSION=3.7.2 MUTTER_MIN_VERSION=3.7.1
GTK_MIN_VERSION=3.3.9 GTK_MIN_VERSION=3.3.9
GIO_MIN_VERSION=2.35.0 GIO_MIN_VERSION=2.35.0
LIBECAL_MIN_VERSION=3.5.3 LIBECAL_MIN_VERSION=3.5.3
@ -124,7 +122,7 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11) PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
PKG_CHECK_MODULES(TRAY, gtk+-3.0) PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0) PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.2) PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.4)
AC_MSG_CHECKING([for bluetooth support]) AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0], PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
@ -209,18 +207,6 @@ AC_SUBST(TYPELIBDIR)
GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
AC_ARG_ENABLE(man,
[AS_HELP_STRING([--enable-man],
[generate man pages [default=yes]])],,
enable_man=yes)
if test "$enable_man" != no; then
AC_PATH_PROG([XSLTPROC], [xsltproc])
if test -z "$XSLTPROC"; then
AC_MSG_ERROR([xsltproc is required for --enable-man])
fi
fi
AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no)
# Stay command-line compatible with the gnome-common configure option. Here # Stay command-line compatible with the gnome-common configure option. Here
# minimum/yes/maximum are the same, however. # minimum/yes/maximum are the same, however.
AC_ARG_ENABLE(compile_warnings, AC_ARG_ENABLE(compile_warnings,

View File

@ -8,9 +8,6 @@
<KeyListEntry name="toggle-message-tray" <KeyListEntry name="toggle-message-tray"
_description="Show the message tray"/> _description="Show the message tray"/>
<KeyListEntry name="focus-active-notification"
_description="Focus the active notification"/>
<KeyListEntry name="toggle-application-view" <KeyListEntry name="toggle-application-view"
_description="Show all applications"/> _description="Show all applications"/>

View File

@ -106,13 +106,6 @@ value here is from the GsmPresenceStatus enumeration.</_summary>
Keybinding to toggle the visibility of the message tray. Keybinding to toggle the visibility of the message tray.
</_description> </_description>
</key> </key>
<key name="focus-active-notification" type="as">
<default>["&lt;Super&gt;n"]</default>
<_summary>Keybinding to focus the active notification</_summary>
<_description>
Keybinding to focus the active notification.
</_description>
</key>
<key name="toggle-recording" type="as"> <key name="toggle-recording" type="as">
<default><![CDATA[['<Control><Shift><Alt>r']]]></default> <default><![CDATA[['<Control><Shift><Alt>r']]]></default>
<_summary>Keybinding to toggle the screen recorder</_summary> <_summary>Keybinding to toggle the screen recorder</_summary>

View File

@ -1432,10 +1432,6 @@ StScrollBar StButton#vhandle:active {
padding-right: 4px; padding-right: 4px;
} }
.chat-notification-scrollview{
max-height: 22em;
}
.subscription-message { .subscription-message {
font-style: italic; font-style: italic;
} }
@ -2129,7 +2125,7 @@ StScrollBar StButton#vhandle:active {
font-weight: bold; font-weight: bold;
text-align: left; text-align: left;
padding-left: 15px; padding-left: 15px;
text-shadow: black 0px 4px 3px 0px; text-shadow: black 4px 4px 3px 0px;
} }
.login-dialog-prompt-layout { .login-dialog-prompt-layout {

View File

@ -21,7 +21,16 @@ const GnomeShellIface = <interface name="org.gnome.Shell.Extensions">
</signal> </signal>
</interface>; </interface>;
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface); const GnomeShellProxy = new Gio.DBusProxyClass({
Name: 'GnomeShellProxy',
Interface: GnomeShellIface,
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.gnome.Shell',
g_object_path: '/org/gnome/Shell' });
}
});
function stripPrefix(string, prefix) { function stripPrefix(string, prefix) {
if (string.slice(0, prefix.length) == prefix) if (string.slice(0, prefix.length) == prefix)
@ -191,7 +200,8 @@ const Application = new Lang.Class({
this._extensionPrefsBin.add(label); this._extensionPrefsBin.add(label);
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell'); this._shellProxy = new GnomeShellProxy();
this._shellProxy.init(null);
this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) { this._shellProxy.connectSignal('ExtensionStatusChanged', Lang.bind(this, function(proxy, senderName, [uuid, state, error]) {
if (ExtensionUtils.extensions[uuid] !== undefined) if (ExtensionUtils.extensions[uuid] !== undefined)
this._scanExtensions(); this._scanExtensions();

View File

@ -11,16 +11,14 @@ const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
</method> </method>
</interface>; </interface>;
const FprintManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(FprintManagerIface); const FprintManager = new Gio.DBusProxyClass({
Name: 'FprintManager',
Interface: FprintManagerIface,
function FprintManager() { _init: function() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system, this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_interface_name: FprintManagerInfo.name, g_name: 'net.reactivated.Fprint',
g_interface_info: FprintManagerInfo, g_object_path: '/net/reactivated/Fprint/Manager',
g_name: 'net.reactivated.Fprint', g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
g_object_path: '/net/reactivated/Fprint/Manager', }
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) }); });
self.init(null);
return self;
}

View File

@ -660,7 +660,6 @@ const LoginDialog = new Lang.Class({
this.parent({ shellReactive: true, this.parent({ shellReactive: true,
styleClass: 'login-dialog', styleClass: 'login-dialog',
parentActor: parentActor, parentActor: parentActor,
keybindingMode: Main.KeybindingMode.LOGIN_SCREEN,
shouldFadeIn: false }); shouldFadeIn: false });
this.connect('destroy', this.connect('destroy',
Lang.bind(this, this._onDestroy)); Lang.bind(this, this._onDestroy));
@ -685,10 +684,9 @@ const LoginDialog = new Lang.Class({
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient); this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient);
this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion)); this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion));
this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage)); this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
this._userVerifier.connect('reset', Lang.bind(this, this._reset)); this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint)); this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
this._verifyingUser = false;
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
@ -696,8 +694,6 @@ const LoginDialog = new Lang.Class({
Lang.bind(this, this._updateBanner)); Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY, this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
Lang.bind(this, this._updateBanner)); Lang.bind(this, this._updateBanner));
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
Lang.bind(this, this._updateDisableUserList));
this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
text: '' }); text: '' });
@ -705,8 +701,7 @@ const LoginDialog = new Lang.Class({
this._updateBanner(); this._updateBanner();
this._titleLabel = new St.Label({ style_class: 'login-dialog-title', this._titleLabel = new St.Label({ style_class: 'login-dialog-title',
text: C_("title", "Sign In"), text: C_("title", "Sign In") });
visible: false });
this.contentLayout.add(this._titleLabel, this.contentLayout.add(this._titleLabel,
{ y_fill: false, { y_fill: false,
@ -736,7 +731,6 @@ const LoginDialog = new Lang.Class({
x_align: St.Align.START }); x_align: St.Align.START });
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry', this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
can_focus: true }); can_focus: true });
this._promptEntryTextChangedId = 0;
this._promptBox.add(this._promptEntry, this._promptBox.add(this._promptEntry,
{ expand: true, { expand: true,
x_fill: true, x_fill: true,
@ -775,7 +769,7 @@ const LoginDialog = new Lang.Class({
x_align: St.Align.START, x_align: St.Align.START,
x_fill: true }); x_fill: true });
this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.connect('clicked', Lang.bind(this, this._onNotListedClicked));
this.contentLayout.add(this._notListedButton, this.contentLayout.add(this._notListedButton,
{ expand: false, { expand: false,
@ -801,21 +795,6 @@ const LoginDialog = new Lang.Class({
}, },
_updateDisableUserList: function() {
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
// If this is the first time around, set initial focus
if (this._disableUserList == undefined && disableUserList)
this.setInitialKeyFocus(this._promptEntry);
if (disableUserList != this._disableUserList) {
this._disableUserList = disableUserList;
if (!this._verifyingUser)
this._reset();
}
},
_updateBanner: function() { _updateBanner: function() {
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY);
@ -828,15 +807,31 @@ const LoginDialog = new Lang.Class({
} }
}, },
_reset: function() { _onReset: function(client, serviceName) {
this._promptMessage.hide(); this._promptMessage.hide();
this._user = null;
this._verifyingUser = false;
if (this._disableUserList) let tasks = [this._hidePrompt,
this._hideUserListAndLogIn();
else new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
this._showUserList(); this._fadeInNotListedButton]),
function() {
this._sessionList.close();
this._promptLoginHint.hide();
this._userList.actor.show();
this._userList.actor.opacity = 255;
return this._userList.showItems();
},
function() {
this._userList.actor.reactive = true;
this._userList.actor.grab_key_focus();
}];
this._user = null;
let batch = new Batch.ConsecutiveBatch(this, tasks);
batch.run();
}, },
_onDefaultSessionChanged: function(client, sessionId) { _onDefaultSessionChanged: function(client, sessionId) {
@ -891,9 +886,6 @@ const LoginDialog = new Lang.Class({
if (this._user && this._user.is_logged_in()) if (this._user && this._user.is_logged_in())
return null; return null;
if (!this._verifyingUser)
return null;
return GdmUtil.fadeInActor(this._sessionList.actor); return GdmUtil.fadeInActor(this._sessionList.actor);
}, },
@ -906,21 +898,17 @@ const LoginDialog = new Lang.Class({
return batch.run(); return batch.run();
}, },
_showPrompt: function(forSecret) { _showPrompt: function() {
let hold = new Batch.Hold(); let hold = new Batch.Hold();
let cancelButtonInfo = { action: Lang.bind(this, this.cancel), let buttons = [{ action: Lang.bind(this, this.cancel),
label: _("Cancel"), label: _("Cancel"),
key: Clutter.Escape }; key: Clutter.Escape },
let okButtonInfo = { action: Lang.bind(this, function() { { action: Lang.bind(this, function() {
hold.release(); hold.release();
}), }),
label: forSecret ? C_("button", "Sign In") : _("Next"), label: C_("button", "Sign In"),
default: true }; default: true }];
let buttons = [];
if (!this._disableUserList || this._verifyingUser)
buttons.push(cancelButtonInfo);
buttons.push(okButtonInfo);
let tasks = [function() { let tasks = [function() {
return this._fadeInPrompt(); return this._fadeInPrompt();
@ -928,16 +916,6 @@ const LoginDialog = new Lang.Class({
function() { function() {
this.setButtons(buttons); this.setButtons(buttons);
let updateOkButtonEnabled = Lang.bind(this, function() {
let sensitive = this._promptEntry.text.length > 0;
okButtonInfo.button.reactive = sensitive;
okButtonInfo.button.can_focus = sensitive;
});
updateOkButtonEnabled();
this._promptEntryTextChangedId = this._promptEntry.clutter_text.connect('text-changed', updateOkButtonEnabled);
}, },
hold]; hold];
@ -950,11 +928,6 @@ const LoginDialog = new Lang.Class({
_hidePrompt: function() { _hidePrompt: function() {
this.setButtons([]); this.setButtons([]);
if (this._promptEntryTextChangedId > 0) {
this._promptEntry.clutter_text.disconnect(this._promptEntryTextChangedId);
this._promptEntryTextChangedId = 0;
}
let tasks = [function() { let tasks = [function() {
return GdmUtil.fadeOutActor(this._promptBox); return GdmUtil.fadeOutActor(this._promptBox);
}, },
@ -976,9 +949,7 @@ const LoginDialog = new Lang.Class({
this._promptEntry.set_text(''); this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char(passwordChar); this._promptEntry.clutter_text.set_password_char(passwordChar);
let tasks = [function() { let tasks = [this._showPrompt,
return this._showPrompt(!!passwordChar);
},
function() { function() {
let _text = this._promptEntry.get_text(); let _text = this._promptEntry.get_text();
@ -990,23 +961,6 @@ const LoginDialog = new Lang.Class({
return batch.run(); return batch.run();
}, },
_askForUsernameAndLogIn: function() {
this._promptLabel.set_text(_("Username: "));
this._promptEntry.set_text('');
this._promptEntry.clutter_text.set_password_char('');
let tasks = [this._showPrompt,
function() {
let userName = this._promptEntry.get_text();
this._promptEntry.reactive = false;
return this._beginVerificationForUser(userName);
}];
let batch = new Batch.ConsecutiveBatch(this, tasks);
return batch.run();
},
_onSessionOpened: function(client, serviceName) { _onSessionOpened: function(client, serviceName) {
this._greeter.call_start_session_when_ready_sync(serviceName, true, null); this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
}, },
@ -1135,7 +1089,7 @@ const LoginDialog = new Lang.Class({
})); }));
}, },
_hideUserListAndLogIn: function() { _onNotListedClicked: function() {
let tasks = [function() { let tasks = [function() {
return this._userList.hideItems(); return this._userList.hideItems();
}, },
@ -1152,30 +1106,10 @@ const LoginDialog = new Lang.Class({
this._fadeOutNotListedButton]), this._fadeOutNotListedButton]),
function() { function() {
return this._askForUsernameAndLogIn(); let hold = new Batch.Hold();
}];
let batch = new Batch.ConsecutiveBatch(this, tasks); this._userVerifier.begin(null, hold);
batch.run(); return hold;
},
_showUserList: function() {
let tasks = [this._hidePrompt,
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
this._fadeInNotListedButton]),
function() {
this._sessionList.close();
this._promptLoginHint.hide();
this._userList.actor.show();
this._userList.actor.opacity = 255;
return this._userList.showItems();
},
function() {
this._userList.actor.reactive = true;
this._userList.actor.grab_key_focus();
}]; }];
let batch = new Batch.ConsecutiveBatch(this, tasks); let batch = new Batch.ConsecutiveBatch(this, tasks);
@ -1210,7 +1144,6 @@ const LoginDialog = new Lang.Class({
let hold = new Batch.Hold(); let hold = new Batch.Hold();
this._userVerifier.begin(userName, hold); this._userVerifier.begin(userName, hold);
this._verifyingUser = true;
return hold; return hold;
}, },
@ -1263,8 +1196,6 @@ const LoginDialog = new Lang.Class({
this._userList.addUser(users[i]); this._userList.addUser(users[i]);
} }
this._updateDisableUserList();
this._userManager.connect('user-added', this._userManager.connect('user-added',
Lang.bind(this, function(userManager, user) { Lang.bind(this, function(userManager, user) {
this._userList.addUser(user); this._userList.addUser(user);
@ -1288,7 +1219,7 @@ const LoginDialog = new Lang.Class({
_onOpened: function() { _onOpened: function() {
Main.ctrlAltTabManager.addGroup(this.dialogLayout, Main.ctrlAltTabManager.addGroup(this.dialogLayout,
_("Login Window"), _("Login Window"),
'dialog-password-symbolic', 'dialog-password',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE }); { sortGroup: CtrlAltTab.SortGroup.MIDDLE });
}, },
@ -1296,6 +1227,6 @@ const LoginDialog = new Lang.Class({
close: function() { close: function() {
this.parent(); this.parent();
Main.ctrlAltTabManager.removeGroup(this.dialogLayout); Main.ctrlAltTabManager.removeGroup(this._group);
} }
}); });

View File

@ -35,7 +35,13 @@ const PowerMenuButton = new Lang.Class({
/* Translators: accessible name of the power menu in the login screen */ /* Translators: accessible name of the power menu in the login screen */
this.parent('system-shutdown-symbolic', _("Power")); this.parent('system-shutdown-symbolic', _("Power"));
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
this._updateHaveShutdown();
this._updateHaveRestart();
this._updateHaveSuspend();
}));
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
this._settings.connect('changed::disable-restart-buttons', this._settings.connect('changed::disable-restart-buttons',
@ -64,6 +70,12 @@ const PowerMenuButton = new Lang.Class({
}, },
_updateHaveShutdown: function() { _updateHaveShutdown: function() {
if (!this._loginManager) {
this._haveShutdown = false;
this._powerOffItem.actor.visible = false;
return;
}
this._loginManager.canPowerOff(Lang.bind(this, function(result) { this._loginManager.canPowerOff(Lang.bind(this, function(result) {
this._haveShutdown = result; this._haveShutdown = result;
this._powerOffItem.actor.visible = this._haveShutdown; this._powerOffItem.actor.visible = this._haveShutdown;
@ -72,6 +84,12 @@ const PowerMenuButton = new Lang.Class({
}, },
_updateHaveRestart: function() { _updateHaveRestart: function() {
if (!this._loginManager) {
this._haveRestart = false;
this._restartItem.actor.visible = false;
return;
}
this._loginManager.canReboot(Lang.bind(this, function(result) { this._loginManager.canReboot(Lang.bind(this, function(result) {
this._haveRestart = result; this._haveRestart = result;
this._restartItem.actor.visible = this._haveRestart; this._restartItem.actor.visible = this._haveRestart;
@ -80,6 +98,12 @@ const PowerMenuButton = new Lang.Class({
}, },
_updateHaveSuspend: function() { _updateHaveSuspend: function() {
if (!this._loginManager) {
this._haveSuspend = false;
this._suspendItem.actor.visible = false;
return;
}
this._loginManager.canSuspend(Lang.bind(this, function(result) { this._loginManager.canSuspend(Lang.bind(this, function(result) {
this._haveSuspend = result; this._haveSuspend = result;
this._suspendItem.actor.visible = this._haveSuspend; this._suspendItem.actor.visible = this._haveSuspend;

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang; const Lang = imports.lang;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Signals = imports.signals; const Signals = imports.signals;
@ -16,7 +17,16 @@ const ProviderIface = <interface name='org.freedesktop.realmd.Provider'>
<arg name="realm" type="ao" direction="out"/> <arg name="realm" type="ao" direction="out"/>
</method> </method>
</interface>; </interface>;
const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface); const Provider = new Gio.DBusProxyClass({
Name: 'RealmdProvider',
Interface: ProviderIface,
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.realmd',
g_object_path: '/org/freedesktop/realmd' });
}
});
const ServiceIface = <interface name="org.freedesktop.realmd.Service"> const ServiceIface = <interface name="org.freedesktop.realmd.Service">
<method name="Cancel"> <method name="Cancel">
@ -31,7 +41,16 @@ const ServiceIface = <interface name="org.freedesktop.realmd.Service">
<arg name="operation" type="s"/> <arg name="operation" type="s"/>
</signal> </signal>
</interface>; </interface>;
const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface); const Service = new Gio.DBusProxyClass({
Name: 'RealmdService',
Interface: ServiceIface,
_init: function(service) {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.realmd',
g_object_path: service });
}
});
const RealmIface = <interface name="org.freedesktop.realmd.Realm"> const RealmIface = <interface name="org.freedesktop.realmd.Realm">
<property name="Name" type="s" access="read"/> <property name="Name" type="s" access="read"/>
@ -51,16 +70,22 @@ const RealmIface = <interface name="org.freedesktop.realmd.Realm">
<arg name="options" type="a{sv}" direction="in"/> <arg name="options" type="a{sv}" direction="in"/>
</method> </method>
</interface>; </interface>;
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface); const Realm = new Gio.DBusProxyClass({
Name: 'RealmdRealm',
Interface: RealmIface,
_init: function(realm) {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.realmd',
g_object_path: realm });
}
});
const Manager = new Lang.Class({ const Manager = new Lang.Class({
Name: 'Manager', Name: 'Manager',
_init: function(parentActor) { _init: function(parentActor) {
this._aggregateProvider = Provider(Gio.DBus.system, this._aggregateProvider = new Provider();
'org.freedesktop.realmd',
'/org/freedesktop/realmd',
Lang.bind(this, this._reloadRealms))
this._realms = {}; this._realms = {};
this._aggregateProvider.connect('g-properties-changed', this._aggregateProvider.connect('g-properties-changed',
@ -68,6 +93,16 @@ const Manager = new Lang.Class({
if ('Realms' in properties.deep_unpack()) if ('Realms' in properties.deep_unpack())
this._reloadRealms(); this._reloadRealms();
})); }));
this._aggregateProvider.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
} catch(e) {
return;
}
this._reloadRealms();
}));
}, },
_reloadRealms: function() { _reloadRealms: function() {
@ -77,10 +112,8 @@ const Manager = new Lang.Class({
return; return;
for (let i = 0; i < realmPaths.length; i++) { for (let i = 0; i < realmPaths.length; i++) {
let realm = Realm(Gio.DBus.system, let realm = new Realm(realmPaths[i]);
'org.freedesktop.realmd', realm.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, this._onRealmLoaded));
realmPaths[i],
Lang.bind(this, this._onRealmLoaded));
} }
}, },
@ -97,9 +130,10 @@ const Manager = new Lang.Class({
this._updateLoginFormat(); this._updateLoginFormat();
}, },
_onRealmLoaded: function(realm, error) { _onRealmLoaded: function(realm, result) {
if (error) try {
return; realm.init_finish(result);
} catch(e) { return; }
this._reloadRealm(realm); this._reloadRealm(realm);

View File

@ -23,7 +23,6 @@ const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
const ALLOWED_FAILURES_KEY = 'allowed-failures'; const ALLOWED_FAILURES_KEY = 'allowed-failures';
const LOGO_KEY = 'logo'; const LOGO_KEY = 'logo';
const DISABLE_USER_LIST_KEY = 'disable-user-list';
function fadeInActor(actor) { function fadeInActor(actor) {
if (actor.opacity == 255 && actor.visible) if (actor.opacity == 255 && actor.visible)
@ -83,6 +82,8 @@ const ShellUserVerifier = new Lang.Class({
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
this._fprintManager = new Fprint.FprintManager(); this._fprintManager = new Fprint.FprintManager();
this._fprintManager.init(null);
this._realmManager = new Realmd.Manager(); this._realmManager = new Realmd.Manager();
this._failCounter = 0; this._failCounter = 0;
@ -138,11 +139,14 @@ const ShellUserVerifier = new Lang.Class({
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY))
return; return;
this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this, this._fprintManager.GetDefaultDeviceRemote(this._cancellable, Lang.bind(this, function(manager, result) {
function(device, error) { try {
if (!error && device) let device = manager.GetDefaultDeviceFinish(result);
this._haveFingerprintReader = true; this._haveFingerprintReader = !!device;
})); } catch(e) {
this._haveFingerprintReader = false;
}
}));
}, },
_reportInitError: function(where, error) { _reportInitError: function(where, error) {

View File

@ -21,11 +21,16 @@ const PresenceStatus = {
IDLE: 3 IDLE: 3
}; };
var PresenceProxy = Gio.DBusProxy.makeProxyWrapper(PresenceIface); const Presence = new Gio.DBusProxyClass({
function Presence(initCallback, cancellable) { Name: 'GnomeSessionPresence',
return new PresenceProxy(Gio.DBus.session, 'org.gnome.SessionManager', Interface: PresenceIface,
'/org/gnome/SessionManager/Presence', initCallback, cancellable);
} _init: function() {
this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.gnome.SessionManager',
g_object_path: '/org/gnome/SessionManager/Presence' });
}
});
// Note inhibitors are immutable objects, so they don't // Note inhibitors are immutable objects, so they don't
// change at runtime (changes always come in the form // change at runtime (changes always come in the form
@ -39,10 +44,16 @@ const InhibitorIface = <interface name="org.gnome.SessionManager.Inhibitor">
</method> </method>
</interface>; </interface>;
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface); const Inhibitor = new Gio.DBusProxyClass({
function Inhibitor(objectPath, initCallback, cancellable) { Name: 'GnomeSessionInhibitor',
return new InhibitorProxy(Gio.DBus.session, 'org.gnome.SessionManager', objectPath, initCallback, cancellable); Interface: InhibitorIface,
}
_init: function(inhibitor) {
this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.gnome.SessionManager',
g_object_path: inhibitor });
}
});
// Not the full interface, only the methods we use // Not the full interface, only the methods we use
const SessionManagerIface = <interface name="org.gnome.SessionManager"> const SessionManagerIface = <interface name="org.gnome.SessionManager">
@ -66,7 +77,14 @@ const SessionManagerIface = <interface name="org.gnome.SessionManager">
</signal> </signal>
</interface>; </interface>;
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface); const SessionManager = new Gio.DBusProxyClass({
function SessionManager(initCallback, cancellable) { Name: 'GnomeSessionManager',
return new SessionManagerProxy(Gio.DBus.session, 'org.gnome.SessionManager', '/org/gnome/SessionManager', initCallback, cancellable); Interface: SessionManagerIface,
}
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.gnome.SessionManager',
g_object_path: '/org/gnome/SessionManager' });
},
});

View File

@ -2,6 +2,7 @@
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Lang = imports.lang; const Lang = imports.lang;
const Mainloop = imports.mainloop; const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
@ -33,8 +34,26 @@ const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session
<signal name='Unlock' /> <signal name='Unlock' />
</interface>; </interface>;
const SystemdLoginManager = Gio.DBusProxy.makeProxyWrapper(SystemdLoginManagerIface); const SystemdLoginManager = new Gio.DBusProxyClass({
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface); Name: 'SystemdLoginManager',
Interface: SystemdLoginManagerIface,
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.login1',
g_object_path: '/org/freedesktop/login1' });
}
});
const SystemdLoginSession = new Gio.DBusProxyClass({
Name: 'SystemdLoginSession',
Interface: SystemdLoginSessionIface,
_init: function(session) {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.login1',
g_object_path: session });
}
});
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'> const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
<method name='CanRestart'> <method name='CanRestart'>
@ -61,51 +80,128 @@ const ConsoleKitSessionIface = <interface name='org.freedesktop.ConsoleKit.Sessi
<signal name='Unlock' /> <signal name='Unlock' />
</interface>; </interface>;
const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface); const ConsoleKitSession = new Gio.DBusProxyClass({
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface); Name: 'ConsoleKitSession',
Interface: ConsoleKitSessionIface,
_init: function(session) {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.ConsoleKit',
g_object_path: session });
}
});
const ConsoleKitManager = new Gio.DBusProxyClass({
Name: 'ConsoleKitManager',
Interface: ConsoleKitManagerIface,
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.ConsoleKit',
g_object_path: '/org/freedesktop/ConsoleKit/Manager' });
}
});
function haveSystemd() { function haveSystemd() {
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0; return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
} }
let _loginManager = null; let _loginManager = null;
let _pendingAsyncCallbacks = [];
/** /**
* LoginManager: * LoginManager:
* An abstraction over systemd/logind and ConsoleKit. * An abstraction over systemd/logind and ConsoleKit.
* *
*/ */
function getLoginManager() { function getLoginManager(asyncCallback) {
if (_loginManager == null) { if (_loginManager == null) {
if (haveSystemd()) if (_pendingAsyncCallbacks.length == 0) {
_loginManager = new LoginManagerSystemd(); let manager;
else
_loginManager = new LoginManagerConsoleKit();
}
return _loginManager; if (haveSystemd())
manager = new LoginManagerSystemd();
else
manager = new LoginManagerConsoleKit();
manager.initAsync(null, function(obj, result) {
obj.initFinish(result);
_loginManager = manager;
_pendingAsyncCallbacks.forEach(function (f) { f(obj) });
_pendingAsyncCallbacks = [];
});
_pendingAsyncCallbacks = [asyncCallback];
} else {
_pendingAsyncCallbacks.push(asyncCallback);
}
} else {
GLib.idle_add(GLib.PRIORITY_DEFAULT, function() {
asyncCallback(_loginManager);
});
}
} }
const LoginManagerSystemd = new Lang.Class({ const LoginManagerSystemd = new Lang.Class({
Name: 'LoginManagerSystemd', Name: 'LoginManagerSystemd',
Extends: GObject.Object,
_init: function() { _init: function() {
this._proxy = new SystemdLoginManager(Gio.DBus.system, this.parent();
'org.freedesktop.login1',
'/org/freedesktop/login1'); this._proxy = new SystemdLoginManager();
},
initAsync: function(cancellable, asyncCallback) {
let simpleResult = Gio.SimpleAsyncResult.new(this, asyncCallback, null);
simpleResult.set_check_cancellable(cancellable);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
if (cancellable && cancellable.is_cancelled())
return;
this._fetchCurrentSession(cancellable, simpleResult);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
simpleResult.complete();
}
}));
},
initFinish: function(simpleResult) {
if (!simpleResult.propagate_error())
return simpleResult.get_op_res_gboolean();
return true;
},
_fetchCurrentSession: function(cancellable, simpleResult) {
this._currentSession = new SystemdLoginSession('/org/freedesktop/login1/session/' +
GLib.getenv('XDG_SESSION_ID'));
this._currentSession.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
simpleResult.set_op_res_gboolean(true);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
}
simpleResult.complete();
}));
}, },
// Having this function is a bit of a hack since the Systemd and ConsoleKit // Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are // session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment. // Lock/Unlock signals, and that's all we count upon at the moment.
//
// This is only valid after async initialization
getCurrentSessionProxy: function() { getCurrentSessionProxy: function() {
if (!this._currentSession) {
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
'org.freedesktop.login1',
'/org/freedesktop/login1/session/' +
GLib.getenv('XDG_SESSION_ID'));
}
return this._currentSession; return this._currentSession;
}, },
@ -114,66 +210,126 @@ const LoginManagerSystemd = new Lang.Class({
}, },
canPowerOff: function(asyncCallback) { canPowerOff: function(asyncCallback) {
this._proxy.CanPowerOffRemote(function(result, error) { this._proxy.CanPowerOffRemote(null, function(proxy, result) {
if (error) let val = false;
asyncCallback(false);
else try {
asyncCallback(result[0] != 'no'); val = proxy.CanPowerOffFinish(result)[0] != 'no';
} catch(e) { }
asyncCallback(val);
}); });
}, },
canReboot: function(asyncCallback) { canReboot: function(asyncCallback) {
this._proxy.CanRebootRemote(function(result, error) { this._proxy.CanRebootRemote(null, function(proxy, result) {
if (error) let val = false;
asyncCallback(false);
else try {
asyncCallback(result[0] != 'no'); val = proxy.CanRebootFinish(result)[0] != 'no';
} catch(e) { }
asyncCallback(val);
}); });
}, },
canSuspend: function(asyncCallback) { canSuspend: function(asyncCallback) {
this._proxy.CanSuspendRemote(function(result, error) { this._proxy.CanSuspendRemote(null, function(proxy, result) {
if (error) let val = false;
asyncCallback(false);
else try {
asyncCallback(result[0] != 'no'); val = proxy.CanRebootFinish(result)[0] != 'no';
} catch(e) { }
asyncCallback(val);
}); });
}, },
powerOff: function() { powerOff: function() {
this._proxy.PowerOffRemote(true); this._proxy.PowerOffRemote(true, null, null);
}, },
reboot: function() { reboot: function() {
this._proxy.RebootRemote(true); this._proxy.RebootRemote(true, null, null);
}, },
suspend: function() { suspend: function() {
this._proxy.SuspendRemote(true); this._proxy.SuspendRemote(true, null, null);
} }
}); });
const LoginManagerConsoleKit = new Lang.Class({ const LoginManagerConsoleKit = new Lang.Class({
Name: 'LoginManagerConsoleKit', Name: 'LoginManagerConsoleKit',
Extends: GObject.Object,
_init: function() { _init: function() {
this._proxy = new ConsoleKitManager(Gio.DBus.system, this.parent();
'org.freedesktop.ConsoleKit',
'/org/freedesktop/ConsoleKit/Manager'); this._proxy = new ConsoleKitManager();
this._upClient = new UPowerGlib.Client(); this._upClient = new UPowerGlib.Client();
}, },
initAsync: function(cancellable, asyncCallback) {
let simpleResult = Gio.SimpleAsyncResult.new(this, asyncCallback, null);
simpleResult.set_check_cancellable(cancellable);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
if (cancellable && cancellable.is_cancelled())
return;
this._fetchCurrentSession(cancellable, simpleResult);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
simpleResult.complete();
}
}));
},
initFinish: function(simpleResult) {
if (!simpleResult.propagate_error())
return simpleResult.get_op_res_gboolean();
return true;
},
_fetchCurrentSession: function(cancellable, simpleResult) {
this._proxy.GetCurrentSessionRemote(cancellable, Lang.bind(this, function(proxy, result) {
try {
let [currentSessionId] = proxy.GetCurrentSessionFinish(result);
if (cancellable && cancellable.is_cancelled())
return;
this._createSessionProxy(currentSessionId, cancellable, simpleResult);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
simpleResult.complete();
}
}));
},
_createSessionProxy: function(currentSessionId, cancellable, simpleResult) {
this._currentSession = new ConsoleKitSession(currentSessionId);
this._currentSession.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
simpleResult.set_op_res_gboolean(true);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
}
simpleResult.complete();
}));
},
// Having this function is a bit of a hack since the Systemd and ConsoleKit // Having this function is a bit of a hack since the Systemd and ConsoleKit
// session objects have different interfaces - but in both cases there are // session objects have different interfaces - but in both cases there are
// Lock/Unlock signals, and that's all we count upon at the moment. // Lock/Unlock signals, and that's all we count upon at the moment.
getCurrentSessionProxy: function() { getCurrentSessionProxy: function() {
if (!this._currentSession) {
let [currentSessionId] = this._proxy.GetCurrentSessionSync();
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
'org.freedesktop.ConsoleKit',
currentSessionId);
}
return this._currentSession; return this._currentSession;
}, },
@ -185,26 +341,32 @@ const LoginManagerConsoleKit = new Lang.Class({
session.connectSignal('ActiveChanged', Lang.bind(this, function(object, senderName, [isActive]) { session.connectSignal('ActiveChanged', Lang.bind(this, function(object, senderName, [isActive]) {
this._sessionActive = isActive; this._sessionActive = isActive;
})); }));
[this._sessionActive] = session.IsActiveSync(); [this._sessionActive] = session.IsActiveSync(null);
return this._sessionActive; return this._sessionActive;
}, },
canPowerOff: function(asyncCallback) { canPowerOff: function(asyncCallback) {
this._proxy.CanStopRemote(function(result, error) { this._proxy.CanStopRemote(null, function(proxy, result) {
if (error) let val = false;
asyncCallback(false);
else try {
asyncCallback(result[0]); [val] = proxy.CanStopFinish(result);
} catch(e) { }
asyncCallback(val);
}); });
}, },
canReboot: function(asyncCallback) { canReboot: function(asyncCallback) {
this._proxy.CanRestartRemote(function(result, error) { this._proxy.CanRestartRemote(null, function(proxy, result) {
if (error) let val = false;
asyncCallback(false);
else try {
asyncCallback(result[0]); [val] = proxy.CanRestartFinish(result);
} catch(e) { }
asyncCallback(val);
}); });
}, },
@ -216,11 +378,11 @@ const LoginManagerConsoleKit = new Lang.Class({
}, },
powerOff: function() { powerOff: function() {
this._proxy.StopRemote(); this._proxy.StopRemote(null, null);
}, },
reboot: function() { reboot: function() {
this._proxy.RestartRemote(); this._proxy.RestartRemote(null, null);
}, },
suspend: function() { suspend: function() {

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang; const Lang = imports.lang;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Signals = imports.signals; const Signals = imports.signals;
@ -26,7 +27,16 @@ const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.M
</signal> </signal>
</interface>; </interface>;
const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface); const ModemGsmNetworkProxy = new Gio.DBusProxyClass({
Name: 'ModemGsmNetworkProxy',
Interface: ModemGsmNetworkInterface,
_init: function(modem) {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.ModemManager',
g_object_path: modem });
}
});
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma"> const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
<method name="GetSignalQuality"> <method name="GetSignalQuality">
@ -40,87 +50,41 @@ const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.C
</signal> </signal>
</interface>; </interface>;
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface); const ModemCdmaProxy = new Gio.DBusProxyClass({
Name: 'ModemCdmaProxy',
Interface: ModemCdmaInterface,
_init: function(modem) {
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
g_name: 'org.freedesktop.ModemManager',
g_object_path: modem });
},
});
let _providersTable; let _providersTable;
function _getProvidersTable() { function _getProvidersTable() {
if (_providersTable) if (_providersTable)
return _providersTable; return _providersTable;
return _providersTable = Shell.mobile_providers_parse(null,null); let [providers, countryCodes] = Shell.mobile_providers_parse();
} return _providersTable = providers;
function findProviderForMCCMNC(table, needle) {
let needlemcc = needle.substring(0, 3);
let needlemnc = needle.substring(3, needle.length);
let name2, name3;
for (let iter in table) {
let country = table[iter];
let providers = country.get_providers();
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
// Search through MCC/MNC list
let list = provider.get_gsm_mcc_mnc();
for (let j = 0; j < list.length; j++) {
let mccmnc = list[j];
// Match both 2-digit and 3-digit MNC; prefer a
// 3-digit match if found, otherwise a 2-digit one.
if (mccmnc.mcc != needlemcc)
continue; // MCC was wrong
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
name3 = provider.name;
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
name2 = provider.name;
if (name2 && name3)
break;
}
}
}
return name3 || name2 || null;
}
function findProviderForSid(table, sid) {
if (sid == 0)
return null;
// Search through each country
for (let iter in table) {
let country = table[iter];
let providers = country.get_providers();
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
let cdma_sid = provider.get_cdma_sid();
// Search through CDMA SID list
for (let j = 0; j < cdma_sid.length; j++) {
if (cdma_sid[j] == sid)
return provider.name;
}
}
}
return null;
} }
const ModemGsm = new Lang.Class({ const ModemGsm = new Lang.Class({
Name: 'ModemGsm', Name: 'ModemGsm',
_init: function(path) { _init: function(path) {
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path); this._proxy = new ModemGsmNetworkProxy(path);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
obj.init_finish(result);
this._finishInit();
}));
this.signal_quality = 0; this.signal_quality = 0;
this.operator_name = null; this.operator_name = null;
},
_finishInit: function() {
// Code is duplicated because the function have different signatures // Code is duplicated because the function have different signatures
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) { this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
this.signal_quality = quality; this.signal_quality = quality;
@ -130,52 +94,82 @@ const ModemGsm = new Lang.Class({
this.operator_name = this._findOperatorName(name, code); this.operator_name = this._findOperatorName(name, code);
this.emit('notify::operator-name'); this.emit('notify::operator-name');
})); }));
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function([result], err) { this._proxy.GetRegistrationInfoRemote(null, Lang.bind(this, function(proxy, result) {
if (err) { let [status, code, name] = proxy.GetRegistrationInfoFinish(result);
log(err);
return;
}
let [status, code, name] = result;
this.operator_name = this._findOperatorName(name, code); this.operator_name = this._findOperatorName(name, code);
this.emit('notify::operator-name'); this.emit('notify::operator-name');
})); }));
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) { this._proxy.GetSignalQualityRemote(null, Lang.bind(this, function(proxy, result) {
if (err) { try {
[this.signal_quality] = proxy.GetSignalQualityFinish(result);
} catch(e) {
// it will return an error if the device is not connected // it will return an error if the device is not connected
this.signal_quality = 0; this.signal_quality = 0;
} else {
let [quality] = result;
this.signal_quality = quality;
} }
this.emit('notify::signal-quality'); this.emit('notify::signal-quality');
})); }));
}, },
_findOperatorName: function(name, opCode) { _findOperatorName: function(name, opCode) {
if (name) { if (name.length != 0 && (name.length > 6 || name.length < 5)) {
if (name && name.length != 0 && (name.length > 6 || name.length < 5)) { // this looks like a valid name, i.e. not an MCCMNC (that some
// this looks like a valid name, i.e. not an MCCMNC (that some // devices return when not yet connected
// devices return when not yet connected return name;
return name; }
} if (isNaN(parseInt(name))) {
if (isNaN(parseInt(name))) { // name is definitely not a MCCMNC, so it may be a name
// name is definitely not a MCCMNC, so it may be a name // after all; return that
// after all; return that return name;
return name;
}
} }
let needle; let needle;
if ((name == null || name.length == 0) && opCode) if (name.length == 0 && opCode)
needle = opCode; needle = opCode;
else if (name.length == 6 || name.length == 5) else if (name.length == 6 || name.length == 5)
needle = name; needle = name;
else // nothing to search else // nothing to search
return null; return null;
return this._findProviderForMCCMNC(needle);
},
_findProviderForMCCMNC: function(needle) {
let table = _getProvidersTable(); let table = _getProvidersTable();
return findProviderForMCCMNC(table, needle); let needlemcc = needle.substring(0, 3);
let needlemnc = needle.substring(3, needle.length);
let name2, name3;
for (let iter in table) {
let providers = table[iter];
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
// Search through MCC/MNC list
let list = provider.get_gsm_mcc_mnc();
for (let j = 0; j < list.length; j++) {
let mccmnc = list[j];
// Match both 2-digit and 3-digit MNC; prefer a
// 3-digit match if found, otherwise a 2-digit one.
if (mccmnc.mcc != needlemcc)
continue; // MCC was wrong
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
name3 = provider.name;
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
name2 = provider.name;
if (name2 && name3)
break;
}
}
}
return name3 || name2 || null;
} }
}); });
Signals.addSignalMethods(ModemGsm.prototype); Signals.addSignalMethods(ModemGsm.prototype);
@ -184,10 +178,18 @@ const ModemCdma = new Lang.Class({
Name: 'ModemCdma', Name: 'ModemCdma',
_init: function(path) { _init: function(path) {
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path); this._proxy = new ModemCdmaProxy(path);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
obj.init_finish(result);
this._finishInit();
}));
this.signal_quality = 0; this.signal_quality = 0;
this.operator_name = null; this.operator_name = null;
},
_finishInit: function() {
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) { this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
this.signal_quality = params[0]; this.signal_quality = params[0];
this.emit('notify::signal-quality'); this.emit('notify::signal-quality');
@ -197,33 +199,59 @@ const ModemCdma = new Lang.Class({
if (this.operator_name == null) if (this.operator_name == null)
this._refreshServingSystem(); this._refreshServingSystem();
})); }));
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) { this._proxy.GetSignalQualityRemote(null, Lang.bind(this, function(proxy, result) {
if (err) { try {
[this.signal_quality] = proxy.GetSignalQualityFinish(result);
} catch(e) {
// it will return an error if the device is not connected // it will return an error if the device is not connected
this.signal_quality = 0; this.signal_quality = 0;
} else {
let [quality] = result;
this.signal_quality = quality;
} }
this.emit('notify::signal-quality'); this.emit('notify::signal-quality');
})); }));
}, },
_refreshServingSystem: function() { _refreshServingSystem: function() {
this._proxy.GetServingSystemRemote(Lang.bind(this, function([result], err) { this._proxy.GetServingSystemRemote(null, Lang.bind(this, function(proxy, result) {
if (err) { try {
let [bandClass, band, name] = proxy.GetServingSystemFinish(result);
if (name.length > 0)
this.operator_name = this._findProviderForSid(name);
else
this.operator_name = null;
} catch(e) {
// it will return an error if the device is not connected // it will return an error if the device is not connected
this.operator_name = null; this.operator_name = null;
} else {
let [bandClass, band, id] = result;
if (name.length > 0) {
let table = _getProvidersTable();
this.operator_name = findProviderForSid(table, id);
} else
this.operator_name = null;
} }
this.emit('notify::operator-name'); this.emit('notify::operator-name');
})); }));
},
_findProviderForSid: function(sid) {
if (sid == 0)
return null;
let table = _getProvidersTable();
// Search through each country
for (let iter in table) {
let providers = table[iter];
// Search through each country's providers
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
let cdma_sid = provider.get_cdma_sid();
// Search through CDMA SID list
for (let j = 0; j < cdma_sid.length; j++) {
if (cdma_sid[j] == sid)
return provider.name;
}
}
}
return null;
} }
}); });
Signals.addSignalMethods(ModemCdma.prototype); Signals.addSignalMethods(ModemCdma.prototype);

View File

@ -172,7 +172,7 @@ const AltTabPopup = new Lang.Class({
if (!Main.pushModal(this.actor)) { if (!Main.pushModal(this.actor)) {
// Probably someone else has a pointer grab, try again with keyboard only // Probably someone else has a pointer grab, try again with keyboard only
if (!Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED })) { if (!Main.pushModal(this.actor, global.get_current_time(), Meta.ModalOptions.POINTER_ALREADY_GRABBED)) {
return false; return false;
} }
} }

View File

@ -479,6 +479,7 @@ const AppWellIcon = new Lang.Class({
Lang.bind(this, Lang.bind(this,
this._onStateChanged)); this._onStateChanged));
this._onStateChanged(); this._onStateChanged();
this.isMenuUp = false;
}, },
_onDestroy: function() { _onDestroy: function() {
@ -560,8 +561,7 @@ const AppWellIcon = new Lang.Class({
this._menuManager.addMenu(this._menu); this._menuManager.addMenu(this._menu);
} }
this.emit('menu-state-changed', true); this.isMenuUp = true;
this.actor.set_hover(true); this.actor.set_hover(true);
this._menu.popup(); this._menu.popup();
@ -578,7 +578,7 @@ const AppWellIcon = new Lang.Class({
_onMenuPoppedDown: function() { _onMenuPoppedDown: function() {
this.actor.sync_hover(); this.actor.sync_hover();
this.emit('menu-state-changed', false); this.isMenuUp = false;
}, },
_onActivate: function (event) { _onActivate: function (event) {

View File

@ -84,12 +84,9 @@ const AppFavorites = new Lang.Class({
let app = Shell.AppSystem.get_default().lookup_app(appId); let app = Shell.AppSystem.get_default().lookup_app(appId);
Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()), Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()), Lang.bind(this, function () {
{ forFeedback: true, this._removeFavorite(appId);
undoCallback: Lang.bind(this, function () { }));
this._removeFavorite(appId);
})
});
}, },
addFavorite: function(appId) { addFavorite: function(appId) {
@ -119,11 +116,9 @@ const AppFavorites = new Lang.Class({
return; return;
Main.overview.setMessage(_("%s has been removed from your favorites.").format(app.get_name()), Main.overview.setMessage(_("%s has been removed from your favorites.").format(app.get_name()),
{ forFeedback: true, Lang.bind(this, function () {
undoCallback: Lang.bind(this, function () { this._addFavorite(appId, pos);
this._addFavorite(appId, pos); }));
})
});
} }
}); });
Signals.addSignalMethods(AppFavorites.prototype); Signals.addSignalMethods(AppFavorites.prototype);

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Lang = imports.lang; const Lang = imports.lang;
const St = imports.gi.St; const St = imports.gi.St;
@ -200,19 +201,17 @@ const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
<signal name="Changed" /> <signal name="Changed" />
</interface>; </interface>;
const CalendarServerInfo = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface); const CalendarServer = new Gio.DBusProxyClass({
Name: 'CalendarServer',
Interface: CalendarServerIface,
function CalendarServer() { _init: function() {
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session, this.parent({ g_bus_type: Gio.BusType.SESSION,
g_interface_name: CalendarServerInfo.name, g_name: 'org.gnome.Shell.CalendarServer',
g_interface_info: CalendarServerInfo, g_object_path: '/org/gnome/Shell/CalendarServer',
g_name: 'org.gnome.Shell.CalendarServer', g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
g_object_path: '/org/gnome/Shell/CalendarServer', }
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES }); });
self.init(null);
return self;
}
function _datesEqual(a, b) { function _datesEqual(a, b) {
if (a < b) if (a < b)
@ -242,11 +241,15 @@ const DBusEventSource = new Lang.Class({
this._dbusProxy = new CalendarServer(); this._dbusProxy = new CalendarServer();
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged)); this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() { this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
if (this._dbusProxy.g_name_owner) try {
this._onNameAppeared(); proxy.init_finish(result);
else } catch(e) {
this._onNameVanished(); return;
}
this._resetCache();
this.emit('changed');
})); }));
}, },
@ -256,52 +259,52 @@ const DBusEventSource = new Lang.Class({
this._lastRequestEnd = null; this._lastRequestEnd = null;
}, },
_onNameAppeared: function(owner) {
this._resetCache();
this._loadEvents(true);
},
_onNameVanished: function(oldOwner) {
this._resetCache();
this.emit('changed');
},
_onChanged: function() { _onChanged: function() {
this._loadEvents(false); this._loadEvents(false);
}, },
_onEventsReceived: function(results, error) { _onEventsReceived: function(proxy, result) {
let newEvents = []; let appointments;
let appointments = results ? results[0] : null; try {
if (appointments != null) { [appointments] = proxy.call_finish(result).deep_unpack();
for (let n = 0; n < appointments.length; n++) { } catch(e if e instanceof GLib.Error) {
let a = appointments[n]; // ignore errors coming from DBus
let date = new Date(a[4] * 1000); appointments = [];
let end = new Date(a[5] * 1000);
let summary = a[1];
let allDay = a[3];
let event = new CalendarEvent(date, end, summary, allDay);
newEvents.push(event);
}
newEvents.sort(function(event1, event2) {
return event1.date.getTime() - event2.date.getTime();
});
} }
let newEvents = [];
for (let n = 0; n < appointments.length; n++) {
let a = appointments[n];
let date = new Date(a[4] * 1000);
let end = new Date(a[5] * 1000);
let summary = a[1];
let allDay = a[3];
let event = new CalendarEvent(date, end, summary, allDay);
newEvents.push(event);
}
newEvents.sort(function(event1, event2) {
return event1.date.getTime() - event2.date.getTime();
});
this._events = newEvents; this._events = newEvents;
this.emit('changed'); this.emit('changed');
}, },
_loadEvents: function(forceReload) { _loadEvents: function(forceReload) {
if (this._curRequestBegin && this._curRequestEnd){ if (this._curRequestBegin && this._curRequestEnd){
/* Can't use GetEventsRemote because we need to pass the
flags here */
let callFlags = Gio.DBusCallFlags.NO_AUTO_START; let callFlags = Gio.DBusCallFlags.NO_AUTO_START;
if (forceReload) if (forceReload)
callFlags = Gio.DBusCallFlags.NONE; callFlags = Gio.DBusCallFlags.NONE;
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000, this._dbusProxy.call("GetEvents",
this._curRequestEnd.getTime() / 1000, GLib.Variant.new("(xxb)", [this._curRequestBegin.getTime() / 1000,
forceReload, this._curRequestEnd.getTime() / 1000,
Lang.bind(this, this._onEventsReceived), forceReload]),
callFlags); callFlags,
-1,
null,
Lang.bind(this, this._onEventsReceived));
} }
}, },
@ -394,7 +397,6 @@ const Calendar = new Lang.Class({
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() { this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
this._update(false); this._update(false);
})); }));
this._update(true);
} }
}, },

View File

@ -33,7 +33,9 @@ const AutomountManager = new Lang.Class({
Lang.bind(this, this._InhibitorsChanged)); Lang.bind(this, this._InhibitorsChanged));
this._inhibited = false; this._inhibited = false;
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
}));
this._volumeMonitor = Gio.VolumeMonitor.get(); this._volumeMonitor = Gio.VolumeMonitor.get();
}, },
@ -85,7 +87,7 @@ const AutomountManager = new Lang.Class({
_onDriveConnected: function() { _onDriveConnected: function() {
// if we're not in the current ConsoleKit session, // if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds // or screensaver is active, don't play sounds
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
global.play_theme_sound(0, 'device-added-media'); global.play_theme_sound(0, 'device-added-media');
@ -94,7 +96,7 @@ const AutomountManager = new Lang.Class({
_onDriveDisconnected: function() { _onDriveDisconnected: function() {
// if we're not in the current ConsoleKit session, // if we're not in the current ConsoleKit session,
// or screensaver is active, don't play sounds // or screensaver is active, don't play sounds
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
global.play_theme_sound(0, 'device-removed-media'); global.play_theme_sound(0, 'device-removed-media');
@ -103,7 +105,7 @@ const AutomountManager = new Lang.Class({
_onDriveEjectButton: function(monitor, drive) { _onDriveEjectButton: function(monitor, drive) {
// TODO: this code path is not tested, as the GVfs volume monitor // TODO: this code path is not tested, as the GVfs volume monitor
// doesn't emit this signal just yet. // doesn't emit this signal just yet.
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
// we force stop/eject in this case, so we don't have to pass a // we force stop/eject in this case, so we don't have to pass a
@ -143,7 +145,7 @@ const AutomountManager = new Lang.Class({
if (params.checkSession) { if (params.checkSession) {
// if we're not in the current ConsoleKit session, // if we're not in the current ConsoleKit session,
// don't attempt automount // don't attempt automount
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
} }

View File

@ -2,6 +2,7 @@
const Lang = imports.lang; const Lang = imports.lang;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const St = imports.gi.St; const St = imports.gi.St;
const LoginManager = imports.misc.loginManager; const LoginManager = imports.misc.loginManager;
@ -82,12 +83,16 @@ const HotplugSnifferIface = <interface name="org.gnome.Shell.HotplugSniffer">
</method> </method>
</interface>; </interface>;
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface); const HotplugSniffer = new Gio.DBusProxyClass({
function HotplugSniffer() { Name: 'HotplugSnifferProxy',
return new HotplugSnifferProxy(Gio.DBus.session, Interface: HotplugSnifferIface,
'org.gnome.Shell.HotplugSniffer',
'/org/gnome/Shell/HotplugSniffer'); _init: function() {
} this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.gnome.Shell.HotplugSniffer',
g_object_path: '/org/gnome/Shell/HotplugSniffer' });
}
});
const ContentTypeDiscoverer = new Lang.Class({ const ContentTypeDiscoverer = new Lang.Class({
Name: 'ContentTypeDiscoverer', Name: 'ContentTypeDiscoverer',
@ -127,10 +132,14 @@ const ContentTypeDiscoverer = new Lang.Class({
let root = mount.get_root(); let root = mount.get_root();
let hotplugSniffer = new HotplugSniffer(); let hotplugSniffer = new HotplugSniffer();
hotplugSniffer.SniffURIRemote(root.get_uri(), hotplugSniffer.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
Lang.bind(this, function([contentTypes]) { proxy.init_finish(result);
this._emitCallback(mount, contentTypes);
})); proxy.SniffURIRemote(root.get_uri(), null, Lang.bind(this, function(proxy, result) {
let [contentTypes] = proxy.SniffURIFinish(result);
this._emitCallback(mount, contentTypes);
}));
}));
} }
}, },
@ -162,7 +171,9 @@ const AutorunManager = new Lang.Class({
Name: 'AutorunManager', Name: 'AutorunManager',
_init: function() { _init: function() {
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
}));
this._volumeMonitor = Gio.VolumeMonitor.get(); this._volumeMonitor = Gio.VolumeMonitor.get();
@ -215,7 +226,7 @@ const AutorunManager = new Lang.Class({
_onMountAdded: function(monitor, mount) { _onMountAdded: function(monitor, mount) {
// don't do anything if our session is not the currently // don't do anything if our session is not the currently
// active one // active one
if (!this._loginManager.sessionActive) if (!this._loginManager || !this._loginManager.sessionActive)
return; return;
this._processMount(mount, true); this._processMount(mount, true);

View File

@ -49,7 +49,7 @@ const AuthenticationDialog = new Lang.Class({
let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout', let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
vertical: true }); vertical: true });
mainContentBox.add(messageBox, mainContentBox.add(messageBox,
{ expand: true, y_align: St.Align.START }); { y_align: St.Align.START });
this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline', this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline',
text: _("Authentication Required") }); text: _("Authentication Required") });

View File

@ -1,6 +1,5 @@
const Lang = imports.lang; const Lang = imports.lang;
const Main = imports.ui.main;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
@ -17,16 +16,13 @@ const Recorder = new Lang.Class({
}, },
enable: function() { enable: function() {
Main.wm.addKeybinding('toggle-recording', global.display.add_keybinding('toggle-recording',
this._bindingSettings, this._bindingSettings,
Meta.KeyBindingFlags.NONE, Meta.KeyBindingFlags.NONE, Lang.bind(this, this._toggleRecorder));
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._toggleRecorder));
}, },
disable: function() { disable: function() {
Main.wm.removeKeybinding('toggle-recording'); global.display.remove_keybinding('toggle-recording');
}, },
_ensureRecorder: function() { _ensureRecorder: function() {

View File

@ -771,19 +771,16 @@ const ChatNotification = new Lang.Class({
this.emit('unfocused'); this.emit('unfocused');
})); }));
this._oldMaxScrollAdjustment = 0;
this._createScrollArea(); this._createScrollArea();
this._lastGroup = null; this._lastGroup = null;
this._lastGroupActor = null; this._lastGroupActor = null;
// Keep track of the bottom position for the current adjustment and
// force a scroll to the bottom if things change while we were at the
// bottom
this._oldMaxScrollValue = this._scrollArea.vscroll.adjustment.value;
this._scrollArea.add_style_class_name('chat-notification-scrollview');
this._scrollArea.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) { this._scrollArea.vscroll.adjustment.connect('changed', Lang.bind(this, function(adjustment) {
if (adjustment.value == this._oldMaxScrollValue) let currentValue = adjustment.value + adjustment.page_size;
if (currentValue == this._oldMaxScrollAdjustment)
this.scrollTo(St.Side.BOTTOM); this.scrollTo(St.Side.BOTTOM);
this._oldMaxScrollValue = Math.max(adjustment.lower, adjustment.upper - adjustment.page_size); this._oldMaxScrollAdjustment = adjustment.upper;
})); }));
this._inputHistory = new History.HistoryManager({ entry: this._responseEntry.clutter_text }); this._inputHistory = new History.HistoryManager({ entry: this._responseEntry.clutter_text });
@ -1136,7 +1133,7 @@ const AudioVideoNotification = new Lang.Class({
this.parent(source, title, null, { customContent: true }); this.parent(source, title, null, { customContent: true });
this.setResident(true); this.setResident(true);
this.addButton('reject', _("Decline")); this.addButton('reject', _("Reject"));
/* translators: this is a button label (verb), not a noun */ /* translators: this is a button label (verb), not a noun */
this.addButton('answer', _("Answer")); this.addButton('answer', _("Answer"));

View File

@ -23,7 +23,8 @@ const DASH_ITEM_HOVER_TIMEOUT = 300;
function getAppFromSource(source) { function getAppFromSource(source) {
if (source instanceof AppDisplay.AppWellIcon) { if (source instanceof AppDisplay.AppWellIcon) {
return source.app; let appSystem = Shell.AppSystem.get_default();
return appSystem.lookup_app(source.getId());
} else if (source.metaWindow) { } else if (source.metaWindow) {
let tracker = Shell.WindowTracker.get_default(); let tracker = Shell.WindowTracker.get_default();
return tracker.get_window_app(source.metaWindow); return tracker.get_window_app(source.metaWindow);
@ -141,7 +142,6 @@ const DashItemContainer = new Lang.Class({
setLabelText: function(text) { setLabelText: function(text) {
this._labelText = text; this._labelText = text;
this.child.accessible_name = text;
}, },
hideLabel: function () { hideLabel: function () {
@ -259,6 +259,7 @@ const ShowAppsIcon = new Lang.Class({
this.setChild(this.toggleButton); this.setChild(this.toggleButton);
this.setDragApp(null); this.setDragApp(null);
this.toggleButton.label_actor = this.label;
}, },
_createIcon: function(size) { _createIcon: function(size) {
@ -491,51 +492,32 @@ const Dash = new Lang.Class({
}, },
_createAppItem: function(app) { _createAppItem: function(app) {
let appIcon = new AppDisplay.AppWellIcon(app, let display = new AppDisplay.AppWellIcon(app,
{ setSizeManually: true, { setSizeManually: true,
showLabel: false }); showLabel: false });
appIcon._draggable.connect('drag-begin', display._draggable.connect('drag-begin',
Lang.bind(this, function() { Lang.bind(this, function() {
appIcon.actor.opacity = 50; display.actor.opacity = 50;
})); }));
appIcon._draggable.connect('drag-end', display._draggable.connect('drag-end',
Lang.bind(this, function() { Lang.bind(this, function() {
appIcon.actor.opacity = 255; display.actor.opacity = 255;
})); }));
appIcon.connect('menu-state-changed',
Lang.bind(this, function(appIcon, opened) {
this._itemMenuStateChanged(item, opened);
}));
let item = new DashItemContainer(); let item = new DashItemContainer();
item.setChild(appIcon.actor); item.setChild(display.actor);
// Override default AppWellIcon label_actor, now the
// accessible_name is set at DashItemContainer.setLabelText
appIcon.actor.label_actor = null;
item.setLabelText(app.get_name()); item.setLabelText(app.get_name());
// Override default AppWellIcon label_actor
appIcon.icon.setIconSize(this.iconSize); display.actor.label_actor = item.label;
display.icon.setIconSize(this.iconSize);
this._hookUpLabel(item); this._hookUpLabel(item);
return item; return item;
}, },
_itemMenuStateChanged: function(item, opened) {
// When the menu closes, it calls sync_hover, which means
// that the notify::hover handler does everything we need to.
if (opened) {
if (this._showLabelTimeoutId > 0) {
Mainloop.source_remove(this._showLabelTimeoutId);
this._showLabelTimeoutId = 0;
}
item.hideLabel();
}
},
_onHover: function (item) { _onHover: function (item) {
if (item.child.get_hover()) { if (item.child.get_hover() && !item.child._delegate.isMenuUp) {
if (this._showLabelTimeoutId == 0) { if (this._showLabelTimeoutId == 0) {
let timeout = this._labelShowing ? 0 : DASH_ITEM_HOVER_TIMEOUT; let timeout = this._labelShowing ? 0 : DASH_ITEM_HOVER_TIMEOUT;
this._showLabelTimeoutId = Mainloop.timeout_add(timeout, this._showLabelTimeoutId = Mainloop.timeout_add(timeout,
@ -637,10 +619,8 @@ const Dash = new Lang.Class({
icon.setIconSize(this.iconSize); icon.setIconSize(this.iconSize);
// Don't animate the icon size change when the overview // Don't animate the icon size change when the overview
// is transitioning, not visible or when initially filling // is not visible or when initially filling the dash
// the dash if (!Main.overview.visible || !this._shownInitially)
if (!Main.overview.visible || Main.overview.animationInProgress ||
!this._shownInitially)
continue; continue;
let [targetWidth, targetHeight] = icon.icon.get_size(); let [targetWidth, targetHeight] = icon.icon.get_size();
@ -764,9 +744,8 @@ const Dash = new Lang.Class({
for (let i = 0; i < removedActors.length; i++) { for (let i = 0; i < removedActors.length; i++) {
let item = removedActors[i]._delegate; let item = removedActors[i]._delegate;
// Don't animate item removal when the overview is transitioning // Don't animate item removal when the overview is hidden
// or hidden if (Main.overview.visible)
if (Main.overview.visible && !Main.overview.animationInProgress)
item.animateOutAndDestroy(); item.animateOutAndDestroy();
else else
item.destroy(); item.destroy();
@ -781,9 +760,8 @@ const Dash = new Lang.Class({
return; return;
} }
// Don't animate item addition when the overview is transitioning // Don't animate item addition when the overview is hidden
// or hidden if (!Main.overview.visible)
if (!Main.overview.visible || Main.overview.animationInProgress)
return; return;
for (let i = 0; i < addedItems.length; i++) for (let i = 0; i < addedItems.length; i++)

View File

@ -218,6 +218,34 @@ function init() {
_endSessionDialog = new EndSessionDialog(); _endSessionDialog = new EndSessionDialog();
} }
const EndSessionExporter = new Gio.DBusImplementerClass({
Name: 'EndSessionExporter',
Interface: EndSessionDialogIface,
_init: function() {
this.parent();
this.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
},
OpenAsync: function(parameters, invocation) {
this.emit('open', parameters, invocation);
},
close: function() {
this.emit_signal('Closed');
},
cancel: function() {
this.emit_signal('Canceled');
},
confirm: function(type) {
this.emit_signal(type);
},
});
Signals.addSignalMethods(EndSessionExporter.prototype);
const EndSessionDialog = new Lang.Class({ const EndSessionDialog = new Lang.Class({
Name: 'EndSessionDialog', Name: 'EndSessionDialog',
Extends: ModalDialog.ModalDialog, Extends: ModalDialog.ModalDialog,
@ -295,8 +323,8 @@ const EndSessionDialog = new Lang.Class({
scrollView.hide(); scrollView.hide();
})); }));
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this); this._exporter = new EndSessionExporter();
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog'); this._exporter.connect('open', Lang.bind(this, this._onOpenRequest));
}, },
_onDestroy: function() { _onDestroy: function() {
@ -387,19 +415,19 @@ const EndSessionDialog = new Lang.Class({
close: function() { close: function() {
this.parent(); this.parent();
this._dbusImpl.emit_signal('Closed', null); this._exporter.close();
}, },
cancel: function() { cancel: function() {
this._stopTimer(); this._stopTimer();
this._dbusImpl.emit_signal('Canceled', null); this._exporter.cancel();
this.close(global.get_current_time()); this.close(global.get_current_time());
}, },
_confirm: function(signal) { _confirm: function(signal) {
this._fadeOutDialog(); this._fadeOutDialog();
this._stopTimer(); this._stopTimer();
this._dbusImpl.emit_signal(signal, null); this._exporter.confirm(signal);
}, },
_onOpened: function() { _onOpened: function() {
@ -452,7 +480,7 @@ const EndSessionDialog = new Lang.Class({
this._updateContent(); this._updateContent();
}, },
OpenAsync: function(parameters, invocation) { _onOpenRequest: function(exporter, parameters, invocation) {
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters; let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
this._totalSecondsToStayOpen = totalSecondsToStayOpen; this._totalSecondsToStayOpen = totalSecondsToStayOpen;
this._inhibitors = []; this._inhibitors = [];
@ -466,7 +494,10 @@ const EndSessionDialog = new Lang.Class({
} }
for (let i = 0; i < inhibitorObjectPaths.length; i++) { for (let i = 0; i < inhibitorObjectPaths.length; i++) {
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) { let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i]);
inhibitor.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
proxy.init_finish(result);
this._onInhibitorLoaded(proxy); this._onInhibitorLoaded(proxy);
})); }));

View File

@ -23,7 +23,6 @@ function _navigateActor(actor) {
// GrabHelper: // GrabHelper:
// @owner: the actor that owns the GrabHelper // @owner: the actor that owns the GrabHelper
// @params: optional parameters to pass to Main.pushModal()
// //
// Creates a new GrabHelper object, for dealing with keyboard and pointer grabs // Creates a new GrabHelper object, for dealing with keyboard and pointer grabs
// associated with a set of actors. // associated with a set of actors.
@ -35,9 +34,8 @@ function _navigateActor(actor) {
const GrabHelper = new Lang.Class({ const GrabHelper = new Lang.Class({
Name: 'GrabHelper', Name: 'GrabHelper',
_init: function(owner, params) { _init: function(owner) {
this._owner = owner; this._owner = owner;
this._modalParams = params;
this._grabStack = []; this._grabStack = [];
@ -167,7 +165,7 @@ const GrabHelper = new Lang.Class({
_takeModalGrab: function() { _takeModalGrab: function() {
let firstGrab = (this._modalCount == 0); let firstGrab = (this._modalCount == 0);
if (firstGrab) { if (firstGrab) {
if (!Main.pushModal(this._owner, this._modalParams)) if (!Main.pushModal(this._owner))
return false; return false;
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent)); this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));

View File

@ -2,7 +2,6 @@
const Caribou = imports.gi.Caribou; const Caribou = imports.gi.Caribou;
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const DBus = imports.dbus;
const Gdk = imports.gi.Gdk; const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
@ -20,6 +19,25 @@ const KEYBOARD_TYPE = 'keyboard-type';
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications'; const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
const SHOW_KEYBOARD = 'screen-keyboard-enabled'; const SHOW_KEYBOARD = 'screen-keyboard-enabled';
// Key constants taken from Antler
// FIXME: ought to be moved into libcaribou
const PRETTY_KEYS = {
'BackSpace': '\u232b',
'space': ' ',
'Return': '\u23ce',
'Caribou_Prefs': '\u2328',
'Caribou_ShiftUp': '\u2b06',
'Caribou_ShiftDown': '\u2b07',
'Caribou_Emoticons': '\u263a',
'Caribou_Symbols': '123',
'Caribou_Symbols_More': '{#*',
'Caribou_Alpha': 'Abc',
'Tab': 'Tab',
'Escape': 'Esc',
'Control_L': 'Ctrl',
'Alt_L': 'Alt'
};
const CaribouKeyboardIface = <interface name='org.gnome.Caribou.Keyboard'> const CaribouKeyboardIface = <interface name='org.gnome.Caribou.Keyboard'>
<method name='Show'> <method name='Show'>
<arg type='u' direction='in' /> <arg type='u' direction='in' />
@ -79,7 +97,17 @@ const Key = new Lang.Class({
}, },
_makeKey: function () { _makeKey: function () {
let label = GLib.markup_escape_text(this._key.label, -1); let label = this._key.name;
if (label.length > 1) {
let pretty = PRETTY_KEYS[label];
if (pretty)
label = pretty;
else
label = this._getUnichar(this._key);
}
label = GLib.markup_escape_text(label, -1);
let button = new St.Button ({ label: label, let button = new St.Button ({ label: label,
style_class: 'keyboard-key' }); style_class: 'keyboard-key' });
@ -162,13 +190,14 @@ const Key = new Lang.Class({
} }
}); });
const Keyboard = new Lang.Class({ const Keyboard = new Gio.DBusImplementerClass({
// HACK: we can't set Name, because it collides with Name dbus property // HACK: we can't set Name, because it collides with Name dbus property
// Name: 'Keyboard', // Name: 'Keyboard',
Interface: CaribouKeyboardIface,
_init: function () { _init: function () {
this._impl = Gio.DBusExportedObject.wrapJSObject(CaribouKeyboardIface, this); this.parent();
this._impl.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard'); this.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard');
this.actor = null; this.actor = null;
this._focusInTray = false; this._focusInTray = false;

View File

@ -128,6 +128,8 @@ const LayoutManager = new Lang.Class({
this.trayBox = new St.Widget({ name: 'trayBox', this.trayBox = new St.Widget({ name: 'trayBox',
layout_manager: new Clutter.BinLayout() }); layout_manager: new Clutter.BinLayout() });
this.addChrome(this.trayBox); this.addChrome(this.trayBox);
this.trayBox.connect('allocation-changed',
Lang.bind(this, this._updateTrayBarrier));
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox', this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
reactive: true, reactive: true,
@ -278,6 +280,22 @@ const LayoutManager = new Lang.Class({
} }
}, },
_updateTrayBarrier: function() {
let monitor = this.bottomMonitor;
if (this._trayBarrier)
global.destroy_pointer_barrier(this._trayBarrier);
if (Main.messageTray) {
this._trayBarrier =
global.create_pointer_barrier(monitor.x + monitor.width, monitor.y + monitor.height - Main.messageTray.actor.height,
monitor.x + monitor.width, monitor.y + monitor.height,
4 /* BarrierNegativeX */);
} else {
this._trayBarrier = 0;
}
},
_monitorsChanged: function() { _monitorsChanged: function() {
this._updateMonitors(); this._updateMonitors();
this._updateBoxes(); this._updateBoxes();

View File

@ -1129,7 +1129,7 @@ const LookingGlass = new Lang.Class({
if (this._open) if (this._open)
return; return;
if (!Main.pushModal(this._entry, { keybindingMode: Main.KeybindingMode.LOOKING_GLASS })) if (!Main.pushModal(this._entry))
return; return;
this._notebook.selectIndex(0); this._notebook.selectIndex(0);

View File

@ -96,14 +96,15 @@ const ZoomRegionIface = <interface name={ZOOM_SERVICE_NAME}>
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc. // '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
let _zoomRegionInstanceCount = 0; let _zoomRegionInstanceCount = 0;
const ShellMagnifier = new Lang.Class({ const ShellMagnifier = new Gio.DBusImplementerClass({
Name: 'ShellMagnifier', Name: 'ShellMagnifier',
Interface: MagnifierIface,
_init: function() { _init: function() {
this._zoomers = {}; this.parent();
this.export(Gio.DBus.session, MAG_SERVICE_PATH);
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this); this._zoomers = {};
this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH);
}, },
/** /**
@ -332,14 +333,15 @@ const ShellMagnifier = new Lang.Class({
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion. * @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
* @zoomRegion: The actual zoom region associated with the object path. * @zoomRegion: The actual zoom region associated with the object path.
*/ */
const ShellMagnifierZoomRegion = new Lang.Class({ const ShellMagnifierZoomRegion = new Gio.DBusImplementerClass({
Name: 'ShellMagnifierZoomRegion', Name: 'ShellMagnifierZoomRegion',
Interface: ZoomRegionIface,
_init: function(zoomerObjectPath, zoomRegion) { _init: function(zoomerObjectPath, zoomRegion) {
this._zoomRegion = zoomRegion; this.parent();
this.export(Gio.DBus.session, zoomerObjectPath);
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this); this._zoomRegion = zoomRegion;
this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath);
}, },
/** /**
@ -417,6 +419,6 @@ const ShellMagnifierZoomRegion = new Lang.Class({
}, },
destroy: function() { destroy: function() {
this._dbusImpl.unexport(); this.unexport();
} }
}); });

View File

@ -20,7 +20,6 @@ const Keyboard = imports.ui.keyboard;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
const Overview = imports.ui.overview; const Overview = imports.ui.overview;
const Panel = imports.ui.panel; const Panel = imports.ui.panel;
const Params = imports.misc.params;
const RunDialog = imports.ui.runDialog; const RunDialog = imports.ui.runDialog;
const Layout = imports.ui.layout; const Layout = imports.ui.layout;
const LookingGlass = imports.ui.lookingGlass; const LookingGlass = imports.ui.lookingGlass;
@ -40,18 +39,6 @@ const Util = imports.misc.util;
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides'; const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff); const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const KeybindingMode = {
NONE: 0, // block all keybindings
NORMAL: 1 << 0, // window mode
OVERVIEW: 1 << 1,
LOCK_SCREEN: 1 << 2,
UNLOCK_SCREEN: 1 << 3,
LOGIN_SCREEN: 1 << 4,
MESSAGE_TRAY: 1 << 5,
SYSTEM_MODAL: 1 << 6,
LOOKING_GLASS: 1 << 7
};
let componentManager = null; let componentManager = null;
let panel = null; let panel = null;
let overview = null; let overview = null;
@ -68,7 +55,6 @@ let shellDBusService = null;
let shellMountOpDBusService = null; let shellMountOpDBusService = null;
let screenSaverDBus = null; let screenSaverDBus = null;
let modalCount = 0; let modalCount = 0;
let keybindingMode = KeybindingMode.NORMAL;
let modalActorFocusStack = []; let modalActorFocusStack = [];
let uiGroup = null; let uiGroup = null;
let magnifier = null; let magnifier = null;
@ -83,17 +69,7 @@ let _overridesSettings = null;
let background = null; let background = null;
function _sessionUpdated() { function _sessionUpdated() {
wm.setCustomKeybindingHandler('panel-main-menu', Meta.keybindings_set_custom_handler('panel-run-dialog', sessionMode.hasRunDialog ? openRunDialog : null);
KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW,
sessionMode.hasOverview ? Lang.bind(overview, overview.toggle) : null);
wm.allowKeybinding('overlay-key', KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW);
wm.setCustomKeybindingHandler('panel-run-dialog',
KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW,
sessionMode.hasRunDialog ? openRunDialog : null);
if (sessionMode.isGreeter) if (sessionMode.isGreeter)
screenShield.showDialog(); screenShield.showDialog();
} }
@ -179,7 +155,9 @@ function start() {
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1); false, -1, 1);
Meta.keybindings_set_custom_handler('panel-main-menu', Lang.bind(overview, overview.toggle));
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle)); global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
sessionMode.connect('update', _sessionUpdated); sessionMode.connect('update', _sessionUpdated);
_sessionUpdated(); _sessionUpdated();
@ -189,6 +167,8 @@ function start() {
_startDate = new Date(); _startDate = new Date();
global.stage.connect('captured-event', _globalKeyPressHandler);
log('GNOME Shell started at ' + _startDate); log('GNOME Shell started at ' + _startDate);
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE"); let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
@ -485,6 +465,80 @@ function getWindowActorsForWorkspace(workspaceIndex) {
}); });
} }
// This function encapsulates hacks to make certain global keybindings
// work even when we are in one of our modes where global keybindings
// are disabled with a global grab. (When there is a global grab, then
// all key events will be delivered to the stage, so ::captured-event
// on the stage can be used for global keybindings.)
function _globalKeyPressHandler(actor, event) {
if (modalCount == 0)
return false;
if (event.type() != Clutter.EventType.KEY_PRESS)
return false;
if (!sessionMode.allowKeybindingsWhenModal) {
if (modalCount > (overview.visible ? 1 : 0))
return false;
}
let symbol = event.get_key_symbol();
let keyCode = event.get_key_code();
let ignoredModifiers = global.display.get_ignored_modifier_mask();
let modifierState = event.get_state() & ~ignoredModifiers;
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
let action = global.display.get_keybinding_action(keyCode, modifierState);
if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
modifierState);
return true;
}
switch (action) {
// left/right would effectively act as synonyms for up/down if we enabled them;
// but that could be considered confusing; we also disable them in the main view.
//
// case Meta.KeyBindingAction.WORKSPACE_LEFT:
// if (!sessionMode.hasWorkspaces)
// return false;
//
// wm.actionMoveWorkspaceLeft();
// return true;
// case Meta.KeyBindingAction.WORKSPACE_RIGHT:
// if (!sessionMode.hasWorkspaces)
// return false;
//
// wm.actionMoveWorkspaceRight();
// return true;
case Meta.KeyBindingAction.WORKSPACE_UP:
if (!sessionMode.hasWorkspaces)
return false;
wm.actionMoveWorkspace(Meta.MotionDirection.UP);
return true;
case Meta.KeyBindingAction.WORKSPACE_DOWN:
if (!sessionMode.hasWorkspaces)
return false;
wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
return true;
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
case Meta.KeyBindingAction.COMMAND_2:
if (!sessionMode.hasRunDialog)
return false;
openRunDialog();
return true;
case Meta.KeyBindingAction.PANEL_MAIN_MENU:
case Meta.KeyBindingAction.OVERLAY_KEY:
overview.hide();
return true;
}
return false;
}
function _findModal(actor) { function _findModal(actor) {
for (let i = 0; i < modalActorFocusStack.length; i++) { for (let i = 0; i < modalActorFocusStack.length; i++) {
if (modalActorFocusStack[i].actor == actor) if (modalActorFocusStack[i].actor == actor)
@ -500,7 +554,7 @@ function isInModalStack(actor) {
/** /**
* pushModal: * pushModal:
* @actor: #ClutterActor which will be given keyboard focus * @actor: #ClutterActor which will be given keyboard focus
* @params: optional parameters * @timestamp: optional timestamp
* *
* Ensure we are in a mode where all keyboard and mouse input goes to * Ensure we are in a mode where all keyboard and mouse input goes to
* the stage, and focus @actor. Multiple calls to this function act in * the stage, and focus @actor. Multiple calls to this function act in
@ -511,27 +565,21 @@ function isInModalStack(actor) {
* modal stack returns to this actor, reset the focus to the actor * modal stack returns to this actor, reset the focus to the actor
* which was focused at the time pushModal() was invoked. * which was focused at the time pushModal() was invoked.
* *
* @params may be used to provide the following parameters: * @timestamp is optionally used to associate the call with a specific user
* - timestamp: used to associate the call with a specific user initiated * initiated event. If not provided then the value of
* event. If not provided then the value of * global.get_current_time() is assumed.
* global.get_current_time() is assumed.
* *
* - options: Meta.ModalOptions flags to indicate that the pointer is * @options: optional Meta.ModalOptions flags to indicate that the
* already grabbed * pointer is alrady grabbed
*
* - keybindingMode: used to set the current Main.KeybindingMode to filter
* global keybindings; the default of NONE will filter
* out all keybindings
* *
* Returns: true iff we successfully acquired a grab or already had one * Returns: true iff we successfully acquired a grab or already had one
*/ */
function pushModal(actor, params) { function pushModal(actor, timestamp, options) {
params = Params.parse(params, { timestamp: global.get_current_time(), if (timestamp == undefined)
options: 0, timestamp = global.get_current_time();
keybindingMode: KeybindingMode.NONE });
if (modalCount == 0) { if (modalCount == 0) {
if (!global.begin_modal(params.timestamp, params.options)) { if (!global.begin_modal(timestamp, options ? options : 0)) {
log('pushModal: invocation of begin_modal failed'); log('pushModal: invocation of begin_modal failed');
return false; return false;
} }
@ -558,10 +606,8 @@ function pushModal(actor, params) {
modalActorFocusStack.push({ actor: actor, modalActorFocusStack.push({ actor: actor,
focus: curFocus, focus: curFocus,
destroyId: actorDestroyId, destroyId: actorDestroyId,
focusDestroyId: curFocusDestroyId, focusDestroyId: curFocusDestroyId });
keybindingMode: keybindingMode });
keybindingMode = params.keybindingMode;
global.stage.set_key_focus(actor); global.stage.set_key_focus(actor);
return true; return true;
} }
@ -588,7 +634,6 @@ function popModal(actor, timestamp) {
global.stage.set_key_focus(null); global.stage.set_key_focus(null);
global.end_modal(timestamp); global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL); global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
keybindingMode = KeybindingMode.NORMAL;
throw new Error('incorrect pop'); throw new Error('incorrect pop');
} }
@ -601,7 +646,6 @@ function popModal(actor, timestamp) {
if (focusIndex == modalActorFocusStack.length - 1) { if (focusIndex == modalActorFocusStack.length - 1) {
if (record.focus) if (record.focus)
record.focus.disconnect(record.focusDestroyId); record.focus.disconnect(record.focusDestroyId);
keybindingMode = record.keybindingMode;
global.stage.set_key_focus(record.focus); global.stage.set_key_focus(record.focus);
} else { } else {
let t = modalActorFocusStack[modalActorFocusStack.length - 1]; let t = modalActorFocusStack[modalActorFocusStack.length - 1];
@ -611,7 +655,6 @@ function popModal(actor, timestamp) {
for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) { for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) {
modalActorFocusStack[i].focus = modalActorFocusStack[i - 1].focus; modalActorFocusStack[i].focus = modalActorFocusStack[i - 1].focus;
modalActorFocusStack[i].focusDestroyId = modalActorFocusStack[i - 1].focusDestroyId; modalActorFocusStack[i].focusDestroyId = modalActorFocusStack[i - 1].focusDestroyId;
modalActorFocusStack[i].keybindingMode = modalActorFocusStack[i - 1].keybindingMode;
} }
} }
modalActorFocusStack.splice(focusIndex, 1); modalActorFocusStack.splice(focusIndex, 1);
@ -622,7 +665,6 @@ function popModal(actor, timestamp) {
global.end_modal(timestamp); global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL); global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
Meta.enable_unredirect_for_screen(global.screen); Meta.enable_unredirect_for_screen(global.screen);
keybindingMode = KeybindingMode.NORMAL;
} }
function createLookingGlass() { function createLookingGlass() {

View File

@ -314,7 +314,6 @@ const Notification = new Lang.Class({
this.resident = false; this.resident = false;
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name // 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
this.isTransient = false; this.isTransient = false;
this.forFeedback = false;
this.expanded = false; this.expanded = false;
this.focused = false; this.focused = false;
this.acknowledged = false; this.acknowledged = false;
@ -714,10 +713,6 @@ const Notification = new Lang.Class({
this.isTransient = isTransient; this.isTransient = isTransient;
}, },
setForFeedback: function(forFeedback) {
this.forFeedback = forFeedback;
},
setUseActionIcons: function(useIcons) { setUseActionIcons: function(useIcons) {
this._useActionIcons = useIcons; this._useActionIcons = useIcons;
}, },
@ -1370,13 +1365,16 @@ const MessageTray = new Lang.Class({
Name: 'MessageTray', Name: 'MessageTray',
_init: function() { _init: function() {
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) { this._presence = new GnomeSession.Presence();
this._presence.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
proxy.init_finish(result);
this._onStatusChanged(proxy.status); this._onStatusChanged(proxy.status);
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
this._onStatusChanged(status);
}));
})); }));
this._busy = false; this._busy = false;
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
this._onStatusChanged(status);
}));
this.actor = new St.Widget({ name: 'message-tray', this.actor = new St.Widget({ name: 'message-tray',
reactive: true, reactive: true,
@ -1394,8 +1392,6 @@ const MessageTray = new Lang.Class({
y_expand: true, y_expand: true,
x_expand: true, x_expand: true,
layout_manager: new Clutter.BinLayout() }); layout_manager: new Clutter.BinLayout() });
this._notificationWidget.connect('key-release-event', Lang.bind(this, this._onNotificationKeyRelease));
this.actor.add_actor(this._notificationWidget); this.actor.add_actor(this._notificationWidget);
this._notificationBin = new St.Bin({ y_expand: true }); this._notificationBin = new St.Bin({ y_expand: true });
@ -1445,7 +1441,7 @@ const MessageTray = new Lang.Class({
this._closeButton = makeCloseButton(); this._closeButton = makeCloseButton();
this._closeButton.hide(); this._closeButton.hide();
this._closeButton.connect('clicked', Lang.bind(this, this._closeNotification)); this._closeButton.connect('clicked', Lang.bind(this, this._onCloseClicked));
this._notificationWidget.add_actor(this._closeButton); this._notificationWidget.add_actor(this._closeButton);
this._idleMonitorBecameActiveId = 0; this._idleMonitorBecameActiveId = 0;
@ -1453,8 +1449,7 @@ const MessageTray = new Lang.Class({
this.idleMonitor = new GnomeDesktop.IdleMonitor(); this.idleMonitor = new GnomeDesktop.IdleMonitor();
this._grabHelper = new GrabHelper.GrabHelper(this.actor, this._grabHelper = new GrabHelper.GrabHelper(this.actor);
{ keybindingMode: Main.KeybindingMode.MESSAGE_TRAY });
this._grabHelper.addActor(this._summaryBoxPointer.actor); this._grabHelper.addActor(this._summaryBoxPointer.actor);
this._grabHelper.addActor(this.actor); this._grabHelper.addActor(this.actor);
if (Main.panel.statusArea.activities) if (Main.panel.statusArea.activities)
@ -1518,20 +1513,10 @@ const MessageTray = new Lang.Class({
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
Main.wm.addKeybinding('toggle-message-tray', global.display.add_keybinding('toggle-message-tray',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }), new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE, Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL | Lang.bind(this, this.toggleAndNavigate));
Main.KeybindingMode.MESSAGE_TRAY |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this.toggleAndNavigate));
Main.wm.addKeybinding('focus-active-notification',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.MESSAGE_TRAY |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._expandActiveNotification));
this._summaryItems = []; this._summaryItems = [];
this._chatSummaryItemsCount = 0; this._chatSummaryItemsCount = 0;
@ -1607,19 +1592,7 @@ const MessageTray = new Lang.Class({
return false; return false;
}, },
_onNotificationKeyRelease: function(actor, event) { _onCloseClicked: function() {
let ignoredModifiers = global.display.get_ignored_modifier_mask();
let modifierState = event.get_state() & ~ignoredModifiers;
if (event.get_key_symbol() == Clutter.KEY_Escape && modifierState == 0) {
this._closeNotification();
return true;
}
return false;
},
_closeNotification: function() {
if (this._notificationState == State.SHOWN) { if (this._notificationState == State.SHOWN) {
this._closeButton.hide(); this._closeButton.hide();
this._notificationClosed = true; this._notificationClosed = true;
@ -1979,9 +1952,8 @@ const MessageTray = new Lang.Class({
// Notifications // Notifications
let notificationQueue = this._notificationQueue; let notificationQueue = this._notificationQueue;
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL; let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback;
let notificationsLimited = this._busy || this._inFullscreen; let notificationsLimited = this._busy || this._inFullscreen;
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && Main.sessionMode.hasNotifications; let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent) && Main.sessionMode.hasNotifications;
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null; let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved; let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
let notificationExpanded = this._notification && this._notification.expanded; let notificationExpanded = this._notification && this._notification.expanded;
@ -2317,18 +2289,6 @@ const MessageTray = new Lang.Class({
}, },
_hideNotification: function() { _hideNotification: function() {
// HACK!
// There seems to be a reentrancy issue in calling .ungrab() here,
// which causes _updateState to be called before _notificationState
// becomes HIDING. That hides the notification again, nullifying the
// object but not setting _notificationState (and that's the weird part)
// As then _notificationState is stuck into SHOWN but _notification
// is null, every new _updateState fails and the message tray is
// lost forever.
//
// See more at https://bugzilla.gnome.org/show_bug.cgi?id=683986
this._notificationState = State.HIDING;
this._grabHelper.ungrab({ actor: this._notification.actor }); this._grabHelper.ungrab({ actor: this._notification.actor });
if (this._idleMonitorBecameActiveId) { if (this._idleMonitorBecameActiveId) {
@ -2375,13 +2335,6 @@ const MessageTray = new Lang.Class({
notification.destroy(NotificationDestroyedReason.EXPIRED); notification.destroy(NotificationDestroyedReason.EXPIRED);
}, },
_expandActiveNotification: function() {
if (!this._notification)
return;
this._expandNotification(false);
},
_expandNotification: function(autoExpanding) { _expandNotification: function(autoExpanding) {
// Don't grab focus in notifications that are auto-expanded. // Don't grab focus in notifications that are auto-expanded.
if (!autoExpanding) if (!autoExpanding)
@ -2405,13 +2358,8 @@ const MessageTray = new Lang.Class({
if (this._notificationWidget.y < expandedY) { if (this._notificationWidget.y < expandedY) {
this._notificationWidget.y = expandedY; this._notificationWidget.y = expandedY;
} else if (this._notification.y != expandedY) { } else if (this._notification.y != expandedY) {
// Tween also opacity here, to override a possible tween that's
// currently hiding the notification. This will ensure that the
// notification is not removed when the onComplete handler for this
// one triggers.
this._tween(this._notificationWidget, '_notificationState', State.SHOWN, this._tween(this._notificationWidget, '_notificationState', State.SHOWN,
{ y: expandedY, { y: expandedY,
opacity: 255,
time: ANIMATION_TIME, time: ANIMATION_TIME,
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });

View File

@ -37,12 +37,10 @@ const ModalDialog = new Lang.Class({
params = Params.parse(params, { shellReactive: false, params = Params.parse(params, { shellReactive: false,
styleClass: null, styleClass: null,
parentActor: Main.uiGroup, parentActor: Main.uiGroup,
keybindingMode: Main.KeybindingMode.SYSTEM_MODAL,
shouldFadeIn: true }); shouldFadeIn: true });
this.state = State.CLOSED; this.state = State.CLOSED;
this._hasModal = false; this._hasModal = false;
this._keybindingMode = params.keybindingMode;
this._shellReactive = params.shellReactive; this._shellReactive = params.shellReactive;
this._shouldFadeIn = params.shouldFadeIn; this._shouldFadeIn = params.shouldFadeIn;
@ -228,7 +226,7 @@ const ModalDialog = new Lang.Class({
if (this.state == State.OPENED || this.state == State.OPENING) if (this.state == State.OPENED || this.state == State.OPENING)
return true; return true;
if (!this.pushModal({ timestamp: timestamp })) if (!this.pushModal(timestamp))
return false; return false;
this._fadeOpen(onPrimary); this._fadeOpen(onPrimary);
@ -278,8 +276,7 @@ const ModalDialog = new Lang.Class({
pushModal: function (timestamp) { pushModal: function (timestamp) {
if (this._hasModal) if (this._hasModal)
return true; return true;
if (!Main.pushModal(this._group, { timestamp: timestamp, if (!Main.pushModal(this._group, timestamp))
keybindingMode: this._keybindingMode }))
return false; return false;
this._hasModal = true; this._hasModal = true;

View File

@ -25,10 +25,19 @@ const BusIface = <interface name="org.freedesktop.DBus">
</method> </method>
</interface>; </interface>;
var BusProxy = Gio.DBusProxy.makeProxyWrapper(BusIface); const Bus = new Gio.DBusProxyClass({
function Bus() { Name: 'SessionBusProxy',
return new BusProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus'); Interface: BusIface,
}
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.freedesktop.DBus',
g_object_path: '/org/freedesktop/DBus',
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES |
Gio.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS |
Gio.DBusProxyFlags.DO_NOT_AUTO_START) });
}
});
const NotificationDaemonIface = <interface name="org.freedesktop.Notifications"> const NotificationDaemonIface = <interface name="org.freedesktop.Notifications">
<method name="Notify"> <method name="Notify">
@ -103,17 +112,20 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'ibus-ui-gtk': 'keyboard' 'ibus-ui-gtk': 'keyboard'
}; };
const NotificationDaemon = new Lang.Class({ const NotificationDaemon = new Gio.DBusImplementerClass({
Name: 'NotificationDaemon', Name: 'NotificationDaemon',
Interface: NotificationDaemonIface,
_init: function() { _init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(NotificationDaemonIface, this); this.parent();
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications'); this.export(Gio.DBus.session, '/org/freedesktop/Notifications');
this._sources = []; this._sources = [];
this._senderToPid = {}; this._senderToPid = {};
this._notifications = {}; this._notifications = {};
this._busProxy = new Bus(); this._busProxy = new Bus();
// This is synchronous but fast because of the flags we use.
this._busProxy.init(null);
this._trayManager = new Shell.TrayManager(); this._trayManager = new Shell.TrayManager();
this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded)); this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
@ -316,18 +328,20 @@ const NotificationDaemon = new Lang.Class({
return invocation.return_value(GLib.Variant.new('(u)', [id]));; return invocation.return_value(GLib.Variant.new('(u)', [id]));;
} }
this._busProxy.GetConnectionUnixProcessIDRemote(sender, Lang.bind(this, function (result, excp) { this._busProxy.GetConnectionUnixProcessIDRemote(sender, null, Lang.bind(this, function (proxy, result) {
// The app may have updated or removed the notification // The app may have updated or removed the notification
ndata = this._notifications[id]; ndata = this._notifications[id];
if (!ndata) if (!ndata)
return; return;
if (excp) { let pid;
try {
[pid] = proxy.GetConnectionUnixProcessIDFinish(result);
} catch(excp) {
logError(excp, 'Call to GetConnectionUnixProcessID failed'); logError(excp, 'Call to GetConnectionUnixProcessID failed');
return; return;
} }
let [pid] = result;
source = this._getSource(appName, pid, ndata, sender, null); source = this._getSource(appName, pid, ndata, sender, null);
// We only store sender-pid entries for persistent sources. // We only store sender-pid entries for persistent sources.
@ -487,13 +501,11 @@ const NotificationDaemon = new Lang.Class({
}, },
_emitNotificationClosed: function(id, reason) { _emitNotificationClosed: function(id, reason) {
this._dbusImpl.emit_signal('NotificationClosed', this.emit_signal('NotificationClosed', id, reason);
GLib.Variant.new('(uu)', [id, reason]));
}, },
_emitActionInvoked: function(id, action) { _emitActionInvoked: function(id, action) {
this._dbusImpl.emit_signal('ActionInvoked', this.emit_signal('ActionInvoked', id, action);
GLib.Variant.new('(us)', [id, action]));
}, },
_onTrayIconAdded: function(o, icon) { _onTrayIconAdded: function(o, icon) {

View File

@ -28,24 +28,6 @@ const DASH_MAX_WIDTH = 96;
const DND_WINDOW_SWITCH_TIMEOUT = 1250; const DND_WINDOW_SWITCH_TIMEOUT = 1250;
const GLSL_DIM_EFFECT_DECLARATIONS = '';
const GLSL_DIM_EFFECT_CODE = '\
vec2 dist = cogl_tex_coord_in[0].xy - vec2(0.5, 0.5); \
float elipse_radius = 0.5; \
/* from https://bugzilla.gnome.org/show_bug.cgi?id=669798: \
the alpha on the gradient goes from 165 at its darkest to 98 at its most transparent. */ \
float y = 165.0 / 255.0; \
float x = 98.0 / 255.0; \
/* interpolate darkening value, based on distance from screen center */ \
float val = min(length(dist), elipse_radius); \
float a = mix(x, y, val / elipse_radius); \
/* dim_factor varies from [1.0 -> 0.5] when overview is showing \
We use it to smooth value, then we clamp it to valid color interval */ \
a = clamp(a - cogl_color_in.r + 0.5, 0.0, 1.0); \
/* We\'re blending between: color and black color (obviously omitted in the equation) */ \
cogl_color_out.xyz = cogl_color_out.xyz * (1.0 - a); \
cogl_color_out.a = 1.0;';
const SwipeScrollDirection = { const SwipeScrollDirection = {
NONE: 0, NONE: 0,
HORIZONTAL: 1, HORIZONTAL: 1,
@ -75,14 +57,7 @@ const ShellInfo = new Lang.Class({
this._source.destroy(); this._source.destroy();
}, },
setMessage: function(text, options) { setMessage: function(text, undoCallback, undoLabel) {
options = Params.parse(options, { undoCallback: null,
forFeedback: false
});
let undoCallback = options.undoCallback;
let forFeedback = options.forFeedback;
if (this._source == null) { if (this._source == null) {
this._source = new MessageTray.SystemNotificationSource(); this._source = new MessageTray.SystemNotificationSource();
this._source.connect('destroy', Lang.bind(this, this._source.connect('destroy', Lang.bind(this,
@ -96,7 +71,6 @@ const ShellInfo = new Lang.Class({
if (this._source.notifications.length == 0) { if (this._source.notifications.length == 0) {
notification = new MessageTray.Notification(this._source, text, null); notification = new MessageTray.Notification(this._source, text, null);
notification.setTransient(true); notification.setTransient(true);
notification.setForFeedback(forFeedback);
} else { } else {
notification = this._source.notifications[0]; notification = this._source.notifications[0];
notification.update(text, null, { clear: true }); notification.update(text, null, { clear: true });
@ -104,8 +78,10 @@ const ShellInfo = new Lang.Class({
this._undoCallback = undoCallback; this._undoCallback = undoCallback;
if (undoCallback) { if (undoCallback) {
notification.addButton('system-undo', _("Undo")); notification.addButton('system-undo',
notification.connect('action-invoked', Lang.bind(this, this._onUndoClicked)); undoLabel ? undoLabel : _("Undo"));
notification.connect('action-invoked',
Lang.bind(this, this._onUndoClicked));
} }
this._source.notify(notification); this._source.notify(notification);
@ -137,10 +113,6 @@ const Overview = new Lang.Class({
// scenes which allows us to show the background with different // scenes which allows us to show the background with different
// rendering options without duplicating the texture data. // rendering options without duplicating the texture data.
this._background = Meta.BackgroundActor.new_for_screen(global.screen); this._background = Meta.BackgroundActor.new_for_screen(global.screen);
this._background.add_glsl_snippet(Meta.SnippetHook.FRAGMENT,
GLSL_DIM_EFFECT_DECLARATIONS,
GLSL_DIM_EFFECT_CODE,
false);
this._background.hide(); this._background.hide();
global.overlay_group.add_actor(this._background); global.overlay_group.add_actor(this._background);
@ -261,16 +233,11 @@ const Overview = new Lang.Class({
this._viewSelector.removeSearchProvider(provider); this._viewSelector.removeSearchProvider(provider);
}, },
// setMessage: function(text, undoCallback, undoLabel) {
// options:
// - undoCallback (function): the callback to be called if undo support is needed
// - forFeedback (boolean): whether the message is for direct feedback of a user action
//
setMessage: function(text, options) {
if (this.isDummy) if (this.isDummy)
return; return;
this._shellInfo.setMessage(text, options); this._shellInfo.setMessage(text, undoCallback, undoLabel);
}, },
_onDragBegin: function() { _onDragBegin: function() {
@ -591,7 +558,7 @@ const Overview = new Lang.Class({
if (this._shown) if (this._shown)
return; return;
// Do this manually instead of using _syncInputMode, to handle failure // Do this manually instead of using _syncInputMode, to handle failure
if (!Main.pushModal(this._group, { keybindingMode: Main.KeybindingMode.OVERVIEW })) if (!Main.pushModal(this._group))
return; return;
this._modal = true; this._modal = true;
this._animateVisible(); this._animateVisible();
@ -655,7 +622,7 @@ const Overview = new Lang.Class({
}); });
Tweener.addTween(this._background, Tweener.addTween(this._background,
{ dim_factor: 0.8, { dim_factor: 0.4,
time: ANIMATION_TIME, time: ANIMATION_TIME,
transition: 'easeOutQuad' transition: 'easeOutQuad'
}); });
@ -742,8 +709,7 @@ const Overview = new Lang.Class({
if (this._shown) { if (this._shown) {
if (!this._modal) { if (!this._modal) {
if (Main.pushModal(this._group, if (Main.pushModal(this._group))
{ keybindingMode: Main.KeybindingMode.OVERVIEW }))
this._modal = true; this._modal = true;
else else
this.hide(); this.hide();

View File

@ -82,34 +82,26 @@ const AnimatedIcon = new Lang.Class({
_init: function(name, size) { _init: function(name, size) {
this.actor = new St.Bin({ visible: false }); this.actor = new St.Bin({ visible: false });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this.actor.connect('notify::visible', Lang.bind(this, this._onVisibleNotify));
this._isLoaded = false;
this._isPlaying = false;
this._timeoutId = 0; this._timeoutId = 0;
this._frame = 0; this._frame = 0;
this._animations = St.TextureCache.get_default().load_sliced_image (global.datadir + '/theme/' + name, size, size, this._animations = St.TextureCache.get_default().load_sliced_image (global.datadir + '/theme/' + name, size, size);
Lang.bind(this, this._animationsLoaded));
this.actor.set_child(this._animations); this.actor.set_child(this._animations);
}, },
play: function() { _disconnectTimeout: function() {
if (this._isLoaded && this._timeoutId == 0) {
if (this._frame == 0)
this._showFrame(0);
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
}
this._isPlaying = true;
},
stop: function() {
if (this._timeoutId > 0) { if (this._timeoutId > 0) {
Mainloop.source_remove(this._timeoutId); Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0; this._timeoutId = 0;
} }
},
this._isPlaying = false; _onVisibleNotify: function() {
if (this.actor.visible)
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
else
this._disconnectTimeout();
}, },
_showFrame: function(frame) { _showFrame: function(frame) {
@ -129,17 +121,8 @@ const AnimatedIcon = new Lang.Class({
return true; return true;
}, },
_animationsLoaded: function() {
this._isLoaded = true;
if (this._isPlaying) {
this._showFrame(0);
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
}
},
_onDestroy: function() { _onDestroy: function() {
this.stop(); this._disconnectTimeout();
} }
}); });
@ -384,7 +367,6 @@ const AppMenuButton = new Lang.Class({
transition: "easeOutQuad", transition: "easeOutQuad",
onCompleteScope: this, onCompleteScope: this,
onComplete: function() { onComplete: function() {
this._spinner.stop();
this._spinner.actor.opacity = 255; this._spinner.actor.opacity = 255;
this._spinner.actor.hide(); this._spinner.actor.hide();
} }
@ -394,7 +376,6 @@ const AppMenuButton = new Lang.Class({
startAnimation: function() { startAnimation: function() {
this._stop = false; this._stop = false;
this.actor.reactive = false; this.actor.reactive = false;
this._spinner.play();
this._spinner.actor.show(); this._spinner.actor.show();
}, },

View File

@ -29,39 +29,29 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
</method> </method>
</interface>; </interface>;
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface); var SearchProviderProxy = new Gio.DBusProxyClass({
Name: 'SearchProviderProxy',
Interface: SearchProviderIface,
_init: function(params) {
params.g_bus_type = Gio.BusType.SESSION;
this.parent(params);
}
});
function loadRemoteSearchProviders(addProviderCallback) { function loadRemoteSearchProviders(addProviderCallback) {
let loadState = { loadedProviders: [],
objectPaths: {},
numLoading: 0,
addProviderCallback: addProviderCallback };
let dataDirs = GLib.get_system_data_dirs(); let dataDirs = GLib.get_system_data_dirs();
let loadedProviders = {};
for (let i = 0; i < dataDirs.length; i++) { for (let i = 0; i < dataDirs.length; i++) {
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'search-providers']); let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'search-providers']);
let dir = Gio.file_new_for_path(path); let dir = Gio.file_new_for_path(path);
if (!dir.query_exists(null))
dir.query_info_async('standard:type', Gio.FileQueryInfoFlags.NONE, continue;
GLib.PRIORITY_DEFAULT, null, loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallback);
function(object, res) {
let exists = false;
try {
object.query_info_finish(res);
exists = true;
} catch (e) {
}
if (!exists)
return;
loadState.numLoading++;
loadRemoteSearchProvidersFromDir(dir, loadState);
});
} }
}; };
function loadRemoteSearchProvidersFromDir(dir, loadState) { function loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallback) {
let dirPath = dir.get_path(); let dirPath = dir.get_path();
FileUtils.listDirAsync(dir, Lang.bind(this, function(files) { FileUtils.listDirAsync(dir, Lang.bind(this, function(files) {
for (let i = 0; i < files.length; i++) { for (let i = 0; i < files.length; i++) {
@ -77,13 +67,13 @@ function loadRemoteSearchProvidersFromDir(dir, loadState) {
if (!keyfile.has_group(KEY_FILE_GROUP)) if (!keyfile.has_group(KEY_FILE_GROUP))
continue; continue;
let remoteProvider; let remoteProvider, title;
try { try {
let group = KEY_FILE_GROUP; let group = KEY_FILE_GROUP;
let busName = keyfile.get_string(group, 'BusName'); let busName = keyfile.get_string(group, 'BusName');
let objectPath = keyfile.get_string(group, 'ObjectPath'); let objectPath = keyfile.get_string(group, 'ObjectPath');
if (loadState.objectPaths[objectPath]) if (loadedProviders[objectPath])
continue; continue;
let appInfo = null; let appInfo = null;
@ -91,91 +81,81 @@ function loadRemoteSearchProvidersFromDir(dir, loadState) {
let desktopId = keyfile.get_string(group, 'DesktopId'); let desktopId = keyfile.get_string(group, 'DesktopId');
appInfo = Gio.DesktopAppInfo.new(desktopId); appInfo = Gio.DesktopAppInfo.new(desktopId);
} catch (e) { } catch (e) {
log('Ignoring search provider ' + path + ': missing DesktopId');
continue;
} }
remoteProvider = new RemoteSearchProvider(appInfo, let icon;
if (appInfo) {
icon = appInfo.get_icon();
title = appInfo.get_name();
} else {
let iconName = keyfile.get_string(group, 'Icon');
icon = new Gio.ThemedIcon({ name: iconName });
title = keyfile.get_locale_string(group, 'Title', null);
}
remoteProvider = new RemoteSearchProvider(title,
icon,
busName, busName,
objectPath); objectPath);
loadState.objectPaths[objectPath] = remoteProvider; remoteProvider.initAsync(null, function(obj, result) {
loadState.loadedProviders.push(remoteProvider); try {
remoteProvider.initFinish(result);
} catch(e) {
log('Failed to add search provider "%s": %s'.format(title, e.toString()));
return;
}
addProviderCallback(remoteProvider);
});
loadedProviders[objectPath] = remoteProvider;
} catch(e) { } catch(e) {
log('Failed to add search provider %s: %s'.format(path, e.toString())); log('Failed to add search provider "%s": %s'.format(title, e.toString()));
continue; continue;
} }
} }
remoteProvidersDirLoaded(loadState);
})); }));
}; };
function remoteProvidersDirLoaded(loadState) {
loadState.numLoading--;
if (loadState.numLoading > 0)
return;
let searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
let sortOrder = searchSettings.get_strv('sort-order');
let numSorted = sortOrder.length;
loadState.loadedProviders.sort(
function(providerA, providerB) {
let idxA, idxB;
let appIdA, appIdB;
appIdA = providerA.appInfo.get_id();
appIdB = providerB.appInfo.get_id();
idxA = sortOrder.indexOf(appIdA);
idxB = sortOrder.indexOf(appIdB);
// if no provider is found in the order, use alphabetical order
if ((idxA == -1) && (idxB == -1))
return GLib.utf8_collate(providerA.title, providerB.title);
if (numSorted > 1) {
// if providerA is the last, it goes after everything
if ((idxA + 1) == numSorted)
return 1;
// if providerB is the last, it goes after everything
else if ((idxB + 1) == numSorted)
return -1;
}
// if providerA isn't found, it's sorted after providerB
if (idxA == -1)
return 1;
// if providerB isn't found, it's sorted after providerA
if (idxB == -1)
return -1;
// finally, if both providers are found, return their order in the list
return (idxA - idxB);
});
loadState.loadedProviders.forEach(
function(provider) {
loadState.addProviderCallback(provider);
});
}
const RemoteSearchProvider = new Lang.Class({ const RemoteSearchProvider = new Lang.Class({
Name: 'RemoteSearchProvider', Name: 'RemoteSearchProvider',
Extends: Search.SearchProvider, Extends: Search.SearchProvider,
_init: function(appInfo, dbusName, dbusPath) { _init: function(title, icon, dbusName, dbusPath) {
this._proxy = new SearchProviderProxy(Gio.DBus.session, this.parent(title.toUpperCase());
dbusName, dbusPath, Lang.bind(this, this._onProxyConstructed));
this.parent(appInfo.get_name().toUpperCase(), appInfo, true); this._proxy = new SearchProviderProxy({ g_name: dbusName,
g_object_path: dbusPath });
this._cancellable = new Gio.Cancellable(); this._cancellable = new Gio.Cancellable();
}, },
_onProxyConstructed: function(proxy) { initAsync: function(cancellable, asyncCallback) {
// Do nothing // Can't pass "this" as source object, because RemoteSearchProvider
// is not a GObject.Object (and in gjs you can't inherit from a JS
// type that in turn inherits from GObject)
let simpleResult = Gio.SimpleAsyncResult.new(null, asyncCallback, null);
simpleResult.set_check_cancellable(cancellable);
this._proxy.init_async(GLib.PRIORITY_DEFAULT, cancellable, Lang.bind(this, function(proxy, result) {
try {
proxy.init_finish(result);
simpleResult.set_op_res_gboolean(true);
} catch(e if e instanceof GLib.Error) {
simpleResult.set_from_error(e);
}
simpleResult.complete();
}));
},
initFinish: function(simpleResult) {
if (!simpleResult.propagate_error())
return simpleResult.get_op_res_gboolean();
return false;
}, },
createIcon: function(size, meta) { createIcon: function(size, meta) {
@ -195,10 +175,17 @@ const RemoteSearchProvider = new Lang.Class({
icon_size: size }); icon_size: size });
}, },
_getResultsFinished: function(results, error) { _getResultsFinished: function(proxy, result) {
if (error) try {
return; // We rely on a small implementation detail of the
this.searchSystem.pushResults(this, results[0]); // GDBus bindings here: all *Finish are equal
let [results] = proxy.GetInitialResultSetFinish(result);
this.searchSystem.pushResults(this, results);
} catch(e) {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
log('Received error from search provider %s: %s'.format(this.title, String(e)));
}
}, },
getInitialResultSet: function(terms) { getInitialResultSet: function(terms) {
@ -206,8 +193,8 @@ const RemoteSearchProvider = new Lang.Class({
this._cancellable.reset(); this._cancellable.reset();
try { try {
this._proxy.GetInitialResultSetRemote(terms, this._proxy.GetInitialResultSetRemote(terms,
Lang.bind(this, this._getResultsFinished), this._cancellable,
this._cancellable); Lang.bind(this, this._getResultsFinished));
} catch(e) { } catch(e) {
log('Error calling GetInitialResultSet for provider %s: %s'.format( this.title, e.toString())); log('Error calling GetInitialResultSet for provider %s: %s'.format( this.title, e.toString()));
this.searchSystem.pushResults(this, []); this.searchSystem.pushResults(this, []);
@ -219,30 +206,30 @@ const RemoteSearchProvider = new Lang.Class({
this._cancellable.reset(); this._cancellable.reset();
try { try {
this._proxy.GetSubsearchResultSetRemote(previousResults, newTerms, this._proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
Lang.bind(this, this._getResultsFinished), this._cancellable,
this._cancellable); Lang.bind(this, this._getResultsFinished))
} catch(e) { } catch(e) {
log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.title, e.toString())); log('Error calling GetSubsearchResultSet for provider %s: %s'.format(this.title, e.toString()));
this.searchSystem.pushResults(this, []); this.searchSystem.pushResults(this, []);
} }
}, },
_getResultMetasFinished: function(results, error, callback) { _getResultMetasFinished: function(proxy, result, callback) {
if (error) { try {
let [metas] = results.GetResultMetasFinish(result);
let resultMetas = [];
for (let i = 0; i < metas.length; i++) {
for (let prop in metas[i])
metas[i][prop] = metas[i][prop].deep_unpack();
resultMetas.push({ id: metas[i]['id'],
name: metas[i]['name'],
createIcon: Lang.bind(this,
this.createIcon, metas[i]) });
}
callback(resultMetas);
} catch(e) {
callback([]); callback([]);
return;
} }
let metas = results[0];
let resultMetas = [];
for (let i = 0; i < metas.length; i++) {
for (let prop in metas[i])
metas[i][prop] = metas[i][prop].deep_unpack();
resultMetas.push({ id: metas[i]['id'],
name: metas[i]['name'],
createIcon: Lang.bind(this,
this.createIcon, metas[i]) });
}
callback(resultMetas);
}, },
getResultMetas: function(ids, callback) { getResultMetas: function(ids, callback) {
@ -250,8 +237,8 @@ const RemoteSearchProvider = new Lang.Class({
this._cancellable.reset(); this._cancellable.reset();
try { try {
this._proxy.GetResultMetasRemote(ids, this._proxy.GetResultMetasRemote(ids,
Lang.bind(this, this._getResultMetasFinished, callback), this._cancellable,
this._cancellable); Lang.bind(this, this._getResultMetasFinished, callback));
} catch(e) { } catch(e) {
log('Error calling GetResultMetas for provider %s: %s'.format(this.title, e.toString())); log('Error calling GetResultMetas for provider %s: %s'.format(this.title, e.toString()));
callback([]); callback([]);
@ -259,7 +246,7 @@ const RemoteSearchProvider = new Lang.Class({
}, },
activateResult: function(id) { activateResult: function(id) {
this._proxy.ActivateResultRemote(id); this._proxy.ActivateResultRemote(id, null, null);
} }
}); });

View File

@ -49,38 +49,6 @@ const SUMMARY_ICON_SIZE = 48;
const STANDARD_FADE_TIME = 10; const STANDARD_FADE_TIME = 10;
const SHORT_FADE_TIME = 0.3; const SHORT_FADE_TIME = 0.3;
function sample(offx, offy) {
return 'texel += texture2D (sampler, tex_coord.st + pixel_step * ' +
'vec2 (' + offx + ',' + offy + '));\n'
}
const GLSL_BLUR_EFFECT_DECLARATIONS = ' \
uniform vec2 pixel_step;\n \
uniform float desaturation;\n \
vec4 apply_blur(in sampler2D sampler, in vec2 tex_coord) {\n \
vec4 texel;\n \
texel = texture2D (sampler, tex_coord.st);\n'
+ sample(-1.0, -1.0)
+ sample( 0.0, -1.0)
+ sample(+1.0, -1.0)
+ sample(-1.0, 0.0)
+ sample(+1.0, 0.0)
+ sample(-1.0, +1.0)
+ sample( 0.0, +1.0)
+ sample(+1.0, +1.0) + ' \
texel /= 9.0;\n \
return texel;\n \
}\n \
vec3 desaturate (const vec3 color)\n \
{\n \
const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n \
vec3 gray = vec3 (dot (gray_conv, color));\n \
return vec3 (mix (color.rgb, gray, desaturation));\n \
}';
const GLSL_BLUR_EFFECT_CODE = ' \
cogl_texel = apply_blur(cogl_sampler, cogl_tex_coord.st);\n \
cogl_texel.rgb = desaturate(cogl_texel.rgb);\n';
const Clock = new Lang.Class({ const Clock = new Lang.Class({
Name: 'ScreenShieldClock', Name: 'ScreenShieldClock',
@ -367,10 +335,6 @@ const Arrow = new Lang.Class({
} }
}); });
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
/** /**
* To test screen shield, make sure to kill gnome-screensaver. * To test screen shield, make sure to kill gnome-screensaver.
* *
@ -398,25 +362,13 @@ const ScreenShield = new Lang.Class({
Lang.bind(this, this._onLockScreenKeyRelease)); Lang.bind(this, this._onLockScreenKeyRelease));
this._lockScreenGroup.connect('scroll-event', this._lockScreenGroup.connect('scroll-event',
Lang.bind(this, this._onLockScreenScroll)); Lang.bind(this, this._onLockScreenScroll));
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(), this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
name: 'lockScreenContents' }); name: 'lockScreenContents' });
this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true })); this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
let backgroundActor = Meta.BackgroundActor.new_for_screen(global.screen);
backgroundActor.add_glsl_snippet(Meta.SnippetHook.TEXTURE_LOOKUP,
GLSL_BLUR_EFFECT_DECLARATIONS,
GLSL_BLUR_EFFECT_CODE,
true);
backgroundActor.set_uniform_float('desaturation',
1, 1, [0.6]);
backgroundActor.connect('notify::size', function(actor) {
actor.set_uniform_float('pixel_step', 2, 1, [1/actor.width, 1/actor.height]);
});
this._background = new St.Bin({ style_class: 'screen-shield-background', this._background = new St.Bin({ style_class: 'screen-shield-background',
child: backgroundActor }); child: Meta.BackgroundActor.new_for_screen(global.screen) });
this._lockScreenGroup.add_actor(this._background); this._lockScreenGroup.add_actor(this._background);
this._lockScreenGroup.add_actor(this._lockScreenContents); this._lockScreenGroup.add_actor(this._lockScreenContents);
@ -435,11 +387,14 @@ const ScreenShield = new Lang.Class({
} }
this._lockScreenContents.add_actor(this._arrowContainer); this._lockScreenContents.add_actor(this._arrowContainer);
this._dragAction = new Clutter.GestureAction(); let dragArea = new Clutter.Rect({ origin: new Clutter.Point({ x: 0, y: -global.screen_height, }),
this._dragAction.connect('gesture-begin', Lang.bind(this, this._onDragBegin)); size: new Clutter.Size({ width: global.screen_width,
this._dragAction.connect('gesture-progress', Lang.bind(this, this._onDragMotion)); height: global.screen_height }) });
this._dragAction.connect('gesture-end', Lang.bind(this, this._onDragEnd)); let action = new Clutter.DragAction({ drag_axis: Clutter.DragAxis.Y_AXIS,
this._lockScreenGroup.add_action(this._dragAction); drag_area: dragArea });
action.connect('drag-begin', Lang.bind(this, this._onDragBegin));
action.connect('drag-end', Lang.bind(this, this._onDragEnd));
this._lockScreenGroup.add_action(action);
this._lockDialogGroup = new St.Widget({ x_expand: true, this._lockDialogGroup = new St.Widget({ x_expand: true,
y_expand: true, y_expand: true,
@ -463,10 +418,11 @@ const ScreenShield = new Lang.Class({
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this); this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginSession = this._loginManager.getCurrentSessionProxy(); this._loginSession = manager.getCurrentSessionProxy();
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); })); this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); })); this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
}));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
@ -481,8 +437,6 @@ const ScreenShield = new Lang.Class({
{ inhibitEvents: true, { inhibitEvents: true,
fadeInTime: STANDARD_FADE_TIME, fadeInTime: STANDARD_FADE_TIME,
fadeFactor: 1 }); fadeFactor: 1 });
this.idleMonitor = new GnomeDesktop.IdleMonitor();
}, },
_onLockScreenKeyRelease: function(actor, event) { _onLockScreenKeyRelease: function(actor, event) {
@ -503,7 +457,7 @@ const ScreenShield = new Lang.Class({
symbol == Clutter.KEY_Return || symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter) { symbol == Clutter.KEY_KP_Enter) {
this._ensureUnlockDialog(true); this._ensureUnlockDialog(true);
this._hideLockScreen(true, 0); this._hideLockScreen(true);
return true; return true;
} }
@ -526,7 +480,7 @@ const ScreenShield = new Lang.Class({
// 7 standard scrolls to lift up // 7 standard scrolls to lift up
if (this._lockScreenScrollCounter > 35) { if (this._lockScreenScrollCounter > 35) {
this._ensureUnlockDialog(false); this._ensureUnlockDialog(false);
this._hideLockScreen(true, 0); this._hideLockScreen(true);
} }
return true; return true;
@ -558,27 +512,12 @@ const ScreenShield = new Lang.Class({
Tweener.removeTweens(this._lockScreenGroup); Tweener.removeTweens(this._lockScreenGroup);
this._lockScreenState = MessageTray.State.HIDING; this._lockScreenState = MessageTray.State.HIDING;
this._ensureUnlockDialog(false); this._ensureUnlockDialog(false);
return true;
},
_onDragMotion: function() {
let [origX, origY] = this._dragAction.get_press_coords(0);
let [currentX, currentY] = this._dragAction.get_motion_coords(0);
let newY = currentY - origY;
newY = clamp(newY, -global.stage.height, 0);
this._lockScreenGroup.y = newY;
return true;
}, },
_onDragEnd: function(action, actor, eventX, eventY, modifiers) { _onDragEnd: function(action, actor, eventX, eventY, modifiers) {
if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) { if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
// Complete motion automatically // Complete motion automatically
let [velocity, velocityX, velocityY] = this._dragAction.get_velocity(0); this._hideLockScreen(true);
this._hideLockScreen(true, -velocityY);
} else { } else {
// restore the lock screen to its original place // restore the lock screen to its original place
// try to use the same speed as the normal animation // try to use the same speed as the normal animation
@ -607,43 +546,35 @@ const ScreenShield = new Lang.Class({
}, },
_onStatusChanged: function(status) { _onStatusChanged: function(status) {
if (status != GnomeSession.PresenceStatus.IDLE) if (status == GnomeSession.PresenceStatus.IDLE) {
return; if (this._dialog) {
this._dialog.cancel();
if (this._dialog) { if (!this._isGreeter) {
this._dialog.cancel(); this._dialog = null;
if (!this._isGreeter) {
this._dialog = null;
}
}
if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
this._isModal = true;
}
if (!this._isActive) {
this._lightbox.show();
if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time();
this._becameActiveId = this.idleMonitor.connect('became-active', Lang.bind(this, function() {
this.idleMonitor.disconnect(this._becameActiveId);
let lightboxWasShown = this._lightbox.shown;
this._lightbox.hide();
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
if (shouldLock || this._isLocked) {
this.lock(false);
} else if (this._isActive) {
this.unlock();
} }
})); }
this._isActive = true; if (!this._isModal) {
this.emit('lock-status-changed'); Main.pushModal(this.actor);
this._isModal = true;
}
if (!this._isActive) {
this._lightbox.show();
if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time();
}
} else {
let lightboxWasShown = this._lightbox.shown;
this._lightbox.hide();
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
if (shouldLock || this._isActive) {
this.lock(false);
} else if (this._isModal) {
this.unlock();
}
} }
}, },
@ -662,7 +593,7 @@ const ScreenShield = new Lang.Class({
this.actor.show(); this.actor.show();
this._isGreeter = Main.sessionMode.isGreeter; this._isGreeter = Main.sessionMode.isGreeter;
this._ensureUnlockDialog(true); this._ensureUnlockDialog(true);
this._hideLockScreen(false, 0); this._hideLockScreen(false);
}, },
_bumpLockScreen: function() { _bumpLockScreen: function() {
@ -680,21 +611,14 @@ const ScreenShield = new Lang.Class({
}); });
}, },
_hideLockScreen: function(animate, velocity) { _hideLockScreen: function(animate) {
this._lockScreenState = MessageTray.State.HIDING; this._lockScreenState = MessageTray.State.HIDING;
if (animate) { if (animate) {
// Tween the lock screen out of screen // Tween the lock screen out of screen
// if velocity is not specified (i.e. we come here from pressing ESC), // try to use the same speed regardless of original position
// use the same speed regardless of original position
// if velocity is specified, it's in pixels per milliseconds
let h = global.stage.height; let h = global.stage.height;
let delta = (h + this._lockScreenGroup.y); let time = CURTAIN_SLIDE_TIME * (h + this._lockScreenGroup.y) / h;
let min_velocity = global.stage.height / (CURTAIN_SLIDE_TIME * 1000);
velocity = Math.max(min_velocity, velocity);
let time = (delta / velocity) / 1000;
Tweener.removeTweens(this._lockScreenGroup); Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup, Tweener.addTween(this._lockScreenGroup,
{ y: -h, { y: -h,
@ -711,8 +635,6 @@ const ScreenShield = new Lang.Class({
this._lockScreenGroup.hide(); this._lockScreenGroup.hide();
} }
global.stage.show_cursor();
if (Main.sessionMode.currentMode == 'lock-screen') if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen'); Main.sessionMode.popMode('lock-screen');
}, },
@ -720,15 +642,13 @@ const ScreenShield = new Lang.Class({
_ensureUnlockDialog: function(onPrimary) { _ensureUnlockDialog: function(onPrimary) {
if (!this._dialog) { if (!this._dialog) {
let constructor = Main.sessionMode.unlockDialog; let constructor = Main.sessionMode.unlockDialog;
if (!constructor) { this._dialog = new constructor(this._lockDialogGroup);
if (!this._dialog) {
// This session mode has no locking capabilities // This session mode has no locking capabilities
this.unlock(); this.unlock();
return; return;
} }
this._dialog = new constructor(this._lockDialogGroup);
let time = global.get_current_time(); let time = global.get_current_time();
this._dialog.connect('loaded', Lang.bind(this, function() { this._dialog.connect('loaded', Lang.bind(this, function() {
if (!this._dialog.open(time, onPrimary)) { if (!this._dialog.open(time, onPrimary)) {
@ -803,16 +723,6 @@ const ScreenShield = new Lang.Class({
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows)); this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
this._animateArrows(); this._animateArrows();
let motionId = global.stage.connect('captured-event', function(stage, event) {
if (event.type() == Clutter.EventType.MOTION) {
global.stage.show_cursor();
global.stage.disconnect(motionId);
}
return false;
});
global.stage.hide_cursor();
this._lockScreenState = MessageTray.State.SHOWN; this._lockScreenState = MessageTray.State.SHOWN;
this._lockScreenGroup.fixed_position_set = false; this._lockScreenGroup.fixed_position_set = false;
this._lockScreenScrollCounter = 0; this._lockScreenScrollCounter = 0;
@ -921,13 +831,12 @@ const ScreenShield = new Lang.Class({
this._activationTime = 0; this._activationTime = 0;
this._isActive = false; this._isActive = false;
this._isLocked = false;
this.emit('lock-status-changed'); this.emit('lock-status-changed');
}, },
lock: function(animate) { lock: function(animate) {
if (!this._isModal) { if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN }); Main.pushModal(this.actor);
this._isModal = true; this._isModal = true;
} }
@ -946,7 +855,6 @@ const ScreenShield = new Lang.Class({
this._resetLockScreen(animate, animate); this._resetLockScreen(animate, animate);
this._isActive = true; this._isActive = true;
this._isLocked = true;
this.emit('lock-status-changed'); this.emit('lock-status-changed');
}, },
}); });
@ -968,6 +876,7 @@ const ScreenShieldFallback = new Lang.Class({
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START | g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES), Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
}); });
// This is synchronous but it is the fallback case.
this._proxy.init(null); this._proxy.init(null);
this._proxy.connect('g-signal', Lang.bind(this, this._onSignal)); this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));

View File

@ -80,15 +80,23 @@ const PerfHelperIface = <interface name="org.gnome.Shell.PerfHelper">
<method name="DestroyWindows" /> <method name="DestroyWindows" />
</interface>; </interface>;
var PerfHelperProxy = Gio.DBusProxy.makeProxyWrapper(PerfHelperIface); const PerfHelper = new Gio.DBusProxyClass({
function PerfHelper() { Name: 'PerfHelperProxy',
return new PerfHelperProxy(Gio.DBus.session, 'org.gnome.Shell.PerfHelper', '/org/gnome/Shell/PerfHelper'); Interface: PerfHelperIface,
}
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: 'org.gnome.Shell.PerfHelper',
g_object_path: '/org/gnome/Shell/PerfHelper' });
}
});
let _perfHelper = null; let _perfHelper = null;
function _getPerfHelper() { function _getPerfHelper() {
if (_perfHelper == null) if (_perfHelper == null) {
_perfHelper = new PerfHelper(); _perfHelper = new PerfHelper();
_perfHelper.init(null);
}
return _perfHelper; return _perfHelper;
} }
@ -111,7 +119,8 @@ function createTestWindow(width, height, alpha, maximized) {
let perfHelper = _getPerfHelper(); let perfHelper = _getPerfHelper();
perfHelper.CreateWindowRemote(width, height, alpha, maximized, perfHelper.CreateWindowRemote(width, height, alpha, maximized,
function(result, excp) { null,
function(proxy, result) {
if (cb) if (cb)
cb(); cb();
}); });
@ -131,7 +140,7 @@ function waitTestWindows() {
let cb; let cb;
let perfHelper = _getPerfHelper(); let perfHelper = _getPerfHelper();
perfHelper.WaitWindowsRemote(function(result, excp) { perfHelper.WaitWindowsRemote(null, function(proxy, result) {
if (cb) if (cb)
cb(); cb();
}); });
@ -154,7 +163,7 @@ function destroyTestWindows() {
let cb; let cb;
let perfHelper = _getPerfHelper(); let perfHelper = _getPerfHelper();
perfHelper.DestroyWindowsRemote(function(result, excp) { perfHelper.DestroyWindowsRemote(null, function(proxy, result) {
if (cb) if (cb)
cb(); cb();
}); });

View File

@ -2,6 +2,7 @@
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib; const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang; const Lang = imports.lang;
const Signals = imports.signals; const Signals = imports.signals;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
@ -10,8 +11,6 @@ const Util = imports.misc.util;
const FileUtils = imports.misc.fileUtils; const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main; const Main = imports.ui.main;
const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers';
// Not currently referenced by the search API, but // Not currently referenced by the search API, but
// this enumeration can be useful for provider // this enumeration can be useful for provider
// implementations. // implementations.
@ -76,11 +75,11 @@ const SearchResultDisplay = new Lang.Class({
const SearchProvider = new Lang.Class({ const SearchProvider = new Lang.Class({
Name: 'SearchProvider', Name: 'SearchProvider',
_init: function(title, appInfo, isRemoteProvider) { _init: function(title) {
this.parent();
this.title = title; this.title = title;
this.appInfo = appInfo;
this.searchSystem = null; this.searchSystem = null;
this.isRemoteProvider = !!isRemoteProvider;
}, },
/** /**
@ -176,16 +175,12 @@ const SearchSystem = new Lang.Class({
_init: function() { _init: function() {
this._providers = []; this._providers = [];
this._remoteProviders = [];
this.reset(); this.reset();
}, },
registerProvider: function (provider) { registerProvider: function (provider) {
provider.searchSystem = this; provider.searchSystem = this;
this._providers.push(provider); this._providers.push(provider);
if (provider.isRemoteProvider)
this._remoteProviders.push(provider);
}, },
unregisterProvider: function (provider) { unregisterProvider: function (provider) {
@ -194,20 +189,12 @@ const SearchSystem = new Lang.Class({
return; return;
provider.searchSystem = null; provider.searchSystem = null;
this._providers.splice(index, 1); this._providers.splice(index, 1);
let remoteIndex = this._remoteProviders.indexOf(provider);
if (remoteIndex != -1)
this._remoteProviders.splice(index, 1);
}, },
getProviders: function() { getProviders: function() {
return this._providers; return this._providers;
}, },
getRemoteProviders: function() {
return this._remoteProviders;
},
getTerms: function() { getTerms: function() {
return this._previousTerms; return this._previousTerms;
}, },

View File

@ -14,6 +14,7 @@ const _modes = {
showCalendarEvents: false, showCalendarEvents: false,
allowSettings: false, allowSettings: false,
allowExtensions: false, allowExtensions: false,
allowKeybindingsWhenModal: false,
hasRunDialog: false, hasRunDialog: false,
hasWorkspaces: false, hasWorkspaces: false,
hasWindows: false, hasWindows: false,
@ -31,6 +32,7 @@ const _modes = {
}, },
'gdm': { 'gdm': {
allowKeybindingsWhenModal: true,
hasNotifications: true, hasNotifications: true,
isGreeter: true, isGreeter: true,
isPrimary: true, isPrimary: true,

View File

@ -67,14 +67,16 @@ const ScreenSaverIface = <interface name="org.gnome.ScreenSaver">
</signal> </signal>
</interface>; </interface>;
const GnomeShell = new Lang.Class({ const GnomeShell = new Gio.DBusImplementerClass({
Name: 'GnomeShellDBus', Name: 'GnomeShellDBus',
Interface: GnomeShellIface,
_init: function() { _init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this); this.parent();
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
this._extensionsSerivce = new GnomeShellExtensions(); this.export(Gio.DBus.session, '/org/gnome/Shell');
this._extensionsService = new GnomeShellExtensions();
}, },
/** /**
@ -236,12 +238,14 @@ const GnomeShellExtensionsIface = <interface name="org.gnome.Shell.Extensions">
<property name="ShellVersion" type="s" access="read" /> <property name="ShellVersion" type="s" access="read" />
</interface>; </interface>;
const GnomeShellExtensions = new Lang.Class({ const GnomeShellExtensions = new Gio.DBusImplementerClass({
Name: 'GnomeShellExtensionsDBus', Name: 'GnomeShellExtensionsDBus',
Interface: GnomeShellExtensionsIface,
_init: function() { _init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellExtensionsIface, this); this.parent();
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
this.export(Gio.DBus.session, '/org/gnome/Shell');
ExtensionSystem.connect('extension-state-changed', ExtensionSystem.connect('extension-state-changed',
Lang.bind(this, this._extensionStateChanged)); Lang.bind(this, this._extensionStateChanged));
}, },
@ -335,25 +339,23 @@ const GnomeShellExtensions = new Lang.Class({
ShellVersion: Config.PACKAGE_VERSION, ShellVersion: Config.PACKAGE_VERSION,
_extensionStateChanged: function(_, newState) { _extensionStateChanged: function(_, newState) {
this._dbusImpl.emit_signal('ExtensionStatusChanged', this.emit_signal('ExtensionStatusChanged', newState.uuid, newState.state, newState.error);
GLib.Variant.new('(sis)', [newState.uuid, newState.state, newState.error]));
} }
}); });
const ScreenSaverDBus = new Lang.Class({ const ScreenSaverDBus = new Gio.DBusImplementerClass({
Name: 'ScreenSaverDBus', Name: 'ScreenSaverDBus',
Interface: ScreenSaverIface,
_init: function(screenShield) { _init: function(screenShield) {
this.parent(); this.parent();
this._screenShield = screenShield; this._screenShield = screenShield;
screenShield.connect('lock-status-changed', Lang.bind(this, function(shield) { screenShield.connect('lock-status-changed', Lang.bind(this, function(shield) {
this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [shield.locked])); this.emit_signal('ActiveChanged', shield.locked);
})); }));
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenSaverIface, this); this.export(Gio.DBus.session, '/org/gnome/ScreenSaver');
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/ScreenSaver');
Gio.DBus.session.own_name('org.gnome.ScreenSaver', Gio.BusNameOwnerFlags.REPLACE, null, null); Gio.DBus.session.own_name('org.gnome.ScreenSaver', Gio.BusNameOwnerFlags.REPLACE, null, null);
}, },

View File

@ -554,14 +554,16 @@ const ShellMountOperationType = {
SHOW_PROCESSES: 3 SHOW_PROCESSES: 3
}; };
const GnomeShellMountOpHandler = new Lang.Class({ const GnomeShellMountOpHandler = new Gio.DBusImplementerClass({
Name: 'GnomeShellMountOpHandler', Name: 'GnomeShellMountOpHandler',
Interface: GnomeShellMountOpIface,
_init: function() { _init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellMountOpIface, this); this.parent();
this._dbusImpl.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
Gio.bus_own_name_on_connection(Gio.DBus.session, 'org.gtk.MountOperationHandler', this.export(Gio.DBus.session, '/org/gtk/MountOperationHandler');
Gio.BusNameOwnerFlags.REPLACE, null, null); Gio.DBus.session.own_name('org.gtk.MountOperationHandler',
Gio.BusNameOwnerFlags.REPLACE, null, null);
this._dialog = null; this._dialog = null;
this._volumeMonitor = Gio.VolumeMonitor.get(); this._volumeMonitor = Gio.VolumeMonitor.get();

View File

@ -27,7 +27,6 @@ const KEY_VISUAL_BELL = 'visual-bell';
const DESKTOP_INTERFACE_SCHEMA = 'org.gnome.desktop.interface'; const DESKTOP_INTERFACE_SCHEMA = 'org.gnome.desktop.interface';
const KEY_GTK_THEME = 'gtk-theme'; const KEY_GTK_THEME = 'gtk-theme';
const KEY_ICON_THEME = 'icon-theme'; const KEY_ICON_THEME = 'icon-theme';
const KEY_WM_THEME = 'theme';
const KEY_TEXT_SCALING_FACTOR = 'text-scaling-factor'; const KEY_TEXT_SCALING_FACTOR = 'text-scaling-factor';
const HIGH_CONTRAST_THEME = 'HighContrast'; const HIGH_CONTRAST_THEME = 'HighContrast';
@ -102,35 +101,28 @@ const ATIndicator = new Lang.Class({
}, },
_buildHCItem: function() { _buildHCItem: function() {
let interfaceSettings = new Gio.Settings({ schema: DESKTOP_INTERFACE_SCHEMA }); let settings = new Gio.Settings({ schema: DESKTOP_INTERFACE_SCHEMA });
let wmSettings = new Gio.Settings({ schema: WM_SCHEMA }); let gtkTheme = settings.get_string(KEY_GTK_THEME);
let gtkTheme = interfaceSettings.get_string(KEY_GTK_THEME); let iconTheme = settings.get_string(KEY_ICON_THEME);
let iconTheme = interfaceSettings.get_string(KEY_ICON_THEME);
let wmTheme = wmSettings.get_string(KEY_WM_THEME);
let hasHC = (gtkTheme == HIGH_CONTRAST_THEME); let hasHC = (gtkTheme == HIGH_CONTRAST_THEME);
let highContrast = this._buildItemExtended( let highContrast = this._buildItemExtended(
_("High Contrast"), _("High Contrast"),
hasHC, hasHC,
interfaceSettings.is_writable(KEY_GTK_THEME) && settings.is_writable(KEY_GTK_THEME) && settings.is_writable(KEY_ICON_THEME),
interfaceSettings.is_writable(KEY_ICON_THEME) &&
wmSettings.is_writable(KEY_WM_THEME),
function (enabled) { function (enabled) {
if (enabled) { if (enabled) {
interfaceSettings.set_string(KEY_GTK_THEME, HIGH_CONTRAST_THEME); settings.set_string(KEY_GTK_THEME, HIGH_CONTRAST_THEME);
interfaceSettings.set_string(KEY_ICON_THEME, HIGH_CONTRAST_THEME); settings.set_string(KEY_ICON_THEME, HIGH_CONTRAST_THEME);
wmSettings.set_string(KEY_WM_THEME, HIGH_CONTRAST_THEME);
} else if(!hasHC) { } else if(!hasHC) {
interfaceSettings.set_string(KEY_GTK_THEME, gtkTheme); settings.set_string(KEY_GTK_THEME, gtkTheme);
interfaceSettings.set_string(KEY_ICON_THEME, iconTheme); settings.set_string(KEY_ICON_THEME, iconTheme);
wmSettings.set_string(KEY_WM_THEME, wmTheme);
} else { } else {
interfaceSettings.reset(KEY_GTK_THEME); settings.reset(KEY_GTK_THEME);
interfaceSettings.reset(KEY_ICON_THEME); settings.reset(KEY_ICON_THEME);
wmSettings.reset(KEY_WM_THEME);
} }
}); });
interfaceSettings.connect('changed::' + KEY_GTK_THEME, function() { settings.connect('changed::' + KEY_GTK_THEME, function() {
let value = interfaceSettings.get_string(KEY_GTK_THEME); let value = settings.get_string(KEY_GTK_THEME);
if (value == HIGH_CONTRAST_THEME) { if (value == HIGH_CONTRAST_THEME) {
highContrast.setToggleState(true); highContrast.setToggleState(true);
} else { } else {
@ -138,16 +130,11 @@ const ATIndicator = new Lang.Class({
gtkTheme = value; gtkTheme = value;
} }
}); });
interfaceSettings.connect('changed::' + KEY_ICON_THEME, function() { settings.connect('changed::' + KEY_ICON_THEME, function() {
let value = interfaceSettings.get_string(KEY_ICON_THEME); let value = settings.get_string(KEY_ICON_THEME);
if (value != HIGH_CONTRAST_THEME) if (value != HIGH_CONTRAST_THEME)
iconTheme = value; iconTheme = value;
}); });
wmSettings.connect('changed::' + KEY_WM_THEME, function() {
let value = wmSettings.get_string(KEY_WM_THEME);
if (value != HIGH_CONTRAST_THEME)
wmTheme = value;
});
return highContrast; return highContrast;
}, },

View File

@ -239,6 +239,22 @@ const Indicator = new Lang.Class({
this._applet.send_to_address(device.bdaddr, device.alias); this._applet.send_to_address(device.bdaddr, device.alias);
})); }));
} }
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_FILE_TRANSFER) {
item.menu.addAction(_("Browse Files..."), Lang.bind(this, function(event) {
this._applet.browse_address(device.bdaddr, event.get_time(),
Lang.bind(this, function(applet, result) {
try {
applet.browse_address_finish(result);
} catch (e) {
this._ensureSource();
this._source.notify(new MessageTray.Notification(this._source,
_("Bluetooth"),
_("Error browsing device"),
{ body: _("The requested device cannot be browsed, error is '%s'").format(e) }));
}
}));
}));
}
switch (device.type) { switch (device.type) {
case GnomeBluetoothApplet.Type.KEYBOARD: case GnomeBluetoothApplet.Type.KEYBOARD:
@ -353,7 +369,6 @@ const ConfirmNotification = new Lang.Class({
_init: function(source, applet, device_path, name, long_name, pin) { _init: function(source, applet, device_path, name, long_name, pin) {
this.parent(source, this.parent(source,
_("Bluetooth"), _("Bluetooth"),
/* Translators: argument is the device short name */
_("Pairing confirmation for %s").format(name), _("Pairing confirmation for %s").format(name),
{ customContent: true }); { customContent: true });
this.setResident(true); this.setResident(true);
@ -363,7 +378,6 @@ const ConfirmNotification = new Lang.Class({
this.addBody(_("Device %s wants to pair with this computer").format(long_name)); this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin)); this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin));
/* Translators: this is the verb, not the noun */
this.addButton('matches', _("Matches")); this.addButton('matches', _("Matches"));
this.addButton('does-not-match', _("Does not match")); this.addButton('does-not-match', _("Does not match"));

View File

@ -1629,7 +1629,44 @@ const NMApplet = new Lang.Class({
this.secondaryIcon = this.addIcon(new Gio.ThemedIcon({ name: 'network-vpn-symbolic' })); this.secondaryIcon = this.addIcon(new Gio.ThemedIcon({ name: 'network-vpn-symbolic' }));
this.secondaryIcon.hide(); this.secondaryIcon.hide();
this._client = NMClient.Client.new(); // Device types
this._dtypes = { };
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
// TODO: WiMax support
// Connection types
this._ctypes = { };
this._ctypes[NetworkManager.SETTING_WIRELESS_SETTING_NAME] = NMConnectionCategory.WIRELESS;
this._ctypes[NetworkManager.SETTING_WIRED_SETTING_NAME] = NMConnectionCategory.WIRED;
this._ctypes[NetworkManager.SETTING_PPPOE_SETTING_NAME] = NMConnectionCategory.WIRED;
this._ctypes[NetworkManager.SETTING_PPP_SETTING_NAME] = NMConnectionCategory.WIRED;
this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
NMClient.Client.new_async(null, Lang.bind(this, this._clientGot));
NMClient.RemoteSettings.new_async(null, null, Lang.bind(this, this._remoteSettingsGot));
},
_clientGot: function(obj, result) {
this._client = NMClient.Client.new_finish(result);
this._tryLateInit();
},
_remoteSettingsGot: function(obj, result) {
this._settings = NMClient.RemoteSettings.new_finish(result);
this._tryLateInit();
},
_tryLateInit: function() {
if (!this._client || !this._settings)
return;
this._statusSection = new PopupMenu.PopupMenuSection(); this._statusSection = new PopupMenu.PopupMenuSection();
this._statusItem = new PopupMenu.PopupMenuItem('', { reactive: false }); this._statusItem = new PopupMenu.PopupMenuItem('', { reactive: false });
@ -1690,44 +1727,17 @@ const NMApplet = new Lang.Class({
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop'); this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
// Device types this._readConnections();
this._dtypes = { }; this._readDevices();
this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired; this._syncNMState();
this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
// TODO: WiMax support
// Connection types this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
this._ctypes = { }; this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
this._ctypes[NetworkManager.SETTING_WIRELESS_SETTING_NAME] = NMConnectionCategory.WIRELESS; this._client.connect('notify::state', Lang.bind(this, this._syncNMState));
this._ctypes[NetworkManager.SETTING_WIRED_SETTING_NAME] = NMConnectionCategory.WIRED; this._client.connect('notify::active-connections', Lang.bind(this, this._updateIcon));
this._ctypes[NetworkManager.SETTING_PPPOE_SETTING_NAME] = NMConnectionCategory.WIRED; this._client.connect('device-added', Lang.bind(this, this._deviceAdded));
this._ctypes[NetworkManager.SETTING_PPP_SETTING_NAME] = NMConnectionCategory.WIRED; this._client.connect('device-removed', Lang.bind(this, this._deviceRemoved));
this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN; this._settings.connect('new-connection', Lang.bind(this, this._newConnection));
this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
this._settings = NMClient.RemoteSettings.new(null);
this._connectionsReadId = this._settings.connect('connections-read', Lang.bind(this, function() {
this._readConnections();
this._readDevices();
this._syncNMState();
// Connect to signals late so that early signals don't find in inconsistent state
// and connect only once (this signal handler can be called again if NetworkManager goes up and down)
if (!this._inited) {
this._inited = true;
this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
this._client.connect('notify::state', Lang.bind(this, this._syncNMState));
this._client.connect('notify::active-connections', Lang.bind(this, this._updateIcon));
this._client.connect('device-added', Lang.bind(this, this._deviceAdded));
this._client.connect('device-removed', Lang.bind(this, this._deviceRemoved));
this._settings.connect('new-connection', Lang.bind(this, this._newConnection));
}
}));
}, },
_ensureSource: function() { _ensureSource: function() {

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang; const Lang = imports.lang;
const St = imports.gi.St; const St = imports.gi.St;
@ -45,7 +46,16 @@ const PowerManagerInterface = <interface name="org.gnome.SettingsDaemon.Power">
<property name="Icon" type="s" access="read" /> <property name="Icon" type="s" access="read" />
</interface>; </interface>;
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(PowerManagerInterface); const PowerManagerProxy = new Gio.DBusProxyClass({
Name: 'PowerManagerProxy',
Interface: PowerManagerInterface,
_init: function() {
this.parent({ g_bus_type: Gio.BusType.SESSION,
g_name: BUS_NAME,
g_object_path: OBJECT_PATH });
}
});
const Indicator = new Lang.Class({ const Indicator = new Lang.Class({
Name: 'PowerIndicator', Name: 'PowerIndicator',
@ -54,7 +64,7 @@ const Indicator = new Lang.Class({
_init: function() { _init: function() {
this.parent('battery-missing-symbolic', _("Battery")); this.parent('battery-missing-symbolic', _("Battery"));
this._proxy = new PowerManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH); this._proxy = new PowerManagerProxy();
this._deviceItems = [ ]; this._deviceItems = [ ];
this._hasPrimary = false; this._hasPrimary = false;
@ -73,18 +83,26 @@ const Indicator = new Lang.Class({
this._proxy.connect('g-properties-changed', this._proxy.connect('g-properties-changed',
Lang.bind(this, this._devicesChanged)); Lang.bind(this, this._devicesChanged));
this._devicesChanged(); this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
proxy.init_finish(result);
this._devicesChanged();
}));
}, },
_readPrimaryDevice: function() { _readPrimaryDevice: function() {
this._proxy.GetPrimaryDeviceRemote(Lang.bind(this, function(result, error) { this._proxy.GetPrimaryDeviceRemote(null, Lang.bind(this, function(proxy, result) {
if (error) { let device_id, device_type, icon, percentage, state, seconds;
try {
[[device_id, device_type, icon, percentage, state, seconds]] =
proxy.GetPrimaryDeviceFinish(result);
} catch(e) {
this._hasPrimary = false; this._hasPrimary = false;
this._primaryDeviceId = null; this._primaryDeviceId = null;
this._batteryItem.actor.hide(); this._batteryItem.actor.hide();
return; return;
} }
let [[device_id, device_type, icon, percentage, state, seconds]] = result;
if (device_type == UPDeviceType.BATTERY) { if (device_type == UPDeviceType.BATTERY) {
this._hasPrimary = true; this._hasPrimary = true;
let time = Math.round(seconds / 60); let time = Math.round(seconds / 60);
@ -96,7 +114,7 @@ const Indicator = new Lang.Class({
let minutes = time % 60; let minutes = time % 60;
let hours = Math.floor(time / 60); let hours = Math.floor(time / 60);
let timestring; let timestring;
if (time >= 60) { if (time > 60) {
if (minutes == 0) { if (minutes == 0) {
timestring = ngettext("%d hour remaining", "%d hours remaining", hours).format(hours); timestring = ngettext("%d hour remaining", "%d hours remaining", hours).format(hours);
} else { } else {
@ -121,16 +139,18 @@ const Indicator = new Lang.Class({
}, },
_readOtherDevices: function() { _readOtherDevices: function() {
this._proxy.GetDevicesRemote(Lang.bind(this, function(result, error) { this._proxy.GetDevicesRemote(null, Lang.bind(this, function(proxy, result) {
this._deviceItems.forEach(function(i) { i.destroy(); }); this._deviceItems.forEach(function(i) { i.destroy(); });
this._deviceItems = []; this._deviceItems = [];
if (error) { let devices;
try {
[devices] = proxy.GetDevicesFinish(result);
} catch(e) {
return; return;
} }
let position = 0; let position = 0;
let [devices] = result;
for (let i = 0; i < devices.length; i++) { for (let i = 0; i < devices.length; i++) {
let [device_id, device_type] = devices[i]; let [device_id, device_type] = devices[i];
if (device_type == UPDeviceType.AC_POWER || device_id == this._primaryDeviceId) if (device_type == UPDeviceType.AC_POWER || device_id == this._primaryDeviceId)

View File

@ -113,7 +113,6 @@ const UnlockDialog = new Lang.Class({
_init: function(parentActor) { _init: function(parentActor) {
this.parent({ shellReactive: true, this.parent({ shellReactive: true,
styleClass: 'login-dialog', styleClass: 'login-dialog',
keybindingMode: Main.KeybindingMode.UNLOCK_SCREEN,
parentActor: parentActor parentActor: parentActor
}); });
@ -152,9 +151,6 @@ const UnlockDialog = new Lang.Class({
ShellEntry.addContextMenu(this._promptEntry, { isPassword: true }); ShellEntry.addContextMenu(this._promptEntry, { isPassword: true });
this.setInitialKeyFocus(this._promptEntry); this.setInitialKeyFocus(this._promptEntry);
this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock)); this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
this._promptEntry.clutter_text.connect('text-changed', Lang.bind(this, function() {
this._updateOkButtonSensitivity(this._promptEntry.text.length > 0);
}));
this._promptLayout.add(this._promptEntry, this._promptLayout.add(this._promptEntry,
{ expand: true, { expand: true,
@ -200,8 +196,6 @@ const UnlockDialog = new Lang.Class({
return false; return false;
})); }));
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
this._idleMonitor = new GnomeDesktop.IdleMonitor(); this._idleMonitor = new GnomeDesktop.IdleMonitor();
this._idleWatchId = this._idleMonitor.add_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape)); this._idleWatchId = this._idleMonitor.add_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
}, },
@ -209,10 +203,6 @@ const UnlockDialog = new Lang.Class({
_updateSensitivity: function(sensitive) { _updateSensitivity: function(sensitive) {
this._promptEntry.reactive = sensitive; this._promptEntry.reactive = sensitive;
this._promptEntry.clutter_text.editable = sensitive; this._promptEntry.clutter_text.editable = sensitive;
this._updateOkButtonSensitivity(sensitive && this._promptEntry.text.length > 0);
},
_updateOkButtonSensitivity: function(sensitive) {
this._okButton.button.reactive = sensitive; this._okButton.button.reactive = sensitive;
this._okButton.button.can_focus = sensitive; this._okButton.button.can_focus = sensitive;
}, },

View File

@ -195,8 +195,12 @@ const IMStatusChooserItem = new Lang.Class({
Lang.bind(this, this._changeIMStatus)); Lang.bind(this, this._changeIMStatus));
this._presence = new GnomeSession.Presence(); this._presence = new GnomeSession.Presence();
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) { this._presence.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
this._sessionStatusChanged(status); obj.init_finish(result);
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
this._sessionStatusChanged(status);
}));
})); }));
this._sessionPresenceRestored = false; this._sessionPresenceRestored = false;
@ -480,14 +484,33 @@ const UserMenuButton = new Lang.Class({
this._userManager = AccountsService.UserManager.get_default(); this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name()); this._user = this._userManager.get_user(GLib.get_user_name());
this._presence = new GnomeSession.Presence(); this._presence = new GnomeSession.Presence();
this._session = new GnomeSession.SessionManager(); this._presence.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
proxy.init_finish(result);
this._updateSwitch(this._presence.status);
this._presence.connectSignal('StatusChanged', Lang.bind(this, function (proxy, senderName, [status]) {
this._updateSwitch(status);
}));
}));
let session = new GnomeSession.SessionManager();
session.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(proxy, result) {
// This should never fail.
proxy.init_finish(result);
this._session = proxy;
this._updateHaveShutdown();
}));
this._haveShutdown = true; this._haveShutdown = true;
this._haveSuspend = true; this._haveSuspend = true;
this._accountMgr = Tp.AccountManager.dup(); this._accountMgr = Tp.AccountManager.dup();
this._loginManager = LoginManager.getLoginManager(); LoginManager.getLoginManager(Lang.bind(this, function(manager) {
this._loginManager = manager;
}));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._iconBox = new St.Bin(); this._iconBox = new St.Bin();
@ -533,11 +556,6 @@ const UserMenuButton = new Lang.Class({
this._createSubMenu(); this._createSubMenu();
this._updateSwitch(this._presence.status);
this._presence.connectSignal('StatusChanged', Lang.bind(this, function (proxy, senderName, [status]) {
this._updateSwitch(status);
}));
this._userManager.connect('notify::is-loaded', this._userManager.connect('notify::is-loaded',
Lang.bind(this, this._updateMultiUser)); Lang.bind(this, this._updateMultiUser));
this._userManager.connect('notify::has-multiple-users', this._userManager.connect('notify::has-multiple-users',
@ -637,17 +655,29 @@ const UserMenuButton = new Lang.Class({
}, },
_updateHaveShutdown: function() { _updateHaveShutdown: function() {
this._session.CanShutdownRemote(Lang.bind(this, if (!this._session) {
function(result, error) { this._haveShutdown = false;
if (!error) { return;
this._haveShutdown = result[0]; }
this._updateInstallUpdates();
this._updateSuspendOrPowerOff(); this._session.CanShutdownRemote(null, Lang.bind(this, function(proxy, result) {
} try {
})); [this._haveShutdown] = proxy.CanShutdownFinish(result);
} catch(e) {
this._haveShutdown = false;
}
this._updateInstallUpdates();
this._updateSuspendOrPowerOff();
}));
}, },
_updateHaveSuspend: function() { _updateHaveSuspend: function() {
if (!this._loginManager) {
this._haveSuspend = false;
return;
}
this._loginManager.canSuspend(Lang.bind(this, this._loginManager.canSuspend(Lang.bind(this,
function(result) { function(result) {
this._haveSuspend = result; this._haveSuspend = result;
@ -752,7 +782,7 @@ const UserMenuButton = new Lang.Class({
item = new PopupMenu.PopupSeparatorMenuItem(); item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item); this.menu.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Settings")); item = new PopupMenu.PopupMenuItem(_("System Settings"));
item.connect('activate', Lang.bind(this, this._onPreferencesActivate)); item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
this.menu.addMenuItem(item); this.menu.addMenuItem(item);
this._systemSettings = item; this._systemSettings = item;
@ -837,14 +867,17 @@ const UserMenuButton = new Lang.Class({
_onQuitSessionActivate: function() { _onQuitSessionActivate: function() {
Main.overview.hide(); Main.overview.hide();
this._session.LogoutRemote(0);
if (this._session)
this._session.LogoutRemote(0, null, null);
}, },
_onInstallUpdatesActivate: function() { _onInstallUpdatesActivate: function() {
Main.overview.hide(); Main.overview.hide();
Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']); Util.spawn(['pkexec', '/usr/libexec/pk-trigger-offline-update']);
this._session.RebootRemote(); if (this._haveShutdown)
this._session.RebootRemote(null, null);
}, },
_onSuspendOrPowerOffActivate: function() { _onSuspendOrPowerOffActivate: function() {
@ -852,8 +885,8 @@ const UserMenuButton = new Lang.Class({
if (this._haveShutdown && if (this._haveShutdown &&
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) { this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
this._session.ShutdownRemote(); this._session.ShutdownRemote(null, null);
} else { } else if (this._haveSuspend) {
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) { if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() { let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId); Main.screenShield.disconnect(tmpId);

View File

@ -94,11 +94,6 @@ const ViewSelector = new Lang.Class({
this._searchPage = this._addPage(this._searchResults.actor, this._entry, this._searchPage = this._addPage(this._searchResults.actor, this._entry,
_("Search"), 'edit-find-symbolic'); _("Search"), 'edit-find-symbolic');
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 // Default search providers
// Wanda comes obviously first // Wanda comes obviously first
this.addSearchProvider(new Wanda.WandaSearchProvider()); this.addSearchProvider(new Wanda.WandaSearchProvider());
@ -149,17 +144,15 @@ const ViewSelector = new Lang.Class({
this.constrainHeight = new Clutter.BindConstraint({ source: this._pageArea, this.constrainHeight = new Clutter.BindConstraint({ source: this._pageArea,
coordinate: Clutter.BindCoordinate.HEIGHT }); coordinate: Clutter.BindCoordinate.HEIGHT });
Main.wm.addKeybinding('toggle-application-view', global.display.add_keybinding('toggle-application-view',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }), new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE, Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL | Lang.bind(this, this._showWithAppsPage));
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._toggleAppsPage));
}, },
_toggleAppsPage: function() { _showWithAppsPage: function() {
Main.overview.show(); Main.overview.show();
this._showAppsButton.checked = !this._showAppsButton.checked; this._showAppsButton.set_checked(true);
}, },
show: function() { show: function() {
@ -203,7 +196,7 @@ const ViewSelector = new Lang.Class({
}) })
});; });;
this._pageArea.add_actor(page); this._pageArea.add_actor(page);
return page; return page
}, },
_showPage: function(page) { _showPage: function(page) {
@ -440,32 +433,7 @@ const ViewSelector = new Lang.Class({
this._showPage(this._searchPage); 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) { addSearchProvider: function(provider) {
if (!this._shouldUseSearchProvider(provider))
return;
this._searchSystem.registerProvider(provider); this._searchSystem.registerProvider(provider);
this._searchResults.createProviderMeta(provider); this._searchResults.createProviderMeta(provider);
}, },

View File

@ -39,8 +39,6 @@ const WindowAttentionHandler = new Lang.Class({
let [title, banner] = this._getTitleAndBanner(app, window); let [title, banner] = this._getTitleAndBanner(app, window);
let notification = new MessageTray.Notification(source, title, banner); let notification = new MessageTray.Notification(source, title, banner);
notification.setForFeedback(true);
source.notify(notification); source.notify(notification);
source.signalIDs.push(window.connect('notify::title', Lang.bind(this, function() { source.signalIDs.push(window.connect('notify::title', Lang.bind(this, function() {

View File

@ -83,8 +83,6 @@ const WindowManager = new Lang.Class({
this._animationBlockCount = 0; this._animationBlockCount = 0;
this._allowedKeybindings = {};
this._switchData = null; this._switchData = null;
this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone)); this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) { this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) {
@ -101,66 +99,38 @@ const WindowManager = new Lang.Class({
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow)); this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
this._shellwm.connect('map', Lang.bind(this, this._mapWindow)); this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow)); this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding));
this._workspaceSwitcherPopup = null; this._workspaceSwitcherPopup = null;
this.setCustomKeybindingHandler('switch-to-workspace-left', Meta.keybindings_set_custom_handler('switch-to-workspace-left',
Main.KeybindingMode.NORMAL | Lang.bind(this, this._showWorkspaceSwitcher));
Main.KeybindingMode.OVERVIEW, Meta.keybindings_set_custom_handler('switch-to-workspace-right',
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-right', Meta.keybindings_set_custom_handler('switch-to-workspace-up',
Main.KeybindingMode.NORMAL | Lang.bind(this, this._showWorkspaceSwitcher));
Main.KeybindingMode.OVERVIEW, Meta.keybindings_set_custom_handler('switch-to-workspace-down',
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-up', Meta.keybindings_set_custom_handler('move-to-workspace-left',
Main.KeybindingMode.NORMAL | Lang.bind(this, this._showWorkspaceSwitcher));
Main.KeybindingMode.OVERVIEW, Meta.keybindings_set_custom_handler('move-to-workspace-right',
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-down', Meta.keybindings_set_custom_handler('move-to-workspace-up',
Main.KeybindingMode.NORMAL | Lang.bind(this, this._showWorkspaceSwitcher));
Main.KeybindingMode.OVERVIEW, Meta.keybindings_set_custom_handler('move-to-workspace-down',
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-left', Meta.keybindings_set_custom_handler('switch-windows',
Main.KeybindingMode.NORMAL | Lang.bind(this, this._startAppSwitcher));
Main.KeybindingMode.OVERVIEW, Meta.keybindings_set_custom_handler('switch-group',
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-right', Meta.keybindings_set_custom_handler('switch-windows-backward',
Main.KeybindingMode.NORMAL | Lang.bind(this, this._startAppSwitcher));
Main.KeybindingMode.OVERVIEW, Meta.keybindings_set_custom_handler('switch-group-backward',
Lang.bind(this, this._showWorkspaceSwitcher)); Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-up', Meta.keybindings_set_custom_handler('switch-panels',
Main.KeybindingMode.NORMAL | Lang.bind(this, this._startA11ySwitcher));
Main.KeybindingMode.OVERVIEW, global.display.add_keybinding('open-application-menu',
Lang.bind(this, this._showWorkspaceSwitcher)); new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
this.setCustomKeybindingHandler('move-to-workspace-down', Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL | Lang.bind(this, this._openAppMenu));
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-windows',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-windows-backward',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group-backward',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-panels',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW |
Main.KeybindingMode.LOCK_SCREEN |
Main.KeybindingMode.UNLOCK_SCREEN |
Main.KeybindingMode.LOGIN_SCREEN,
Lang.bind(this, this._startA11ySwitcher));
this.addKeybinding('open-application-menu',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._openAppMenu));
Main.overview.connect('showing', Lang.bind(this, function() { Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++) for (let i = 0; i < this._dimmedWindows.length; i++)
@ -172,25 +142,6 @@ const WindowManager = new Lang.Class({
})); }));
}, },
setCustomKeybindingHandler: function(name, modes, handler) {
if (Meta.keybindings_set_custom_handler(name, handler))
this.allowKeybinding(name, modes);
},
addKeybinding: function(name, settings, flags, modes, handler) {
if (global.display.add_keybinding(name, settings, flags, handler))
this.allowKeybinding(name, modes);
},
removeKeybinding: function(name) {
if (global.display.remove_keybinding(name))
this.allowKeybinding(name, Main.KeybindingMode.NONE);
},
allowKeybinding: function(name, modes) {
this._allowedKeybindings[name] = modes;
},
blockAnimations: function() { blockAnimations: function() {
this._animationBlockCount++; this._animationBlockCount++;
}, },
@ -473,21 +424,6 @@ const WindowManager = new Lang.Class({
} }
}, },
_filterKeybinding: function(shellwm, binding) {
if (Main.keybindingMode == Main.KeybindingMode.NONE)
return true;
// There's little sense in implementing a keybinding in mutter and
// not having it work in NORMAL mode; handle this case generically
// so we don't have to explicitly allow all builtin keybindings in
// NORMAL mode.
if (Main.keybindingMode == Main.KeybindingMode.NORMAL &&
binding.is_builtin())
return false;
return !(this._allowedKeybindings[binding.get_name()] & Main.keybindingMode);
},
_switchWorkspace : function(shellwm, from, to, direction) { _switchWorkspace : function(shellwm, from, to, direction) {
if (!this._shouldAnimate()) { if (!this._shouldAnimate()) {
shellwm.completed_switch_workspace(); shellwm.completed_switch_workspace();

View File

@ -1,19 +1 @@
XSLTPROC_FLAGS = \ dist_man_MANS = gnome-shell.1
--nonet \
--stringparam man.output.quietly 1 \
--stringparam funcsynopsis.style ansi \
--stringparam man.th.extra1.suppress 1 \
--stringparam man.authors.section.enabled 0 \
--stringparam man.copyright.section.enabled 0
.xml.1:
$(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
man_MANS = \
gnome-shell.1
xml_files = $(man_MANS:.1=.xml)
EXTRA_DIST = $(xml_files)
DISTCLEANFILES = $(man_MANS)

94
man/gnome-shell.1 Normal file
View File

@ -0,0 +1,94 @@
.\" Copyright (c) 2009, Marcelo Jorge Vieira (metal) <metal@alucinados.com>
.\"
.\" This is free documentation; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License as
.\" published by the Free Software Foundation; either version 2 of
.\" the License, or (at your option) any later version.
.\"
.\" The GNU General Public License's references to "object code"
.\" and "executables" are to be interpreted as the output of any
.\" document formatting or typesetting system, including
.\" intermediate and printed output.
.\"
.\" This manual is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public
.\" License along with this manual; if not, write to the Free
.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
.\" Boston, MA 02111-1301 USA.
.TH GNOME-SHELL 1
.SH NAME
gnome-shell \- Graphical shell for the GNOME desktop
.SH SYNOPSIS
.B gnome-shell [options]
.SH DESCRIPTION
GNOME Shell provides core user interface functions for the GNOME 3
desktop, like switching to windows and launching applications. GNOME
Shell takes advantage of the capabilities of modern graphics hardware
and introduces innovative user interface concepts to provide a
visually attractive and easy to use experience.
.SH OPTIONS
.TP
.B \-\-replace
Replace the running window manager
.br
.TP
.B \-\-sm-disable
Disable connection to the session manager
.br
.TP
.B \-\-sm-client-id=ID
Specify session management ID
.br
.TP
.B \-\-sm-save-file=FILE
Initialize session from savefile
.br
.TP
.B \-\-screen=SCREEN
X screen to use
.br
.TP
.B \-d, \-\-display=DISPLAY
X display to use
.br
.TP
.B \-\-sync
Make X calls synchronous
.br
.TP
.B \-\-version
Print version and exit
.br
.TP
.B \-\-help
Display help and exit
.br
.SH BUGS
The bug tracker can be reached by visiting the website
\fIhttps://bugzilla.gnome.org/buglist.cgi?product=gnome-shell\fR
Before sending a bug report, please verify that you have the latest
version of gnome-shell. Many bugs (major and minor) are fixed at each
release, and if yours is out of date, the problem may already have
been solved.
.SH ADDITIONAL INFORMATION
For further information, visit the website \fIhttp://live.gnome.org/GnomeShell\fR

View File

@ -1,159 +0,0 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<refentry id="gnome-shell">
<refentryinfo>
<title>gnome-shell</title>
<productname>gnome-shell</productname>
<authorgroup>
<author>
<contrib>wrote the original gnome-shell man page</contrib>
<firstname>Marcelo Jorge</firstname>
<surname>Vieira</surname>
<email>metal@alucinados.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>gnome-shell</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>gnome-shell</refname>
<refpurpose>Graphical shell for the GNOME desktop</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>gnome-shell <arg choice="opt" rep="repeat">OPTION</arg></command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>GNOME shell provides core user
interface functions for the GNOME 3 desktop, like switching
to windows and launching applications. GNOME shell takes
advantage of the capabilities of modern graphics hardware
and introduces innovative user interface concepts to provide
a visually attractive and easy to use experience.</para>
<para>gnome-shell is a required component of
the GNOME desktop, i.e. it is listed in the
RequiredComponents field of
<filename>/usr/share/gnome-session/sessions/gnome.session</filename>.
It is started in the window manager phase of the session.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>-r</option>, <option>--replace</option></term>
<listitem><para>Replace the running window manager</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sm-disable</option></term>
<listitem><para>Disable connection to the session manager</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sm-client-id=<replaceable>ID</replaceable></option></term>
<listitem><para>Specify session management <replaceable>ID</replaceable></para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sm-save-file=<replaceable>FILE</replaceable></option></term>
<listitem><para>Initialize session from <replaceable>FILE</replaceable></para></listitem>
</varlistentry>
<varlistentry>
<term><option>--screen=<replaceable>SCREEN</replaceable></option></term>
<listitem><para>X screen to use</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option>, <option>--display=<replaceable>DISPLAY</replaceable></option></term>
<listitem><para>X Display to use</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--sync</option></term>
<listitem><para>Make X calls synchronous</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--version</option></term>
<listitem><para>Print version and exit</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--help</option></term>
<listitem><para>Display help and exit</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--mode=<replaceable>MODE</replaceable></option></term>
<listitem><para>Use a specific mode, e.g. "gdm" for login screen</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--list-modes</option></term>
<listitem><para>List possible modes and exit</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Files</title>
<para>
<filename>/usr/share/gnome-session/sessions/gnome.session</filename>,
<filename>/usr/share/applications/gnome-shell.desktop</filename>.</para>
</refsect1>
<refsect1>
<title>Bugs</title>
<para>The bug tracker can be reached by visiting the
website <ulink url="https://bugzilla.gnome.org/buglist.cgi?product=gnome-shell">https://bugzilla.gnome.org/buglist.cgi?product=gnome-shell</ulink>.
Before sending a bug report, please verify that you have
the latest version of gnome-shell. Many bugs (major and
minor) are fixed at each release, and if yours is out of
date, the problem may already have been solved.</para>
</refsect1>
<refsect1>
<title>Additional Information</title>
<para>For further information, visit the website
<ulink url="http://live.gnome.org/GnomeShell">http://live.gnome.org/GnomeShell</ulink>.</para>
</refsect1>
</refentry>

487
po/cs.po

File diff suppressed because it is too large Load Diff

194
po/de.po
View File

@ -19,9 +19,9 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n" "Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-11-06 04:39+0000\n" "POT-Creation-Date: 2012-10-14 16:48+0000\n"
"PO-Revision-Date: 2012-11-06 20:04+0100\n" "PO-Revision-Date: 2012-10-10 23:10+0100\n"
"Last-Translator: Wolfgang Stoeggl <c72578@yahoo.de>\n" "Last-Translator: Tobias Endrigkeit <tobiasendrigkeit@googlemail.com>\n"
"Language-Team: Deutsch <gnome-de@gnome.org>\n" "Language-Team: Deutsch <gnome-de@gnome.org>\n"
"Language: \n" "Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -148,68 +148,56 @@ msgstr ""
"Aufzählung entnommen." "Aufzählung entnommen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13 #: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Den Menüeintrag »Abmelden« immer im Benutzermenü anzeigen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
"Dieser Schlüssel überschreibt das automatische Verbergen des Menüeintrags "
"»Abmelden« in Einzelbenutzer, Einzelsitzungssituationen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
msgstr "Wochentag im Kalender anzeigen" msgstr "Wochentag im Kalender anzeigen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16 #: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid "If true, display the ISO week date in the calendar." msgid "If true, display the ISO week date in the calendar."
msgstr "" msgstr ""
"Wenn dieser Wert gesetzt ist, wird der ISO-Wochentag im Kalender angezeigt." "Wenn dieser Wert gesetzt ist, wird der ISO-Wochentag im Kalender angezeigt."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Keybinding to open the application menu" msgid "Keybinding to open the application menu"
msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs" msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs." msgstr "Tastenkombination zum Öffnen des Anwendungsmenüs."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "" msgstr ""
"Tastenkombination zum Umschalten der Sichtbarkeit des Benachrichtigungsfeldes" "Tastenkombination zum Umschalten der Sichtbarkeit des Benachrichtigungsfeldes"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "Keybinding to toggle the visibility of the message tray." msgid "Keybinding to toggle the visibility of the message tray."
msgstr "" msgstr ""
"Tastenkombination zum Umschalten der Sichtbarkeit des " "Tastenkombination zum Umschalten der Sichtbarkeit des "
"Benachrichtigungsfeldes." "Benachrichtigungsfeldes."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Keybinding to toggle the screen recorder" msgid "Keybinding to toggle the screen recorder"
msgstr "Tastenkombination zum Umschalten des Bildschirmaufzeichners" msgstr "Tastenkombination zum Umschalten des Bildschirmaufzeichners"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22 #: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to start/stop the builtin screen recorder." msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "" msgstr ""
"Tastenkombination zum Starten/Entfernen des eingebauten " "Tastenkombination zum Starten/Entfernen des eingebauten "
"Bildschirmaufzeichners." "Bildschirmaufzeichners."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23 #: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Which keyboard to use" msgid "Which keyboard to use"
msgstr "Zu verwendende Tastatur" msgstr "Zu verwendende Tastatur"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24 #: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "Der Typ der zu verwendenden Tastatur" msgstr "Der Typ der zu verwendenden Tastatur"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
msgstr "Bildwiederholungsrate zur Aufnahme von Screencasts" msgstr "Bildwiederholungsrate zur Aufnahme von Screencasts"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26 #: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "" msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's " "The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second." "screencast recorder in frames-per-second."
@ -218,11 +206,11 @@ msgstr ""
"der GNOME-Shell aufgezeichnet werden soll, in Einzelbildern pro Sekunde." "der GNOME-Shell aufgezeichnet werden soll, in Einzelbildern pro Sekunde."
# hmm Enkodieren oder Kodieren? # hmm Enkodieren oder Kodieren?
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "The gstreamer pipeline used to encode the screencast" msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Die GStreamer-Weiterleitung zur Enkodierung des Screencasts" msgstr "Die GStreamer-Weiterleitung zur Enkodierung des Screencasts"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29 #: ../data/org.gnome.shell.gschema.xml.in.in.h:27
#, no-c-format #, no-c-format
msgid "" msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax " "Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -250,11 +238,11 @@ msgstr ""
"aufzeichnet. %T wird als Platzhalter für die vermutete optimale Thread-" "aufzeichnet. %T wird als Platzhalter für die vermutete optimale Thread-"
"Anzahl auf dem System verwendet." "Anzahl auf dem System verwendet."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30 #: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "File extension used for storing the screencast" msgid "File extension used for storing the screencast"
msgstr "Die Dateiendung zum Speichern des Screencast" msgstr "Die Dateiendung zum Speichern des Screencast"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31 #: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid "" msgid ""
"The filename for recorded screencasts will be a unique filename based on the " "The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to " "current date, and use this extension. It should be changed when recording to "
@ -315,8 +303,8 @@ msgstr "Anmeldefenster"
msgid "Power" msgid "Power"
msgstr "Ausschalten" msgstr "Ausschalten"
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:664 ../js/ui/userMenu.js:668 #: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:660 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:779 #: ../js/ui/userMenu.js:775
msgid "Suspend" msgid "Suspend"
msgstr "Bereitschaft" msgstr "Bereitschaft"
@ -324,8 +312,8 @@ msgstr "Bereitschaft"
msgid "Restart" msgid "Restart"
msgstr "Neu starten" msgstr "Neu starten"
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:666 ../js/ui/userMenu.js:668 #: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:662 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:778 #: ../js/ui/userMenu.js:774
msgid "Power Off" msgid "Power Off"
msgstr "Ausschalten" msgstr "Ausschalten"
@ -710,35 +698,35 @@ msgstr "Stumm"
#. Translators: this is a time format string followed by a date. #. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your #. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds. #. locale, without seconds.
#: ../js/ui/components/telepathyClient.js:952 #: ../js/ui/components/telepathyClient.js:948
#, no-c-format #, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>" msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Gesendet am <b>%A</b> um <b>%X</b> " msgstr "Gesendet am <b>%A</b> um <b>%X</b> "
#. Translators: this is a time format in the style of "Wednesday, May 25", #. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year. #. shown when you get a chat message in the same year.
#: ../js/ui/components/telepathyClient.js:958 #: ../js/ui/components/telepathyClient.js:954
#, no-c-format #, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>" msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Gesendet am <b>%A</b>, <b>%d. %B</b>" msgstr "Gesendet am <b>%A</b>, <b>%d. %B</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012", #. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year. #. shown when you get a chat message in a different year.
#: ../js/ui/components/telepathyClient.js:963 #: ../js/ui/components/telepathyClient.js:959
#, no-c-format #, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y" msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Gesendet am <b>%A</b>, <b>%d. %B</b> %Y" msgstr "Gesendet am <b>%A</b>, <b>%d. %B</b> %Y"
#. Translators: this is the other person changing their old IM name to their new #. Translators: this is the other person changing their old IM name to their new
#. IM name. #. IM name.
#: ../js/ui/components/telepathyClient.js:992 #: ../js/ui/components/telepathyClient.js:988
#, c-format #, c-format
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "%s heißt jetzt %s" msgstr "%s heißt jetzt %s"
#. translators: argument is a room name like #. translators: argument is a room name like
#. * room@jabber.org for example. #. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1092 #: ../js/ui/components/telepathyClient.js:1088
#, c-format #, c-format
msgid "Invitation to %s" msgid "Invitation to %s"
msgstr "Einladung zum Betreten von %s" msgstr "Einladung zum Betreten von %s"
@ -746,42 +734,42 @@ msgstr "Einladung zum Betreten von %s"
#. translators: first argument is the name of a contact and the second #. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org #. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example. #. * for example.
#: ../js/ui/components/telepathyClient.js:1100 #: ../js/ui/components/telepathyClient.js:1096
#, c-format #, c-format
msgid "%s is inviting you to join %s" msgid "%s is inviting you to join %s"
msgstr "%s lädt Sie ein, %s beizutreten" msgstr "%s lädt Sie ein, %s beizutreten"
#: ../js/ui/components/telepathyClient.js:1102 #: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1181 #: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1244 #: ../js/ui/components/telepathyClient.js:1240
msgid "Decline" msgid "Decline"
msgstr "Ablehnen" msgstr "Ablehnen"
#: ../js/ui/components/telepathyClient.js:1103 #: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1182 #: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1245 #: ../js/ui/components/telepathyClient.js:1241
msgid "Accept" msgid "Accept"
msgstr "Annehmen" msgstr "Annehmen"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1133 #: ../js/ui/components/telepathyClient.js:1129
#, c-format #, c-format
msgid "Video call from %s" msgid "Video call from %s"
msgstr "Video-Anruf von %s" msgstr "Video-Anruf von %s"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1136 #: ../js/ui/components/telepathyClient.js:1132
#, c-format #, c-format
msgid "Call from %s" msgid "Call from %s"
msgstr "Anruf von %s" msgstr "Anruf von %s"
#: ../js/ui/components/telepathyClient.js:1141 #: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/status/bluetooth.js:346 #: ../js/ui/status/bluetooth.js:346
msgid "Reject" msgid "Reject"
msgstr "Abweisen" msgstr "Abweisen"
#. translators: this is a button label (verb), not a noun #. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1143 #: ../js/ui/components/telepathyClient.js:1139
msgid "Answer" msgid "Answer"
msgstr "Antworten" msgstr "Antworten"
@ -790,113 +778,113 @@ msgstr "Antworten"
#. * file name. The string will be something #. * file name. The string will be something
#. * like: "Alice is sending you test.ogg" #. * like: "Alice is sending you test.ogg"
#. #.
#: ../js/ui/components/telepathyClient.js:1175 #: ../js/ui/components/telepathyClient.js:1171
#, c-format #, c-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "%s sendet Ihnen %s" msgstr "%s sendet Ihnen %s"
#. To translators: The parameter is the contact's alias #. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1210 #: ../js/ui/components/telepathyClient.js:1206
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "%s bittet um das Recht, Ihre Online-Verfügbarkeit sehen zu dürfen" msgstr "%s bittet um das Recht, Ihre Online-Verfügbarkeit sehen zu dürfen"
#: ../js/ui/components/telepathyClient.js:1302 #: ../js/ui/components/telepathyClient.js:1298
msgid "Network error" msgid "Network error"
msgstr "Netzwerkfehler" msgstr "Netzwerkfehler"
#: ../js/ui/components/telepathyClient.js:1304 #: ../js/ui/components/telepathyClient.js:1300
msgid "Authentication failed" msgid "Authentication failed"
msgstr "Legitimierung fehlgeschlagen" msgstr "Legitimierung fehlgeschlagen"
#: ../js/ui/components/telepathyClient.js:1306 #: ../js/ui/components/telepathyClient.js:1302
msgid "Encryption error" msgid "Encryption error"
msgstr "Verschlüsselungsfehler" msgstr "Verschlüsselungsfehler"
#: ../js/ui/components/telepathyClient.js:1308 #: ../js/ui/components/telepathyClient.js:1304
msgid "Certificate not provided" msgid "Certificate not provided"
msgstr "Zertifikat wurde nicht bereitgestellt" msgstr "Zertifikat wurde nicht bereitgestellt"
#: ../js/ui/components/telepathyClient.js:1310 #: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate untrusted" msgid "Certificate untrusted"
msgstr "Zertifikat nicht vertrauenswürdig" msgstr "Zertifikat nicht vertrauenswürdig"
#: ../js/ui/components/telepathyClient.js:1312 #: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate expired" msgid "Certificate expired"
msgstr "Zertifikat abgelaufen" msgstr "Zertifikat abgelaufen"
#: ../js/ui/components/telepathyClient.js:1314 #: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate not activated" msgid "Certificate not activated"
msgstr "Zertifikat nicht aktiviert" msgstr "Zertifikat nicht aktiviert"
#: ../js/ui/components/telepathyClient.js:1316 #: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate hostname mismatch" msgid "Certificate hostname mismatch"
msgstr "Rechnername des Zertifikats stimmt nicht überein" msgstr "Rechnername des Zertifikats stimmt nicht überein"
#: ../js/ui/components/telepathyClient.js:1318 #: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate fingerprint mismatch" msgid "Certificate fingerprint mismatch"
msgstr "Fingerabdruck des Zertifikats stimmt nicht überein" msgstr "Fingerabdruck des Zertifikats stimmt nicht überein"
#: ../js/ui/components/telepathyClient.js:1320 #: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate self-signed" msgid "Certificate self-signed"
msgstr "Selbstsigniertes Zertifikat" msgstr "Selbstsigniertes Zertifikat"
#: ../js/ui/components/telepathyClient.js:1322 #: ../js/ui/components/telepathyClient.js:1318
msgid "Status is set to offline" msgid "Status is set to offline"
msgstr "Der Status ist auf »Abgemeldet« gesetzt" msgstr "Der Status ist auf »Abgemeldet« gesetzt"
#: ../js/ui/components/telepathyClient.js:1324 #: ../js/ui/components/telepathyClient.js:1320
msgid "Encryption is not available" msgid "Encryption is not available"
msgstr "Verschlüsselung ist nicht verfügbar" msgstr "Verschlüsselung ist nicht verfügbar"
#: ../js/ui/components/telepathyClient.js:1326 #: ../js/ui/components/telepathyClient.js:1322
msgid "Certificate is invalid" msgid "Certificate is invalid"
msgstr "Zertifikat ist ungültig" msgstr "Zertifikat ist ungültig"
#: ../js/ui/components/telepathyClient.js:1328 #: ../js/ui/components/telepathyClient.js:1324
msgid "Connection has been refused" msgid "Connection has been refused"
msgstr "Verbindungsaufbau wurde verweigert" msgstr "Verbindungsaufbau wurde verweigert"
#: ../js/ui/components/telepathyClient.js:1330 #: ../js/ui/components/telepathyClient.js:1326
msgid "Connection can't be established" msgid "Connection can't be established"
msgstr "Verbindung kann nicht hergestellt werden" msgstr "Verbindung kann nicht hergestellt werden"
#: ../js/ui/components/telepathyClient.js:1332 #: ../js/ui/components/telepathyClient.js:1328
msgid "Connection has been lost" msgid "Connection has been lost"
msgstr "Verbindung wurde unterbrochen" msgstr "Verbindung wurde unterbrochen"
#: ../js/ui/components/telepathyClient.js:1334 #: ../js/ui/components/telepathyClient.js:1330
msgid "This account is already connected to the server" msgid "This account is already connected to the server"
msgstr "Dieses Konto ist bereits mit dem Server verbunden" msgstr "Dieses Konto ist bereits mit dem Server verbunden"
#: ../js/ui/components/telepathyClient.js:1336 #: ../js/ui/components/telepathyClient.js:1332
msgid "" msgid ""
"Connection has been replaced by a new connection using the same resource" "Connection has been replaced by a new connection using the same resource"
msgstr "" msgstr ""
"Die Verbindung wurde durch eine neue Verbindung mit der gleichen Ressource " "Die Verbindung wurde durch eine neue Verbindung mit der gleichen Ressource "
"ersetzt" "ersetzt"
#: ../js/ui/components/telepathyClient.js:1338 #: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server" msgid "The account already exists on the server"
msgstr "Dieses Konto ist bereits auf dem Server vorhanden" msgstr "Dieses Konto ist bereits auf dem Server vorhanden"
#: ../js/ui/components/telepathyClient.js:1340 #: ../js/ui/components/telepathyClient.js:1336
msgid "Server is currently too busy to handle the connection" msgid "Server is currently too busy to handle the connection"
msgstr "" msgstr ""
"Der Server ist derzeit überlastet und kann die Verbindung nicht annehmen" "Der Server ist derzeit überlastet und kann die Verbindung nicht annehmen"
#: ../js/ui/components/telepathyClient.js:1342 #: ../js/ui/components/telepathyClient.js:1338
msgid "Certificate has been revoked" msgid "Certificate has been revoked"
msgstr "Zertifikat wurde zurückgezogen" msgstr "Zertifikat wurde zurückgezogen"
#: ../js/ui/components/telepathyClient.js:1344 #: ../js/ui/components/telepathyClient.js:1340
msgid "" msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak" "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "" msgstr ""
"Das Zertifikat verwendet einen unsicheren Chiffrier-Algorithmus oder ist " "Das Zertifikat verwendet einen unsicheren Chiffrier-Algorithmus oder ist "
"kryptografisch schwach" "kryptografisch schwach"
#: ../js/ui/components/telepathyClient.js:1346 #: ../js/ui/components/telepathyClient.js:1342
msgid "" msgid ""
"The length of the server certificate, or the depth of the server certificate " "The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library" "chain, exceed the limits imposed by the cryptography library"
@ -905,26 +893,26 @@ msgstr ""
"überschreiten die durch die kryptografische Bibliothek gegebenen " "überschreiten die durch die kryptografische Bibliothek gegebenen "
"Beschränkungen" "Beschränkungen"
#: ../js/ui/components/telepathyClient.js:1348 #: ../js/ui/components/telepathyClient.js:1344
msgid "Internal error" msgid "Internal error"
msgstr "Interner Fehler" msgstr "Interner Fehler"
#. translators: argument is the account name, like #. translators: argument is the account name, like
#. * name@jabber.org for example. #. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1358 #: ../js/ui/components/telepathyClient.js:1354
#, c-format #, c-format
msgid "Connection to %s failed" msgid "Connection to %s failed"
msgstr "Verbindung zu %s ist fehlgeschlagen" msgstr "Verbindung zu %s ist fehlgeschlagen"
#: ../js/ui/components/telepathyClient.js:1367 #: ../js/ui/components/telepathyClient.js:1363
msgid "Reconnect" msgid "Reconnect"
msgstr "Erneut verbinden" msgstr "Erneut verbinden"
#: ../js/ui/components/telepathyClient.js:1368 #: ../js/ui/components/telepathyClient.js:1364
msgid "Edit account" msgid "Edit account"
msgstr "Konto bearbeiten" msgstr "Konto bearbeiten"
#: ../js/ui/components/telepathyClient.js:1413 #: ../js/ui/components/telepathyClient.js:1409
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Unbekannter Grund" msgstr "Unbekannter Grund"
@ -1107,23 +1095,23 @@ msgstr "Quelle zeigen"
msgid "Web Page" msgid "Web Page"
msgstr "Webseite" msgstr "Webseite"
#: ../js/ui/messageTray.js:1084 #: ../js/ui/messageTray.js:1081
msgid "Open" msgid "Open"
msgstr "Öffnen" msgstr "Öffnen"
#: ../js/ui/messageTray.js:1091 #: ../js/ui/messageTray.js:1088
msgid "Remove" msgid "Remove"
msgstr "Entfernen" msgstr "Entfernen"
#: ../js/ui/messageTray.js:1543 #: ../js/ui/messageTray.js:1540
msgid "Message Tray" msgid "Message Tray"
msgstr "Benachrichtigungsfeld" msgstr "Benachrichtigungsfeld"
#: ../js/ui/messageTray.js:2549 #: ../js/ui/messageTray.js:2547
msgid "System Information" msgid "System Information"
msgstr "Systeminformationen" msgstr "Systeminformationen"
#: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:374 #: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:373
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Unbekannt" msgstr "Unbekannt"
@ -1183,18 +1171,18 @@ msgstr "Bitte geben Sie einen Befehl ein:"
# %B - ausgeschriebener Name des Monats, abhängig von der gesetzten Umgebung # %B - ausgeschriebener Name des Monats, abhängig von der gesetzten Umgebung
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:80 #: ../js/ui/screenShield.js:79
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %d. %B" msgstr "%A, %d. %B"
#: ../js/ui/screenShield.js:144 #: ../js/ui/screenShield.js:143
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
msgstr[0] "%d neue Nachricht" msgstr[0] "%d neue Nachricht"
msgstr[1] "%d neue Nachrichten" msgstr[1] "%d neue Nachrichten"
#: ../js/ui/screenShield.js:146 #: ../js/ui/screenShield.js:145
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
@ -1650,59 +1638,59 @@ msgstr "Mikrofon"
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Als anderer Benutzer anmelden" msgstr "Als anderer Benutzer anmelden"
#: ../js/ui/userMenu.js:181 #: ../js/ui/userMenu.js:180
msgid "Available" msgid "Available"
msgstr "Verfügbar" msgstr "Verfügbar"
#: ../js/ui/userMenu.js:184 #: ../js/ui/userMenu.js:183
msgid "Busy" msgid "Busy"
msgstr "Beschäftigt" msgstr "Beschäftigt"
#: ../js/ui/userMenu.js:187 #: ../js/ui/userMenu.js:186
msgid "Invisible" msgid "Invisible"
msgstr "Unsichtbar" msgstr "Unsichtbar"
#: ../js/ui/userMenu.js:190 #: ../js/ui/userMenu.js:189
msgid "Away" msgid "Away"
msgstr "Abwesend" msgstr "Abwesend"
#: ../js/ui/userMenu.js:193 #: ../js/ui/userMenu.js:192
msgid "Idle" msgid "Idle"
msgstr "Untätig" msgstr "Untätig"
#: ../js/ui/userMenu.js:196 #: ../js/ui/userMenu.js:195
msgid "Unavailable" msgid "Unavailable"
msgstr "Nicht verfügbar" msgstr "Nicht verfügbar"
#: ../js/ui/userMenu.js:744 #: ../js/ui/userMenu.js:740
msgid "Notifications" msgid "Notifications"
msgstr "Benachrichtigungen" msgstr "Benachrichtigungen"
#: ../js/ui/userMenu.js:752 #: ../js/ui/userMenu.js:748
msgid "System Settings" msgid "System Settings"
msgstr "Systemeinstellungen" msgstr "Systemeinstellungen"
#: ../js/ui/userMenu.js:760 #: ../js/ui/userMenu.js:756
msgid "Switch User" msgid "Switch User"
msgstr "Benutzer wechseln" msgstr "Benutzer wechseln"
#: ../js/ui/userMenu.js:765 #: ../js/ui/userMenu.js:761
msgid "Log Out" msgid "Log Out"
msgstr "Abmelden" msgstr "Abmelden"
#: ../js/ui/userMenu.js:770 #: ../js/ui/userMenu.js:766
msgid "Lock" msgid "Lock"
msgstr "Sperren" msgstr "Sperren"
#: ../js/ui/userMenu.js:785 #: ../js/ui/userMenu.js:781
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Aktualisierungen installieren und neustarten" msgstr "Aktualisierungen installieren und neustarten"
#: ../js/ui/userMenu.js:803 #: ../js/ui/userMenu.js:799
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Ihr Anwesenheitsstatus wird auf »Beschäftigt« gesetzt" msgstr "Ihr Anwesenheitsstatus wird auf »Beschäftigt« gesetzt"
#: ../js/ui/userMenu.js:804 #: ../js/ui/userMenu.js:800
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1789,7 +1777,7 @@ msgstr ""
msgid "List possible modes" msgid "List possible modes"
msgstr "Die möglichen Modi auflisten" msgstr "Die möglichen Modi auflisten"
#: ../src/shell-app.c:622 #: ../src/shell-app.c:621
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "»%s« konnte nicht gestartet werden" msgstr "»%s« konnte nicht gestartet werden"

158
po/et.po
View File

@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: gnome-shell MASTER\n" "Project-Id-Version: gnome-shell MASTER\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-11-16 18:27+0000\n" "POT-Creation-Date: 2012-09-22 22:24+0000\n"
"PO-Revision-Date: 2012-11-16 20:40+0300\n" "PO-Revision-Date: 2012-09-23 08:48+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n" "Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <>\n" "Language-Team: Estonian <>\n"
"Language: et\n" "Language: et\n"
@ -37,15 +37,6 @@ msgstr "Arvuti"
msgid "Show the message tray" msgid "Show the message tray"
msgstr "Teateala näitamine" msgstr "Teateala näitamine"
msgid "Focus the active notification"
msgstr "Aktiivse märguande fokuseerimine"
msgid "Show all applications"
msgstr "Kõigi rakenduste kuvamine"
msgid "Open the application menu"
msgstr "Rakenduste menüü avamine"
msgid "GNOME Shell" msgid "GNOME Shell"
msgstr "GNOME Shell" msgstr "GNOME Shell"
@ -125,16 +116,6 @@ msgstr ""
"Kasutatakse kasutaja poolt viimati vahetult määratud kiirsuhtluse oleku " "Kasutatakse kasutaja poolt viimati vahetult määratud kiirsuhtluse oleku "
"salvestamiseks. See väärtus pärineb GsmPresenceStatus nummerdusest." "salvestamiseks. See väärtus pärineb GsmPresenceStatus nummerdusest."
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Kasutajamenüüs näidatakse alati 'Logi välja' menüükirjet."
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
"üks kasutaja ning avatud üks seanss."
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
msgstr "Kalendris näidatakse kuupäeva nädalavormingus" msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
@ -147,25 +128,12 @@ msgstr "Rakenduste menüü avamise kiirklahv"
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Kiirklahv rakenduste menüü avamiseks." msgstr "Kiirklahv rakenduste menüü avamiseks."
msgid "Keybinding to open the \"Show Applications\" view"
msgstr "\"Rakenduste vaate\" avamise kiirklahv"
msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "\"Rakenduste vaate\" avamise kiirklahv tegevuste ülevaates."
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Teateala nähtavuse muutmise kiirklahv" msgstr "Teateala nähtavuse muutmise kiirklahv"
msgid "Keybinding to toggle the visibility of the message tray." msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Kiirklahv teateala nähtavuse muutmiseks." msgstr "Kiirklahv teateala nähtavuse muutmiseks."
msgid "Keybinding to focus the active notification"
msgstr "Aktiivse teate fokuseerimise kiirklahv"
msgid "Keybinding to focus the active notification."
msgstr "Aktiivse teate fokuseerimise kiirklahv."
msgid "Keybinding to toggle the screen recorder" msgid "Keybinding to toggle the screen recorder"
msgstr "Erkaanilindistaja lülitamise kiirklahv" msgstr "Erkaanilindistaja lülitamise kiirklahv"
@ -227,34 +195,6 @@ msgstr ""
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend " "konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
"määrata." "määrata."
msgid "Attach modal dialog to the parent window"
msgstr "Modaaldialoog kuulub vanemakna juurde"
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"See võti on ülimuslik võtme org.gnome.mutter suhtes, kui kasutatakse GNOME "
"Shelli."
msgid "Arrangement of buttons on the titlebar"
msgstr "Nuppude järjekord tiitliribal"
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"See võti on ülimuslik võtme org.gnome.desktop.wm.preferences suhtes, kui "
"kasutatakse GNOME Shelli."
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Akende lohistamisel ekraani serva lubatakse serva paigutamine"
msgid "Workspaces are managed dynamically"
msgstr "Tööalasid hallatakse dünaamiliselt"
msgid "Workspaces only on primary monitor"
msgstr "Tööalad peamisel monitoril"
#, c-format #, c-format
msgid "There was an error loading the preferences dialog for %s:" msgid "There was an error loading the preferences dialog for %s:"
msgstr "%s jaoks eelistuste dialoogi laadimisel esines viga:" msgstr "%s jaoks eelistuste dialoogi laadimisel esines viga:"
@ -285,22 +225,9 @@ msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Logi sisse" msgstr "Logi sisse"
msgid "Next"
msgstr "Järgmine"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
msgid "Username: "
msgstr "Kasutajanimi: "
msgid "Login Window" msgid "Login Window"
msgstr "Sisselogimisaken" msgstr "Sisselogimisaken"
#. Translators: accessible name of the power menu in the login screen
msgid "Power"
msgstr "Vool"
msgid "Suspend" msgid "Suspend"
msgstr "Uinak" msgstr "Uinak"
@ -510,6 +437,12 @@ msgstr "Parool: "
msgid "Key: " msgid "Key: "
msgstr "Võti: " msgstr "Võti: "
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
msgid "Username: "
msgstr "Kasutajanimi: "
msgid "Identity: " msgid "Identity: "
msgstr "Identiteet: " msgstr "Identiteet: "
@ -600,27 +533,24 @@ msgstr "Heli peale"
msgid "Mute" msgid "Mute"
msgstr "Heli maha" msgstr "Heli maha"
#. Translators: this is a time format string followed by the word "Yesterday". i.e. "14:30 on Yesterday" #. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#, no-c-format #, no-c-format
msgid "<b>%H:%M</b> on Yesterday" msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Eile <b>%H:%M</b>" msgstr "Saadetud: <b>%A</b>, <b>%X</b>"
#. Translators: this is a time format string followed by a week day name. i.e. "14:30 on Monday #. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#, no-c-format #, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>" msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "<b>%H:%M</b>, <b>%A</b>" msgstr "Saadeti <b>%A</b>, <b>%B %d</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25", #. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in the same year #. shown when you get a chat message in a different year.
#, no-c-format #, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>" msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b>" msgstr "Saadeti <b>%A</b>, <b>%B %d</b>, %Y"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b> %Y"
#. Translators: this is the other person changing their old IM name to their new #. Translators: this is the other person changing their old IM name to their new
#. IM name. #. IM name.
@ -657,6 +587,9 @@ msgstr "%s tahab alustada videokõnet"
msgid "Call from %s" msgid "Call from %s"
msgstr "%s helistab" msgstr "%s helistab"
msgid "Reject"
msgstr "Lükka tagasi"
#. translators: this is a button label (verb), not a noun #. translators: this is a button label (verb), not a noun
msgid "Answer" msgid "Answer"
msgstr "Vasta" msgstr "Vasta"
@ -964,11 +897,8 @@ msgstr "Ülemine riba"
msgid "toggle-switch-us" msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
msgid "Enter a Command" msgid "Please enter a command:"
msgstr "Palun sisesta käsk" msgstr "Palun sisesta käsk:"
msgid "Close"
msgstr "Sulge"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
@ -1081,6 +1011,16 @@ msgstr "ühendumine..."
msgid "Send Files..." msgid "Send Files..."
msgstr "Failide saatmine..." msgstr "Failide saatmine..."
msgid "Browse Files..."
msgstr "Failide sirvimine..."
msgid "Error browsing device"
msgstr "Viga seadme sirvimisel"
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "Küsitud seadet pole võimalik sirvida, viga on '%s'"
msgid "Keyboard Settings" msgid "Keyboard Settings"
msgstr "Klaviatuurisätted" msgstr "Klaviatuurisätted"
@ -1104,9 +1044,6 @@ msgstr "Luba alati"
msgid "Grant this time only" msgid "Grant this time only"
msgstr "Luba ainult seekord" msgstr "Luba ainult seekord"
msgid "Reject"
msgstr "Lükka tagasi"
#, c-format #, c-format
msgid "Pairing confirmation for %s" msgid "Pairing confirmation for %s"
msgstr "Paardumise kinnitus seadmele %s" msgstr "Paardumise kinnitus seadmele %s"
@ -1217,6 +1154,9 @@ msgstr "Juhtmeta"
msgid "Mobile broadband" msgid "Mobile broadband"
msgstr "Mobiiliühendus" msgstr "Mobiiliühendus"
msgid "VPN Connections"
msgstr "VPN-ühendused"
msgid "Network Settings" msgid "Network Settings"
msgstr "Võrgusätted" msgstr "Võrgusätted"
@ -1334,17 +1274,20 @@ msgstr "Eemal"
msgid "Idle" msgid "Idle"
msgstr "Jõude" msgstr "Jõude"
msgid "Offline" msgid "Unavailable"
msgstr "Ühendamata" msgstr "Pole saadaval"
msgid "Switch User"
msgstr "Vaheta kasutajat"
msgid "Switch Session"
msgstr "Vaheta seanssi"
msgid "Notifications" msgid "Notifications"
msgstr "Märguanded" msgstr "Märguanded"
msgid "Settings" msgid "System Settings"
msgstr "Sätted" msgstr "Süsteemi sätted"
msgid "Switch User"
msgstr "Vaheta kasutajat"
msgid "Log Out" msgid "Log Out"
msgstr "Logi välja" msgstr "Logi välja"
@ -1461,6 +1404,9 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "If true, display date in the clock, in addition to time." #~ msgid "If true, display date in the clock, in addition to time."
#~ msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva." #~ msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva."
#~ msgid "Offline"
#~ msgstr "Ühendamata"
#~ msgid "CONTACTS" #~ msgid "CONTACTS"
#~ msgstr "KONTAKTID" #~ msgstr "KONTAKTID"

551
po/gl.po

File diff suppressed because it is too large Load Diff

699
po/he.po

File diff suppressed because it is too large Load Diff

419
po/nb.po
View File

@ -6,10 +6,10 @@
# Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010. # Torstein Adolf Winterseth <kvikende@fsfe.org>, 2010.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gnome-shell 3.7.x\n" "Project-Id-Version: gnome-shell 3.5.x\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-11-05 19:06+0100\n" "POT-Creation-Date: 2012-10-11 20:24+0200\n"
"PO-Revision-Date: 2012-11-05 19:10+0100\n" "PO-Revision-Date: 2012-10-11 20:25+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n" "Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n" "Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n" "Language: \n"
@ -34,14 +34,6 @@ msgstr "System"
msgid "Show the message tray" msgid "Show the message tray"
msgstr "Vis meldingstrau" msgstr "Vis meldingstrau"
#: ../data/50-gnome-shell-system.xml.in.h:3
msgid "Show all applications"
msgstr "Vis alle programmer"
#: ../data/50-gnome-shell-system.xml.in.h:4
msgid "Open the application menu"
msgstr "Åpne programmenyen"
#: ../data/gnome-shell.desktop.in.in.h:1 #: ../data/gnome-shell.desktop.in.in.h:1
msgid "GNOME Shell" msgid "GNOME Shell"
msgstr "GNOME Shell" msgstr "GNOME Shell"
@ -136,71 +128,50 @@ msgid ""
msgstr "" msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13 #: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
msgstr "Vis dato for uken i kalender" msgstr "Vis dato for uken i kalender"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16 #: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid "If true, display the ISO week date in the calendar." msgid "If true, display the ISO week date in the calendar."
msgstr "Viser ISO-ukedato i kalenderen hvis «true»." msgstr "Viser ISO-ukedato i kalenderen hvis «true»."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Keybinding to open the application menu" msgid "Keybinding to open the application menu"
msgstr "Tastaturbinding som åpner programmenyen" msgstr "Tastaturbinding som åpner programmenyen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Tastaturbinding som åpner programmenyen." msgstr "Tastaturbinding som åpner programmenyen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
#, fuzzy
msgid "Keybinding to open the \"Show Applications\" view"
msgstr "Tastaturbinding som åpner programmenyen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
#, fuzzy
msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "Tastaturbinding som åpner programmenyen."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Tastaturbinding som slår av/på synlighet for meldingstrau" msgstr "Tastaturbinding som slår av/på synlighet for meldingstrau"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "Keybinding to toggle the visibility of the message tray." msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Tastaturbinding som slår av/på synlighet for meldingstrauet." msgstr "Tastaturbinding som slår av/på synlighet for meldingstrauet."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Keybinding to toggle the screen recorder" msgid "Keybinding to toggle the screen recorder"
msgstr "Tastaturbinding som slår av/på skjermopptak" msgstr "Tastaturbinding som slår av/på skjermopptak"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24 #: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to start/stop the builtin screen recorder." msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "Tastaturbinding som starter/stopper innebygget opptak av skjerm." msgstr "Tastaturbinding som starter/stopper innebygget opptak av skjerm."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Which keyboard to use" msgid "Which keyboard to use"
msgstr "Tastatur som skal brukes" msgstr "Tastatur som skal brukes"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26 #: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "Type tastatur som skal brukes." msgstr "Type tastatur som skal brukes."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27 #: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
msgstr "Bildefrekvens i bruk ved lagring av skjermvideoer." msgstr "Bildefrekvens i bruk ved lagring av skjermvideoer."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28 #: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "" msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's " "The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second." "screencast recorder in frames-per-second."
@ -208,11 +179,11 @@ msgstr ""
"Bildefrekvensen i den ferdige skjermvideoen tatt opp med GNOME Shells " "Bildefrekvensen i den ferdige skjermvideoen tatt opp med GNOME Shells "
"skjermvideoopptaker i bilder per sekund." "skjermvideoopptaker i bilder per sekund."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "The gstreamer pipeline used to encode the screencast" msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Gstreamer-kommandokø brukt til å kode skjermvideoen" msgstr "Gstreamer-kommandokø brukt til å kode skjermvideoen"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31 #: ../data/org.gnome.shell.gschema.xml.in.in.h:27
#, fuzzy, no-c-format #, fuzzy, no-c-format
msgid "" msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax " "Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -229,11 +200,11 @@ msgstr ""
"Setter GStreamer-rør som brukes til å kode opptak. Den følger syntaksen som " "Setter GStreamer-rør som brukes til å kode opptak. Den følger syntaksen som "
"brukes for gst-launch. Røret må ha en..." "brukes for gst-launch. Røret må ha en..."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32 #: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "File extension used for storing the screencast" msgid "File extension used for storing the screencast"
msgstr "Filendelse i bruk ved lagring av skjermvideo" msgstr "Filendelse i bruk ved lagring av skjermvideo"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33 #: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid "" msgid ""
"The filename for recorded screencasts will be a unique filename based on the " "The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to " "current date, and use this extension. It should be changed when recording to "
@ -243,37 +214,6 @@ msgstr ""
"og bruke denne filendelsen. Den bør endres når du gjør opptak til et nytt " "og bruke denne filendelsen. Den bør endres når du gjør opptak til et nytt "
"oppbevaringsformat." "oppbevaringsformat."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
msgid "Attach modal dialog to the parent window"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36
msgid "Arrangement of buttons on the titlebar"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
msgid "Workspaces are managed dynamically"
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
msgid "Workspaces only on primary monitor"
msgstr ""
#: ../js/extensionPrefs/main.js:124 #: ../js/extensionPrefs/main.js:124
#, c-format #, c-format
msgid "There was an error loading the preferences dialog for %s:" msgid "There was an error loading the preferences dialog for %s:"
@ -287,11 +227,11 @@ msgstr "Utvidelse"
msgid "Select an extension to configure using the combobox above." msgid "Select an extension to configure using the combobox above."
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over." msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
#: ../js/gdm/loginDialog.js:560 #: ../js/gdm/loginDialog.js:529
msgid "Session..." msgid "Session..."
msgstr "Økt …" msgstr "Økt …"
#: ../js/gdm/loginDialog.js:704 #: ../js/gdm/loginDialog.js:677
msgctxt "title" msgctxt "title"
msgid "Sign In" msgid "Sign In"
msgstr "Logg inn" msgstr "Logg inn"
@ -299,56 +239,56 @@ msgstr "Logg inn"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:764 #: ../js/gdm/loginDialog.js:736
msgid "Not listed?" msgid "Not listed?"
msgstr "Ikke listet?" msgstr "Ikke listet?"
#: ../js/gdm/loginDialog.js:906 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:889 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396
#: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:171 #: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:166
msgid "Cancel" msgid "Cancel"
msgstr "Avbryt" msgstr "Avbryt"
#: ../js/gdm/loginDialog.js:911 #: ../js/gdm/loginDialog.js:894
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Logg inn" msgstr "Logg inn"
#: ../js/gdm/loginDialog.js:1237 #: ../js/gdm/loginDialog.js:1215
msgid "Login Window" msgid "Login Window"
msgstr "Innloggingsvindu" msgstr "Innloggingsvindu"
#. Translators: accessible name of the power menu in the login screen #. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:36 #: ../js/gdm/powerMenu.js:35
msgid "Power" msgid "Power"
msgstr "Strøm" msgstr "Strøm"
#: ../js/gdm/powerMenu.js:93 ../js/ui/userMenu.js:667 ../js/ui/userMenu.js:671 #: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:660 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:782 #: ../js/ui/userMenu.js:775
msgid "Suspend" msgid "Suspend"
msgstr "Hvilemodus" msgstr "Hvilemodus"
#: ../js/gdm/powerMenu.js:98 #: ../js/gdm/powerMenu.js:94
msgid "Restart" msgid "Restart"
msgstr "Start på nytt" msgstr "Start på nytt"
#: ../js/gdm/powerMenu.js:103 ../js/ui/userMenu.js:669 #: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:662 ../js/ui/userMenu.js:664
#: ../js/ui/userMenu.js:671 ../js/ui/userMenu.js:781 #: ../js/ui/userMenu.js:774
msgid "Power Off" msgid "Power Off"
msgstr "Slå av" msgstr "Slå av"
#: ../js/gdm/util.js:151 #: ../js/gdm/util.js:148
msgid "Authentication error" msgid "Authentication error"
msgstr "Autentiseringsfeil" msgstr "Autentiseringsfeil"
#. Translators: this message is shown below the password entry field #. Translators: this message is shown below the password entry field
#. to indicate the user can swipe their finger instead #. to indicate the user can swipe their finger instead
#: ../js/gdm/util.js:268 #: ../js/gdm/util.js:265
msgid "(or swipe finger)" msgid "(or swipe finger)"
msgstr "(eller dra finger)" msgstr "(eller dra finger)"
#: ../js/gdm/util.js:293 #: ../js/gdm/util.js:290
#, c-format #, c-format
msgid "(e.g., user or %s)" msgid "(e.g., user or %s)"
msgstr "(f.eks. bruker eller %s)" msgstr "(f.eks. bruker eller %s)"
@ -398,7 +338,7 @@ msgstr "Legg til i favoritter"
msgid "%s has been added to your favorites." msgid "%s has been added to your favorites."
msgstr "%s ble lagt til i dine favoritter." msgstr "%s ble lagt til i dine favoritter."
#: ../js/ui/appFavorites.js:121 #: ../js/ui/appFavorites.js:118
#, c-format #, c-format
msgid "%s has been removed from your favorites." msgid "%s has been removed from your favorites."
msgstr "%s ble fjernet fra dine favoritter." msgstr "%s ble fjernet fra dine favoritter."
@ -517,48 +457,48 @@ msgid "S"
msgstr "Lø" msgstr "Lø"
#. Translators: Text to show if there are no events #. Translators: Text to show if there are no events
#: ../js/ui/calendar.js:700 #: ../js/ui/calendar.js:699
msgid "Nothing Scheduled" msgid "Nothing Scheduled"
msgstr "Ingenting planlagt" msgstr "Ingenting planlagt"
#. Translators: Shown on calendar heading when selected day occurs on current year #. Translators: Shown on calendar heading when selected day occurs on current year
#: ../js/ui/calendar.js:716 #: ../js/ui/calendar.js:715
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A %B %d" msgstr "%A %B %d"
#. Translators: Shown on calendar heading when selected day occurs on different year #. Translators: Shown on calendar heading when selected day occurs on different year
#: ../js/ui/calendar.js:719 #: ../js/ui/calendar.js:718
msgctxt "calendar heading" msgctxt "calendar heading"
msgid "%A, %B %d, %Y" msgid "%A, %B %d, %Y"
msgstr "%A %B %d, %Y" msgstr "%A %B %d, %Y"
#: ../js/ui/calendar.js:729 #: ../js/ui/calendar.js:728
msgid "Today" msgid "Today"
msgstr "I dag" msgstr "I dag"
#: ../js/ui/calendar.js:733 #: ../js/ui/calendar.js:732
msgid "Tomorrow" msgid "Tomorrow"
msgstr "I morgen" msgstr "I morgen"
#: ../js/ui/calendar.js:744 #: ../js/ui/calendar.js:743
msgid "This week" msgid "This week"
msgstr "Denne uken" msgstr "Denne uken"
#: ../js/ui/calendar.js:752 #: ../js/ui/calendar.js:751
msgid "Next week" msgid "Next week"
msgstr "Neste uke" msgstr "Neste uke"
#: ../js/ui/components/autorunManager.js:295 #: ../js/ui/components/autorunManager.js:297
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Avtagbare enheter" msgstr "Avtagbare enheter"
#: ../js/ui/components/autorunManager.js:591 #: ../js/ui/components/autorunManager.js:594
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Åpne med %s" msgstr "Åpne med %s"
#: ../js/ui/components/autorunManager.js:617 #: ../js/ui/components/autorunManager.js:620
msgid "Eject" msgid "Eject"
msgstr "Løs ut" msgstr "Løs ut"
@ -712,42 +652,38 @@ msgstr "Fjern demping"
msgid "Mute" msgid "Mute"
msgstr "Demp" msgstr "Demp"
#. Translators: this is a time format string followed by the word "Yesterday". i.e. "14:30 on Yesterday" #. Translators: this is a time format string followed by a date.
#: ../js/ui/components/telepathyClient.js:945 #. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/components/telepathyClient.js:948
#, no-c-format #, no-c-format
msgid "<b>%H:%M</b> on Yesterday" msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "<b>%H.%M</b> i går" msgstr "Sendt <b>%X</b> på <b>%A</b>"
#. Translators: this is a time format string followed by a week day name. i.e. "14:30 on Monday #. Translators: this is a time format in the style of "Wednesday, May 25",
#: ../js/ui/components/telepathyClient.js:951 #. shown when you get a chat message in the same year.
#: ../js/ui/components/telepathyClient.js:954
#, no-c-format #, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>" msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "<b>%H.%M</b> <b>%A</b>" msgstr "Sendt <b>%A</b>, <b>%B %d</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25", #. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in the same year #. shown when you get a chat message in a different year.
#: ../js/ui/components/telepathyClient.js:957 #: ../js/ui/components/telepathyClient.js:959
#, no-c-format #, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>" msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "<b>%H.%M</b>, <b>%A</b>, <b>%B</b> <b>%d</b>" msgstr "Sendt <b>%A</b>, <b>%B %d</b>, %Y"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year
#: ../js/ui/components/telepathyClient.js:962
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
msgstr "<b>%H.%M</b>, <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
#. Translators: this is the other person changing their old IM name to their new #. Translators: this is the other person changing their old IM name to their new
#. IM name. #. IM name.
#: ../js/ui/components/telepathyClient.js:990 #: ../js/ui/components/telepathyClient.js:988
#, c-format #, c-format
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "%s er nå kjent som %s" msgstr "%s er nå kjent som %s"
#. translators: argument is a room name like #. translators: argument is a room name like
#. * room@jabber.org for example. #. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1089 #: ../js/ui/components/telepathyClient.js:1088
#, c-format #, c-format
msgid "Invitation to %s" msgid "Invitation to %s"
msgstr "Invitasjon til %s" msgstr "Invitasjon til %s"
@ -755,42 +691,42 @@ msgstr "Invitasjon til %s"
#. translators: first argument is the name of a contact and the second #. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org #. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example. #. * for example.
#: ../js/ui/components/telepathyClient.js:1097 #: ../js/ui/components/telepathyClient.js:1096
#, c-format #, c-format
msgid "%s is inviting you to join %s" msgid "%s is inviting you to join %s"
msgstr "%s inviterer deg til å bli med i %s" msgstr "%s inviterer deg til å bli med i %s"
#: ../js/ui/components/telepathyClient.js:1099 #: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1178 #: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1241 #: ../js/ui/components/telepathyClient.js:1240
msgid "Decline" msgid "Decline"
msgstr "Avslå" msgstr "Avslå"
#: ../js/ui/components/telepathyClient.js:1100 #: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1179 #: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1242 #: ../js/ui/components/telepathyClient.js:1241
msgid "Accept" msgid "Accept"
msgstr "Godta" msgstr "Godta"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1130 #: ../js/ui/components/telepathyClient.js:1129
#, c-format #, c-format
msgid "Video call from %s" msgid "Video call from %s"
msgstr "Videosamtale fra %s" msgstr "Videosamtale fra %s"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1133 #: ../js/ui/components/telepathyClient.js:1132
#, c-format #, c-format
msgid "Call from %s" msgid "Call from %s"
msgstr "Samtale fra %s" msgstr "Samtale fra %s"
#: ../js/ui/components/telepathyClient.js:1138 #: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/status/bluetooth.js:346 #: ../js/ui/status/bluetooth.js:346
msgid "Reject" msgid "Reject"
msgstr "Avvis" msgstr "Avvis"
#. translators: this is a button label (verb), not a noun #. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1140 #: ../js/ui/components/telepathyClient.js:1139
msgid "Answer" msgid "Answer"
msgstr "Svar" msgstr "Svar"
@ -799,110 +735,110 @@ msgstr "Svar"
#. * file name. The string will be something #. * file name. The string will be something
#. * like: "Alice is sending you test.ogg" #. * like: "Alice is sending you test.ogg"
#. #.
#: ../js/ui/components/telepathyClient.js:1172 #: ../js/ui/components/telepathyClient.js:1171
#, c-format #, c-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "%s sender deg %s" msgstr "%s sender deg %s"
#. To translators: The parameter is the contact's alias #. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1207 #: ../js/ui/components/telepathyClient.js:1206
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "%s vil ha rettigheter til å se når du er tilkoblet" msgstr "%s vil ha rettigheter til å se når du er tilkoblet"
#: ../js/ui/components/telepathyClient.js:1299 #: ../js/ui/components/telepathyClient.js:1298
msgid "Network error" msgid "Network error"
msgstr "Nettverksfeil" msgstr "Nettverksfeil"
#: ../js/ui/components/telepathyClient.js:1301 #: ../js/ui/components/telepathyClient.js:1300
msgid "Authentication failed" msgid "Authentication failed"
msgstr "Autentisering feilet" msgstr "Autentisering feilet"
#: ../js/ui/components/telepathyClient.js:1303 #: ../js/ui/components/telepathyClient.js:1302
msgid "Encryption error" msgid "Encryption error"
msgstr "Feil ved kryptering" msgstr "Feil ved kryptering"
#: ../js/ui/components/telepathyClient.js:1305 #: ../js/ui/components/telepathyClient.js:1304
msgid "Certificate not provided" msgid "Certificate not provided"
msgstr "Sertifikat ikke oppgitt" msgstr "Sertifikat ikke oppgitt"
#: ../js/ui/components/telepathyClient.js:1307 #: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate untrusted" msgid "Certificate untrusted"
msgstr "Stoler ikke på sertifikatet" msgstr "Stoler ikke på sertifikatet"
#: ../js/ui/components/telepathyClient.js:1309 #: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate expired" msgid "Certificate expired"
msgstr "Sertifikatet er utløpt" msgstr "Sertifikatet er utløpt"
#: ../js/ui/components/telepathyClient.js:1311 #: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate not activated" msgid "Certificate not activated"
msgstr "Sertifikatet er ikke aktivert" msgstr "Sertifikatet er ikke aktivert"
#: ../js/ui/components/telepathyClient.js:1313 #: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate hostname mismatch" msgid "Certificate hostname mismatch"
msgstr "Feil vertsnavn for sertifikat" msgstr "Feil vertsnavn for sertifikat"
#: ../js/ui/components/telepathyClient.js:1315 #: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate fingerprint mismatch" msgid "Certificate fingerprint mismatch"
msgstr "Feil fingeravtrykk for sertifikat" msgstr "Feil fingeravtrykk for sertifikat"
#: ../js/ui/components/telepathyClient.js:1317 #: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate self-signed" msgid "Certificate self-signed"
msgstr "Sertifikatet er selvsignert" msgstr "Sertifikatet er selvsignert"
#: ../js/ui/components/telepathyClient.js:1319 #: ../js/ui/components/telepathyClient.js:1318
msgid "Status is set to offline" msgid "Status is set to offline"
msgstr "Status er satt til frakoblet" msgstr "Status er satt til frakoblet"
#: ../js/ui/components/telepathyClient.js:1321 #: ../js/ui/components/telepathyClient.js:1320
msgid "Encryption is not available" msgid "Encryption is not available"
msgstr "Kryptering er ikke tilgjengelig" msgstr "Kryptering er ikke tilgjengelig"
#: ../js/ui/components/telepathyClient.js:1323 #: ../js/ui/components/telepathyClient.js:1322
msgid "Certificate is invalid" msgid "Certificate is invalid"
msgstr "Sertifikatet er ugyldig" msgstr "Sertifikatet er ugyldig"
#: ../js/ui/components/telepathyClient.js:1325 #: ../js/ui/components/telepathyClient.js:1324
msgid "Connection has been refused" msgid "Connection has been refused"
msgstr "Tilkobling ble nektet" msgstr "Tilkobling ble nektet"
#: ../js/ui/components/telepathyClient.js:1327 #: ../js/ui/components/telepathyClient.js:1326
msgid "Connection can't be established" msgid "Connection can't be established"
msgstr "Tilkobling kan ikke etableres" msgstr "Tilkobling kan ikke etableres"
#: ../js/ui/components/telepathyClient.js:1329 #: ../js/ui/components/telepathyClient.js:1328
msgid "Connection has been lost" msgid "Connection has been lost"
msgstr "Tilkobling tapt" msgstr "Tilkobling tapt"
#: ../js/ui/components/telepathyClient.js:1331 #: ../js/ui/components/telepathyClient.js:1330
msgid "This account is already connected to the server" msgid "This account is already connected to the server"
msgstr "Denne kontoen er allerede koblet til tjeneren" msgstr "Denne kontoen er allerede koblet til tjeneren"
#: ../js/ui/components/telepathyClient.js:1333 #: ../js/ui/components/telepathyClient.js:1332
msgid "" msgid ""
"Connection has been replaced by a new connection using the same resource" "Connection has been replaced by a new connection using the same resource"
msgstr "" msgstr ""
"Tilkoblingen har blitt erstattet av en ny tilkobling som bruker samme ressurs" "Tilkoblingen har blitt erstattet av en ny tilkobling som bruker samme ressurs"
#: ../js/ui/components/telepathyClient.js:1335 #: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server" msgid "The account already exists on the server"
msgstr "Kontoen eksisterer allerede på tjeneren" msgstr "Kontoen eksisterer allerede på tjeneren"
#: ../js/ui/components/telepathyClient.js:1337 #: ../js/ui/components/telepathyClient.js:1336
msgid "Server is currently too busy to handle the connection" msgid "Server is currently too busy to handle the connection"
msgstr "Tjener er for opptatt til å håndtere tilkoblingen" msgstr "Tjener er for opptatt til å håndtere tilkoblingen"
#: ../js/ui/components/telepathyClient.js:1339 #: ../js/ui/components/telepathyClient.js:1338
msgid "Certificate has been revoked" msgid "Certificate has been revoked"
msgstr "Sertifikatet er tilbaketrukket" msgstr "Sertifikatet er tilbaketrukket"
#: ../js/ui/components/telepathyClient.js:1341 #: ../js/ui/components/telepathyClient.js:1340
msgid "" msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak" "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "" msgstr ""
"Sertifikatet bruker en usikker sifferalgoritme eller er krytografisk svakt" "Sertifikatet bruker en usikker sifferalgoritme eller er krytografisk svakt"
#: ../js/ui/components/telepathyClient.js:1343 #: ../js/ui/components/telepathyClient.js:1342
msgid "" msgid ""
"The length of the server certificate, or the depth of the server certificate " "The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library" "chain, exceed the limits imposed by the cryptography library"
@ -910,26 +846,26 @@ msgstr ""
"Lengden eller dybden på tjenersertifikatet oversteg grensen som er satt i " "Lengden eller dybden på tjenersertifikatet oversteg grensen som er satt i "
"kryptografibiblioteket" "kryptografibiblioteket"
#: ../js/ui/components/telepathyClient.js:1345 #: ../js/ui/components/telepathyClient.js:1344
msgid "Internal error" msgid "Internal error"
msgstr "Intern feil" msgstr "Intern feil"
#. translators: argument is the account name, like #. translators: argument is the account name, like
#. * name@jabber.org for example. #. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1355 #: ../js/ui/components/telepathyClient.js:1354
#, c-format #, c-format
msgid "Connection to %s failed" msgid "Connection to %s failed"
msgstr "Tilkobling til %s feilet" msgstr "Tilkobling til %s feilet"
#: ../js/ui/components/telepathyClient.js:1364 #: ../js/ui/components/telepathyClient.js:1363
msgid "Reconnect" msgid "Reconnect"
msgstr "Koble til på nytt" msgstr "Koble til på nytt"
#: ../js/ui/components/telepathyClient.js:1365 #: ../js/ui/components/telepathyClient.js:1364
msgid "Edit account" msgid "Edit account"
msgstr "Rediger konto" msgstr "Rediger konto"
#: ../js/ui/components/telepathyClient.js:1410 #: ../js/ui/components/telepathyClient.js:1409
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Ukjent årsak" msgstr "Ukjent årsak"
@ -948,7 +884,7 @@ msgstr "Åpne kalender"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:201 #: ../js/ui/dateMenu.js:190
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%a %e %B, %Y" msgstr "%a %e %B, %Y"
@ -1053,11 +989,11 @@ msgstr "Installer"
msgid "Download and install '%s' from extensions.gnome.org?" msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Last ned og installer «%s» fra extensions.gnome.org?" msgstr "Last ned og installer «%s» fra extensions.gnome.org?"
#: ../js/ui/keyboard.js:308 #: ../js/ui/keyboard.js:337
msgid "tray" msgid "tray"
msgstr "varslingsområde" msgstr "varslingsområde"
#: ../js/ui/keyboard.js:555 ../js/ui/status/keyboard.js:195 #: ../js/ui/keyboard.js:584 ../js/ui/status/keyboard.js:195
#: ../js/ui/status/power.js:205 #: ../js/ui/status/power.js:205
msgid "Keyboard" msgid "Keyboard"
msgstr "Tastatur" msgstr "Tastatur"
@ -1110,32 +1046,32 @@ msgstr "Vis kildekode"
msgid "Web Page" msgid "Web Page"
msgstr "Nettside" msgstr "Nettside"
#: ../js/ui/messageTray.js:1088 #: ../js/ui/messageTray.js:1081
msgid "Open" msgid "Open"
msgstr "Åpne" msgstr "Åpne"
#: ../js/ui/messageTray.js:1095 #: ../js/ui/messageTray.js:1088
msgid "Remove" msgid "Remove"
msgstr "Fjern" msgstr "Fjern"
#: ../js/ui/messageTray.js:1539 #: ../js/ui/messageTray.js:1540
msgid "Message Tray" msgid "Message Tray"
msgstr "Meldingstrau" msgstr "Meldingstrau"
#: ../js/ui/messageTray.js:2563 #: ../js/ui/messageTray.js:2547
msgid "System Information" msgid "System Information"
msgstr "Systeminformasjon" msgstr "Systeminformasjon"
#: ../js/ui/notificationDaemon.js:504 ../src/shell-app.c:374 #: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:373
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Ukjent" msgstr "Ukjent"
#: ../js/ui/overview.js:89 #: ../js/ui/overview.js:82
msgid "Undo" msgid "Undo"
msgstr "Angre" msgstr "Angre"
#: ../js/ui/overview.js:133 #: ../js/ui/overview.js:127
msgid "Overview" msgid "Overview"
msgstr "Oversikt" msgstr "Oversikt"
@ -1143,27 +1079,27 @@ msgstr "Oversikt"
#. in the search entry when no search is #. in the search entry when no search is
#. active; it should not exceed ~30 #. active; it should not exceed ~30
#. characters. #. characters.
#: ../js/ui/overview.js:207 #: ../js/ui/overview.js:201
msgid "Type to search..." msgid "Type to search..."
msgstr "Skriv for å søke …" msgstr "Skriv for å søke …"
#. Translators: this is the name of the dock/favorites area on #. Translators: this is the name of the dock/favorites area on
#. the left of the overview #. the left of the overview
#: ../js/ui/overview.js:228 #: ../js/ui/overview.js:222
msgid "Dash" msgid "Dash"
msgstr "Favoritter" msgstr "Favoritter"
#: ../js/ui/panel.js:581 #: ../js/ui/panel.js:567
msgid "Quit" msgid "Quit"
msgstr "Avslutt" msgstr "Avslutt"
#. Translators: If there is no suitable word for "Activities" #. Translators: If there is no suitable word for "Activities"
#. in your language, you can use the word for "Overview". #. in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:613 #: ../js/ui/panel.js:599
msgid "Activities" msgid "Activities"
msgstr "Aktiviteter" msgstr "Aktiviteter"
#: ../js/ui/panel.js:980 #: ../js/ui/panel.js:965
msgid "Top Bar" msgid "Top Bar"
msgstr "Topp-panel" msgstr "Topp-panel"
@ -1177,27 +1113,23 @@ msgid "toggle-switch-us"
msgstr "toggle-switch-intl" msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:205 #: ../js/ui/runDialog.js:205
msgid "Enter a Command" msgid "Please enter a command:"
msgstr "Oppgi en kommando" msgstr "Oppgi en kommando:"
#: ../js/ui/runDialog.js:241
msgid "Close"
msgstr "Lukk"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:80 #: ../js/ui/screenShield.js:79
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%A, %B %d" msgstr "%A, %B %d"
#: ../js/ui/screenShield.js:144 #: ../js/ui/screenShield.js:143
#, c-format #, c-format
msgid "%d new message" msgid "%d new message"
msgid_plural "%d new messages" msgid_plural "%d new messages"
msgstr[0] "%d ny melding" msgstr[0] "%d ny melding"
msgstr[1] "%d nye meldinger" msgstr[1] "%d nye meldinger"
#: ../js/ui/screenShield.js:146 #: ../js/ui/screenShield.js:145
#, c-format #, c-format
msgid "%d new notification" msgid "%d new notification"
msgid_plural "%d new notifications" msgid_plural "%d new notifications"
@ -1236,7 +1168,7 @@ msgstr "Passord"
msgid "Remember Password" msgid "Remember Password"
msgstr "Husk passord" msgstr "Husk passord"
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:174 #: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:169
msgid "Unlock" msgid "Unlock"
msgstr "Lås opp" msgstr "Lås opp"
@ -1291,7 +1223,7 @@ msgstr "Stor tekst"
#: ../js/ui/status/bluetooth.js:27 ../js/ui/status/bluetooth.js:31 #: ../js/ui/status/bluetooth.js:27 ../js/ui/status/bluetooth.js:31
#: ../js/ui/status/bluetooth.js:251 ../js/ui/status/bluetooth.js:304 #: ../js/ui/status/bluetooth.js:251 ../js/ui/status/bluetooth.js:304
#: ../js/ui/status/bluetooth.js:335 ../js/ui/status/bluetooth.js:371 #: ../js/ui/status/bluetooth.js:335 ../js/ui/status/bluetooth.js:371
#: ../js/ui/status/bluetooth.js:400 ../js/ui/status/network.js:873 #: ../js/ui/status/bluetooth.js:400 ../js/ui/status/network.js:867
msgid "Bluetooth" msgid "Bluetooth"
msgstr "Bluetooth" msgstr "Bluetooth"
@ -1320,12 +1252,12 @@ msgstr "maskinvare slått av"
msgid "Connection" msgid "Connection"
msgstr "Tilkobling" msgstr "Tilkobling"
#: ../js/ui/status/bluetooth.js:207 ../js/ui/status/network.js:475 #: ../js/ui/status/bluetooth.js:207 ../js/ui/status/network.js:458
msgid "disconnecting..." msgid "disconnecting..."
msgstr "kobler fra …" msgstr "kobler fra …"
#: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:481 #: ../js/ui/status/bluetooth.js:220 ../js/ui/status/network.js:464
#: ../js/ui/status/network.js:1507 #: ../js/ui/status/network.js:934
msgid "connecting..." msgid "connecting..."
msgstr "kobler til …" msgstr "kobler til …"
@ -1435,106 +1367,109 @@ msgstr "slått av"
#. Translators: this is for network devices that are physically present but are not #. Translators: this is for network devices that are physically present but are not
#. under NetworkManager's control (and thus cannot be used in the menu) #. under NetworkManager's control (and thus cannot be used in the menu)
#: ../js/ui/status/network.js:473 #: ../js/ui/status/network.js:456
msgid "unmanaged" msgid "unmanaged"
msgstr "ikke håndtert" msgstr "ikke håndtert"
#. Translators: this is for network connections that require some kind of key or password #. Translators: this is for network connections that require some kind of key or password
#: ../js/ui/status/network.js:484 ../js/ui/status/network.js:1510 #: ../js/ui/status/network.js:467 ../js/ui/status/network.js:937
msgid "authentication required" msgid "authentication required"
msgstr "autentisering kreves" msgstr "autentisering kreves"
#. Translators: this is for devices that require some kind of firmware or kernel #. Translators: this is for devices that require some kind of firmware or kernel
#. module, which is missing #. module, which is missing
#: ../js/ui/status/network.js:494 #: ../js/ui/status/network.js:477
msgid "firmware missing" msgid "firmware missing"
msgstr "fastvare mangler" msgstr "fastvare mangler"
#. Translators: this is for wired network devices that are physically disconnected #. Translators: this is for wired network devices that are physically disconnected
#: ../js/ui/status/network.js:501 #: ../js/ui/status/network.js:484
msgid "cable unplugged" msgid "cable unplugged"
msgstr "kabel koblet fra" msgstr "kabel koblet fra"
#. Translators: this is for a network device that cannot be activated (for example it #. Translators: this is for a network device that cannot be activated (for example it
#. is disabled by rfkill, or it has no coverage #. is disabled by rfkill, or it has no coverage
#: ../js/ui/status/network.js:506 #: ../js/ui/status/network.js:489
msgid "unavailable" msgid "unavailable"
msgstr "ikke tilgjengelig" msgstr "ikke tilgjengelig"
#: ../js/ui/status/network.js:508 ../js/ui/status/network.js:1512 #: ../js/ui/status/network.js:491 ../js/ui/status/network.js:939
msgid "connection failed" msgid "connection failed"
msgstr "tilkobling feilet" msgstr "tilkobling feilet"
#: ../js/ui/status/network.js:560 ../js/ui/status/network.js:1446 #: ../js/ui/status/network.js:552 ../js/ui/status/network.js:1529
#: ../js/ui/status/network.js:1588
msgid "More..." msgid "More..."
msgstr "Mer …" msgstr "Mer …"
#. TRANSLATORS: this is the indication that a connection for another logged in user is active, #. TRANSLATORS: this is the indication that a connection for another logged in user is active,
#. and we cannot access its settings (including the name) #. and we cannot access its settings (including the name)
#: ../js/ui/status/network.js:596 ../js/ui/status/network.js:1376 #: ../js/ui/status/network.js:588 ../js/ui/status/network.js:1459
msgid "Connected (private)" msgid "Connected (private)"
msgstr "Tilkoblet (privat)" msgstr "Tilkoblet (privat)"
#: ../js/ui/status/network.js:669 #: ../js/ui/status/network.js:663
msgid "Auto Ethernet" msgid "Auto Ethernet"
msgstr "Automatisk Ethernet" msgstr "Automatisk Ethernet"
#: ../js/ui/status/network.js:727 #: ../js/ui/status/network.js:721
msgid "Auto broadband" msgid "Auto broadband"
msgstr "Automatisk bredbånd" msgstr "Automatisk bredbånd"
#: ../js/ui/status/network.js:730 #: ../js/ui/status/network.js:724
msgid "Auto dial-up" msgid "Auto dial-up"
msgstr "Automatisk oppringt" msgstr "Automatisk oppringt"
#. TRANSLATORS: this the automatic wireless connection name (including the network name) #. TRANSLATORS: this the automatic wireless connection name (including the network name)
#: ../js/ui/status/network.js:859 ../js/ui/status/network.js:1393 #: ../js/ui/status/network.js:853 ../js/ui/status/network.js:1476
#, c-format #, c-format
msgid "Auto %s" msgid "Auto %s"
msgstr "Automatisk %s" msgstr "Automatisk %s"
#: ../js/ui/status/network.js:861 #: ../js/ui/status/network.js:855
msgid "Auto bluetooth" msgid "Auto bluetooth"
msgstr "Automatisk Bluetooth" msgstr "Automatisk Bluetooth"
#: ../js/ui/status/network.js:1395 #: ../js/ui/status/network.js:1478
msgid "Auto wireless" msgid "Auto wireless"
msgstr "Automatisk trådløst" msgstr "Automatisk trådløst"
#: ../js/ui/status/network.js:1637 #: ../js/ui/status/network.js:1575
msgid "Enable networking" msgid "Enable networking"
msgstr "Slå på nettverk" msgstr "Slå på nettverk"
#: ../js/ui/status/network.js:1659 #: ../js/ui/status/network.js:1597
msgid "Wired" msgid "Wired"
msgstr "Kablet" msgstr "Kablet"
#: ../js/ui/status/network.js:1670 #: ../js/ui/status/network.js:1608
msgid "Wireless" msgid "Wireless"
msgstr "Trådløst" msgstr "Trådløst"
#: ../js/ui/status/network.js:1680 #: ../js/ui/status/network.js:1618
msgid "Mobile broadband" msgid "Mobile broadband"
msgstr "Mobilt bredbånd" msgstr "Mobilt bredbånd"
#: ../js/ui/status/network.js:1691 #: ../js/ui/status/network.js:1628
msgid "VPN Connections"
msgstr "VPN-tilkoblinger"
#: ../js/ui/status/network.js:1635
msgid "Network Settings" msgid "Network Settings"
msgstr "Innstillinger for nettverk" msgstr "Innstillinger for nettverk"
#: ../js/ui/status/network.js:1735 #: ../js/ui/status/network.js:1679
msgid "Network Manager" msgid "Network Manager"
msgstr "Nettverkshåndtering" msgstr "Nettverkshåndtering"
#: ../js/ui/status/network.js:1809 #: ../js/ui/status/network.js:1769
msgid "Connection failed" msgid "Connection failed"
msgstr "Tilkobling feilet" msgstr "Tilkobling feilet"
#: ../js/ui/status/network.js:1810 #: ../js/ui/status/network.js:1770
msgid "Activation of network connection failed" msgid "Activation of network connection failed"
msgstr "Aktivering av nettverkstilkobling feilet" msgstr "Aktivering av nettverkstilkobling feilet"
#: ../js/ui/status/network.js:2108 #: ../js/ui/status/network.js:2065
msgid "Networking is disabled" msgid "Networking is disabled"
msgstr "Nettverk er slått av" msgstr "Nettverk er slått av"
@ -1644,63 +1579,63 @@ msgstr "Volum"
msgid "Microphone" msgid "Microphone"
msgstr "Mikrofon" msgstr "Mikrofon"
#: ../js/ui/unlockDialog.js:181 #: ../js/ui/unlockDialog.js:176
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Logg inn som en annen bruker" msgstr "Logg inn som en annen bruker"
#: ../js/ui/userMenu.js:176 #: ../js/ui/userMenu.js:180
msgid "Available" msgid "Available"
msgstr "Tilgjengelig" msgstr "Tilgjengelig"
#: ../js/ui/userMenu.js:179 #: ../js/ui/userMenu.js:183
msgid "Busy" msgid "Busy"
msgstr "Opptatt" msgstr "Opptatt"
#: ../js/ui/userMenu.js:182 #: ../js/ui/userMenu.js:186
msgid "Invisible" msgid "Invisible"
msgstr "Usynlig" msgstr "Usynlig"
#: ../js/ui/userMenu.js:185 #: ../js/ui/userMenu.js:189
msgid "Away" msgid "Away"
msgstr "Borte" msgstr "Borte"
#: ../js/ui/userMenu.js:188 #: ../js/ui/userMenu.js:192
msgid "Idle" msgid "Idle"
msgstr "Ledig" msgstr "Ledig"
#: ../js/ui/userMenu.js:191 #: ../js/ui/userMenu.js:195
msgid "Offline" msgid "Unavailable"
msgstr "Frakoblet" msgstr "Ikke tilgjengelig"
#: ../js/ui/userMenu.js:747 #: ../js/ui/userMenu.js:740
msgid "Notifications" msgid "Notifications"
msgstr "Varslinger" msgstr "Varslinger"
#: ../js/ui/userMenu.js:755 #: ../js/ui/userMenu.js:748
msgid "System Settings" msgid "System Settings"
msgstr "Systeminnstillinger" msgstr "Systeminnstillinger"
#: ../js/ui/userMenu.js:763 #: ../js/ui/userMenu.js:756
msgid "Switch User" msgid "Switch User"
msgstr "Bytt bruker" msgstr "Bytt bruker"
#: ../js/ui/userMenu.js:768 #: ../js/ui/userMenu.js:761
msgid "Log Out" msgid "Log Out"
msgstr "Logg ut" msgstr "Logg ut"
#: ../js/ui/userMenu.js:773 #: ../js/ui/userMenu.js:766
msgid "Lock" msgid "Lock"
msgstr "Lås" msgstr "Lås"
#: ../js/ui/userMenu.js:788 #: ../js/ui/userMenu.js:781
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Installer oppdateringer og start på nytt" msgstr "Installer oppdateringer og start på nytt"
#: ../js/ui/userMenu.js:806 #: ../js/ui/userMenu.js:799
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Din pratestatus vil bli satt til opptatt" msgstr "Din pratestatus vil bli satt til opptatt"
#: ../js/ui/userMenu.js:807 #: ../js/ui/userMenu.js:800
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1709,15 +1644,15 @@ msgstr ""
"tilkoblingsstatus er justert for å la andre vite at du kanskje ikke ser " "tilkoblingsstatus er justert for å la andre vite at du kanskje ikke ser "
"deres meldinger." "deres meldinger."
#: ../js/ui/viewSelector.js:87 #: ../js/ui/viewSelector.js:85
msgid "Windows" msgid "Windows"
msgstr "Vinduer" msgstr "Vinduer"
#: ../js/ui/viewSelector.js:91 #: ../js/ui/viewSelector.js:89
msgid "Applications" msgid "Applications"
msgstr "Programmer" msgstr "Programmer"
#: ../js/ui/viewSelector.js:95 #: ../js/ui/viewSelector.js:93
msgid "Search" msgid "Search"
msgstr "Søk" msgstr "Søk"
@ -1786,7 +1721,7 @@ msgstr "Bruk spesifikt modus, f.eks «gdm» for innloggingsskjerm"
msgid "List possible modes" msgid "List possible modes"
msgstr "Vis mulige modi" msgstr "Vis mulige modi"
#: ../src/shell-app.c:622 #: ../src/shell-app.c:621
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "Klarte ikke å starte «%s»" msgstr "Klarte ikke å starte «%s»"

262
po/ru.po
View File

@ -15,8 +15,8 @@ msgstr ""
"Project-Id-Version: gnome-shell\n" "Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n" "shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-10-31 16:48+0000\n" "POT-Creation-Date: 2012-09-25 00:06+0000\n"
"PO-Revision-Date: 2012-11-04 20:48+0400\n" "PO-Revision-Date: 2012-09-27 16:38+0400\n"
"Last-Translator: Yuri Myasoedov <omerta13@yandex.ru>\n" "Last-Translator: Yuri Myasoedov <omerta13@yandex.ru>\n"
"Language-Team: русский <gnome-cyr@gnome.org>\n" "Language-Team: русский <gnome-cyr@gnome.org>\n"
"Language: ru\n" "Language: ru\n"
@ -141,63 +141,51 @@ msgstr ""
"Данное значение берётся из перечисления GsmPresenceStatus." "Данное значение берётся из перечисления GsmPresenceStatus."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13 #: ../data/org.gnome.shell.gschema.xml.in.in.h:13
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Всегда показывать в меню пункт «Завершить сеанс»."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
"Этот ключ переопределяет автоматическое скрытие пункта «Завершить сеанс» при "
"использовании одиночного сеанса."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Show the week date in the calendar" msgid "Show the week date in the calendar"
msgstr "Показывать в часах дату недели" msgstr "Показывать в часах дату недели"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16 #: ../data/org.gnome.shell.gschema.xml.in.in.h:14
msgid "If true, display the ISO week date in the calendar." msgid "If true, display the ISO week date in the calendar."
msgstr "Если установлено, календарь будет показывать неделю в формате ISO." msgstr "Если установлено, календарь будет показывать неделю в формате ISO."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17 #: ../data/org.gnome.shell.gschema.xml.in.in.h:15
msgid "Keybinding to open the application menu" msgid "Keybinding to open the application menu"
msgstr "Комбинация клавиш для открытия меню приложения" msgstr "Комбинация клавиш для открытия меню приложения"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18 #: ../data/org.gnome.shell.gschema.xml.in.in.h:16
msgid "Keybinding to open the application menu." msgid "Keybinding to open the application menu."
msgstr "Комбинация клавиш для открытия меню приложения." msgstr "Комбинация клавиш для открытия меню приложения."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19 #: ../data/org.gnome.shell.gschema.xml.in.in.h:17
msgid "Keybinding to toggle the visibility of the message tray" msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Комбинация клавиш для переключения видимости панели сообщений" msgstr "Комбинация клавиш для переключения видимости панели сообщений"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20 #: ../data/org.gnome.shell.gschema.xml.in.in.h:18
msgid "Keybinding to toggle the visibility of the message tray." msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Комбинация клавиш для переключения видимости панели сообщений." msgstr "Комбинация клавиш для переключения видимости панели сообщений."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21 #: ../data/org.gnome.shell.gschema.xml.in.in.h:19
msgid "Keybinding to toggle the screen recorder" msgid "Keybinding to toggle the screen recorder"
msgstr "Комбинация клавиш для переключения записи экрана" msgstr "Комбинация клавиш для переключения записи экрана"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22 #: ../data/org.gnome.shell.gschema.xml.in.in.h:20
msgid "Keybinding to start/stop the builtin screen recorder." msgid "Keybinding to start/stop the builtin screen recorder."
msgstr "" msgstr ""
"Комбинация клавиш для запуска/остановки встроенного средства записи экрана." "Комбинация клавиш для запуска/остановки встроенного средства записи экрана."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23 #: ../data/org.gnome.shell.gschema.xml.in.in.h:21
msgid "Which keyboard to use" msgid "Which keyboard to use"
msgstr "Какую клавиатуру использовать" msgstr "Какую клавиатуру использовать"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24 #: ../data/org.gnome.shell.gschema.xml.in.in.h:22
msgid "The type of keyboard to use." msgid "The type of keyboard to use."
msgstr "Тип используемой клавиатуры." msgstr "Тип используемой клавиатуры."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25 #: ../data/org.gnome.shell.gschema.xml.in.in.h:23
msgid "Framerate used for recording screencasts." msgid "Framerate used for recording screencasts."
msgstr "Частота смены кадров для записи скринкастов." msgstr "Частота смены кадров для записи скринкастов."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26 #: ../data/org.gnome.shell.gschema.xml.in.in.h:24
msgid "" msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's " "The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second." "screencast recorder in frames-per-second."
@ -205,11 +193,11 @@ msgstr ""
"Частота смены кадров в скринкасте, записанном с помощью GNOME Shell (кадров/" "Частота смены кадров в скринкасте, записанном с помощью GNOME Shell (кадров/"
"сек)." "сек)."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27 #: ../data/org.gnome.shell.gschema.xml.in.in.h:25
msgid "The gstreamer pipeline used to encode the screencast" msgid "The gstreamer pipeline used to encode the screencast"
msgstr "Конвейер gstreamer, используемый для кодирования скринкастов" msgstr "Конвейер gstreamer, используемый для кодирования скринкастов"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29 #: ../data/org.gnome.shell.gschema.xml.in.in.h:27
#, no-c-format #, no-c-format
msgid "" msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax " "Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
@ -236,11 +224,11 @@ msgstr ""
"используется как заполнитель для определения оптимального количества потоков " "используется как заполнитель для определения оптимального количества потоков "
"в системе." "в системе."
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30 #: ../data/org.gnome.shell.gschema.xml.in.in.h:28
msgid "File extension used for storing the screencast" msgid "File extension used for storing the screencast"
msgstr "Расширение файла, использующееся для хранения скринкастов" msgstr "Расширение файла, использующееся для хранения скринкастов"
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31 #: ../data/org.gnome.shell.gschema.xml.in.in.h:29
msgid "" msgid ""
"The filename for recorded screencasts will be a unique filename based on the " "The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to " "current date, and use this extension. It should be changed when recording to "
@ -263,11 +251,11 @@ msgstr "Расширение"
msgid "Select an extension to configure using the combobox above." msgid "Select an extension to configure using the combobox above."
msgstr "Выберите расширение из выпадающего списка." msgstr "Выберите расширение из выпадающего списка."
#: ../js/gdm/loginDialog.js:529 #: ../js/gdm/loginDialog.js:527
msgid "Session..." msgid "Session..."
msgstr "Сеанс…" msgstr "Сеанс…"
#: ../js/gdm/loginDialog.js:677 #: ../js/gdm/loginDialog.js:675
msgctxt "title" msgctxt "title"
msgid "Sign In" msgid "Sign In"
msgstr "Вход в систему" msgstr "Вход в систему"
@ -275,33 +263,34 @@ msgstr "Вход в систему"
#. translators: this message is shown below the user list on the #. translators: this message is shown below the user list on the
#. login screen. It can be activated to reveal an entry for #. login screen. It can be activated to reveal an entry for
#. manually entering the username. #. manually entering the username.
#: ../js/gdm/loginDialog.js:736 #: ../js/gdm/loginDialog.js:742
msgid "Not listed?" msgid "Not listed?"
msgstr "Нет в списке?" msgstr "Нет в списке?"
#: ../js/gdm/loginDialog.js:889 ../js/ui/components/networkAgent.js:137 #: ../js/gdm/loginDialog.js:895 ../js/ui/components/networkAgent.js:137
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373 #: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:373
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396 #: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:396
#: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:167 #: ../js/ui/status/bluetooth.js:427 ../js/ui/unlockDialog.js:166
msgid "Cancel" msgid "Cancel"
msgstr "Отмена" msgstr "Отмена"
#: ../js/gdm/loginDialog.js:894 #: ../js/gdm/loginDialog.js:900
msgctxt "button" msgctxt "button"
msgid "Sign In" msgid "Sign In"
msgstr "Войти" msgstr "Войти"
#: ../js/gdm/loginDialog.js:1215 #: ../js/gdm/loginDialog.js:1239
msgid "Login Window" msgid "Login Window"
msgstr "Окно входа в систему" msgstr "Окно входа в систему"
#. Translators: accessible name of the power menu in the login screen #. Translators: accessible name of the power menu in the login screen
#: ../js/gdm/powerMenu.js:35 #: ../js/gdm/powerMenu.js:35
#| msgid "Power Off"
msgid "Power" msgid "Power"
msgstr "Питание" msgstr "Питание"
#: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:664 ../js/ui/userMenu.js:668 #: ../js/gdm/powerMenu.js:89 ../js/ui/userMenu.js:663 ../js/ui/userMenu.js:667
#: ../js/ui/userMenu.js:779 #: ../js/ui/userMenu.js:778
msgid "Suspend" msgid "Suspend"
msgstr "Ждущий режим" msgstr "Ждущий режим"
@ -309,8 +298,8 @@ msgstr "Ждущий режим"
msgid "Restart" msgid "Restart"
msgstr "Перезапустить" msgstr "Перезапустить"
#: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:666 ../js/ui/userMenu.js:668 #: ../js/gdm/powerMenu.js:99 ../js/ui/userMenu.js:665 ../js/ui/userMenu.js:667
#: ../js/ui/userMenu.js:778 #: ../js/ui/userMenu.js:777
msgid "Power Off" msgid "Power Off"
msgstr "Выключить" msgstr "Выключить"
@ -361,7 +350,7 @@ msgstr "НАСТРОЙКИ"
msgid "New Window" msgid "New Window"
msgstr "Новое окно" msgstr "Новое окно"
#: ../js/ui/appDisplay.js:678 ../js/ui/dash.js:290 #: ../js/ui/appDisplay.js:678 ../js/ui/dash.js:271
msgid "Remove from Favorites" msgid "Remove from Favorites"
msgstr "Удалить из избранного" msgstr "Удалить из избранного"
@ -525,16 +514,16 @@ msgstr "Эта неделя"
msgid "Next week" msgid "Next week"
msgstr "Следующая неделя" msgstr "Следующая неделя"
#: ../js/ui/components/autorunManager.js:297 #: ../js/ui/components/autorunManager.js:278
msgid "Removable Devices" msgid "Removable Devices"
msgstr "Cъёмные устройства" msgstr "Cъёмные устройства"
#: ../js/ui/components/autorunManager.js:594 #: ../js/ui/components/autorunManager.js:575
#, c-format #, c-format
msgid "Open with %s" msgid "Open with %s"
msgstr "Открыть с помощью %s" msgstr "Открыть с помощью %s"
#: ../js/ui/components/autorunManager.js:620 #: ../js/ui/components/autorunManager.js:601
msgid "Eject" msgid "Eject"
msgstr "Извлечь" msgstr "Извлечь"
@ -690,35 +679,35 @@ msgstr "Приглушить звук"
#. Translators: this is a time format string followed by a date. #. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your #. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds. #. locale, without seconds.
#: ../js/ui/components/telepathyClient.js:950 #: ../js/ui/components/telepathyClient.js:948
#, no-c-format #, no-c-format
msgid "Sent at <b>%X</b> on <b>%A</b>" msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Отправлено в <b>%X</b> в <b>%A</b>" msgstr "Отправлено в <b>%X</b> в <b>%A</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25", #. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year. #. shown when you get a chat message in the same year.
#: ../js/ui/components/telepathyClient.js:956 #: ../js/ui/components/telepathyClient.js:954
#, no-c-format #, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>" msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Отправлено в <b>%A</b>, <b>%B %d</b>" msgstr "Отправлено в <b>%A</b>, <b>%B %d</b>"
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012", #. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year. #. shown when you get a chat message in a different year.
#: ../js/ui/components/telepathyClient.js:961 #: ../js/ui/components/telepathyClient.js:959
#, no-c-format #, no-c-format
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y" msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Отправлено в <b>%A</b>, <b>%B %d</b>, %Y" msgstr "Отправлено в <b>%A</b>, <b>%B %d</b>, %Y"
#. Translators: this is the other person changing their old IM name to their new #. Translators: this is the other person changing their old IM name to their new
#. IM name. #. IM name.
#: ../js/ui/components/telepathyClient.js:990 #: ../js/ui/components/telepathyClient.js:988
#, c-format #, c-format
msgid "%s is now known as %s" msgid "%s is now known as %s"
msgstr "%s теперь известен как %s" msgstr "%s теперь известен как %s"
#. translators: argument is a room name like #. translators: argument is a room name like
#. * room@jabber.org for example. #. * room@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1090 #: ../js/ui/components/telepathyClient.js:1088
#, c-format #, c-format
msgid "Invitation to %s" msgid "Invitation to %s"
msgstr "Приглашение в %s" msgstr "Приглашение в %s"
@ -726,42 +715,42 @@ msgstr "Приглашение в %s"
#. translators: first argument is the name of a contact and the second #. translators: first argument is the name of a contact and the second
#. * one the name of a room. "Alice is inviting you to join room@jabber.org #. * one the name of a room. "Alice is inviting you to join room@jabber.org
#. * for example. #. * for example.
#: ../js/ui/components/telepathyClient.js:1098 #: ../js/ui/components/telepathyClient.js:1096
#, c-format #, c-format
msgid "%s is inviting you to join %s" msgid "%s is inviting you to join %s"
msgstr "%s приглашает вас присоединиться к %s" msgstr "%s приглашает вас присоединиться к %s"
#: ../js/ui/components/telepathyClient.js:1100 #: ../js/ui/components/telepathyClient.js:1098
#: ../js/ui/components/telepathyClient.js:1179 #: ../js/ui/components/telepathyClient.js:1177
#: ../js/ui/components/telepathyClient.js:1242 #: ../js/ui/components/telepathyClient.js:1240
msgid "Decline" msgid "Decline"
msgstr "Отказаться" msgstr "Отказаться"
#: ../js/ui/components/telepathyClient.js:1101 #: ../js/ui/components/telepathyClient.js:1099
#: ../js/ui/components/telepathyClient.js:1180 #: ../js/ui/components/telepathyClient.js:1178
#: ../js/ui/components/telepathyClient.js:1243 #: ../js/ui/components/telepathyClient.js:1241
msgid "Accept" msgid "Accept"
msgstr "Принять" msgstr "Принять"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1131 #: ../js/ui/components/telepathyClient.js:1129
#, c-format #, c-format
msgid "Video call from %s" msgid "Video call from %s"
msgstr "Вас вызывает %s по видео" msgstr "Вас вызывает %s по видео"
#. translators: argument is a contact name like Alice for example. #. translators: argument is a contact name like Alice for example.
#: ../js/ui/components/telepathyClient.js:1134 #: ../js/ui/components/telepathyClient.js:1132
#, c-format #, c-format
msgid "Call from %s" msgid "Call from %s"
msgstr "Вас вызывает %s" msgstr "Вас вызывает %s"
#: ../js/ui/components/telepathyClient.js:1139 #: ../js/ui/components/telepathyClient.js:1137
#: ../js/ui/status/bluetooth.js:346 #: ../js/ui/status/bluetooth.js:346
msgid "Reject" msgid "Reject"
msgstr "Отклонить" msgstr "Отклонить"
#. translators: this is a button label (verb), not a noun #. translators: this is a button label (verb), not a noun
#: ../js/ui/components/telepathyClient.js:1141 #: ../js/ui/components/telepathyClient.js:1139
msgid "Answer" msgid "Answer"
msgstr "Ответить" msgstr "Ответить"
@ -770,111 +759,111 @@ msgstr "Ответить"
#. * file name. The string will be something #. * file name. The string will be something
#. * like: "Alice is sending you test.ogg" #. * like: "Alice is sending you test.ogg"
#. #.
#: ../js/ui/components/telepathyClient.js:1173 #: ../js/ui/components/telepathyClient.js:1171
#, c-format #, c-format
msgid "%s is sending you %s" msgid "%s is sending you %s"
msgstr "%s отправляет вам %s" msgstr "%s отправляет вам %s"
#. To translators: The parameter is the contact's alias #. To translators: The parameter is the contact's alias
#: ../js/ui/components/telepathyClient.js:1208 #: ../js/ui/components/telepathyClient.js:1206
#, c-format #, c-format
msgid "%s would like permission to see when you are online" msgid "%s would like permission to see when you are online"
msgstr "%s хотел бы получить разрешение видеть, когда вы в сети" msgstr "%s хотел бы получить разрешение видеть, когда вы в сети"
#: ../js/ui/components/telepathyClient.js:1300 #: ../js/ui/components/telepathyClient.js:1298
msgid "Network error" msgid "Network error"
msgstr "Ошибка сети" msgstr "Ошибка сети"
#: ../js/ui/components/telepathyClient.js:1302 #: ../js/ui/components/telepathyClient.js:1300
msgid "Authentication failed" msgid "Authentication failed"
msgstr "Ошибка аутентификации" msgstr "Ошибка аутентификации"
#: ../js/ui/components/telepathyClient.js:1304 #: ../js/ui/components/telepathyClient.js:1302
msgid "Encryption error" msgid "Encryption error"
msgstr "Ошибка шифрования" msgstr "Ошибка шифрования"
#: ../js/ui/components/telepathyClient.js:1306 #: ../js/ui/components/telepathyClient.js:1304
msgid "Certificate not provided" msgid "Certificate not provided"
msgstr "Сертификат не предоставляется" msgstr "Сертификат не предоставляется"
#: ../js/ui/components/telepathyClient.js:1308 #: ../js/ui/components/telepathyClient.js:1306
msgid "Certificate untrusted" msgid "Certificate untrusted"
msgstr "Недоверенный сертификат" msgstr "Недоверенный сертификат"
#: ../js/ui/components/telepathyClient.js:1310 #: ../js/ui/components/telepathyClient.js:1308
msgid "Certificate expired" msgid "Certificate expired"
msgstr "Срок действия сертификата истёк" msgstr "Срок действия сертификата истёк"
#: ../js/ui/components/telepathyClient.js:1312 #: ../js/ui/components/telepathyClient.js:1310
msgid "Certificate not activated" msgid "Certificate not activated"
msgstr "Сертификат не активирован" msgstr "Сертификат не активирован"
#: ../js/ui/components/telepathyClient.js:1314 #: ../js/ui/components/telepathyClient.js:1312
msgid "Certificate hostname mismatch" msgid "Certificate hostname mismatch"
msgstr "Имя узла сертификата не совпадает" msgstr "Имя узла сертификата не совпадает"
#: ../js/ui/components/telepathyClient.js:1316 #: ../js/ui/components/telepathyClient.js:1314
msgid "Certificate fingerprint mismatch" msgid "Certificate fingerprint mismatch"
msgstr "Отпечаток сертификата не совпадает" msgstr "Отпечаток сертификата не совпадает"
#: ../js/ui/components/telepathyClient.js:1318 #: ../js/ui/components/telepathyClient.js:1316
msgid "Certificate self-signed" msgid "Certificate self-signed"
msgstr "Самоподписанный сертификат" msgstr "Самоподписанный сертификат"
#: ../js/ui/components/telepathyClient.js:1320 #: ../js/ui/components/telepathyClient.js:1318
msgid "Status is set to offline" msgid "Status is set to offline"
msgstr "Установлен статус «не в сети»" msgstr "Установлен статус «не в сети»"
#: ../js/ui/components/telepathyClient.js:1322 #: ../js/ui/components/telepathyClient.js:1320
msgid "Encryption is not available" msgid "Encryption is not available"
msgstr "Шифрование недоступно" msgstr "Шифрование недоступно"
#: ../js/ui/components/telepathyClient.js:1324 #: ../js/ui/components/telepathyClient.js:1322
msgid "Certificate is invalid" msgid "Certificate is invalid"
msgstr "Недействительный сертификат" msgstr "Недействительный сертификат"
#: ../js/ui/components/telepathyClient.js:1326 #: ../js/ui/components/telepathyClient.js:1324
msgid "Connection has been refused" msgid "Connection has been refused"
msgstr "В соединении отказано" msgstr "В соединении отказано"
#: ../js/ui/components/telepathyClient.js:1328 #: ../js/ui/components/telepathyClient.js:1326
msgid "Connection can't be established" msgid "Connection can't be established"
msgstr "Соединение не может быть установлено" msgstr "Соединение не может быть установлено"
#: ../js/ui/components/telepathyClient.js:1330 #: ../js/ui/components/telepathyClient.js:1328
msgid "Connection has been lost" msgid "Connection has been lost"
msgstr "Соединение потеряно" msgstr "Соединение потеряно"
#: ../js/ui/components/telepathyClient.js:1332 #: ../js/ui/components/telepathyClient.js:1330
msgid "This account is already connected to the server" msgid "This account is already connected to the server"
msgstr "Эта учётная запись уже подключена к серверу" msgstr "Эта учётная запись уже подключена к серверу"
#: ../js/ui/components/telepathyClient.js:1334 #: ../js/ui/components/telepathyClient.js:1332
msgid "" msgid ""
"Connection has been replaced by a new connection using the same resource" "Connection has been replaced by a new connection using the same resource"
msgstr "Соединение было заменено новым, используя тот же источник" msgstr "Соединение было заменено новым, используя тот же источник"
#: ../js/ui/components/telepathyClient.js:1336 #: ../js/ui/components/telepathyClient.js:1334
msgid "The account already exists on the server" msgid "The account already exists on the server"
msgstr "Учётная запись уже существует на сервере" msgstr "Учётная запись уже существует на сервере"
#: ../js/ui/components/telepathyClient.js:1338 #: ../js/ui/components/telepathyClient.js:1336
msgid "Server is currently too busy to handle the connection" msgid "Server is currently too busy to handle the connection"
msgstr "" msgstr ""
"Сервер в настоящее время сильно перегружен, чтобы обработать соединение" "Сервер в настоящее время сильно перегружен, чтобы обработать соединение"
#: ../js/ui/components/telepathyClient.js:1340 #: ../js/ui/components/telepathyClient.js:1338
msgid "Certificate has been revoked" msgid "Certificate has been revoked"
msgstr "Сертификат аннулирован" msgstr "Сертификат аннулирован"
#: ../js/ui/components/telepathyClient.js:1342 #: ../js/ui/components/telepathyClient.js:1340
msgid "" msgid ""
"Certificate uses an insecure cipher algorithm or is cryptographically weak" "Certificate uses an insecure cipher algorithm or is cryptographically weak"
msgstr "" msgstr ""
"Сертификат использует небезопасный алгоритм шифрования или он " "Сертификат использует небезопасный алгоритм шифрования или он "
"криптографически нестоек" "криптографически нестоек"
#: ../js/ui/components/telepathyClient.js:1344 #: ../js/ui/components/telepathyClient.js:1342
msgid "" msgid ""
"The length of the server certificate, or the depth of the server certificate " "The length of the server certificate, or the depth of the server certificate "
"chain, exceed the limits imposed by the cryptography library" "chain, exceed the limits imposed by the cryptography library"
@ -882,30 +871,30 @@ msgstr ""
"Длина сертификата сервера, или глубина цепочки сертификатов сервера, " "Длина сертификата сервера, или глубина цепочки сертификатов сервера, "
"превышает пределы, установленные библиотекой криптографии" "превышает пределы, установленные библиотекой криптографии"
#: ../js/ui/components/telepathyClient.js:1346 #: ../js/ui/components/telepathyClient.js:1344
msgid "Internal error" msgid "Internal error"
msgstr "Внутренняя ошибка" msgstr "Внутренняя ошибка"
#. translators: argument is the account name, like #. translators: argument is the account name, like
#. * name@jabber.org for example. #. * name@jabber.org for example.
#: ../js/ui/components/telepathyClient.js:1356 #: ../js/ui/components/telepathyClient.js:1354
#, c-format #, c-format
msgid "Connection to %s failed" msgid "Connection to %s failed"
msgstr "Сбой подключения к %s" msgstr "Сбой подключения к %s"
#: ../js/ui/components/telepathyClient.js:1365 #: ../js/ui/components/telepathyClient.js:1363
msgid "Reconnect" msgid "Reconnect"
msgstr "Переподключиться" msgstr "Переподключиться"
#: ../js/ui/components/telepathyClient.js:1366 #: ../js/ui/components/telepathyClient.js:1364
msgid "Edit account" msgid "Edit account"
msgstr "Изменить учётную запись" msgstr "Изменить учётную запись"
#: ../js/ui/components/telepathyClient.js:1411 #: ../js/ui/components/telepathyClient.js:1409
msgid "Unknown reason" msgid "Unknown reason"
msgstr "Неизвестная причина" msgstr "Неизвестная причина"
#: ../js/ui/dash.js:253 ../js/ui/dash.js:292 #: ../js/ui/dash.js:245 ../js/ui/dash.js:273
msgid "Show Applications" msgid "Show Applications"
msgstr "Показать приложения" msgstr "Показать приложения"
@ -913,14 +902,14 @@ msgstr "Показать приложения"
msgid "Date and Time Settings" msgid "Date and Time Settings"
msgstr "Настроить дату и время" msgstr "Настроить дату и время"
#: ../js/ui/dateMenu.js:111 #: ../js/ui/dateMenu.js:109
msgid "Open Calendar" msgid "Open Calendar"
msgstr "Открыть календарь" msgstr "Открыть календарь"
#. Translators: This is the date format to use when the calendar popup is #. Translators: This is the date format to use when the calendar popup is
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM"). #. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
#. #.
#: ../js/ui/dateMenu.js:201 #: ../js/ui/dateMenu.js:175
msgid "%A %B %e, %Y" msgid "%A %B %e, %Y"
msgstr "%A, %e %B, %Y" msgstr "%A, %e %B, %Y"
@ -1030,11 +1019,11 @@ msgstr "Установить"
msgid "Download and install '%s' from extensions.gnome.org?" msgid "Download and install '%s' from extensions.gnome.org?"
msgstr "Загрузить и установить расширение «%s» с extensions.gnome.org?" msgstr "Загрузить и установить расширение «%s» с extensions.gnome.org?"
#: ../js/ui/keyboard.js:337 #: ../js/ui/keyboard.js:327
msgid "tray" msgid "tray"
msgstr "лоток" msgstr "лоток"
#: ../js/ui/keyboard.js:584 ../js/ui/status/keyboard.js:195 #: ../js/ui/keyboard.js:561 ../js/ui/status/keyboard.js:195
#: ../js/ui/status/power.js:205 #: ../js/ui/status/power.js:205
msgid "Keyboard" msgid "Keyboard"
msgstr "Клавиатура" msgstr "Клавиатура"
@ -1087,23 +1076,23 @@ msgstr "Показать код"
msgid "Web Page" msgid "Web Page"
msgstr "Веб-страница" msgstr "Веб-страница"
#: ../js/ui/messageTray.js:1084 #: ../js/ui/messageTray.js:1080
msgid "Open" msgid "Open"
msgstr "Открыть" msgstr "Открыть"
#: ../js/ui/messageTray.js:1091 #: ../js/ui/messageTray.js:1087
msgid "Remove" msgid "Remove"
msgstr "Удалить" msgstr "Удалить"
#: ../js/ui/messageTray.js:1543 #: ../js/ui/messageTray.js:2055
msgid "Message Tray" msgid "Message Tray"
msgstr "Панель сообщений" msgstr "Панель сообщений"
#: ../js/ui/messageTray.js:2549 #: ../js/ui/messageTray.js:2511
msgid "System Information" msgid "System Information"
msgstr "Системная информация" msgstr "Системная информация"
#: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:374 #: ../js/ui/notificationDaemon.js:506 ../src/shell-app.c:373
msgctxt "program" msgctxt "program"
msgid "Unknown" msgid "Unknown"
msgstr "Неизвестно" msgstr "Неизвестно"
@ -1159,7 +1148,7 @@ msgstr "Введите команду:"
#. Translators: This is a time format for a date in #. Translators: This is a time format for a date in
#. long format #. long format
#: ../js/ui/screenShield.js:80 #: ../js/ui/screenShield.js:79
msgid "%A, %B %d" msgid "%A, %B %d"
msgstr "%d %B, %A" msgstr "%d %B, %A"
@ -1211,7 +1200,7 @@ msgstr "Пароль"
msgid "Remember Password" msgid "Remember Password"
msgstr "Запомнить пароль" msgstr "Запомнить пароль"
#: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:170 #: ../js/ui/shellMountOperation.js:400 ../js/ui/unlockDialog.js:169
msgid "Unlock" msgid "Unlock"
msgstr "Разблокировать" msgstr "Разблокировать"
@ -1329,7 +1318,7 @@ msgstr "Настроить клавиатуру"
msgid "Mouse Settings" msgid "Mouse Settings"
msgstr "Настроить мышь" msgstr "Настроить мышь"
#: ../js/ui/status/bluetooth.js:269 ../js/ui/status/volume.js:234 #: ../js/ui/status/bluetooth.js:269 ../js/ui/status/volume.js:236
msgid "Sound Settings" msgid "Sound Settings"
msgstr "Настроить звук" msgstr "Настроить звук"
@ -1618,7 +1607,7 @@ msgid "Unknown"
msgstr "Неизвестно" msgstr "Неизвестно"
#. Translators: This is the label for audio volume #. Translators: This is the label for audio volume
#: ../js/ui/status/volume.js:47 ../js/ui/status/volume.js:221 #: ../js/ui/status/volume.js:47 ../js/ui/status/volume.js:223
msgid "Volume" msgid "Volume"
msgstr "Громкость" msgstr "Громкость"
@ -1626,63 +1615,67 @@ msgstr "Громкость"
msgid "Microphone" msgid "Microphone"
msgstr "Микрофон" msgstr "Микрофон"
#: ../js/ui/unlockDialog.js:177 #: ../js/ui/unlockDialog.js:176
msgid "Log in as another user" msgid "Log in as another user"
msgstr "Войти от имени другого пользователя" msgstr "Войти от имени другого пользователя"
#: ../js/ui/userMenu.js:181 #: ../js/ui/userMenu.js:180
msgid "Available" msgid "Available"
msgstr "Доступен" msgstr "Доступен"
#: ../js/ui/userMenu.js:184 #: ../js/ui/userMenu.js:183
msgid "Busy" msgid "Busy"
msgstr "Занят" msgstr "Занят"
#: ../js/ui/userMenu.js:187 #: ../js/ui/userMenu.js:186
msgid "Invisible" msgid "Invisible"
msgstr "Невидим" msgstr "Невидим"
#: ../js/ui/userMenu.js:190 #: ../js/ui/userMenu.js:189
msgid "Away" msgid "Away"
msgstr "Отошёл" msgstr "Отошёл"
#: ../js/ui/userMenu.js:193 #: ../js/ui/userMenu.js:192
msgid "Idle" msgid "Idle"
msgstr "Бездействует" msgstr "Бездействует"
#: ../js/ui/userMenu.js:196 #: ../js/ui/userMenu.js:195
msgid "Unavailable" msgid "Unavailable"
msgstr "Недоступен" msgstr "Недоступен"
#: ../js/ui/userMenu.js:744 #: ../js/ui/userMenu.js:618 ../js/ui/userMenu.js:759
msgid "Notifications"
msgstr "Уведомления"
#: ../js/ui/userMenu.js:752
msgid "System Settings"
msgstr "Системные параметры"
#: ../js/ui/userMenu.js:760
msgid "Switch User" msgid "Switch User"
msgstr "Сменить пользователя" msgstr "Сменить пользователя"
#: ../js/ui/userMenu.js:765 #: ../js/ui/userMenu.js:619
msgid "Switch Session"
msgstr "Переключить сеанс"
#: ../js/ui/userMenu.js:743
msgid "Notifications"
msgstr "Уведомления"
#: ../js/ui/userMenu.js:751
msgid "System Settings"
msgstr "Системные параметры"
#: ../js/ui/userMenu.js:764
msgid "Log Out" msgid "Log Out"
msgstr "Выйти из системы" msgstr "Выйти из системы"
#: ../js/ui/userMenu.js:770 #: ../js/ui/userMenu.js:769
msgid "Lock" msgid "Lock"
msgstr "Заблокировать" msgstr "Заблокировать"
#: ../js/ui/userMenu.js:785 #: ../js/ui/userMenu.js:784
msgid "Install Updates & Restart" msgid "Install Updates & Restart"
msgstr "Установить обновления и выполнить перезагрузку" msgstr "Установить обновления и выполнить перезагрузку"
#: ../js/ui/userMenu.js:803 #: ../js/ui/userMenu.js:802
msgid "Your chat status will be set to busy" msgid "Your chat status will be set to busy"
msgstr "Будет установлен статус «не беспокоить»" msgstr "Будет установлен статус «не беспокоить»"
#: ../js/ui/userMenu.js:804 #: ../js/ui/userMenu.js:803
msgid "" msgid ""
"Notifications are now disabled, including chat messages. Your online status " "Notifications are now disabled, including chat messages. Your online status "
"has been adjusted to let others know that you might not see their messages." "has been adjusted to let others know that you might not see their messages."
@ -1702,7 +1695,7 @@ msgstr "Приложения"
msgid "Search" msgid "Search"
msgstr "Поиск" msgstr "Поиск"
#: ../js/ui/wanda.js:117 #: ../js/ui/wanda.js:119
#, c-format #, c-format
msgid "" msgid ""
"Sorry, no wisdom for you today:\n" "Sorry, no wisdom for you today:\n"
@ -1711,12 +1704,12 @@ msgstr ""
"Извините, на сегодня нет никаких советов:\n" "Извините, на сегодня нет никаких советов:\n"
"%s" "%s"
#: ../js/ui/wanda.js:121 #: ../js/ui/wanda.js:123
#, c-format #, c-format
msgid "%s the Oracle says" msgid "%s the Oracle says"
msgstr "Оракул говорит: «%s»" msgstr "Оракул говорит: «%s»"
#: ../js/ui/wanda.js:162 #: ../js/ui/wanda.js:164
msgid "Your favorite Easter Egg" msgid "Your favorite Easter Egg"
msgstr "Ваше любимое «пасхальное яйцо»" msgstr "Ваше любимое «пасхальное яйцо»"
@ -1753,24 +1746,24 @@ msgstr[2] "%u входов"
msgid "System Sounds" msgid "System Sounds"
msgstr "Системные звуки" msgstr "Системные звуки"
#: ../src/main.c:332 #: ../src/main.c:330
msgid "Print version" msgid "Print version"
msgstr "Показать номер версии" msgstr "Показать номер версии"
#: ../src/main.c:338 #: ../src/main.c:336
msgid "Mode used by GDM for login screen" msgid "Mode used by GDM for login screen"
msgstr "Режим, используемый GDM для окна входа в систему" msgstr "Режим, используемый GDM для окна входа в систему"
#: ../src/main.c:344 #: ../src/main.c:342
msgid "Use a specific mode, e.g. \"gdm\" for login screen" msgid "Use a specific mode, e.g. \"gdm\" for login screen"
msgstr "" msgstr ""
"Использовать для экрана входа в систему определённый режим, например «gdm»" "Использовать для экрана входа в систему определённый режим, например «gdm»"
#: ../src/main.c:350 #: ../src/main.c:348
msgid "List possible modes" msgid "List possible modes"
msgstr "Список возможных режимов" msgstr "Список возможных режимов"
#: ../src/shell-app.c:622 #: ../src/shell-app.c:621
#, c-format #, c-format
msgid "Failed to launch '%s'" msgid "Failed to launch '%s'"
msgstr "Не удалось запустить «%s»" msgstr "Не удалось запустить «%s»"
@ -1795,9 +1788,6 @@ msgstr "По умолчанию"
msgid "Authentication dialog was dismissed by the user" msgid "Authentication dialog was dismissed by the user"
msgstr "Пользователь отклонил диалог аутентификации" msgstr "Пользователь отклонил диалог аутентификации"
#~ msgid "Switch Session"
#~ msgstr "Переключить сеанс"
#~ msgid "disabled OpenSearch providers" #~ msgid "disabled OpenSearch providers"
#~ msgstr "отключённые провайдеры OpenSearch" #~ msgstr "отключённые провайдеры OpenSearch"

View File

@ -119,6 +119,7 @@ shell_public_headers_h = \
shell-network-agent.h \ shell-network-agent.h \
shell-perf-log.h \ shell-perf-log.h \
shell-screenshot.h \ shell-screenshot.h \
shell-screen-grabber.h \
shell-slicer.h \ shell-slicer.h \
shell-stack.h \ shell-stack.h \
shell-tp-client.h \ shell-tp-client.h \
@ -166,6 +167,7 @@ libgnome_shell_la_SOURCES = \
shell-polkit-authentication-agent.h \ shell-polkit-authentication-agent.h \
shell-polkit-authentication-agent.c \ shell-polkit-authentication-agent.c \
shell-screenshot.c \ shell-screenshot.c \
shell-screen-grabber.c \
shell-secure-text-buffer.c \ shell-secure-text-buffer.c \
shell-secure-text-buffer.h \ shell-secure-text-buffer.h \
shell-slicer.c \ shell-slicer.c \
@ -230,6 +232,8 @@ test_recorder_LDADD = $(TEST_SHELL_RECORDER_LIBS)
test_recorder_SOURCES = \ test_recorder_SOURCES = \
$(shell_recorder_sources) $(shell_recorder_private_sources) \ $(shell_recorder_sources) $(shell_recorder_private_sources) \
shell-screen-grabber.c \
shell-screen-grabber.h \
test-recorder.c test-recorder.c
endif BUILD_RECORDER endif BUILD_RECORDER

View File

@ -1035,6 +1035,8 @@ main (int argc,
name_owner_id = 0; name_owner_id = 0;
stdin_channel = NULL; stdin_channel = NULL;
g_type_init ();
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL); g_assert (introspection_data != NULL);

View File

@ -28,7 +28,7 @@ def show_version(option, opt_str, value, parser):
def wait_for_dbus_name(wait_name): def wait_for_dbus_name(wait_name):
loop = GLib.MainLoop() loop = GLib.MainLoop()
def on_name_appeared(connection, name, new_owner, *args): def on_name_appeared(connection, name, name_owner, *args):
if not (name == wait_name and new_owner != ''): if not (name == wait_name and new_owner != ''):
return return
loop.quit() loop.quit()
@ -60,18 +60,13 @@ def start_perf_helper():
wait_for_dbus_name (PERF_HELPER_NAME) wait_for_dbus_name (PERF_HELPER_NAME)
def stop_perf_helper(): def stop_perf_helper():
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None) proxy = Gio.DBusProxy(g_bus_type=Gio.BusType.SESSION,
g_name=PERF_HELPER_NAME,
proxy = Gio.DBusProxy.new_sync(bus, g_interface=PERF_HELPER_IFACE,
Gio.DBusProxyFlags.NONE, g_object_path=PERF_HELPER_PATH)
None,
PERF_HELPER_NAME,
PERF_HELPER_PATH,
PERF_HELPER_IFACE,
None)
proxy.Exit() proxy.Exit()
def start_shell(perf_output=None): def start_shell(extra_args, perf_output=None):
# Set up environment # Set up environment
env = dict(os.environ) env = dict(os.environ)
env['SHELL_PERF_MODULE'] = options.perf env['SHELL_PERF_MODULE'] = options.perf
@ -81,21 +76,19 @@ def start_shell(perf_output=None):
env['SHELL_PERF_OUTPUT'] = perf_output env['SHELL_PERF_OUTPUT'] = perf_output
self_dir = os.path.dirname(os.path.abspath(sys.argv[0])) self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
args = []
args.append(os.path.join(self_dir, 'gnome-shell')) args.append(os.path.join(self_dir, 'gnome-shell'))
# pass on any additional arguments
if options.replace: args += extra_args
args.append('--replace')
return subprocess.Popen(args, env=env) return subprocess.Popen(args, env=env)
def run_shell(perf_output=None): def run_shell(args, perf_output=None):
# we do no additional supervision of gnome-shell, # we do no additional supervision of gnome-shell,
# beyond that of wait # beyond that of wait
# in particular, we don't kill the shell upon # in particular, we don't kill the shell upon
# receving a KeyboardInterrupt, as we expect to be # receving a KeyboardInterrupt, as we expect to be
# in the same process group # in the same process group
shell = start_shell(perf_output=perf_output) shell = start_shell(extra_args, perf_output=perf_output)
shell.wait() shell.wait()
return shell.returncode == 0 return shell.returncode == 0
@ -180,7 +173,7 @@ def upload_performance_report(report_text):
print "Performance report upload failed with status %d" % response.status print "Performance report upload failed with status %d" % response.status
print response.read() print response.read()
def run_performance_test(): def run_performance_test(args):
iters = options.perf_iters iters = options.perf_iters
if options.perf_warmup: if options.perf_warmup:
iters += 1 iters += 1
@ -199,7 +192,7 @@ def run_performance_test():
# Run the performance test and collect the output as JSON # Run the performance test and collect the output as JSON
normal_exit = False normal_exit = False
try: try:
normal_exit = run_shell(perf_output=output_file) normal_exit = run_shell(args, perf_output=output_file)
except: except:
stop_perf_helper() stop_perf_helper()
raise raise
@ -295,8 +288,7 @@ def run_performance_test():
parser = optparse.OptionParser() parser = optparse.OptionParser()
parser.add_option("", "--perf", metavar="PERF_MODULE", parser.add_option("", "--perf", metavar="PERF_MODULE",
help="Specify the name of a performance module to run", help="Specify the name of a performance module to run")
default="core")
parser.add_option("", "--perf-iters", type="int", metavar="ITERS", parser.add_option("", "--perf-iters", type="int", metavar="ITERS",
help="Numbers of iterations of performance module to run", help="Numbers of iterations of performance module to run",
default=1) default=1)
@ -309,16 +301,9 @@ parser.add_option("", "--perf-upload", action="store_true",
parser.add_option("", "--version", action="callback", callback=show_version, parser.add_option("", "--version", action="callback", callback=show_version,
help="Display version and exit") help="Display version and exit")
parser.add_option("-r", "--replace", action="store_true",
help="Replace the running window manager")
options, args = parser.parse_args() options, args = parser.parse_args()
if args: normal_exit = run_performance_test(args)
parser.print_usage()
sys.exit(1)
normal_exit = run_performance_test()
if normal_exit: if normal_exit:
sys.exit(0) sys.exit(0)
else: else:

View File

@ -72,9 +72,6 @@ static void gnome_shell_plugin_kill_switch_workspace (MetaPlugin *plugin);
static gboolean gnome_shell_plugin_xevent_filter (MetaPlugin *plugin, static gboolean gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
XEvent *event); XEvent *event);
static gboolean gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
MetaKeyBinding *binding);
static const MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin); static const MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin);
@ -129,9 +126,8 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
plugin_class->kill_window_effects = gnome_shell_plugin_kill_window_effects; plugin_class->kill_window_effects = gnome_shell_plugin_kill_window_effects;
plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace; plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace;
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter; plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
plugin_class->keybinding_filter = gnome_shell_plugin_keybinding_filter; plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
} }
static void static void
@ -341,13 +337,6 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE; return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
} }
static gboolean
gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
MetaKeyBinding *binding)
{
return _shell_wm_filter_keybinding (get_shell_wm (), binding);
}
static const static const
MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin) MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
{ {

View File

@ -38,7 +38,7 @@ extern GType gnome_shell_plugin_get_type (void);
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides" #define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
#define WM_NAME "GNOME Shell" #define WM_NAME "GNOME Shell"
#define GNOME_WM_KEYBINDINGS "Mutter,GNOME Shell" #define GNOME_WM_KEYBINDINGS "Metacity,Mutter,GNOME Shell"
static gboolean is_gdm_mode = FALSE; static gboolean is_gdm_mode = FALSE;
static char *session_mode = NULL; static char *session_mode = NULL;

View File

@ -37,11 +37,10 @@
#define ISO_3166_COUNTRY_CODES DATADIR "/zoneinfo/iso3166.tab" #define ISO_3166_COUNTRY_CODES DATADIR "/zoneinfo/iso3166.tab"
static ShellCountryMobileProvider *country_mobile_provider_new (const char *country_code,
const gchar *country_name);
static GHashTable * static GHashTable *
read_country_codes (const gchar *country_codes) read_country_codes (void)
{ {
GHashTable *table; GHashTable *table;
GIOChannel *channel; GIOChannel *channel;
@ -49,21 +48,18 @@ read_country_codes (const gchar *country_codes)
GError *error = NULL; GError *error = NULL;
GIOStatus status; GIOStatus status;
channel = g_io_channel_new_file (country_codes, "r", &error); channel = g_io_channel_new_file (ISO_3166_COUNTRY_CODES, "r", &error);
if (!channel) { if (!channel) {
if (error) { if (error) {
g_warning ("Could not read %s: %s", country_codes, error->message); g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": %s", error->message);
g_error_free (error); g_error_free (error);
} else } else
g_warning ("Could not read %s: Unknown error", country_codes); g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": Unknown error");
return NULL; return NULL;
} }
table = g_hash_table_new_full (g_str_hash, table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
g_str_equal,
g_free,
(GDestroyNotify)shell_country_mobile_provider_unref);
buffer = g_string_sized_new (32); buffer = g_string_sized_new (32);
status = G_IO_STATUS_NORMAL; status = G_IO_STATUS_NORMAL;
@ -73,7 +69,6 @@ read_country_codes (const gchar *country_codes)
switch (status) { switch (status) {
case G_IO_STATUS_NORMAL: case G_IO_STATUS_NORMAL:
if (buffer->str[0] != '#') { if (buffer->str[0] != '#') {
ShellCountryMobileProvider *country_provider;
char **pieces; char **pieces;
pieces = g_strsplit (buffer->str, "\t", 2); pieces = g_strsplit (buffer->str, "\t", 2);
@ -85,8 +80,7 @@ read_country_codes (const gchar *country_codes)
pieces[1] = g_strdup (_("United Kingdom")); pieces[1] = g_strdup (_("United Kingdom"));
} }
country_provider = country_mobile_provider_new (pieces[0], pieces[1]); g_hash_table_insert (table, pieces[0], pieces[1]);
g_hash_table_insert (table, pieces[0], country_provider);
g_free (pieces); g_free (pieces);
} }
@ -123,6 +117,7 @@ typedef enum {
} MobileContextState; } MobileContextState;
typedef struct { typedef struct {
GHashTable *country_codes;
GHashTable *table; GHashTable *table;
char *current_country; char *current_country;
@ -281,86 +276,6 @@ shell_mobile_provider_get_type (void)
return type; return type;
} }
static ShellCountryMobileProvider *
country_mobile_provider_new (const char *country_code,
const gchar *country_name)
{
ShellCountryMobileProvider *country_provider;
country_provider = g_slice_new0 (ShellCountryMobileProvider);
country_provider->refs = 1;
country_provider->country_code = g_strdup (country_code);
country_provider->country_name = g_strdup (country_name);
return country_provider;
}
ShellCountryMobileProvider *
shell_country_mobile_provider_ref (ShellCountryMobileProvider *country_provider)
{
country_provider->refs++;
return country_provider;
}
void
shell_country_mobile_provider_unref (ShellCountryMobileProvider *country_provider)
{
if (--country_provider->refs == 0) {
g_free (country_provider->country_code);
g_free (country_provider->country_name);
g_slist_free_full (country_provider->providers,
(GDestroyNotify) shell_mobile_provider_unref);
g_slice_free (ShellCountryMobileProvider, country_provider);
}
}
/**
* shell_country_mobile_provider_get_country_code:
*
* Returns: (transfer none): the code of the country.
*/
const gchar *
shell_country_mobile_provider_get_country_code (ShellCountryMobileProvider *country_provider)
{
return country_provider->country_code;
}
/**
* shell_country_mobile_provider_get_country_name:
*
* Returns: (transfer none): the name of the country.
*/
const gchar *
shell_country_mobile_provider_get_country_name (ShellCountryMobileProvider *country_provider)
{
return country_provider->country_name;
}
/**
* shell_country_mobile_provider_get_providers:
*
* Returns: (element-type Shell.MobileProvider) (transfer none): the
* list of #ShellMobileProvider this country exposes.
*/
GSList *
shell_country_mobile_provider_get_providers (ShellCountryMobileProvider *country_provider)
{
return country_provider->providers;
}
GType
shell_country_mobile_provider_get_type (void)
{
static GType type = 0;
if (G_UNLIKELY (type == 0)) {
type = g_boxed_type_register_static ("ShellCountryMobileProvider",
(GBoxedCopyFunc) shell_country_mobile_provider_ref,
(GBoxedFreeFunc) shell_country_mobile_provider_unref);
}
return type;
}
static void static void
provider_list_free (gpointer data) provider_list_free (gpointer data)
{ {
@ -395,17 +310,15 @@ parser_toplevel_start (MobileParser *parser,
for (i = 0; attribute_names && attribute_names[i]; i++) { for (i = 0; attribute_names && attribute_names[i]; i++) {
if (!strcmp (attribute_names[i], "code")) { if (!strcmp (attribute_names[i], "code")) {
char *country_code; char *country_code;
ShellCountryMobileProvider *country_provider; char *country;
country_code = g_ascii_strup (attribute_values[i], -1); country_code = g_ascii_strup (attribute_values[i], -1);
country_provider = g_hash_table_lookup (parser->table, country_code); country = g_hash_table_lookup (parser->country_codes, country_code);
/* Ensure we have a country provider for this country code */ if (country) {
if (!country_provider) { parser->current_country = g_strdup (country);
g_warning ("%s: adding providers for unknown country '%s'", __func__, country_code); g_free (country_code);
country_provider = country_mobile_provider_new (country_code, NULL); } else
g_hash_table_insert (parser->table, country_code, country_provider); parser->current_country = country_code;
}
parser->current_country = country_code;
parser->state = PARSER_COUNTRY; parser->state = PARSER_COUNTRY;
break; break;
@ -542,13 +455,7 @@ parser_country_end (MobileParser *parser,
const char *name) const char *name)
{ {
if (!strcmp (name, "country")) { if (!strcmp (name, "country")) {
ShellCountryMobileProvider *country_provider; g_hash_table_insert (parser->table, parser->current_country, parser->current_providers);
country_provider = g_hash_table_lookup (parser->table, parser->current_country);
if (country_provider)
/* Store providers for this country */
country_provider->providers = parser->current_providers;
parser->current_country = NULL; parser->current_country = NULL;
parser->current_providers = NULL; parser->current_providers = NULL;
parser->text_buffer = NULL; parser->text_buffer = NULL;
@ -709,16 +616,15 @@ static const GMarkupParser mobile_parser = {
/** /**
* shell_mobile_providers_parse: * shell_mobile_providers_parse:
* @country_codes: (allow-none) File with the list of country codes. * @out_ccs: (out) (allow-none): (element-type utf8 utf8): a #GHashTable containing
* @service_providers: (allow-none) File with the list of service providers. * country codes
* *
* Returns: (element-type utf8 Shell.CountryMobileProvider) (transfer full): a * Returns: (element-type utf8 GList) (transfer container): a
* hash table where keys are country names #gchar and values are #ShellCountryMobileProvider. * hash table where keys are country names #gchar, values are a #GSList
* Everything is destroyed with g_hash_table_destroy(). * of #ShellMobileProvider. Everything is destroyed with g_hash_table_destroy().
*/ */
GHashTable * GHashTable *
shell_mobile_providers_parse (const gchar *country_codes, shell_mobile_providers_parse (GHashTable **out_ccs)
const gchar *service_providers)
{ {
GMarkupParseContext *ctx; GMarkupParseContext *ctx;
GIOChannel *channel; GIOChannel *channel;
@ -728,29 +634,24 @@ shell_mobile_providers_parse (const gchar *country_codes,
GIOStatus status; GIOStatus status;
gsize len = 0; gsize len = 0;
/* Use default paths if none given */
if (!country_codes)
country_codes = ISO_3166_COUNTRY_CODES;
if (!service_providers)
service_providers = MOBILE_BROADBAND_PROVIDER_INFO;
memset (&parser, 0, sizeof (MobileParser)); memset (&parser, 0, sizeof (MobileParser));
parser.table = read_country_codes (country_codes); parser.country_codes = read_country_codes ();
if (!parser.table) if (!parser.country_codes)
goto out; goto out;
channel = g_io_channel_new_file (service_providers, "r", &error); channel = g_io_channel_new_file (MOBILE_BROADBAND_PROVIDER_INFO, "r", &error);
if (!channel) { if (!channel) {
if (error) { if (error) {
g_warning ("Could not read %s: %s", service_providers, error->message); g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": %s", error->message);
g_error_free (error); g_error_free (error);
} else } else
g_warning ("Could not read %s: Unknown error", service_providers); g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": Unknown error");
goto out; goto out;
} }
parser.table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, provider_list_free);
parser.state = PARSER_TOPLEVEL; parser.state = PARSER_TOPLEVEL;
ctx = g_markup_parse_context_new (&mobile_parser, 0, &parser, NULL); ctx = g_markup_parse_context_new (&mobile_parser, 0, &parser, NULL);
@ -795,7 +696,13 @@ shell_mobile_providers_parse (const gchar *country_codes,
g_free (parser.current_country); g_free (parser.current_country);
g_free (parser.text_buffer); g_free (parser.text_buffer);
out: out:
if (parser.country_codes) {
if (out_ccs)
*out_ccs = parser.country_codes;
else
g_hash_table_destroy (parser.country_codes);
}
return parser.table; return parser.table;
} }
@ -837,17 +744,12 @@ dump_gsm (ShellMobileAccessMethod *method)
static void static void
dump_country (gpointer key, gpointer value, gpointer user_data) dump_country (gpointer key, gpointer value, gpointer user_data)
{ {
GSList *miter, *citer; GSList *citer, *miter;
ShellCountryMobileProvider *country_provider = value;
g_print ("Country: %s (%s)\n", for (citer = value; citer; citer = g_slist_next (citer)) {
country_provider->country_code,
country_provider->country_name);
for (citer = country_provider->providers; citer; citer = g_slist_next (citer)) {
ShellMobileProvider *provider = citer->data; ShellMobileProvider *provider = citer->data;
g_print (" Provider: %s (%s)\n", provider->name, (const char *) key); g_print ("Provider: %s (%s)\n", provider->name, (const char *) key);
for (miter = provider->methods; miter; miter = g_slist_next (miter)) { for (miter = provider->methods; miter; miter = g_slist_next (miter)) {
ShellMobileAccessMethod *method = miter->data; ShellMobileAccessMethod *method = miter->data;
GSList *liter; GSList *liter;
@ -877,10 +779,10 @@ dump_country (gpointer key, gpointer value, gpointer user_data)
} }
void void
shell_mobile_providers_dump (GHashTable *country_providers) shell_mobile_providers_dump (GHashTable *providers)
{ {
g_return_if_fail (country_providers != NULL); g_return_if_fail (providers != NULL);
g_hash_table_foreach (country_providers, dump_country, NULL); g_hash_table_foreach (providers, dump_country, NULL);
} }
/* All the following don't exist in nm-applet, because C doesn't need /* All the following don't exist in nm-applet, because C doesn't need

View File

@ -76,19 +76,10 @@ typedef struct {
gint refs; gint refs;
} ShellMobileProvider; } ShellMobileProvider;
typedef struct {
char *country_code;
char *country_name;
GSList *providers;
gint refs;
} ShellCountryMobileProvider;
GType shell_gsm_mcc_mnc_get_type (void); /* added in porting */ GType shell_gsm_mcc_mnc_get_type (void); /* added in porting */
GType shell_mobile_access_method_get_type (void);
GType shell_mobile_provider_get_type (void); GType shell_mobile_provider_get_type (void);
GType shell_country_mobile_provider_get_type (void); GType shell_mobile_access_method_get_type (void);
ShellMobileProvider *shell_mobile_provider_ref (ShellMobileProvider *provider); ShellMobileProvider *shell_mobile_provider_ref (ShellMobileProvider *provider);
void shell_mobile_provider_unref (ShellMobileProvider *provider); void shell_mobile_provider_unref (ShellMobileProvider *provider);
@ -98,14 +89,8 @@ GSList * shell_mobile_provider_get_cdma_sid (ShellMobileProvider *pr
ShellMobileAccessMethod *shell_mobile_access_method_ref (ShellMobileAccessMethod *method); ShellMobileAccessMethod *shell_mobile_access_method_ref (ShellMobileAccessMethod *method);
void shell_mobile_access_method_unref (ShellMobileAccessMethod *method); void shell_mobile_access_method_unref (ShellMobileAccessMethod *method);
ShellCountryMobileProvider *shell_country_mobile_provider_ref (ShellCountryMobileProvider *country_provider); GHashTable *shell_mobile_providers_parse (GHashTable **out_ccs);
void shell_country_mobile_provider_unref (ShellCountryMobileProvider *country_provider);
const gchar *shell_country_mobile_provider_get_country_code (ShellCountryMobileProvider *country_provider);
const gchar *shell_country_mobile_provider_get_country_name (ShellCountryMobileProvider *country_provider);
GSList *shell_country_mobile_provider_get_providers (ShellCountryMobileProvider *country_provider);
GHashTable *shell_mobile_providers_parse (const gchar *country_codes, void shell_mobile_providers_dump (GHashTable *providers);
const gchar *service_providers);
void shell_mobile_providers_dump (GHashTable *country_providers);
#endif /* SHELL_MOBILE_PROVIDERS_H */ #endif /* SHELL_MOBILE_PROVIDERS_H */

View File

@ -14,9 +14,6 @@ struct _ShellRecorderSrc
GMutex mutex_data; GMutex mutex_data;
GMutex *mutex; GMutex *mutex;
GstClock *clock;
GstClockTime last_frame_time;
GstCaps *caps; GstCaps *caps;
GAsyncQueue *queue; GAsyncQueue *queue;
gboolean closed; gboolean closed;
@ -44,10 +41,6 @@ static void
shell_recorder_src_init (ShellRecorderSrc *src) shell_recorder_src_init (ShellRecorderSrc *src)
{ {
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME); gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
src->clock = gst_system_clock_obtain ();
src->last_frame_time = 0;
src->queue = g_async_queue_new (); src->queue = g_async_queue_new ();
src->mutex = &src->mutex_data; src->mutex = &src->mutex_data;
@ -96,10 +89,6 @@ shell_recorder_src_create (GstPushSrc *push_src,
return GST_FLOW_EOS; return GST_FLOW_EOS;
buffer = g_async_queue_pop (src->queue); buffer = g_async_queue_pop (src->queue);
if (src->last_frame_time == 0)
src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
if (buffer == RECORDER_QUEUE_END) if (buffer == RECORDER_QUEUE_END)
{ {
/* Returning UNEXPECTED here will cause a EOS message to be sent */ /* Returning UNEXPECTED here will cause a EOS message to be sent */
@ -111,9 +100,6 @@ shell_recorder_src_create (GstPushSrc *push_src,
- (int)(gst_buffer_get_size(buffer) / 1024)); - (int)(gst_buffer_get_size(buffer) / 1024));
*buffer_out = buffer; *buffer_out = buffer;
GST_BUFFER_DURATION(*buffer_out) = GST_CLOCK_DIFF (src->last_frame_time, gst_clock_get_time (GST_CLOCK (src->clock)));
src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
return GST_FLOW_OK; return GST_FLOW_OK;
} }
@ -155,8 +141,6 @@ shell_recorder_src_finalize (GObject *object)
g_mutex_clear (src->mutex); g_mutex_clear (src->mutex);
gst_object_unref (src->clock);
G_OBJECT_CLASS (shell_recorder_src_parent_class)->finalize (object); G_OBJECT_CLASS (shell_recorder_src_parent_class)->finalize (object);
} }

View File

@ -12,10 +12,10 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "shell-recorder-src.h" #include "shell-recorder-src.h"
#include "shell-recorder.h" #include "shell-recorder.h"
#include "shell-screen-grabber.h"
#include <clutter/x11/clutter-x11.h> #include <clutter/x11/clutter-x11.h>
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
@ -48,7 +48,7 @@ struct _ShellRecorder {
int stage_width; int stage_width;
int stage_height; int stage_height;
GdkScreen *gdk_screen; ShellScreenGrabber *grabber;
gboolean have_pointer; gboolean have_pointer;
int pointer_x; int pointer_x;
@ -259,11 +259,11 @@ shell_recorder_init (ShellRecorder *recorder)
shell_recorder_src_register (); shell_recorder_src_register ();
recorder->gdk_screen = gdk_screen_get_default ();
recorder->recording_icon = create_recording_icon (); recorder->recording_icon = create_recording_icon ();
recorder->memory_target = get_memory_target(); recorder->memory_target = get_memory_target();
recorder->grabber = shell_screen_grabber_new ();
recorder->state = RECORDER_STATE_CLOSED; recorder->state = RECORDER_STATE_CLOSED;
recorder->framerate = DEFAULT_FRAMES_PER_SECOND; recorder->framerate = DEFAULT_FRAMES_PER_SECOND;
} }
@ -283,6 +283,8 @@ shell_recorder_finalize (GObject *object)
recorder_set_pipeline (recorder, NULL); recorder_set_pipeline (recorder, NULL);
recorder_set_file_template (recorder, NULL); recorder_set_file_template (recorder, NULL);
g_object_unref (recorder->grabber);
cogl_handle_unref (recorder->recording_icon); cogl_handle_unref (recorder->recording_icon);
G_OBJECT_CLASS (shell_recorder_parent_class)->finalize (object); G_OBJECT_CLASS (shell_recorder_parent_class)->finalize (object);
@ -460,12 +462,6 @@ static void
recorder_draw_buffer_meter (ShellRecorder *recorder) recorder_draw_buffer_meter (ShellRecorder *recorder)
{ {
int fill_level; int fill_level;
GdkRectangle primary_monitor;
float rects[16];
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
recorder_update_memory_used (recorder, FALSE); recorder_update_memory_used (recorder, FALSE);
@ -480,27 +476,14 @@ recorder_draw_buffer_meter (ShellRecorder *recorder)
fill_level = MIN (60, (recorder->memory_used * 60) / recorder->memory_target); fill_level = MIN (60, (recorder->memory_used * 60) / recorder->memory_target);
/* A hollow rectangle filled from the left to fill_level */ /* A hollow rectangle filled from the left to fill_level */
rects[0] = primary_monitor.x + primary_monitor.width - 64; cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 10,
rects[1] = primary_monitor.y + primary_monitor.height - 10; recorder->stage_width - 2, recorder->stage_height - 9);
rects[2] = primary_monitor.x + primary_monitor.width - 2; cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 9,
rects[3] = primary_monitor.y + primary_monitor.height - 9; recorder->stage_width - (63 - fill_level), recorder->stage_height - 3);
cogl_rectangle (recorder->stage_width - 3, recorder->stage_height - 9,
rects[4] = primary_monitor.x + primary_monitor.width - 64; recorder->stage_width - 2, recorder->stage_height - 3);
rects[5] = primary_monitor.y + primary_monitor.height - 9; cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 3,
rects[6] = primary_monitor.x + primary_monitor.width - (63 - fill_level); recorder->stage_width - 2, recorder->stage_height - 2);
rects[7] = primary_monitor.y + primary_monitor.height - 3;
rects[8] = primary_monitor.x + primary_monitor.width - 3;
rects[9] = primary_monitor.y + primary_monitor.height - 9;
rects[10] = primary_monitor.x + primary_monitor.width - 2;
rects[11] = primary_monitor.y + primary_monitor.height - 3;
rects[12] = primary_monitor.x + primary_monitor.width - 64;
rects[13] = primary_monitor.y + primary_monitor.height - 3;
rects[14] = primary_monitor.x + primary_monitor.width - 2;
rects[15] = primary_monitor.y + primary_monitor.height - 2;
cogl_rectangles (rects, 4);
} }
/* We want to time-stamp each frame based on the actual time it was /* We want to time-stamp each frame based on the actual time it was
@ -550,13 +533,8 @@ recorder_record_frame (ShellRecorder *recorder)
size = recorder->stage_width * recorder->stage_height * 4; size = recorder->stage_width * recorder->stage_height * 4;
data = g_malloc (recorder->stage_width * 4 * recorder->stage_height); data = shell_screen_grabber_grab (recorder->grabber,
cogl_read_pixels (0, 0, /* x/y */ 0, 0, recorder->stage_width, recorder->stage_height);
recorder->stage_width,
recorder->stage_height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
buffer = gst_buffer_new(); buffer = gst_buffer_new();
gst_buffer_insert_memory (buffer, -1, gst_buffer_insert_memory (buffer, -1,
@ -584,17 +562,12 @@ recorder_on_stage_paint (ClutterActor *actor,
{ {
if (recorder->state == RECORDER_STATE_RECORDING) if (recorder->state == RECORDER_STATE_RECORDING)
{ {
GdkRectangle primary_monitor;
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
if (!recorder->only_paint) if (!recorder->only_paint)
recorder_record_frame (recorder); recorder_record_frame (recorder);
cogl_set_source_texture (recorder->recording_icon); cogl_set_source_texture (recorder->recording_icon);
cogl_rectangle (primary_monitor.x + primary_monitor.width - 32, primary_monitor.y + primary_monitor.height - 42, cogl_rectangle (recorder->stage_width - 32, recorder->stage_height - 42,
primary_monitor.x + primary_monitor.width, primary_monitor.y + primary_monitor.height - 10); recorder->stage_width, recorder->stage_height - 10);
} }
if (recorder->state == RECORDER_STATE_RECORDING || recorder->memory_used != 0) if (recorder->state == RECORDER_STATE_RECORDING || recorder->memory_used != 0)
@ -1730,6 +1703,9 @@ shell_recorder_close (ShellRecorder *recorder)
recorder->repaint_hook_id = 0; recorder->repaint_hook_id = 0;
} }
recorder_remove_redraw_timeout (recorder);
recorder_close_pipeline (recorder);
recorder->state = RECORDER_STATE_CLOSED; recorder->state = RECORDER_STATE_CLOSED;
/* Release the refcount we took when we started recording */ /* Release the refcount we took when we started recording */

210
src/shell-screen-grabber.c Normal file
View File

@ -0,0 +1,210 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include <string.h>
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glext.h>
#include "shell-screen-grabber.h"
PFNGLBINDBUFFERARBPROC pf_glBindBufferARB;
PFNGLBUFFERDATAARBPROC pf_glBufferDataARB;
PFNGLDELETEBUFFERSARBPROC pf_glDeleteBuffersARB;
PFNGLGENBUFFERSARBPROC pf_glGenBuffersARB;
PFNGLMAPBUFFERARBPROC pf_glMapBufferARB;
PFNGLUNMAPBUFFERARBPROC pf_glUnmapBufferARB;
struct _ShellScreenGrabberClass
{
GObjectClass parent_class;
};
struct _ShellScreenGrabber
{
GObject parent_instance;
int have_pixel_buffers;
int have_pack_invert;
int width, height;
GLuint pixel_buffer;
};
G_DEFINE_TYPE(ShellScreenGrabber, shell_screen_grabber, G_TYPE_OBJECT);
static void
shell_screen_grabber_finalize (GObject *gobject)
{
ShellScreenGrabber *grabber = SHELL_SCREEN_GRABBER (gobject);
if (grabber->pixel_buffer != 0)
pf_glDeleteBuffersARB (1, &grabber->pixel_buffer);
}
static void
shell_screen_grabber_class_init (ShellScreenGrabberClass *grabber_class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (grabber_class);
gobject_class->finalize = shell_screen_grabber_finalize;
}
static void
shell_screen_grabber_init (ShellScreenGrabber *grabber)
{
grabber->have_pixel_buffers = -1;
grabber->width = -1;
grabber->height= -1;
grabber->pixel_buffer = 0;
}
ShellScreenGrabber *
shell_screen_grabber_new (void)
{
return g_object_new (SHELL_TYPE_SCREEN_GRABBER, NULL);
}
/**
* shell_screen_grabber_grab:
* x: X coordinate of the rectangle to grab
* y: Y coordinate of the rectangle to grab
* width: width of the rectangle to grab
* height: heigth of the rectangle to grab
*
* Grabs pixel data from a portion of the screen.
*
* Return value: buffer holding the grabbed data. The data is stored as 32-bit
* words with native-endian xRGB pixels (i.e., the same as CAIRO_FORMAT_RGB24)
* with no padding on the rows. So, the size of the buffer is width * height * 4
* bytes. Free with g_free().
**/
guchar *
shell_screen_grabber_grab (ShellScreenGrabber *grabber,
int x,
int y,
int width,
int height)
{
guchar *data;
gsize row_bytes;
gsize data_size;
row_bytes = width * 4;
data_size = row_bytes * height;
data = g_malloc (data_size);
if (grabber->have_pixel_buffers == -1)
{
const GLubyte* extensions = glGetString (GL_EXTENSIONS);
grabber->have_pixel_buffers = strstr ((const char *)extensions, "GL_EXT_pixel_buffer_object") != NULL;
grabber->have_pack_invert = strstr ((const char *)extensions, "GL_MESA_pack_invert") != NULL;
}
if (grabber->have_pixel_buffers)
{
GLubyte *mapped_data;
GLint old_swap_bytes, old_lsb_first, old_row_length, old_skip_pixels, old_skip_rows, old_alignment;
GLint old_pack_invert = GL_FALSE;
GLint vp_size[4];
guchar *src_row, *dest_row;
int i;
cogl_flush ();
if (pf_glBindBufferARB == NULL)
{
pf_glBindBufferARB = (PFNGLBINDBUFFERARBPROC) cogl_get_proc_address ("glBindBufferARB");
pf_glBufferDataARB = (PFNGLBUFFERDATAARBPROC) cogl_get_proc_address ("glBufferDataARB");
pf_glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) cogl_get_proc_address ("glDeleteBuffersARB");
pf_glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) cogl_get_proc_address ("glGenBuffersARB");
pf_glMapBufferARB = (PFNGLMAPBUFFERARBPROC) cogl_get_proc_address ("glMapBufferARB");
pf_glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC) cogl_get_proc_address ("glUnmapBufferARB");
}
glGetIntegerv (GL_PACK_SWAP_BYTES, &old_swap_bytes);
glGetIntegerv (GL_PACK_LSB_FIRST, &old_lsb_first);
glGetIntegerv (GL_PACK_ROW_LENGTH, &old_row_length);
glGetIntegerv (GL_PACK_SKIP_PIXELS, &old_skip_pixels);
glGetIntegerv (GL_PACK_SKIP_ROWS, &old_skip_rows);
glGetIntegerv (GL_PACK_ALIGNMENT, &old_alignment);
glPixelStorei (GL_PACK_SWAP_BYTES, GL_FALSE);
glPixelStorei (GL_PACK_LSB_FIRST, GL_FALSE);
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
glPixelStorei (GL_PACK_SKIP_PIXELS, 0);
glPixelStorei (GL_PACK_SKIP_ROWS, 0);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
if (grabber->have_pack_invert)
{
glGetIntegerv (GL_PACK_INVERT_MESA, &old_pack_invert);
glPixelStorei (GL_PACK_INVERT_MESA, GL_FALSE);
}
if (grabber->pixel_buffer != 0 &&
(grabber->width != width ||
grabber->height != height))
{
pf_glDeleteBuffersARB (1, &grabber->pixel_buffer);
grabber->pixel_buffer = 0;
}
if (grabber->pixel_buffer == 0)
{
pf_glGenBuffersARB (1, &grabber->pixel_buffer);
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, grabber->pixel_buffer);
pf_glBufferDataARB (GL_PIXEL_PACK_BUFFER_ARB, data_size, 0, GL_STREAM_READ_ARB);
grabber->width = width;
grabber->height = height;
}
else
{
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, grabber->pixel_buffer);
}
/* In OpenGL, (x,y) specifies the bottom-left corner rather than the
* top-left */
glGetIntegerv (GL_VIEWPORT, vp_size);
y = vp_size[3] - (y + height);
glReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
mapped_data = pf_glMapBufferARB (GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
src_row = mapped_data + (height - 1) * row_bytes;
dest_row = data;
for (i = 0; i < height; i++)
{
memcpy (dest_row, src_row, row_bytes);
src_row -= row_bytes;
dest_row += row_bytes;
}
pf_glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_ARB);
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, 0);
glPixelStorei (GL_PACK_SWAP_BYTES, old_swap_bytes);
glPixelStorei (GL_PACK_LSB_FIRST, old_lsb_first);
glPixelStorei (GL_PACK_ROW_LENGTH, old_row_length);
glPixelStorei (GL_PACK_SKIP_PIXELS, old_skip_pixels);
glPixelStorei (GL_PACK_SKIP_ROWS, old_skip_rows);
glPixelStorei (GL_PACK_ALIGNMENT, old_alignment);
if (grabber->have_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, old_pack_invert);
}
else
{
cogl_read_pixels (x, y,
width, height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
}
return data;
}

View File

@ -0,0 +1,44 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __SHELL_SCREEN_GRABBER_H__
#define __SHELL_SCREEN_GRABBER_H__
#include <glib-object.h>
G_BEGIN_DECLS
/**
* SECTION:shell-screen-grabber
* @short_description: Grab pixel data from the screen
*
* The #ShellScreenGrabber object is used to download previous drawn
* content to the screen. It internally uses pixel-buffer objects if
* available, otherwise falls back to cogl_read_pixels().
*
* If you are repeatedly grabbing images of the same size from the
* screen, it makes sense to create one #ShellScreenGrabber and keep
* it around. Otherwise, it's fine to simply create one as needed and
* then get rid of it.
*/
typedef struct _ShellScreenGrabber ShellScreenGrabber;
typedef struct _ShellScreenGrabberClass ShellScreenGrabberClass;
#define SHELL_TYPE_SCREEN_GRABBER (shell_screen_grabber_get_type ())
#define SHELL_SCREEN_GRABBER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabber))
#define SHELL_SCREEN_GRABBER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabberClass))
#define SHELL_IS_SCREEN_GRABBER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_SCREEN_GRABBER))
#define SHELL_IS_SCREEN_GRABBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_SCREEN_GRABBER))
#define SHELL_SCREEN_GRABBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabberClass))
GType shell_screen_grabber_get_type (void) G_GNUC_CONST;
ShellScreenGrabber *shell_screen_grabber_new (void);
guchar * shell_screen_grabber_grab (ShellScreenGrabber *grabber,
int x,
int y,
int width,
int height);
G_END_DECLS
#endif /* __SHELL_SCREEN_GRABBER_H__ */

View File

@ -1,8 +1,5 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#define COGL_ENABLE_EXPERIMENTAL_API
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
#include <clutter/x11/clutter-x11.h> #include <clutter/x11/clutter-x11.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
@ -13,6 +10,7 @@
#include <meta/meta-shaped-texture.h> #include <meta/meta-shaped-texture.h>
#include "shell-global.h" #include "shell-global.h"
#include "shell-screen-grabber.h"
#include "shell-screenshot.h" #include "shell-screenshot.h"
struct _ShellScreenshotClass struct _ShellScreenshotClass
@ -92,33 +90,18 @@ do_grab_screenshot (_screenshot_data *screenshot_data,
int width, int width,
int height) int height)
{ {
CoglBitmap *bitmap; ShellScreenGrabber *grabber;
ClutterBackend *backend; static const cairo_user_data_key_t key;
CoglContext *context;
int stride;
guchar *data; guchar *data;
backend = clutter_get_default_backend (); grabber = shell_screen_grabber_new ();
context = clutter_backend_get_cogl_context (backend); data = shell_screen_grabber_grab (grabber, x, y, width, height);
g_object_unref (grabber);
screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, screenshot_data->image = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24,
width, height); width, height, width * 4);
cairo_surface_set_user_data (screenshot_data->image, &key,
data, (cairo_destroy_func_t)g_free);
data = cairo_image_surface_get_data (screenshot_data->image);
stride = cairo_image_surface_get_stride (screenshot_data->image);
bitmap = cogl_bitmap_new_for_data (context,
width,
height,
CLUTTER_CAIRO_FORMAT_ARGB32,
stride,
data);
cogl_framebuffer_read_pixels_into_bitmap (cogl_get_draw_framebuffer (),
x, y,
COGL_READ_PIXELS_COLOR_BUFFER,
bitmap);
cogl_object_unref (bitmap);
} }
static void static void

View File

@ -35,9 +35,6 @@ void _shell_wm_kill_window_effects (ShellWM *wm,
MetaWindowActor *actor); MetaWindowActor *actor);
void _shell_wm_kill_switch_workspace (ShellWM *wm); void _shell_wm_kill_switch_workspace (ShellWM *wm);
gboolean _shell_wm_filter_keybinding (ShellWM *wm,
MetaKeyBinding *binding);
G_END_DECLS G_END_DECLS
#endif /* __SHELL_WM_PRIVATE_H__ */ #endif /* __SHELL_WM_PRIVATE_H__ */

View File

@ -26,7 +26,6 @@ enum
SWITCH_WORKSPACE, SWITCH_WORKSPACE,
KILL_SWITCH_WORKSPACE, KILL_SWITCH_WORKSPACE,
KILL_WINDOW_EFFECTS, KILL_WINDOW_EFFECTS,
FILTER_KEYBINDING,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -116,14 +115,6 @@ shell_wm_class_init (ShellWMClass *klass)
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
META_TYPE_WINDOW_ACTOR); META_TYPE_WINDOW_ACTOR);
shell_wm_signals[FILTER_KEYBINDING] =
g_signal_new ("filter-keybinding",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
g_signal_accumulator_true_handled, NULL, NULL,
G_TYPE_BOOLEAN, 1,
META_TYPE_KEY_BINDING);
} }
void void
@ -276,17 +267,6 @@ _shell_wm_destroy (ShellWM *wm,
g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor); g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
} }
gboolean
_shell_wm_filter_keybinding (ShellWM *wm,
MetaKeyBinding *binding)
{
gboolean rv;
g_signal_emit (wm, shell_wm_signals[FILTER_KEYBINDING], 0, binding, &rv);
return rv;
}
/** /**
* shell_wm_new: * shell_wm_new:
* @plugin: the #MetaPlugin * @plugin: the #MetaPlugin

View File

@ -65,10 +65,6 @@
#include "st-clipboard.h" #include "st-clipboard.h"
#include "st-private.h" #include "st-private.h"
#include <clutter/x11/clutter-x11.h>
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include "st-widget-accessible.h" #include "st-widget-accessible.h"
#define HAS_FOCUS(actor) (clutter_actor_get_stage (actor) && clutter_stage_get_key_focus ((ClutterStage *) clutter_actor_get_stage (actor)) == actor) #define HAS_FOCUS(actor) (clutter_actor_get_stage (actor) && clutter_stage_get_key_focus ((ClutterStage *) clutter_actor_get_stage (actor)) == actor)
@ -617,38 +613,6 @@ st_entry_key_focus_in (ClutterActor *actor)
clutter_actor_grab_key_focus (priv->entry); clutter_actor_grab_key_focus (priv->entry);
} }
static void
st_entry_set_cursor (StEntry *entry,
gboolean use_ibeam)
{
Display *dpy;
ClutterActor *stage, *actor = CLUTTER_ACTOR (entry);
Window wid;
static Cursor ibeam = None;
dpy = clutter_x11_get_default_display ();
stage = clutter_actor_get_stage (actor);
wid = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
if (ibeam == None)
ibeam = XCreateFontCursor (dpy, XC_xterm);
if (use_ibeam)
XDefineCursor (dpy, wid, ibeam);
else
XUndefineCursor (dpy, wid);
}
static gboolean
st_entry_crossing_event (ClutterActor *actor,
ClutterCrossingEvent *event)
{
if (event->source == ST_ENTRY (actor)->priv->entry && event->related != NULL)
st_entry_set_cursor (ST_ENTRY (actor), (event->type == CLUTTER_ENTER));
return FALSE;
}
static void static void
st_entry_class_init (StEntryClass *klass) st_entry_class_init (StEntryClass *klass)
{ {
@ -671,9 +635,6 @@ st_entry_class_init (StEntryClass *klass)
actor_class->key_press_event = st_entry_key_press_event; actor_class->key_press_event = st_entry_key_press_event;
actor_class->key_focus_in = st_entry_key_focus_in; actor_class->key_focus_in = st_entry_key_focus_in;
actor_class->enter_event = st_entry_crossing_event;
actor_class->leave_event = st_entry_crossing_event;
widget_class->style_changed = st_entry_style_changed; widget_class->style_changed = st_entry_style_changed;
widget_class->navigate_focus = st_entry_navigate_focus; widget_class->navigate_focus = st_entry_navigate_focus;
widget_class->get_accessible_type = st_entry_accessible_get_type; widget_class->get_accessible_type = st_entry_accessible_get_type;

View File

@ -1073,8 +1073,6 @@ typedef struct {
gchar *path; gchar *path;
gint grid_width, grid_height; gint grid_width, grid_height;
ClutterActor *actor; ClutterActor *actor;
GFunc load_callback;
gpointer load_callback_data;
} AsyncImageData; } AsyncImageData;
static void static void
@ -1091,7 +1089,6 @@ on_sliced_image_loaded (GObject *source_object,
GAsyncResult *res, GAsyncResult *res,
gpointer user_data) gpointer user_data)
{ {
GObject *cache = source_object;
AsyncImageData *data = (AsyncImageData *)user_data; AsyncImageData *data = (AsyncImageData *)user_data;
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
GList *list; GList *list;
@ -1105,9 +1102,6 @@ on_sliced_image_loaded (GObject *source_object,
clutter_actor_hide (actor); clutter_actor_hide (actor);
clutter_actor_add_child (data->actor, actor); clutter_actor_add_child (data->actor, actor);
} }
if (data->load_callback != NULL)
data->load_callback (cache, data->load_callback_data);
} }
static void static void
@ -1162,8 +1156,6 @@ load_sliced_image (GSimpleAsyncResult *result,
* @path: Path to a filename * @path: Path to a filename
* @grid_width: Width in pixels * @grid_width: Width in pixels
* @grid_height: Height in pixels * @grid_height: Height in pixels
* @load_callback: (scope async) (allow-none): Function called when the image is loaded, or %NULL
* @user_data: Data to pass to the load callback
* *
* This function reads a single image file which contains multiple images internally. * This function reads a single image file which contains multiple images internally.
* The image file will be divided using @grid_width and @grid_height; * The image file will be divided using @grid_width and @grid_height;
@ -1173,12 +1165,10 @@ load_sliced_image (GSimpleAsyncResult *result,
* Returns: (transfer none): A new #ClutterActor * Returns: (transfer none): A new #ClutterActor
*/ */
ClutterActor * ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache, st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path, const gchar *path,
gint grid_width, gint grid_width,
gint grid_height, gint grid_height)
GFunc load_callback,
gpointer user_data)
{ {
AsyncImageData *data; AsyncImageData *data;
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
@ -1189,8 +1179,6 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
data->grid_height = grid_height; data->grid_height = grid_height;
data->path = g_strdup (path); data->path = g_strdup (path);
data->actor = actor; data->actor = actor;
data->load_callback = load_callback;
data->load_callback_data = user_data;
g_object_ref (G_OBJECT (actor)); g_object_ref (G_OBJECT (actor));
result = g_simple_async_result_new (G_OBJECT (cache), on_sliced_image_loaded, data, st_texture_cache_load_sliced_image); result = g_simple_async_result_new (G_OBJECT (cache), on_sliced_image_loaded, data, st_texture_cache_load_sliced_image);

View File

@ -69,12 +69,10 @@ GType st_texture_cache_get_type (void) G_GNUC_CONST;
StTextureCache* st_texture_cache_get_default (void); StTextureCache* st_texture_cache_get_default (void);
ClutterActor * ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache, st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path, const gchar *path,
gint grid_width, gint grid_width,
gint grid_height, gint grid_height);
GFunc load_callback,
gpointer user_data);
ClutterActor *st_texture_cache_bind_pixbuf_property (StTextureCache *cache, ClutterActor *st_texture_cache_bind_pixbuf_property (StTextureCache *cache,
GObject *object, GObject *object,

View File

@ -31,9 +31,6 @@ struct _StThemeContext {
PangoFontDescription *font; PangoFontDescription *font;
StThemeNode *root_node; StThemeNode *root_node;
StTheme *theme; StTheme *theme;
/* set of StThemeNode */
GHashTable *nodes;
}; };
struct _StThemeContextClass { struct _StThemeContextClass {
@ -69,8 +66,6 @@ st_theme_context_finalize (GObject *object)
(gpointer) st_theme_context_changed, (gpointer) st_theme_context_changed,
context); context);
if (context->nodes)
g_hash_table_unref (context->nodes);
if (context->root_node) if (context->root_node)
g_object_unref (context->root_node); g_object_unref (context->root_node);
if (context->theme) if (context->theme)
@ -110,10 +105,6 @@ st_theme_context_init (StThemeContext *context)
"resolution-changed", "resolution-changed",
G_CALLBACK (st_theme_context_changed), G_CALLBACK (st_theme_context_changed),
context); context);
context->nodes = g_hash_table_new_full ((GHashFunc) st_theme_node_hash,
(GEqualFunc) st_theme_node_equal,
g_object_unref, NULL);
} }
/** /**
@ -155,7 +146,6 @@ st_theme_context_changed (StThemeContext *context)
{ {
StThemeNode *old_root = context->root_node; StThemeNode *old_root = context->root_node;
context->root_node = NULL; context->root_node = NULL;
g_hash_table_remove_all (context->nodes);
emit_changed (context); emit_changed (context);
@ -309,27 +299,3 @@ st_theme_context_get_root_node (StThemeContext *context)
return context->root_node; return context->root_node;
} }
/**
* st_theme_context_intern_node:
* @context: a #StThemeContext
* @node: a #StThemeNode
*
* Return an existing node matching @node, or if that isn't possible,
* @node itself.
*
* Return value: (transfer none): a node with the same properties as @node
*/
StThemeNode *
st_theme_context_intern_node (StThemeContext *context,
StThemeNode *node)
{
StThemeNode *mine = g_hash_table_lookup (context->nodes, node);
/* this might be node or not - it doesn't actually matter */
if (mine != NULL)
return mine;
g_hash_table_add (context->nodes, g_object_ref (node));
return node;
}

View File

@ -62,9 +62,6 @@ const PangoFontDescription *st_theme_context_get_font (StThemeContext
StThemeNode * st_theme_context_get_root_node (StThemeContext *context); StThemeNode * st_theme_context_get_root_node (StThemeContext *context);
StThemeNode * st_theme_context_intern_node (StThemeContext *context,
StThemeNode *node);
G_END_DECLS G_END_DECLS
#endif /* __ST_THEME_CONTEXT_H__ */ #endif /* __ST_THEME_CONTEXT_H__ */

View File

@ -1553,7 +1553,7 @@ st_theme_node_paint_borders (StThemeNode *node,
{ {
ClutterColor effective_border; ClutterColor effective_border;
gboolean skip_corner_1, skip_corner_2; gboolean skip_corner_1, skip_corner_2;
float rects[16]; float x1, y1, x2, y2;
over (&border_color, &node->background_color, &effective_border); over (&border_color, &node->background_color, &effective_border);
alpha = paint_opacity * effective_border.alpha / 255; alpha = paint_opacity * effective_border.alpha / 255;
@ -1569,44 +1569,46 @@ st_theme_node_paint_borders (StThemeNode *node,
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0; skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_TOPRIGHT] > 0; skip_corner_2 = border_radius[ST_CORNER_TOPRIGHT] > 0;
rects[0] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0; x1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0;
rects[1] = 0; y1 = 0;
rects[2] = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width; x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width;
rects[3] = border_width[ST_SIDE_TOP]; y2 = border_width[ST_SIDE_TOP];
cogl_rectangle (x1, y1, x2, y2);
/* EAST */ /* EAST */
skip_corner_1 = border_radius[ST_CORNER_TOPRIGHT] > 0; skip_corner_1 = border_radius[ST_CORNER_TOPRIGHT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0; skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
rects[4] = width - border_width[ST_SIDE_RIGHT]; x1 = width - border_width[ST_SIDE_RIGHT];
rects[5] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT] y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT]
: border_width[ST_SIDE_TOP]; : border_width[ST_SIDE_TOP];
rects[6] = width; x2 = width;
rects[7] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT] y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT]
: height - border_width[ST_SIDE_BOTTOM]; : height - border_width[ST_SIDE_BOTTOM];
cogl_rectangle (x1, y1, x2, y2);
/* SOUTH */ /* SOUTH */
skip_corner_1 = border_radius[ST_CORNER_BOTTOMLEFT] > 0; skip_corner_1 = border_radius[ST_CORNER_BOTTOMLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0; skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
rects[8] = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0; x1 = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0;
rects[9] = height - border_width[ST_SIDE_BOTTOM]; y1 = height - border_width[ST_SIDE_BOTTOM];
rects[10] = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT] x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT]
: width; : width;
rects[11] = height; y2 = height;
cogl_rectangle (x1, y1, x2, y2);
/* WEST */ /* WEST */
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0; skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMLEFT] > 0; skip_corner_2 = border_radius[ST_CORNER_BOTTOMLEFT] > 0;
rects[12] = 0; x1 = 0;
rects[13] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT]
: border_width[ST_SIDE_TOP]; : border_width[ST_SIDE_TOP];
rects[14] = border_width[ST_SIDE_LEFT]; x2 = border_width[ST_SIDE_LEFT];
rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT] y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
: height - border_width[ST_SIDE_BOTTOM]; : height - border_width[ST_SIDE_BOTTOM];
cogl_rectangle (x1, y1, x2, y2);
cogl_rectangles (rects, 4);
} }
} }
@ -1873,7 +1875,6 @@ st_theme_node_paint_outline (StThemeNode *node,
{ {
float width, height; float width, height;
int outline_width; int outline_width;
float rects[16];
ClutterColor outline_color, effective_outline; ClutterColor outline_color, effective_outline;
width = box->x2 - box->x1; width = box->x2 - box->x1;
@ -1898,30 +1899,20 @@ st_theme_node_paint_outline (StThemeNode *node,
*/ */
/* NORTH */ /* NORTH */
rects[0] = -outline_width; cogl_rectangle (-outline_width, -outline_width,
rects[1] = -outline_width; width + outline_width, 0);
rects[2] = width + outline_width;
rects[3] = 0;
/* EAST */ /* EAST */
rects[4] = width; cogl_rectangle (width, 0,
rects[5] = 0; width + outline_width, height);
rects[6] = width + outline_width;
rects[7] = height;
/* SOUTH */ /* SOUTH */
rects[8] = -outline_width; cogl_rectangle (-outline_width, height,
rects[9] = height; width + outline_width, height + outline_width);
rects[10] = width + outline_width;
rects[11] = height + outline_width;
/* WEST */ /* WEST */
rects[12] = -outline_width; cogl_rectangle (-outline_width, 0,
rects[13] = 0; 0, height);
rects[14] = 0;
rects[15] = height;
cogl_rectangles (rects, 4);
} }
void void
@ -2069,9 +2060,6 @@ st_theme_node_copy_cached_paint_state (StThemeNode *node,
g_return_if_fail (ST_IS_THEME_NODE (node)); g_return_if_fail (ST_IS_THEME_NODE (node));
g_return_if_fail (ST_IS_THEME_NODE (other)); g_return_if_fail (ST_IS_THEME_NODE (other));
if (node == other)
return;
/* Check omitted for speed: */ /* Check omitted for speed: */
/* g_return_if_fail (st_theme_node_paint_equal (node, other)); */ /* g_return_if_fail (st_theme_node_paint_equal (node, other)); */

View File

@ -77,8 +77,8 @@ struct _StThemeNode {
GType element_type; GType element_type;
char *element_id; char *element_id;
GStrv element_classes; char *element_class;
GStrv pseudo_classes; char *pseudo_class;
char *inline_style; char *inline_style;
CRDeclaration **properties; CRDeclaration **properties;

View File

@ -41,6 +41,7 @@ struct _StThemeNodeTransitionPrivate {
CoglHandle material; CoglHandle material;
ClutterAlpha *alpha;
ClutterTimeline *timeline; ClutterTimeline *timeline;
guint timeline_completed_id; guint timeline_completed_id;
@ -90,6 +91,7 @@ st_theme_node_transition_new (StThemeNode *from_node,
transition->priv->old_theme_node = g_object_ref (from_node); transition->priv->old_theme_node = g_object_ref (from_node);
transition->priv->new_theme_node = g_object_ref (to_node); transition->priv->new_theme_node = g_object_ref (to_node);
transition->priv->alpha = clutter_alpha_new ();
transition->priv->timeline = clutter_timeline_new (duration); transition->priv->timeline = clutter_timeline_new (duration);
transition->priv->timeline_completed_id = transition->priv->timeline_completed_id =
@ -99,7 +101,9 @@ st_theme_node_transition_new (StThemeNode *from_node,
g_signal_connect (transition->priv->timeline, "new-frame", g_signal_connect (transition->priv->timeline, "new-frame",
G_CALLBACK (on_timeline_new_frame), transition); G_CALLBACK (on_timeline_new_frame), transition);
clutter_timeline_set_progress_mode (transition->priv->timeline, CLUTTER_EASE_IN_OUT_QUAD); clutter_alpha_set_mode (transition->priv->alpha, CLUTTER_EASE_IN_OUT_QUAD);
clutter_alpha_set_timeline (transition->priv->alpha,
transition->priv->timeline);
clutter_timeline_start (transition->priv->timeline); clutter_timeline_start (transition->priv->timeline);
@ -330,7 +334,7 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
} }
cogl_color_set_from_4f (&constant, 0., 0., 0., cogl_color_set_from_4f (&constant, 0., 0., 0.,
clutter_timeline_get_progress (priv->timeline)); clutter_alpha_get_alpha (priv->alpha));
cogl_material_set_layer_combine_constant (priv->material, 1, &constant); cogl_material_set_layer_combine_constant (priv->material, 1, &constant);
cogl_material_set_color4ub (priv->material, cogl_material_set_color4ub (priv->material,
@ -408,6 +412,12 @@ st_theme_node_transition_dispose (GObject *object)
priv->timeline_completed_id = 0; priv->timeline_completed_id = 0;
priv->timeline_new_frame_id = 0; priv->timeline_new_frame_id = 0;
if (priv->alpha)
{
g_object_unref (priv->alpha);
priv->alpha = NULL;
}
G_OBJECT_CLASS (st_theme_node_transition_parent_class)->dispose (object); G_OBJECT_CLASS (st_theme_node_transition_parent_class)->dispose (object);
} }
@ -426,6 +436,8 @@ st_theme_node_transition_init (StThemeNodeTransition *transition)
transition->priv->new_offscreen = NULL; transition->priv->new_offscreen = NULL;
transition->priv->needs_setup = TRUE; transition->priv->needs_setup = TRUE;
transition->priv->alpha = NULL;
} }
static void static void

View File

@ -96,8 +96,8 @@ st_theme_node_finalize (GObject *object)
StThemeNode *node = ST_THEME_NODE (object); StThemeNode *node = ST_THEME_NODE (object);
g_free (node->element_id); g_free (node->element_id);
g_strfreev (node->element_classes); g_free (node->element_class);
g_strfreev (node->pseudo_classes); g_free (node->pseudo_class);
g_free (node->inline_style); g_free (node->inline_style);
if (node->properties) if (node->properties)
@ -145,33 +145,6 @@ st_theme_node_finalize (GObject *object)
G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object); G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object);
} }
static GStrv
split_on_whitespace (const gchar *s)
{
gchar *cur;
gchar *l;
gchar *temp;
GPtrArray *arr;
if (s == NULL)
return NULL;
arr = g_ptr_array_new ();
l = g_strdup (s);
cur = strtok_r (l, " \t\f\r\n", &temp);
while (cur != NULL)
{
g_ptr_array_add (arr, g_strdup (cur));
cur = strtok_r (NULL, " \t\f\r\n", &temp);
}
g_free (l);
g_ptr_array_add (arr, NULL);
return (GStrv) g_ptr_array_free (arr, FALSE);
}
/** /**
* st_theme_node_new: * st_theme_node_new:
* @context: the context representing global state for this themed tree * @context: the context representing global state for this themed tree
@ -228,8 +201,8 @@ st_theme_node_new (StThemeContext *context,
node->element_type = element_type; node->element_type = element_type;
node->element_id = g_strdup (element_id); node->element_id = g_strdup (element_id);
node->element_classes = split_on_whitespace (element_class); node->element_class = g_strdup (element_class);
node->pseudo_classes = split_on_whitespace (pseudo_class); node->pseudo_class = g_strdup (pseudo_class);
node->inline_style = g_strdup (inline_style); node->inline_style = g_strdup (inline_style);
return node; return node;
@ -284,30 +257,20 @@ st_theme_node_get_element_id (StThemeNode *node)
return node->element_id; return node->element_id;
} }
/** const char *
* st_theme_node_get_element_classes: st_theme_node_get_element_class (StThemeNode *node)
*
* Returns: (transfer none): the element's classes
*/
GStrv
st_theme_node_get_element_classes (StThemeNode *node)
{ {
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL); g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
return node->element_classes; return node->element_class;
} }
/** const char *
* st_theme_node_get_pseudo_classes: st_theme_node_get_pseudo_class (StThemeNode *node)
*
* Returns: (transfer none): the element's pseudo-classes
*/
GStrv
st_theme_node_get_pseudo_classes (StThemeNode *node)
{ {
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL); g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
return node->pseudo_classes; return node->pseudo_class;
} }
/** /**
@ -341,91 +304,16 @@ gboolean
st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b) st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b)
{ {
g_return_val_if_fail (ST_IS_THEME_NODE (node_a), FALSE); g_return_val_if_fail (ST_IS_THEME_NODE (node_a), FALSE);
if (node_a == node_b)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (node_b), FALSE); g_return_val_if_fail (ST_IS_THEME_NODE (node_b), FALSE);
if (node_a->parent_node != node_b->parent_node || return node_a->parent_node == node_b->parent_node &&
node_a->context != node_b->context || node_a->context == node_b->context &&
node_a->theme != node_b->theme || node_a->theme == node_b->theme &&
node_a->element_type != node_b->element_type || node_a->element_type == node_b->element_type &&
g_strcmp0 (node_a->element_id, node_b->element_id) || !g_strcmp0 (node_a->element_id, node_b->element_id) &&
g_strcmp0 (node_a->inline_style, node_b->inline_style)) !g_strcmp0 (node_a->element_class, node_b->element_class) &&
return FALSE; !g_strcmp0 (node_a->pseudo_class, node_b->pseudo_class) &&
!g_strcmp0 (node_a->inline_style, node_b->inline_style);
if ((node_a->element_classes == NULL) != (node_b->element_classes == NULL))
return FALSE;
if ((node_a->pseudo_classes == NULL) != (node_b->pseudo_classes == NULL))
return FALSE;
if (node_a->element_classes != NULL)
{
int i;
for (i = 0; ; i++)
{
if (g_strcmp0 (node_a->element_classes[i],
node_b->element_classes[i]))
return FALSE;
if (node_a->element_classes[i] == NULL)
break;
}
}
if (node_a->pseudo_classes != NULL)
{
int i;
for (i = 0; ; i++)
{
if (g_strcmp0 (node_a->pseudo_classes[i],
node_b->pseudo_classes[i]))
return FALSE;
if (node_a->pseudo_classes[i] == NULL)
break;
}
}
return TRUE;
}
guint
st_theme_node_hash (StThemeNode *node)
{
guint hash = GPOINTER_TO_UINT (node->parent_node);
hash = hash * 33 + GPOINTER_TO_UINT (node->context);
hash = hash * 33 + GPOINTER_TO_UINT (node->theme);
hash = hash * 33 + ((guint) node->element_type);
if (node->element_id != NULL)
hash = hash * 33 + g_str_hash (node->element_id);
if (node->inline_style != NULL)
hash = hash * 33 + g_str_hash (node->inline_style);
if (node->element_classes != NULL)
{
gchar **it;
for (it = node->element_classes; *it != NULL; it++)
hash = hash * 33 + g_str_hash (*it) + 1;
}
if (node->pseudo_classes != NULL)
{
gchar **it;
for (it = node->pseudo_classes; *it != NULL; it++)
hash = hash * 33 + g_str_hash (*it) + 1;
}
return hash;
} }
static void static void
@ -3552,10 +3440,6 @@ st_theme_node_geometry_equal (StThemeNode *node,
StSide side; StSide side;
g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE); g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE);
if (node == other)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE); g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE);
_st_theme_node_ensure_geometry (node); _st_theme_node_ensure_geometry (node);
@ -3600,10 +3484,6 @@ st_theme_node_paint_equal (StThemeNode *node,
int i; int i;
g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE); g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE);
if (node == other)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE); g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE);
_st_theme_node_ensure_background (node); _st_theme_node_ensure_background (node);

View File

@ -110,12 +110,11 @@ StThemeNode *st_theme_node_get_parent (StThemeNode *node);
StTheme *st_theme_node_get_theme (StThemeNode *node); StTheme *st_theme_node_get_theme (StThemeNode *node);
gboolean st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b); gboolean st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b);
guint st_theme_node_hash (StThemeNode *node);
GType st_theme_node_get_element_type (StThemeNode *node); GType st_theme_node_get_element_type (StThemeNode *node);
const char *st_theme_node_get_element_id (StThemeNode *node); const char *st_theme_node_get_element_id (StThemeNode *node);
GStrv st_theme_node_get_element_classes (StThemeNode *node); const char *st_theme_node_get_element_class (StThemeNode *node);
GStrv st_theme_node_get_pseudo_classes (StThemeNode *node); const char *st_theme_node_get_pseudo_class (StThemeNode *node);
/* Generic getters ... these are not cached so are less efficient. The other /* Generic getters ... these are not cached so are less efficient. The other
* reason for adding the more specific version is that we can handle the * reason for adding the more specific version is that we can handle the

View File

@ -448,17 +448,25 @@ st_theme_new (const char *application_stylesheet,
static gboolean static gboolean
string_in_list (GString *stryng, string_in_list (GString *stryng,
GStrv list) const char *list)
{ {
gchar **it; const char *cur;
if (list == NULL) for (cur = list; *cur;)
return FALSE;
for (it = list; *it != NULL; it++)
{ {
if (!strqcmp (*it, stryng->str, stryng->len)) while (*cur && cr_utils_is_white_space (*cur))
return TRUE; cur++;
if (strncmp (cur, stryng->str, stryng->len) == 0)
{
cur += stryng->len;
if ((!*cur) || cr_utils_is_white_space (*cur))
return TRUE;
}
/* skip to next whitespace character */
while (*cur && !cr_utils_is_white_space (*cur))
cur++;
} }
return FALSE; return FALSE;
@ -469,7 +477,7 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
CRAdditionalSel *a_add_sel, CRAdditionalSel *a_add_sel,
StThemeNode *a_node) StThemeNode *a_node)
{ {
GStrv node_pseudo_classes; const char *node_pseudo_class;
g_return_val_if_fail (a_this g_return_val_if_fail (a_this
&& a_add_sel && a_add_sel
@ -479,10 +487,12 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
&& a_add_sel->content.pseudo->name->stryng->str && a_add_sel->content.pseudo->name->stryng->str
&& a_node, FALSE); && a_node, FALSE);
node_pseudo_classes = st_theme_node_get_pseudo_classes (a_node); node_pseudo_class = st_theme_node_get_pseudo_class (a_node);
return string_in_list (a_add_sel->content.pseudo->name->stryng, if (node_pseudo_class == NULL)
node_pseudo_classes); return FALSE;
return string_in_list (a_add_sel->content.pseudo->name->stryng, node_pseudo_class);
} }
/** /**
@ -497,7 +507,7 @@ static gboolean
class_add_sel_matches_style (CRAdditionalSel *a_add_sel, class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
StThemeNode *a_node) StThemeNode *a_node)
{ {
GStrv element_classes; const char *element_class;
g_return_val_if_fail (a_add_sel g_return_val_if_fail (a_add_sel
&& a_add_sel->type == CLASS_ADD_SELECTOR && a_add_sel->type == CLASS_ADD_SELECTOR
@ -506,10 +516,11 @@ class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
&& a_add_sel->content.class_name->stryng->str && a_add_sel->content.class_name->stryng->str
&& a_node, FALSE); && a_node, FALSE);
element_classes = st_theme_node_get_element_classes (a_node); element_class = st_theme_node_get_element_class (a_node);
if (element_class == NULL)
return FALSE;
return string_in_list (a_add_sel->content.class_name->stryng, return string_in_list (a_add_sel->content.class_name->stryng, element_class);
element_classes);
} }
/* /*

View File

@ -589,8 +589,6 @@ st_widget_get_theme_node (StWidget *widget)
if (priv->theme_node == NULL) if (priv->theme_node == NULL)
{ {
StThemeContext *context;
StThemeNode *tmp_node;
StThemeNode *parent_node = NULL; StThemeNode *parent_node = NULL;
ClutterStage *stage = NULL; ClutterStage *stage = NULL;
ClutterActor *parent; ClutterActor *parent;
@ -631,20 +629,16 @@ st_widget_get_theme_node (StWidget *widget)
else else
pseudo_class = direction_pseudo_class; pseudo_class = direction_pseudo_class;
context = st_theme_context_get_for_stage (stage); priv->theme_node = st_theme_node_new (st_theme_context_get_for_stage (stage),
tmp_node = st_theme_node_new (context, parent_node, priv->theme, parent_node, priv->theme,
G_OBJECT_TYPE (widget), G_OBJECT_TYPE (widget),
clutter_actor_get_name (CLUTTER_ACTOR (widget)), clutter_actor_get_name (CLUTTER_ACTOR (widget)),
priv->style_class, priv->style_class,
pseudo_class, pseudo_class,
priv->inline_style); priv->inline_style);
if (pseudo_class != direction_pseudo_class) if (pseudo_class != direction_pseudo_class)
g_free (pseudo_class); g_free (pseudo_class);
priv->theme_node = g_object_ref (st_theme_context_intern_node (context,
tmp_node));
g_object_unref (tmp_node);
} }
return priv->theme_node; return priv->theme_node;
@ -1532,12 +1526,6 @@ st_widget_recompute_style (StWidget *widget,
int transition_duration; int transition_duration;
gboolean paint_equal; gboolean paint_equal;
if (new_theme_node == old_theme_node)
{
widget->priv->is_style_dirty = FALSE;
return;
}
if (!old_theme_node || if (!old_theme_node ||
!st_theme_node_geometry_equal (old_theme_node, new_theme_node)) !st_theme_node_geometry_equal (old_theme_node, new_theme_node))
clutter_actor_queue_relayout ((ClutterActor *) widget); clutter_actor_queue_relayout ((ClutterActor *) widget);

View File

@ -47,7 +47,7 @@ on_stage_realized (ClutterActor *stage,
gpointer data) gpointer data)
{ {
recorder = shell_recorder_new (CLUTTER_STAGE (stage)); recorder = shell_recorder_new (CLUTTER_STAGE (stage));
shell_recorder_set_file_template (recorder, "test-recorder.webm"); shell_recorder_set_file_template (recorder, "test-recorder.ogg");
shell_recorder_record (recorder); shell_recorder_record (recorder);
} }

View File

@ -18,7 +18,6 @@ TEST_JS = \
interactive/scrolling.js \ interactive/scrolling.js \
interactive/scroll-view-sizing.js \ interactive/scroll-view-sizing.js \
interactive/table.js \ interactive/table.js \
interactive/test-title.js \
interactive/transitions.js \ interactive/transitions.js \
testcommon/100-200.svg \ testcommon/100-200.svg \
testcommon/200-100.svg \ testcommon/200-100.svg \
@ -26,14 +25,11 @@ TEST_JS = \
testcommon/border-image.png \ testcommon/border-image.png \
testcommon/face-plain.png \ testcommon/face-plain.png \
testcommon/ui.js \ testcommon/ui.js \
testcommon/iso3166-test.tab \
testcommon/serviceproviders-test.xml \
unit/format.js \ unit/format.js \
unit/insertSorted.js \ unit/insertSorted.js \
unit/markup.js \ unit/markup.js \
unit/jsParse.js \ unit/jsParse.js \
unit/url.js \ unit/url.js
unit/mobileProviders.js
EXTRA_DIST += $(TEST_JS) EXTRA_DIST += $(TEST_JS)
TEST_MISC = \ TEST_MISC = \

View File

@ -1,3 +0,0 @@
# Test country list
ES Spain
US United States

View File

@ -1,44 +0,0 @@
<?xml version="1.0"?>
<!-- -*- Mode: XML; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- -->
<!DOCTYPE serviceproviders SYSTEM "serviceproviders.2.dtd">
<serviceproviders format="2.0">
<!-- United States -->
<country code="us">
<provider>
<name>AT&amp;T</name>
<gsm>
<network-id mcc="310" mnc="038"/>
<network-id mcc="310" mnc="090"/>
<network-id mcc="310" mnc="150"/>
</gsm>
</provider>
<provider>
<name>Verizon</name>
<gsm>
<network-id mcc="310" mnc="995"/>
<network-id mcc="311" mnc="480"/>
</gsm>
<cdma>
<sid value="2"/>
<sid value="4"/>
<sid value="5"/>
</cdma>
</provider>
</country>
<!-- Spain -->
<country code="es">
<provider>
<name>Movistar (Telefónica)</name>
<gsm>
<network-id mcc="214" mnc="05"/>
<network-id mcc="214" mnc="07"/>
</gsm>
</provider>
</country>
</serviceproviders>

View File

@ -1,78 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const GLib = imports.gi.GLib;
const Shell = imports.gi.Shell;
const JsUnit = imports.jsUnit;
const ModemManager = imports.misc.modemManager;
const Environment = imports.ui.environment;
Environment.init();
// Load test providers table
let countrycodesPath = GLib.getenv("GNOME_SHELL_TESTSDIR") + "/testcommon/iso3166-test.tab";
let serviceprovidersPath = GLib.getenv("GNOME_SHELL_TESTSDIR") + "/testcommon/serviceproviders-test.xml";
let providersTable = Shell.mobile_providers_parse(countrycodesPath, serviceprovidersPath);
function assertCountryFound(country_code, expected_country_name) {
let country = providersTable[country_code];
JsUnit.assertNotUndefined(country);
JsUnit.assertEquals(country.get_country_name(), expected_country_name);
}
function assertCountryNotFound(country_code) {
let country = providersTable[country_code];
JsUnit.assertUndefined(country);
}
function assertProviderFoundForMCCMNC(mccmnc, expected_provider_name) {
let provider_name = ModemManager.findProviderForMCCMNC(providersTable, mccmnc);
JsUnit.assertEquals(provider_name, expected_provider_name);
}
function assertProviderNotFoundForMCCMNC(mccmnc) {
let provider_name = ModemManager.findProviderForMCCMNC(providersTable, mccmnc);
JsUnit.assertNull(provider_name);
}
function assertProviderFoundForSid(sid, expected_provider_name) {
let provider_name = ModemManager.findProviderForSid(providersTable, sid);
JsUnit.assertEquals(provider_name, expected_provider_name);
}
function assertProviderNotFoundForSid(sid) {
let provider_name = ModemManager.findProviderForSid(providersTable, sid);
JsUnit.assertNull(provider_name);
}
// TEST:
// * Both 'US' and 'ES' country info should be loaded
assertCountryFound("ES", "Spain");
assertCountryFound("US", "United States");
// TEST:
// * Country info for 'FR' not given
assertCountryNotFound("FR");
// TEST:
// * Ensure operator names are found for the given MCC/MNC codes
assertProviderFoundForMCCMNC("21405", "Movistar (Telefónica)");
assertProviderFoundForMCCMNC("21407", "Movistar (Telefónica)");
assertProviderFoundForMCCMNC("310038", "AT&T");
assertProviderFoundForMCCMNC("310090", "AT&T");
assertProviderFoundForMCCMNC("310150", "AT&T");
assertProviderFoundForMCCMNC("310995", "Verizon");
assertProviderFoundForMCCMNC("311480", "Verizon");
// TEST:
// * Ensure NULL is given for unexpected MCC/MNC codes
assertProviderNotFoundForMCCMNC("12345");
// TEST:
// * Ensure operator names are found for the given SID codes
assertProviderFoundForSid(2, "Verizon");
assertProviderFoundForSid(4, "Verizon");
assertProviderFoundForSid(5, "Verizon");
// TEST:
// * Ensure NULL is given for unexpected SID codes
assertProviderNotFoundForSid(1);