endSessionDialog: Split into two sections
https://bugzilla.gnome.org/show_bug.cgi?id=706612
This commit is contained in:
parent
a779e2aeca
commit
dd8fd09470
@ -1884,6 +1884,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
spacing: 42px;
|
spacing: 42px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.end-session-dialog-list {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.end-session-dialog-subject {
|
.end-session-dialog-subject {
|
||||||
padding-left: 17px;
|
padding-left: 17px;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
@ -1917,46 +1921,30 @@ StScrollBar StButton#vhandle:active {
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.end-session-dialog-app-list {
|
.end-session-dialog-inhibitor-layout {
|
||||||
font-size: 10pt;
|
spacing: 16px;
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
padding-top: 42px;
|
padding-right: 50px;
|
||||||
padding-left: 49px;
|
padding-left: 50px;
|
||||||
padding-right: 32px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.end-session-dialog-app-list:rtl {
|
.end-session-dialog-list-header {
|
||||||
padding-right: 49px;
|
font-weight: bold;
|
||||||
padding-left: 32px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.end-session-dialog-app-list-item {
|
.end-session-dialog-app-list-item,
|
||||||
color: #ccc;
|
.end-session-dialog-session-list-item {
|
||||||
|
spacing: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.end-session-dialog-app-list-item:ltr {
|
.end-session-dialog-app-list-item-name,
|
||||||
padding-right: 1em;
|
.end-session-dialog-session-list-item-name {
|
||||||
}
|
font-weight: bold;
|
||||||
|
|
||||||
.end-session-dialog-app-list-item:rtl {
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.end-session-dialog-app-list-item-icon:ltr {
|
|
||||||
padding-right: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.end-session-dialog-app-list-item-icon:rtl {
|
|
||||||
padding-left: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.end-session-dialog-app-list-item-name {
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.end-session-dialog-app-list-item-description {
|
.end-session-dialog-app-list-item-description {
|
||||||
font-size: 8pt;
|
color: #cccccc;
|
||||||
color: #444444;
|
font-size: 10pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ShellMountOperation Dialogs */
|
/* ShellMountOperation Dialogs */
|
||||||
|
@ -139,39 +139,6 @@ function findAppFromInhibitor(inhibitor) {
|
|||||||
return Shell.AppSystem.get_default().lookup_heuristic_basename(desktopFile);
|
return Shell.AppSystem.get_default().lookup_heuristic_basename(desktopFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListItem = new Lang.Class({
|
|
||||||
Name: 'ListItem',
|
|
||||||
|
|
||||||
_init: function(icon, name, description) {
|
|
||||||
let layout = new St.BoxLayout({ vertical: false });
|
|
||||||
|
|
||||||
this.actor = new St.Bin({ style_class: 'end-session-dialog-app-list-item',
|
|
||||||
can_focus: true,
|
|
||||||
child: layout,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
x_fill: true });
|
|
||||||
|
|
||||||
let iconBin = new St.Bin({ style_class: 'end-session-dialog-app-list-item-icon',
|
|
||||||
child: icon });
|
|
||||||
layout.add(iconBin);
|
|
||||||
|
|
||||||
let textLayout = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item-text-box',
|
|
||||||
vertical: true });
|
|
||||||
layout.add(textLayout);
|
|
||||||
|
|
||||||
let nameLabel = new St.Label({ text: name,
|
|
||||||
style_class: 'end-session-dialog-app-list-item-name' });
|
|
||||||
textLayout.add(nameLabel, { expand: false, x_fill: true });
|
|
||||||
this.actor.label_actor = nameLabel;
|
|
||||||
|
|
||||||
if (description) {
|
|
||||||
let descriptionLabel = new St.Label({ text: description,
|
|
||||||
style_class: 'end-session-dialog-app-list-item-description' });
|
|
||||||
textLayout.add(descriptionLabel, { expand: true, x_fill: true });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// The logout timer only shows updates every 10 seconds
|
// The logout timer only shows updates every 10 seconds
|
||||||
// until the last 10 seconds, then it shows updates every
|
// until the last 10 seconds, then it shows updates every
|
||||||
// second. This function takes a given time and returns
|
// second. This function takes a given time and returns
|
||||||
@ -228,7 +195,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._secondsLeft = 0;
|
this._secondsLeft = 0;
|
||||||
this._totalSecondsToStayOpen = 0;
|
this._totalSecondsToStayOpen = 0;
|
||||||
this._inhibitors = [];
|
this._applications = [];
|
||||||
this._sessions = [];
|
this._sessions = [];
|
||||||
|
|
||||||
this.connect('destroy',
|
this.connect('destroy',
|
||||||
@ -269,28 +236,28 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
{ y_fill: true,
|
{ y_fill: true,
|
||||||
y_align: St.Align.START });
|
y_align: St.Align.START });
|
||||||
|
|
||||||
let scrollView = new St.ScrollView({ style_class: 'end-session-dialog-app-list'});
|
this._scrollView = new St.ScrollView({ style_class: 'end-session-dialog-list' });
|
||||||
scrollView.set_policy(Gtk.PolicyType.NEVER,
|
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||||
Gtk.PolicyType.AUTOMATIC);
|
this.contentLayout.add(this._scrollView,
|
||||||
this.contentLayout.add(scrollView,
|
|
||||||
{ x_fill: true,
|
{ x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
scrollView.hide();
|
this._scrollView.hide();
|
||||||
|
|
||||||
|
this._inhibitorSection = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'end-session-dialog-inhibitor-layout' });
|
||||||
|
this._scrollView.add_actor(this._inhibitorSection);
|
||||||
|
|
||||||
|
this._applicationHeader = new St.Label({ style_class: 'end-session-dialog-list-header',
|
||||||
|
text: _("Some applications are busy or have unsaved work.") });
|
||||||
this._applicationList = new St.BoxLayout({ vertical: true });
|
this._applicationList = new St.BoxLayout({ vertical: true });
|
||||||
scrollView.add_actor(this._applicationList);
|
this._inhibitorSection.add_actor(this._applicationHeader);
|
||||||
|
this._inhibitorSection.add_actor(this._applicationList);
|
||||||
|
|
||||||
this._applicationList.connect('actor-added',
|
this._sessionHeader = new St.Label({ style_class: 'end-session-dialog-list-header',
|
||||||
Lang.bind(this, function() {
|
text: _("Other users are logged in.") });
|
||||||
if (this._applicationList.get_n_children() == 1)
|
this._sessionList = new St.BoxLayout({ vertical: true });
|
||||||
scrollView.show();
|
this._inhibitorSection.add_actor(this._sessionHeader);
|
||||||
}));
|
this._inhibitorSection.add_actor(this._sessionList);
|
||||||
|
|
||||||
this._applicationList.connect('actor-removed',
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
if (this._applicationList.get_n_children() == 0)
|
|
||||||
scrollView.hide();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
|
||||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
||||||
@ -347,6 +314,12 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
this._iconBin.child = avatarWidget.actor;
|
this._iconBin.child = avatarWidget.actor;
|
||||||
avatarWidget.update();
|
avatarWidget.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hasApplications = this._applications.length > 0;
|
||||||
|
let hasSessions = this._sessions.length > 0;
|
||||||
|
this._scrollView.visible = hasApplications || hasSessions;
|
||||||
|
this._applicationHeader.visible = hasApplications;
|
||||||
|
this._sessionHeader.visible = hasSessions;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateButtons: function() {
|
_updateButtons: function() {
|
||||||
@ -427,8 +400,33 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
this._secondsLeft = 0;
|
this._secondsLeft = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_constructListItemForApp: function(inhibitor, app) {
|
||||||
|
let actor = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item',
|
||||||
|
can_focus: true });
|
||||||
|
actor.add(app.create_icon_texture(_ITEM_ICON_SIZE));
|
||||||
|
|
||||||
|
let textLayout = new St.BoxLayout({ vertical: true,
|
||||||
|
y_expand: true,
|
||||||
|
y_align: Clutter.ActorAlign.CENTER });
|
||||||
|
actor.add(textLayout);
|
||||||
|
|
||||||
|
let nameLabel = new St.Label({ text: app.get_name(),
|
||||||
|
style_class: 'end-session-dialog-app-list-item-name' });
|
||||||
|
textLayout.add(nameLabel);
|
||||||
|
actor.label_actor = nameLabel;
|
||||||
|
|
||||||
|
let [reason] = inhibitor.GetReasonSync();
|
||||||
|
if (reason) {
|
||||||
|
let reasonLabel = new St.Label({ text: reason,
|
||||||
|
style_class: 'end-session-dialog-app-list-item-description' });
|
||||||
|
textLayout.add(reasonLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actor;
|
||||||
|
},
|
||||||
|
|
||||||
_onInhibitorLoaded: function(inhibitor) {
|
_onInhibitorLoaded: function(inhibitor) {
|
||||||
if (this._inhibitors.indexOf(inhibitor) < 0) {
|
if (this._applications.indexOf(inhibitor) < 0) {
|
||||||
// Stale inhibitor
|
// Stale inhibitor
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -436,17 +434,46 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
let app = findAppFromInhibitor(inhibitor);
|
let app = findAppFromInhibitor(inhibitor);
|
||||||
|
|
||||||
if (app) {
|
if (app) {
|
||||||
let [reason] = inhibitor.GetReasonSync();
|
let actor = this._constructListItemForApp(inhibitor, app);
|
||||||
let item = new ListItem(app.create_icon_texture(_ITEM_ICON_SIZE), app.get_name(), reason);
|
this._applicationList.add(actor);
|
||||||
this._applicationList.add(item.actor, { x_fill: true });
|
|
||||||
} else {
|
} else {
|
||||||
// inhibiting app is a service, not an application
|
// inhibiting app is a service, not an application
|
||||||
this._inhibitors.splice(this._inhibitors.indexOf(inhibitor), 1);
|
this._applications.splice(this._applications.indexOf(inhibitor), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._sync();
|
this._sync();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_constructListItemForSession: function(session) {
|
||||||
|
let avatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
|
||||||
|
avatar.update();
|
||||||
|
|
||||||
|
let userName = session.user.get_real_name() ? session.user.get_real_name() : session.username;
|
||||||
|
let userLabelText;
|
||||||
|
|
||||||
|
if (session.remote)
|
||||||
|
/* Translators: Remote here refers to a remote session, like a ssh login */
|
||||||
|
userLabelText = _("%s (remote)").format(userName);
|
||||||
|
else if (session.type == "tty")
|
||||||
|
/* Translators: Console here refers to a tty like a VT console */
|
||||||
|
userLabelText = _("%s (console)").format(userName);
|
||||||
|
else
|
||||||
|
userLabelText = userName;
|
||||||
|
|
||||||
|
let actor = new St.BoxLayout({ style_class: 'end-session-dialog-session-list-item',
|
||||||
|
can_focus: true });
|
||||||
|
actor.add(avatar.actor);
|
||||||
|
|
||||||
|
let nameLabel = new St.Label({ text: userLabelText,
|
||||||
|
style_class: 'end-session-dialog-session-list-item-name',
|
||||||
|
y_expand: true,
|
||||||
|
y_align: Clutter.ActorAlign.CENTER });
|
||||||
|
actor.add(nameLabel);
|
||||||
|
actor.label_actor = nameLabel;
|
||||||
|
|
||||||
|
return actor;
|
||||||
|
},
|
||||||
|
|
||||||
_loadSessions: function() {
|
_loadSessions: function() {
|
||||||
this._loginManager.listSessions(Lang.bind(this, function(result) {
|
this._loginManager.listSessions(Lang.bind(this, function(result) {
|
||||||
let n = 0;
|
let n = 0;
|
||||||
@ -469,25 +496,8 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
remote: proxy.Remote };
|
remote: proxy.Remote };
|
||||||
this._sessions.push(session);
|
this._sessions.push(session);
|
||||||
|
|
||||||
let avatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
|
let actor = this._constructListItemForSession(session);
|
||||||
avatar.update();
|
this._sessionList.add(actor);
|
||||||
|
|
||||||
let userLabel = session.user.get_real_name() ? session.user.get_real_name() : userName;
|
|
||||||
let userLabelText;
|
|
||||||
|
|
||||||
if (session.remote)
|
|
||||||
/* Translators: Remote here refers to a remote session, like a ssh login */
|
|
||||||
userLabelText = _("%s (remote)").format(userName);
|
|
||||||
else if (session.type == "tty")
|
|
||||||
/* Translators: Console here refers to a tty like a VT console */
|
|
||||||
userLabelText = _("%s (console)").format(userName);
|
|
||||||
else
|
|
||||||
userLabelText = userName;
|
|
||||||
|
|
||||||
let item = new ListItem(avatar.actor, userLabelText);
|
|
||||||
|
|
||||||
// XXX -- put them in their own inhibitor section
|
|
||||||
this._applicationList.add(item.actor, { x_fill: true });
|
|
||||||
|
|
||||||
// limit the number of entries
|
// limit the number of entries
|
||||||
n++;
|
n++;
|
||||||
@ -502,10 +512,14 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
OpenAsync: function(parameters, invocation) {
|
OpenAsync: function(parameters, invocation) {
|
||||||
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
|
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
|
||||||
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
||||||
this._inhibitors = [];
|
|
||||||
this._applicationList.destroy_all_children();
|
|
||||||
this._type = type;
|
this._type = type;
|
||||||
|
|
||||||
|
this._applications = [];
|
||||||
|
this._applicationList.destroy_all_children();
|
||||||
|
|
||||||
|
this._sessions = [];
|
||||||
|
this._sessionList.destroy_all_children();
|
||||||
|
|
||||||
if (!(this._type in DialogContent)) {
|
if (!(this._type in DialogContent)) {
|
||||||
invocation.return_dbus_error('org.gnome.Shell.ModalDialog.TypeError',
|
invocation.return_dbus_error('org.gnome.Shell.ModalDialog.TypeError',
|
||||||
"Unknown dialog type requested");
|
"Unknown dialog type requested");
|
||||||
@ -517,7 +531,7 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
this._onInhibitorLoaded(proxy);
|
this._onInhibitorLoaded(proxy);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._inhibitors.push(inhibitor);
|
this._applications.push(inhibitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._loadSessions();
|
this._loadSessions();
|
||||||
|
Loading…
Reference in New Issue
Block a user