endSessionDialog: Add logout/shutdown dialog
This commit adds a dialog for gnome-session to privately use when initiating log outs and shut downs. Coordination is done over the bus. https://bugzilla.gnome.org/show_bug.cgi?id=637187
This commit is contained in:
parent
2905b0318d
commit
e73e4375b8
@ -1165,6 +1165,62 @@ StTooltip StLabel {
|
|||||||
background-color: rgba(0, 0, 0, 0.4);
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* End Session Dialog */
|
||||||
|
.end-session-dialog-subject {
|
||||||
|
font: 12pt sans-serif;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #666666;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 17px;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-description {
|
||||||
|
font: 10pt sans-serif;
|
||||||
|
color: white;
|
||||||
|
padding-left: 17px;
|
||||||
|
padding-right: 40px;
|
||||||
|
width: 16em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-logout-icon {
|
||||||
|
border: 2px solid #8b8b8b;
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-shutdown-icon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-app-list {
|
||||||
|
font: 10pt sans-serif;
|
||||||
|
max-height: 200px;
|
||||||
|
padding-top: 42px;
|
||||||
|
padding-bottom: 42px;
|
||||||
|
padding-left: 17px;
|
||||||
|
padding-right: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-app-list-item {
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-app-list-item-icon {
|
||||||
|
padding-right: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-app-list-item-name {
|
||||||
|
font: 10pt sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-app-list-item-description {
|
||||||
|
font: 8pt sans-serif;
|
||||||
|
color: #444444;
|
||||||
|
}
|
||||||
|
|
||||||
/* Magnifier */
|
/* Magnifier */
|
||||||
|
|
||||||
.magnifier-zoom-region {
|
.magnifier-zoom-region {
|
||||||
|
@ -21,6 +21,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/dash.js \
|
ui/dash.js \
|
||||||
ui/dnd.js \
|
ui/dnd.js \
|
||||||
ui/docDisplay.js \
|
ui/docDisplay.js \
|
||||||
|
ui/endSessionDialog.js \
|
||||||
ui/environment.js \
|
ui/environment.js \
|
||||||
ui/extensionSystem.js \
|
ui/extensionSystem.js \
|
||||||
ui/genericDisplay.js \
|
ui/genericDisplay.js \
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const DBus = imports.dbus;
|
const DBus = imports.dbus;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const PresenceIface = {
|
const PresenceIface = {
|
||||||
name: 'org.gnome.SessionManager.Presence',
|
name: 'org.gnome.SessionManager.Presence',
|
||||||
@ -43,3 +44,60 @@ Presence.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
DBus.proxifyPrototype(Presence.prototype, PresenceIface);
|
DBus.proxifyPrototype(Presence.prototype, PresenceIface);
|
||||||
|
|
||||||
|
// Note inhibitors are immutable objects, so they don't
|
||||||
|
// change at runtime (changes always come in the form
|
||||||
|
// of new inhibitors)
|
||||||
|
const InhibitorIface = {
|
||||||
|
name: 'org.gnome.SessionManager.Inhibitor',
|
||||||
|
properties: [{ name: 'app_id',
|
||||||
|
signature: 's',
|
||||||
|
access: 'readonly' },
|
||||||
|
{ name: 'client_id',
|
||||||
|
signature: 's',
|
||||||
|
access: 'readonly' },
|
||||||
|
{ name: 'reason',
|
||||||
|
signature: 's',
|
||||||
|
access: 'readonly' },
|
||||||
|
{ name: 'flags',
|
||||||
|
signature: 'u',
|
||||||
|
access: 'readonly' },
|
||||||
|
{ name: 'toplevel_xid',
|
||||||
|
signature: 'u',
|
||||||
|
access: 'readonly' },
|
||||||
|
{ name: 'cookie',
|
||||||
|
signature: 'u',
|
||||||
|
access: 'readonly' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
function Inhibitor(objectPath) {
|
||||||
|
this._init(objectPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
Inhibitor.prototype = {
|
||||||
|
_init: function(objectPath) {
|
||||||
|
DBus.session.proxifyObject(this,
|
||||||
|
"org.gnome.SessionManager",
|
||||||
|
objectPath);
|
||||||
|
this.isLoaded = false;
|
||||||
|
this._loadingPropertiesCount = InhibitorIface.properties.length;
|
||||||
|
for (let i = 0; i < InhibitorIface.properties.length; i++) {
|
||||||
|
let propertyName = InhibitorIface.properties[i].name;
|
||||||
|
this.GetRemote(propertyName, Lang.bind(this,
|
||||||
|
function(value, exception) {
|
||||||
|
if (exception)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this[propertyName] = value;
|
||||||
|
this._loadingPropertiesCount--;
|
||||||
|
|
||||||
|
if (this._loadingPropertiesCount == 0) {
|
||||||
|
this.isLoaded = true;
|
||||||
|
this.emit("is-loaded");
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
DBus.proxifyPrototype(Inhibitor.prototype, InhibitorIface);
|
||||||
|
Signals.addSignalMethods(Inhibitor.prototype);
|
||||||
|
504
js/ui/endSessionDialog.js
Normal file
504
js/ui/endSessionDialog.js
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||||
|
*
|
||||||
|
* Copyright 2010 Red Hat, Inc
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const DBus = imports.dbus;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gdm = imports.gi.Gdm;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const Pango = imports.gi.Pango;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const GnomeSession = imports.misc.gnomeSession
|
||||||
|
const Lightbox = imports.ui.lightbox;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
let _endSessionDialog = null;
|
||||||
|
|
||||||
|
const _ITEM_ICON_SIZE = 48;
|
||||||
|
const _DIALOG_ICON_SIZE = 32;
|
||||||
|
|
||||||
|
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
|
||||||
|
|
||||||
|
const EndSessionDialogIface = {
|
||||||
|
name: 'org.gnome.SessionManager.EndSessionDialog',
|
||||||
|
methods: [{ name: 'Open',
|
||||||
|
inSignature: 'uuuao',
|
||||||
|
outSignature: ''
|
||||||
|
}
|
||||||
|
],
|
||||||
|
signals: [{ name: 'Canceled',
|
||||||
|
outSignature: '',
|
||||||
|
}],
|
||||||
|
properties: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const logoutDialogContent = {
|
||||||
|
subjectWithUser: _("Log Out %s"),
|
||||||
|
subject: _("Log Out"),
|
||||||
|
inhibitedDescription: _("Click Log Out to quit these applications and log out of the system."),
|
||||||
|
uninhibitedDescriptionWithUser: _("%s will be logged out automatically in %d seconds."),
|
||||||
|
uninhibitedDescription: _("You will be logged out automatically in %d seconds."),
|
||||||
|
endDescription: _("Logging out of the system."),
|
||||||
|
confirmButtonText: _("Log Out"),
|
||||||
|
iconStyleClass: 'end-session-dialog-logout-icon'
|
||||||
|
};
|
||||||
|
|
||||||
|
const shutdownDialogContent = {
|
||||||
|
subject: _("Shut Down"),
|
||||||
|
inhibitedDescription: _("Click Shut Down to quit these applications and shut down the system."),
|
||||||
|
uninhibitedDescription: _("The system will shut down automatically in %d seconds."),
|
||||||
|
endDescription: _("Shutting down the system."),
|
||||||
|
confirmButtonText: _("Shut Down"),
|
||||||
|
iconName: 'system-shutdown',
|
||||||
|
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
||||||
|
};
|
||||||
|
|
||||||
|
const restartDialogContent = {
|
||||||
|
subject: _("Restart"),
|
||||||
|
inhibitedDescription: _("Click Restart to quit these applications and restart the system."),
|
||||||
|
uninhibitedDescription: _("The system will restart automatically in %d seconds."),
|
||||||
|
endDescription: _("Restarting the system."),
|
||||||
|
confirmButtonText: _("Restart"),
|
||||||
|
iconName: 'system-shutdown',
|
||||||
|
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
||||||
|
};
|
||||||
|
|
||||||
|
const DialogContent = {
|
||||||
|
0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */: logoutDialogContent,
|
||||||
|
1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */: shutdownDialogContent,
|
||||||
|
2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */: restartDialogContent
|
||||||
|
};
|
||||||
|
|
||||||
|
function findAppFromInhibitor(inhibitor) {
|
||||||
|
let desktopFile = inhibitor.app_id;
|
||||||
|
|
||||||
|
if (!GLib.str_has_suffix(desktopFile, '.desktop'))
|
||||||
|
desktopFile += '.desktop';
|
||||||
|
|
||||||
|
let candidateDesktopFiles = [];
|
||||||
|
|
||||||
|
candidateDesktopFiles.push(desktopFile);
|
||||||
|
candidateDesktopFiles.push('gnome-' + desktopFile);
|
||||||
|
|
||||||
|
let appSystem = Shell.AppSystem.get_default();
|
||||||
|
let app = null;
|
||||||
|
for (let i = 0; i < candidateDesktopFiles.length; i++) {
|
||||||
|
try {
|
||||||
|
app = appSystem.get_app(candidateDesktopFiles[i]);
|
||||||
|
|
||||||
|
if (app)
|
||||||
|
break;
|
||||||
|
} catch(e) {
|
||||||
|
// ignore errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ListItem(app, reason) {
|
||||||
|
this._init(app, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListItem.prototype = {
|
||||||
|
_init: function(app, reason) {
|
||||||
|
this._app = app;
|
||||||
|
this._reason = reason;
|
||||||
|
|
||||||
|
if (this._reason == null)
|
||||||
|
this._reason = '';
|
||||||
|
|
||||||
|
let layout = new St.BoxLayout({ vertical: false});
|
||||||
|
|
||||||
|
this.actor = new St.Clickable({ style_class: 'end-session-dialog-app-list-item',
|
||||||
|
can_focus: true,
|
||||||
|
child: layout,
|
||||||
|
reactive: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
x_fill: true });
|
||||||
|
|
||||||
|
this._icon = this._app.create_icon_texture(_ITEM_ICON_SIZE);
|
||||||
|
|
||||||
|
let iconBin = new St.Bin({ style_class: 'end-session-dialog-app-list-item-icon',
|
||||||
|
child: this._icon });
|
||||||
|
layout.add(iconBin);
|
||||||
|
|
||||||
|
let textLayout = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item-text-box',
|
||||||
|
vertical: true });
|
||||||
|
layout.add(textLayout);
|
||||||
|
|
||||||
|
this._nameLabel = new St.Label({ text: this._app.get_name(),
|
||||||
|
style_class: 'end-session-dialog-app-list-item-name' });
|
||||||
|
textLayout.add(this._nameLabel,
|
||||||
|
{ expand: false,
|
||||||
|
x_fill: true });
|
||||||
|
|
||||||
|
this._descriptionLabel = new St.Label({ text: this._reason,
|
||||||
|
style_class: 'end-session-dialog-app-list-item-description' });
|
||||||
|
textLayout.add(this._descriptionLabel,
|
||||||
|
{ expand: true,
|
||||||
|
x_fill: true });
|
||||||
|
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onClicked: function() {
|
||||||
|
this.emit('activate');
|
||||||
|
this._app.activate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(ListItem.prototype);
|
||||||
|
|
||||||
|
// The logout timer only shows updates every 10 seconds
|
||||||
|
// until the last 10 seconds, then it shows updates every
|
||||||
|
// second. This function takes a given time and returns
|
||||||
|
// what we should show to the user for that time.
|
||||||
|
function _roundSecondsToInterval(totalSeconds, secondsLeft, interval) {
|
||||||
|
let time;
|
||||||
|
|
||||||
|
time = Math.ceil(secondsLeft);
|
||||||
|
|
||||||
|
// Final count down is in decrements of 1
|
||||||
|
if (time <= interval)
|
||||||
|
return time;
|
||||||
|
|
||||||
|
// Round up higher than last displayable time interval
|
||||||
|
time += interval - 1;
|
||||||
|
|
||||||
|
// Then round down to that time interval
|
||||||
|
if (time > totalSeconds)
|
||||||
|
time = Math.ceil(totalSeconds);
|
||||||
|
else
|
||||||
|
time -= time % interval;
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _setLabelText(label, text) {
|
||||||
|
if (text) {
|
||||||
|
label.set_text(text);
|
||||||
|
label.show();
|
||||||
|
} else {
|
||||||
|
label.set_text('');
|
||||||
|
label.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function EndSessionDialog() {
|
||||||
|
if (_endSessionDialog == null) {
|
||||||
|
this._init();
|
||||||
|
DBus.session.exportObject('/org/gnome/SessionManager/EndSessionDialog',
|
||||||
|
this);
|
||||||
|
_endSessionDialog = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _endSessionDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
// This always returns the same singleton object
|
||||||
|
// By instantiating it initially, we register the
|
||||||
|
// bus object, etc.
|
||||||
|
let dialog = new EndSessionDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndSessionDialog.prototype = {
|
||||||
|
__proto__: ModalDialog.ModalDialog.prototype,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
ModalDialog.ModalDialog.prototype._init.call(this);
|
||||||
|
|
||||||
|
this._user = Gdm.UserManager.ref_default().get_user(GLib.get_user_name());
|
||||||
|
|
||||||
|
this._secondsLeft = 0;
|
||||||
|
this._totalSecondsToStayOpen = 0;
|
||||||
|
this._inhibitors = [];
|
||||||
|
|
||||||
|
this.connect('destroy',
|
||||||
|
Lang.bind(this, this._onDestroy));
|
||||||
|
this.connect('opened',
|
||||||
|
Lang.bind(this, this._onOpened));
|
||||||
|
|
||||||
|
this._userLoadedId = this._user.connect('notify::is_loaded',
|
||||||
|
Lang.bind(this, this._updateContent));
|
||||||
|
|
||||||
|
this._userChangedId = this._user.connect('changed',
|
||||||
|
Lang.bind(this, this._updateContent));
|
||||||
|
|
||||||
|
let mainContentLayout = new St.BoxLayout({ vertical: false });
|
||||||
|
this.contentLayout.add(mainContentLayout,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false });
|
||||||
|
|
||||||
|
this._iconBin = new St.Bin();
|
||||||
|
mainContentLayout.add(this._iconBin,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.END,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
let messageLayout = new St.BoxLayout({ vertical: true });
|
||||||
|
mainContentLayout.add(messageLayout,
|
||||||
|
{ y_align: St.Align.START });
|
||||||
|
|
||||||
|
this._subjectLabel = new St.Label({ style_class: 'end-session-dialog-subject' });
|
||||||
|
|
||||||
|
messageLayout.add(this._subjectLabel,
|
||||||
|
{ y_fill: false,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
this._descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description' });
|
||||||
|
this._descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
|
this._descriptionLabel.clutter_text.line_wrap = true;
|
||||||
|
|
||||||
|
messageLayout.add(this._descriptionLabel,
|
||||||
|
{ y_fill: true,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
let scrollView = new St.ScrollView({ style_class: 'end-session-dialog-app-list'});
|
||||||
|
scrollView.set_policy(Gtk.PolicyType.NEVER,
|
||||||
|
Gtk.PolicyType.AUTOMATIC);
|
||||||
|
this.contentLayout.add(scrollView,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: true });
|
||||||
|
this._applicationList = new St.BoxLayout({ vertical: true });
|
||||||
|
scrollView.add_actor(this._applicationList,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDestroy: function() {
|
||||||
|
this._user.disconnect(this._userLoadedId);
|
||||||
|
this._user.disconnect(this._userChangedId);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setIconFromFile: function(iconFile, styleClass) {
|
||||||
|
if (styleClass)
|
||||||
|
this._iconBin.set_style_class_name(styleClass);
|
||||||
|
this._iconBin.set_style(null);
|
||||||
|
|
||||||
|
this._iconBin.child = null;
|
||||||
|
if (iconFile) {
|
||||||
|
this._iconBin.show();
|
||||||
|
this._iconBin.set_style('background-image: url("' + iconFile + '");');
|
||||||
|
} else {
|
||||||
|
this._iconBin.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_setIconFromName: function(iconName, styleClass) {
|
||||||
|
if (styleClass)
|
||||||
|
this._iconBin.set_style_class_name(styleClass);
|
||||||
|
this._iconBin.set_style(null);
|
||||||
|
|
||||||
|
if (iconName != null) {
|
||||||
|
let textureCache = St.TextureCache.get_default();
|
||||||
|
let icon = textureCache.load_icon_name(this._iconBin.get_theme_node(),
|
||||||
|
iconName,
|
||||||
|
St.IconType.SYMBOLIC,
|
||||||
|
_DIALOG_ICON_SIZE);
|
||||||
|
|
||||||
|
this._iconBin.child = icon;
|
||||||
|
this._iconBin.show();
|
||||||
|
} else {
|
||||||
|
this._iconBin.child = null;
|
||||||
|
this._iconBin.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateContent: function() {
|
||||||
|
if (this.state != ModalDialog.State.OPENING &&
|
||||||
|
this.state != ModalDialog.State.OPENED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let dialogContent = DialogContent[this._type];
|
||||||
|
|
||||||
|
let subject = dialogContent.subject;
|
||||||
|
let description;
|
||||||
|
|
||||||
|
if (this._user.is_loaded && !dialogContent.iconName) {
|
||||||
|
let iconFile = this._user.get_icon_file();
|
||||||
|
|
||||||
|
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
|
||||||
|
} else if (dialogContent.iconName) {
|
||||||
|
this._setIconFromName(dialogContent.iconName,
|
||||||
|
dialogContent.iconStyleClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._inhibitors.length > 0) {
|
||||||
|
this._stopTimer();
|
||||||
|
description = dialogContent.inhibitedDescription;
|
||||||
|
} else if (this._secondsLeft > 0 && this._inhibitors.length == 0) {
|
||||||
|
let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
|
||||||
|
this._secondsLeft,
|
||||||
|
10);
|
||||||
|
|
||||||
|
if (this._user.is_loaded) {
|
||||||
|
let realName = this._user.get_real_name();
|
||||||
|
|
||||||
|
if (realName != null) {
|
||||||
|
if (dialogContent.subjectWithUser)
|
||||||
|
subject = dialogContent.subjectWithUser.format(realName);
|
||||||
|
|
||||||
|
if (dialogContent.uninhibitedDescriptionWithUser)
|
||||||
|
description = dialogContent.uninhibitedDescriptionWithUser.format(realName, displayTime);
|
||||||
|
else
|
||||||
|
description = dialogContent.uninhibitedDescription.format(displayTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!description)
|
||||||
|
description = dialogContent.uninhibitedDescription.format(displayTime);
|
||||||
|
} else {
|
||||||
|
description = dialogContent.endDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
_setLabelText(this._subjectLabel, subject);
|
||||||
|
_setLabelText(this._descriptionLabel, description);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateButtons: function() {
|
||||||
|
if (this.state != ModalDialog.State.OPENING &&
|
||||||
|
this.state != ModalDialog.State.OPENED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let dialogContent = DialogContent[this._type];
|
||||||
|
let confirmButtonText = _("Confirm");
|
||||||
|
|
||||||
|
if (dialogContent.confirmButtonText)
|
||||||
|
confirmButtonText = dialogContent.confirmButtonText;
|
||||||
|
|
||||||
|
this.setButtons([{ label: _("Cancel"),
|
||||||
|
action: Lang.bind(this, this.cancel),
|
||||||
|
key: Clutter.Escape
|
||||||
|
},
|
||||||
|
{ label: confirmButtonText,
|
||||||
|
action: Lang.bind(this, this._confirm)
|
||||||
|
}]);
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
this._stopTimer();
|
||||||
|
DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
|
||||||
|
'org.gnome.SessionManager.EndSessionDialog',
|
||||||
|
'Canceled', '', []);
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
},
|
||||||
|
|
||||||
|
_confirm: function() {
|
||||||
|
this._fadeOutDialog();
|
||||||
|
this._stopTimer();
|
||||||
|
DBus.session.emit_signal('/org/gnome/SessionManager/EndSessionDialog',
|
||||||
|
'org.gnome.SessionManager.EndSessionDialog',
|
||||||
|
'Confirmed', '', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onOpened: function() {
|
||||||
|
if (this._inhibitors.length == 0)
|
||||||
|
this._startTimer();
|
||||||
|
},
|
||||||
|
|
||||||
|
_startTimer: function() {
|
||||||
|
this._secondsLeft = this._totalSecondsToStayOpen;
|
||||||
|
Tweener.addTween(this,
|
||||||
|
{ _secondsLeft: 0,
|
||||||
|
time: this._secondsLeft,
|
||||||
|
transition: 'linear',
|
||||||
|
onUpdate: Lang.bind(this, this._updateContent),
|
||||||
|
onComplete: Lang.bind(this, this._confirm),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_stopTimer: function() {
|
||||||
|
Tweener.removeTweens(this);
|
||||||
|
this._secondsLeft = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInhibitorLoaded: function(inhibitor) {
|
||||||
|
if (this._inhibitors.indexOf(inhibitor) < 0) {
|
||||||
|
// Stale inhibitor
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let app = findAppFromInhibitor(inhibitor);
|
||||||
|
|
||||||
|
if (app) {
|
||||||
|
let item = new ListItem(app, inhibitor.reason);
|
||||||
|
item.connect('activate',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
}));
|
||||||
|
this._applicationList.add(item.actor, { x_fill: true });
|
||||||
|
this._stopTimer();
|
||||||
|
} else {
|
||||||
|
// inhibiting app is a service, not an application
|
||||||
|
this._inhibitors.splice(this._inhibitors.indexOf(inhibitor), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateContent();
|
||||||
|
},
|
||||||
|
|
||||||
|
OpenAsync: function(type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths, callback) {
|
||||||
|
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
||||||
|
this._inhibitors = [];
|
||||||
|
this._applicationList.remove_all();
|
||||||
|
this._type = type;
|
||||||
|
|
||||||
|
if (!(this._type in DialogContent))
|
||||||
|
throw new DBus.DBusError('org.gnome.Shell.ModalDialog.TypeError',
|
||||||
|
"Unknown dialog type requested");
|
||||||
|
|
||||||
|
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
|
||||||
|
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i]);
|
||||||
|
|
||||||
|
inhibitor.connect('is-loaded',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._onInhibitorLoaded(inhibitor);
|
||||||
|
}));
|
||||||
|
this._inhibitors.push(inhibitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.open(timestamp))
|
||||||
|
throw new DBus.DBusError('org.gnome.Shell.ModalDialog.GrabError',
|
||||||
|
"Cannot grab pointer and keyboard");
|
||||||
|
|
||||||
|
this._updateButtons();
|
||||||
|
this._updateContent();
|
||||||
|
|
||||||
|
let signalId = this.connect('opened',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
callback();
|
||||||
|
this.disconnect(signalId);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
DBus.conformExport(EndSessionDialog.prototype, EndSessionDialogIface);
|
@ -22,6 +22,7 @@ const _ = Gettext.gettext;
|
|||||||
|
|
||||||
const Chrome = imports.ui.chrome;
|
const Chrome = imports.ui.chrome;
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
|
const EndSessionDialog = imports.ui.endSessionDialog;
|
||||||
const Environment = imports.ui.environment;
|
const Environment = imports.ui.environment;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
@ -171,6 +172,10 @@ function start() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Provide the bus object for gnome-session to
|
||||||
|
// initiate logouts.
|
||||||
|
EndSessionDialog.init();
|
||||||
|
|
||||||
global.gdk_screen.connect('monitors-changed', _relayout);
|
global.gdk_screen.connect('monitors-changed', _relayout);
|
||||||
|
|
||||||
ExtensionSystem.init();
|
ExtensionSystem.init();
|
||||||
|
Loading…
Reference in New Issue
Block a user