|
|
13bb5b |
From b0f59711785d43d0d3dd76e09064e36bea516e1b Mon Sep 17 00:00:00 2001
|
|
|
13bb5b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
13bb5b |
Date: Wed, 12 Nov 2014 11:27:50 -0500
|
|
|
13bb5b |
Subject: [PATCH 1/5] Revert "loginDialog: make banner message more prominent."
|
|
|
13bb5b |
|
|
|
13bb5b |
This reverts commit 1f00c48feb75a8749b80a7cace94f622df825f7c.
|
|
|
13bb5b |
---
|
|
|
13bb5b |
data/theme/gnome-shell.css | 13 ++++++++-----
|
|
|
13bb5b |
js/gdm/loginDialog.js | 44 ++++++++++++++++++++++----------------------
|
|
|
13bb5b |
2 files changed, 30 insertions(+), 27 deletions(-)
|
|
|
13bb5b |
|
|
|
13bb5b |
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
|
|
|
13bb5b |
index e12c78d..0db9d1e 100644
|
|
|
13bb5b |
--- a/data/theme/gnome-shell.css
|
|
|
13bb5b |
+++ b/data/theme/gnome-shell.css
|
|
|
13bb5b |
@@ -2188,65 +2188,68 @@ StScrollBar StButton#vhandle:active {
|
|
|
13bb5b |
border-radius: 4px;
|
|
|
13bb5b |
background-color: rgba(255,255,255,0.1);
|
|
|
13bb5b |
}
|
|
|
13bb5b |
.candidate-page-button-box {
|
|
|
13bb5b |
height: 2em;
|
|
|
13bb5b |
width: 80px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.vertical .candidate-page-button-box {
|
|
|
13bb5b |
padding-top: 0.5em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.horizontal .candidate-page-button-box {
|
|
|
13bb5b |
padding-left: 0.5em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-previous {
|
|
|
13bb5b |
border-radius: 4px 0px 0px 4px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-next {
|
|
|
13bb5b |
border-radius: 0px 4px 4px 0px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-icon {
|
|
|
13bb5b |
icon-size: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
/* Login Dialog */
|
|
|
13bb5b |
.login-dialog-banner-view {
|
|
|
13bb5b |
- padding-top: 96px;
|
|
|
13bb5b |
- padding-left: 1em;
|
|
|
13bb5b |
- height: 14em;
|
|
|
13bb5b |
- max-width: 42em;
|
|
|
13bb5b |
- min-width: 25em;
|
|
|
13bb5b |
+ padding-top: 10em;
|
|
|
13bb5b |
+ height: 10em;
|
|
|
13bb5b |
+}
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+.login-dialog-banner {
|
|
|
13bb5b |
+ font-size: 9pt;
|
|
|
13bb5b |
+ color: #666666;
|
|
|
13bb5b |
+ width: 30em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-title {
|
|
|
13bb5b |
font-size: 14pt;
|
|
|
13bb5b |
font-weight: bold;
|
|
|
13bb5b |
color: #666666;
|
|
|
13bb5b |
padding-bottom: 2em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog {
|
|
|
13bb5b |
/* Reset border and background */
|
|
|
13bb5b |
border: none;
|
|
|
13bb5b |
background-color: transparent;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-button-box {
|
|
|
13bb5b |
spacing: 5px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list-view {
|
|
|
13bb5b |
-st-vfade-offset: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list {
|
|
|
13bb5b |
spacing: 12px;
|
|
|
13bb5b |
padding: .2em;
|
|
|
13bb5b |
width: 23em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list-item {
|
|
|
13bb5b |
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
|
|
|
13bb5b |
index 8f5044f..aadc5a9 100644
|
|
|
13bb5b |
--- a/js/gdm/loginDialog.js
|
|
|
13bb5b |
+++ b/js/gdm/loginDialog.js
|
|
|
13bb5b |
@@ -407,136 +407,136 @@ const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
this._userManager = AccountsService.UserManager.get_default()
|
|
|
13bb5b |
let gdmClient = new Gdm.Client();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
|
|
|
13bb5b |
this._greeter = gdmClient.get_greeter_sync(null);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._greeter.connect('default-session-name-changed',
|
|
|
13bb5b |
Lang.bind(this, this._onDefaultSessionChanged));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._greeter.connect('session-opened',
|
|
|
13bb5b |
Lang.bind(this, this._onSessionOpened));
|
|
|
13bb5b |
this._greeter.connect('timed-login-requested',
|
|
|
13bb5b |
Lang.bind(this, this._onTimedLoginRequested));
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateDisableUserList));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateLogo));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._textureCache = St.TextureCache.get_default();
|
|
|
13bb5b |
this._textureCache.connect('texture-file-changed',
|
|
|
13bb5b |
Lang.bind(this, this._updateLogoTexture));
|
|
|
13bb5b |
|
|
|
13bb5b |
- let outerBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
- y_align: Clutter.ActorAlign.START,
|
|
|
13bb5b |
- y_expand: true,
|
|
|
13bb5b |
- vertical: true });
|
|
|
13bb5b |
- table.pack(outerBox, 0, 0);
|
|
|
13bb5b |
- this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
|
|
|
13bb5b |
- opacity: 0,
|
|
|
13bb5b |
- vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
|
|
13bb5b |
- hscrollbar_policy: Gtk.PolicyType.NEVER });
|
|
|
13bb5b |
- outerBox.add_actor(this._bannerView);
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- let innerBox = new St.BoxLayout({ vertical: true });
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- this._bannerView.add_actor(innerBox);
|
|
|
13bb5b |
- this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
|
|
13bb5b |
- text: '' });
|
|
|
13bb5b |
- this._bannerLabel.clutter_text.line_wrap = true;
|
|
|
13bb5b |
- this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
|
|
13bb5b |
- innerBox.add_child(this._bannerLabel);
|
|
|
13bb5b |
- this._updateBanner();
|
|
|
13bb5b |
-
|
|
|
13bb5b |
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
y_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
x_expand: true,
|
|
|
13bb5b |
y_expand: true,
|
|
|
13bb5b |
vertical: true,
|
|
|
13bb5b |
visible: false });
|
|
|
13bb5b |
this._userList = new UserList();
|
|
|
13bb5b |
this._userSelectionBox.add(this._userList.actor,
|
|
|
13bb5b |
{ expand: true,
|
|
|
13bb5b |
x_fill: true,
|
|
|
13bb5b |
y_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
|
|
|
13bb5b |
this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted));
|
|
|
13bb5b |
this._authPrompt.connect('reset', Lang.bind(this, this._onReset));
|
|
|
13bb5b |
this._authPrompt.hide();
|
|
|
13bb5b |
this._authPrompt.actor.x_align = Clutter.ActorAlign.CENTER;
|
|
|
13bb5b |
this._authPrompt.actor.y_align = Clutter.ActorAlign.CENTER;
|
|
|
13bb5b |
this._authPrompt.actor.x_expand = false;
|
|
|
13bb5b |
this._authPrompt.actor.y_expand = false;
|
|
|
13bb5b |
table.pack(this._authPrompt.actor, 0, 0);
|
|
|
13bb5b |
table.set_span(this._authPrompt.actor, 1, 3);
|
|
|
13bb5b |
|
|
|
13bb5b |
// translators: this message is shown below the user list on the
|
|
|
13bb5b |
// login screen. It can be activated to reveal an entry for
|
|
|
13bb5b |
// manually entering the username.
|
|
|
13bb5b |
let notListedLabel = new St.Label({ text: _("Not listed?"),
|
|
|
13bb5b |
style_class: 'login-dialog-not-listed-label' });
|
|
|
13bb5b |
this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
|
|
13bb5b |
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
|
|
13bb5b |
can_focus: true,
|
|
|
13bb5b |
child: notListedLabel,
|
|
|
13bb5b |
reactive: true,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.hide();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userSelectionBox.add(this._notListedButton,
|
|
|
13bb5b |
{ expand: false,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
y_align: Clutter.ActorAlign.END,
|
|
|
13bb5b |
x_expand: true,
|
|
|
13bb5b |
y_expand: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
table.pack(this._userSelectionBox, 0, 0);
|
|
|
13bb5b |
table.set_span(this._userSelectionBox, 1, 3);
|
|
|
13bb5b |
|
|
|
13bb5b |
+ let outerBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
+ y_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
+ vertical: true });
|
|
|
13bb5b |
+ table.pack(outerBox, 0, 2);
|
|
|
13bb5b |
+ table.set_span(outerBox, 1, 1);
|
|
|
13bb5b |
+ this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
|
|
|
13bb5b |
+ opacity: 0,
|
|
|
13bb5b |
+ vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
|
|
13bb5b |
+ hscrollbar_policy: Gtk.PolicyType.NEVER });
|
|
|
13bb5b |
+ outerBox.add_actor(this._bannerView);
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let innerBox = new St.BoxLayout({ vertical: true });
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ this._bannerView.add_actor(innerBox);
|
|
|
13bb5b |
+ this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
|
|
13bb5b |
+ text: '' });
|
|
|
13bb5b |
+ this._bannerLabel.clutter_text.line_wrap = true;
|
|
|
13bb5b |
+ this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
|
|
13bb5b |
+ innerBox.add_child(this._bannerLabel);
|
|
|
13bb5b |
+ this._updateBanner();
|
|
|
13bb5b |
+
|
|
|
13bb5b |
table.pack(this._logoBin, 0, 2);
|
|
|
13bb5b |
table.set_span(this._logoBin, 1, 1);
|
|
|
13bb5b |
this._updateLogo();
|
|
|
13bb5b |
|
|
|
13bb5b |
// We have overlapping widgets to obtain the kind of centering we want.
|
|
|
13bb5b |
// We need to make sure the widgets that take input are on top of the
|
|
|
13bb5b |
// stack.
|
|
|
13bb5b |
this.actor.set_child_above_sibling(this._userSelectionBox, null);
|
|
|
13bb5b |
this.actor.set_child_above_sibling(this._authPrompt.actor, null);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userList.connect('activate',
|
|
|
13bb5b |
Lang.bind(this, function(userList, item) {
|
|
|
13bb5b |
this._onUserListActivated(item);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
this._sessionMenuButton = new SessionMenuButton();
|
|
|
13bb5b |
this._sessionMenuButton.connect('session-activated',
|
|
|
13bb5b |
Lang.bind(this, function(list, sessionId) {
|
|
|
13bb5b |
this._greeter.call_select_session_sync (sessionId, null);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
this._sessionMenuButton.actor.opacity = 0;
|
|
|
13bb5b |
this._sessionMenuButton.actor.show();
|
|
|
13bb5b |
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._disableUserList = undefined;
|
|
|
13bb5b |
this._userListLoaded = false;
|
|
|
13bb5b |
|
|
|
13bb5b |
// If the user list is enabled, it should take key focus; make sure the
|
|
|
13bb5b |
// screen shield is initialized first to prevent it from stealing the
|
|
|
13bb5b |
@@ -599,107 +599,107 @@ const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
Tweener.addTween(this._bannerView,
|
|
|
13bb5b |
{ opacity: 255,
|
|
|
13bb5b |
time: _FADE_ANIMATION_TIME,
|
|
|
13bb5b |
transition: 'easeOutQuad' });
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_hideBannerView: function() {
|
|
|
13bb5b |
Tweener.removeTweens(this._bannerView);
|
|
|
13bb5b |
this._bannerView.opacity = 0;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateLogoTexture: function(cache, uri) {
|
|
|
13bb5b |
if (this._logoFileUri != uri)
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoBin.destroy_all_children();
|
|
|
13bb5b |
if (this._logoFileUri)
|
|
|
13bb5b |
this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri,
|
|
|
13bb5b |
-1, _LOGO_ICON_HEIGHT));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateLogo: function() {
|
|
|
13bb5b |
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
|
|
|
13bb5b |
this._updateLogoTexture(this._textureCache, this._logoFileUri);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onPrompted: function() {
|
|
|
13bb5b |
this._sessionMenuButton.updateSensitivity(true);
|
|
|
13bb5b |
+ this._fadeInBannerView();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._shouldShowSessionMenuButton())
|
|
|
13bb5b |
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
13bb5b |
this._showPrompt();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onReset: function(authPrompt, beginRequest) {
|
|
|
13bb5b |
this._sessionMenuButton.updateSensitivity(true);
|
|
|
13bb5b |
this._hideBannerView();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._user = null;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
|
|
|
13bb5b |
if (!this._disableUserList)
|
|
|
13bb5b |
this._showUserList();
|
|
|
13bb5b |
else
|
|
|
13bb5b |
this._hideUserListAskForUsernameAndBeginVerification();
|
|
|
13bb5b |
} else {
|
|
|
13bb5b |
this._hideUserListAndBeginVerification();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onDefaultSessionChanged: function(client, sessionId) {
|
|
|
13bb5b |
this._sessionMenuButton.setActiveSession(sessionId);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_shouldShowSessionMenuButton: function() {
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
|
|
|
13bb5b |
this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED)
|
|
|
13bb5b |
return false;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._user && this._user.is_loaded && this._user.is_logged_in())
|
|
|
13bb5b |
return false;
|
|
|
13bb5b |
|
|
|
13bb5b |
return true;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_showPrompt: function() {
|
|
|
13bb5b |
if (this._authPrompt.actor.visible)
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
this._authPrompt.actor.opacity = 0;
|
|
|
13bb5b |
this._authPrompt.actor.show();
|
|
|
13bb5b |
Tweener.addTween(this._authPrompt.actor,
|
|
|
13bb5b |
{ opacity: 255,
|
|
|
13bb5b |
time: _FADE_ANIMATION_TIME,
|
|
|
13bb5b |
transition: 'easeOutQuad' });
|
|
|
13bb5b |
- this._fadeInBannerView();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_showRealmLoginHint: function(realmManager, hint) {
|
|
|
13bb5b |
if (!hint)
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
|
|
|
13bb5b |
hint = hint.replace(/%U/g, 'user');
|
|
|
13bb5b |
hint = hint.replace(/%D/g, 'DOMAIN');
|
|
|
13bb5b |
hint = hint.replace(/%[^UD]/g, '');
|
|
|
13bb5b |
|
|
|
13bb5b |
// Translators: this message is shown below the username entry field
|
|
|
13bb5b |
// to clue the user in on how to login to the local network realm
|
|
|
13bb5b |
this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), GdmUtil.MessageType.HINT);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_askForUsernameAndBeginVerification: function() {
|
|
|
13bb5b |
this._authPrompt.setPasswordChar('');
|
|
|
13bb5b |
this._authPrompt.setQuestion(_("Username: "));
|
|
|
13bb5b |
|
|
|
13bb5b |
let realmManager = new Realmd.Manager();
|
|
|
13bb5b |
let realmSignalId = realmManager.connect('login-format-changed',
|
|
|
13bb5b |
Lang.bind(this, this._showRealmLoginHint));
|
|
|
13bb5b |
this._showRealmLoginHint(realmManager.loginFormat);
|
|
|
13bb5b |
|
|
|
13bb5b |
let nextSignalId = this._authPrompt.connect('next',
|
|
|
13bb5b |
Lang.bind(this, function() {
|
|
|
13bb5b |
this._authPrompt.disconnect(nextSignalId);
|
|
|
13bb5b |
this._authPrompt.updateSensitivity(false);
|
|
|
13bb5b |
let answer = this._authPrompt.getAnswer();
|
|
|
13bb5b |
this._user = this._userManager.get_user(answer);
|
|
|
13bb5b |
--
|
|
|
13bb5b |
2.1.0
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
From c5ef28f7ccc96bf6ed57c80fe98cd5fe31f4004d Mon Sep 17 00:00:00 2001
|
|
|
13bb5b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
13bb5b |
Date: Wed, 12 Nov 2014 11:29:22 -0500
|
|
|
13bb5b |
Subject: [PATCH 2/5] Revert "loginDialog: display banner message when
|
|
|
13bb5b |
disable-user-list=true"
|
|
|
13bb5b |
|
|
|
13bb5b |
This reverts commit b94289671424068d973a553fb610398830d25e21.
|
|
|
13bb5b |
|
|
|
13bb5b |
Conflicts:
|
|
|
13bb5b |
js/gdm/loginDialog.js
|
|
|
13bb5b |
---
|
|
|
13bb5b |
data/theme/gnome-shell.css | 10 +++---
|
|
|
13bb5b |
js/gdm/loginDialog.js | 76 +++++++++++++---------------------------------
|
|
|
13bb5b |
2 files changed, 25 insertions(+), 61 deletions(-)
|
|
|
13bb5b |
|
|
|
13bb5b |
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
|
|
|
13bb5b |
index 0db9d1e..aa82632 100644
|
|
|
13bb5b |
--- a/data/theme/gnome-shell.css
|
|
|
13bb5b |
+++ b/data/theme/gnome-shell.css
|
|
|
13bb5b |
@@ -2187,69 +2187,67 @@ StScrollBar StButton#vhandle:active {
|
|
|
13bb5b |
.candidate-box:hover {
|
|
|
13bb5b |
border-radius: 4px;
|
|
|
13bb5b |
background-color: rgba(255,255,255,0.1);
|
|
|
13bb5b |
}
|
|
|
13bb5b |
.candidate-page-button-box {
|
|
|
13bb5b |
height: 2em;
|
|
|
13bb5b |
width: 80px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.vertical .candidate-page-button-box {
|
|
|
13bb5b |
padding-top: 0.5em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.horizontal .candidate-page-button-box {
|
|
|
13bb5b |
padding-left: 0.5em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-previous {
|
|
|
13bb5b |
border-radius: 4px 0px 0px 4px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-next {
|
|
|
13bb5b |
border-radius: 0px 4px 4px 0px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-icon {
|
|
|
13bb5b |
icon-size: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
/* Login Dialog */
|
|
|
13bb5b |
-.login-dialog-banner-view {
|
|
|
13bb5b |
- padding-top: 10em;
|
|
|
13bb5b |
- height: 10em;
|
|
|
13bb5b |
-}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-banner {
|
|
|
13bb5b |
- font-size: 9pt;
|
|
|
13bb5b |
+ font-size: 10pt;
|
|
|
13bb5b |
+ font-weight: bold;
|
|
|
13bb5b |
+ text-align: center;
|
|
|
13bb5b |
color: #666666;
|
|
|
13bb5b |
- width: 30em;
|
|
|
13bb5b |
+ padding-bottom: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-title {
|
|
|
13bb5b |
font-size: 14pt;
|
|
|
13bb5b |
font-weight: bold;
|
|
|
13bb5b |
color: #666666;
|
|
|
13bb5b |
padding-bottom: 2em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog {
|
|
|
13bb5b |
/* Reset border and background */
|
|
|
13bb5b |
border: none;
|
|
|
13bb5b |
background-color: transparent;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-button-box {
|
|
|
13bb5b |
spacing: 5px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list-view {
|
|
|
13bb5b |
-st-vfade-offset: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list {
|
|
|
13bb5b |
spacing: 12px;
|
|
|
13bb5b |
padding: .2em;
|
|
|
13bb5b |
width: 23em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list-item {
|
|
|
13bb5b |
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
|
|
|
13bb5b |
index aadc5a9..f35921c 100644
|
|
|
13bb5b |
--- a/js/gdm/loginDialog.js
|
|
|
13bb5b |
+++ b/js/gdm/loginDialog.js
|
|
|
13bb5b |
@@ -1,61 +1,60 @@
|
|
|
13bb5b |
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
13bb5b |
/*
|
|
|
13bb5b |
* Copyright 2011 Red Hat, Inc
|
|
|
13bb5b |
*
|
|
|
13bb5b |
* This program is free software; you can redistribute it and/or modify
|
|
|
13bb5b |
* it under the terms of the GNU General Public License as published by
|
|
|
13bb5b |
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
13bb5b |
* any later version.
|
|
|
13bb5b |
*
|
|
|
13bb5b |
* This program is distributed in the hope that it will be useful,
|
|
|
13bb5b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
13bb5b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
13bb5b |
* GNU General Public License for more details.
|
|
|
13bb5b |
*
|
|
|
13bb5b |
* You should have received a copy of the GNU General Public License
|
|
|
13bb5b |
* along with this program; if not, write to the Free Software
|
|
|
13bb5b |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
13bb5b |
* 02111-1307, USA.
|
|
|
13bb5b |
*/
|
|
|
13bb5b |
|
|
|
13bb5b |
const AccountsService = imports.gi.AccountsService;
|
|
|
13bb5b |
const Atk = imports.gi.Atk;
|
|
|
13bb5b |
const Clutter = imports.gi.Clutter;
|
|
|
13bb5b |
const Gdm = imports.gi.Gdm;
|
|
|
13bb5b |
const Gio = imports.gi.Gio;
|
|
|
13bb5b |
const GLib = imports.gi.GLib;
|
|
|
13bb5b |
const Gtk = imports.gi.Gtk;
|
|
|
13bb5b |
const Lang = imports.lang;
|
|
|
13bb5b |
const Mainloop = imports.mainloop;
|
|
|
13bb5b |
const Meta = imports.gi.Meta;
|
|
|
13bb5b |
-const Pango = imports.gi.Pango;
|
|
|
13bb5b |
const Shell = imports.gi.Shell;
|
|
|
13bb5b |
const Signals = imports.signals;
|
|
|
13bb5b |
const St = imports.gi.St;
|
|
|
13bb5b |
|
|
|
13bb5b |
const AuthPrompt = imports.gdm.authPrompt;
|
|
|
13bb5b |
const Batch = imports.gdm.batch;
|
|
|
13bb5b |
const BoxPointer = imports.ui.boxpointer;
|
|
|
13bb5b |
const CtrlAltTab = imports.ui.ctrlAltTab;
|
|
|
13bb5b |
const GdmUtil = imports.gdm.util;
|
|
|
13bb5b |
const Layout = imports.ui.layout;
|
|
|
13bb5b |
const Main = imports.ui.main;
|
|
|
13bb5b |
const PopupMenu = imports.ui.popupMenu;
|
|
|
13bb5b |
const Realmd = imports.gdm.realmd;
|
|
|
13bb5b |
const Tweener = imports.ui.tweener;
|
|
|
13bb5b |
const UserMenu = imports.ui.userMenu;
|
|
|
13bb5b |
const UserWidget = imports.ui.userWidget;
|
|
|
13bb5b |
|
|
|
13bb5b |
const _FADE_ANIMATION_TIME = 0.25;
|
|
|
13bb5b |
const _SCROLL_ANIMATION_TIME = 0.5;
|
|
|
13bb5b |
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
|
|
13bb5b |
const _LOGO_ICON_HEIGHT = 48;
|
|
|
13bb5b |
|
|
|
13bb5b |
let _loginDialog = null;
|
|
|
13bb5b |
|
|
|
13bb5b |
const UserListItem = new Lang.Class({
|
|
|
13bb5b |
Name: 'UserListItem',
|
|
|
13bb5b |
|
|
|
13bb5b |
_init: function(user) {
|
|
|
13bb5b |
this.user = user;
|
|
|
13bb5b |
this._userChangedId = this.user.connect('changed',
|
|
|
13bb5b |
@@ -367,185 +366,166 @@ const SessionMenuButton = new Lang.Class({
|
|
|
13bb5b |
ids.sort();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (ids.length <= 1) {
|
|
|
13bb5b |
this._button.hide();
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
for (let i = 0; i < ids.length; i++) {
|
|
|
13bb5b |
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
|
|
|
13bb5b |
|
|
|
13bb5b |
let id = ids[i];
|
|
|
13bb5b |
let item = new PopupMenu.PopupMenuItem(sessionName);
|
|
|
13bb5b |
this._menu.addMenuItem(item);
|
|
|
13bb5b |
this._items[id] = item;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (!this._activeSessionId)
|
|
|
13bb5b |
this.setActiveSession(id);
|
|
|
13bb5b |
|
|
|
13bb5b |
item.connect('activate', Lang.bind(this, function() {
|
|
|
13bb5b |
this.setActiveSession(id);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}
|
|
|
13bb5b |
});
|
|
|
13bb5b |
Signals.addSignalMethods(SessionMenuButton.prototype);
|
|
|
13bb5b |
|
|
|
13bb5b |
const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
Name: 'LoginDialog',
|
|
|
13bb5b |
|
|
|
13bb5b |
_init: function(parentActor) {
|
|
|
13bb5b |
- let table = new Clutter.TableLayout();
|
|
|
13bb5b |
this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW,
|
|
|
13bb5b |
- layout_manager: table,
|
|
|
13bb5b |
+ layout_manager: new Clutter.BinLayout(),
|
|
|
13bb5b |
style_class: 'login-dialog',
|
|
|
13bb5b |
visible: false });
|
|
|
13bb5b |
|
|
|
13bb5b |
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
|
|
13bb5b |
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
|
|
13bb5b |
parentActor.add_child(this.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userManager = AccountsService.UserManager.get_default()
|
|
|
13bb5b |
let gdmClient = new Gdm.Client();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
|
|
|
13bb5b |
this._greeter = gdmClient.get_greeter_sync(null);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._greeter.connect('default-session-name-changed',
|
|
|
13bb5b |
Lang.bind(this, this._onDefaultSessionChanged));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._greeter.connect('session-opened',
|
|
|
13bb5b |
Lang.bind(this, this._onSessionOpened));
|
|
|
13bb5b |
this._greeter.connect('timed-login-requested',
|
|
|
13bb5b |
Lang.bind(this, this._onTimedLoginRequested));
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateDisableUserList));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateLogo));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._textureCache = St.TextureCache.get_default();
|
|
|
13bb5b |
this._textureCache.connect('texture-file-changed',
|
|
|
13bb5b |
Lang.bind(this, this._updateLogoTexture));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
y_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
x_expand: true,
|
|
|
13bb5b |
y_expand: true,
|
|
|
13bb5b |
vertical: true,
|
|
|
13bb5b |
visible: false });
|
|
|
13bb5b |
+ this.actor.add_child(this._userSelectionBox);
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
|
|
13bb5b |
+ text: '' });
|
|
|
13bb5b |
+ this._userSelectionBox.add(this._bannerLabel);
|
|
|
13bb5b |
+ this._updateBanner();
|
|
|
13bb5b |
+
|
|
|
13bb5b |
this._userList = new UserList();
|
|
|
13bb5b |
this._userSelectionBox.add(this._userList.actor,
|
|
|
13bb5b |
{ expand: true,
|
|
|
13bb5b |
x_fill: true,
|
|
|
13bb5b |
y_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
|
|
|
13bb5b |
this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted));
|
|
|
13bb5b |
this._authPrompt.connect('reset', Lang.bind(this, this._onReset));
|
|
|
13bb5b |
this._authPrompt.hide();
|
|
|
13bb5b |
- this._authPrompt.actor.x_align = Clutter.ActorAlign.CENTER;
|
|
|
13bb5b |
- this._authPrompt.actor.y_align = Clutter.ActorAlign.CENTER;
|
|
|
13bb5b |
- this._authPrompt.actor.x_expand = false;
|
|
|
13bb5b |
- this._authPrompt.actor.y_expand = false;
|
|
|
13bb5b |
- table.pack(this._authPrompt.actor, 0, 0);
|
|
|
13bb5b |
- table.set_span(this._authPrompt.actor, 1, 3);
|
|
|
13bb5b |
+ this.actor.add_child(this._authPrompt.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
// translators: this message is shown below the user list on the
|
|
|
13bb5b |
// login screen. It can be activated to reveal an entry for
|
|
|
13bb5b |
// manually entering the username.
|
|
|
13bb5b |
let notListedLabel = new St.Label({ text: _("Not listed?"),
|
|
|
13bb5b |
style_class: 'login-dialog-not-listed-label' });
|
|
|
13bb5b |
this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
|
|
13bb5b |
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
|
|
13bb5b |
can_focus: true,
|
|
|
13bb5b |
child: notListedLabel,
|
|
|
13bb5b |
reactive: true,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.hide();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userSelectionBox.add(this._notListedButton,
|
|
|
13bb5b |
{ expand: false,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
y_align: Clutter.ActorAlign.END,
|
|
|
13bb5b |
x_expand: true,
|
|
|
13bb5b |
y_expand: true });
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- table.pack(this._userSelectionBox, 0, 0);
|
|
|
13bb5b |
- table.set_span(this._userSelectionBox, 1, 3);
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- let outerBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
- y_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
- vertical: true });
|
|
|
13bb5b |
- table.pack(outerBox, 0, 2);
|
|
|
13bb5b |
- table.set_span(outerBox, 1, 1);
|
|
|
13bb5b |
- this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
|
|
|
13bb5b |
- opacity: 0,
|
|
|
13bb5b |
- vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
|
|
13bb5b |
- hscrollbar_policy: Gtk.PolicyType.NEVER });
|
|
|
13bb5b |
- outerBox.add_actor(this._bannerView);
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- let innerBox = new St.BoxLayout({ vertical: true });
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- this._bannerView.add_actor(innerBox);
|
|
|
13bb5b |
- this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
|
|
13bb5b |
- text: '' });
|
|
|
13bb5b |
- this._bannerLabel.clutter_text.line_wrap = true;
|
|
|
13bb5b |
- this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
|
|
13bb5b |
- innerBox.add_child(this._bannerLabel);
|
|
|
13bb5b |
- this._updateBanner();
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- table.pack(this._logoBin, 0, 2);
|
|
|
13bb5b |
- table.set_span(this._logoBin, 1, 1);
|
|
|
13bb5b |
+ this.actor.add_child(this._logoBin);
|
|
|
13bb5b |
this._updateLogo();
|
|
|
13bb5b |
|
|
|
13bb5b |
- // We have overlapping widgets to obtain the kind of centering we want.
|
|
|
13bb5b |
- // We need to make sure the widgets that take input are on top of the
|
|
|
13bb5b |
- // stack.
|
|
|
13bb5b |
- this.actor.set_child_above_sibling(this._userSelectionBox, null);
|
|
|
13bb5b |
- this.actor.set_child_above_sibling(this._authPrompt.actor, null);
|
|
|
13bb5b |
+ if (!this._userManager.is_loaded)
|
|
|
13bb5b |
+ this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
|
|
13bb5b |
+ Lang.bind(this, function() {
|
|
|
13bb5b |
+ if (this._userManager.is_loaded) {
|
|
|
13bb5b |
+ this._loadUserList();
|
|
|
13bb5b |
+ this._userManager.disconnect(this._userManagerLoadedId);
|
|
|
13bb5b |
+ this._userManagerLoadedId = 0;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+ }));
|
|
|
13bb5b |
+ else
|
|
|
13bb5b |
+ this._loadUserList();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userList.connect('activate',
|
|
|
13bb5b |
Lang.bind(this, function(userList, item) {
|
|
|
13bb5b |
this._onUserListActivated(item);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
this._sessionMenuButton = new SessionMenuButton();
|
|
|
13bb5b |
this._sessionMenuButton.connect('session-activated',
|
|
|
13bb5b |
Lang.bind(this, function(list, sessionId) {
|
|
|
13bb5b |
this._greeter.call_select_session_sync (sessionId, null);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
this._sessionMenuButton.actor.opacity = 0;
|
|
|
13bb5b |
this._sessionMenuButton.actor.show();
|
|
|
13bb5b |
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._disableUserList = undefined;
|
|
|
13bb5b |
this._userListLoaded = false;
|
|
|
13bb5b |
|
|
|
13bb5b |
// If the user list is enabled, it should take key focus; make sure the
|
|
|
13bb5b |
// screen shield is initialized first to prevent it from stealing the
|
|
|
13bb5b |
// focus later
|
|
|
13bb5b |
Main.layoutManager.connect('startup-complete',
|
|
|
13bb5b |
Lang.bind(this, this._updateDisableUserList));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_ensureUserListLoaded: function() {
|
|
|
13bb5b |
if (!this._userManager.is_loaded)
|
|
|
13bb5b |
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
|
|
13bb5b |
Lang.bind(this, function() {
|
|
|
13bb5b |
@@ -568,101 +548,87 @@ const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
|
|
13bb5b |
this._authPrompt.reset();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateCancelButton: function() {
|
|
|
13bb5b |
let cancelVisible;
|
|
|
13bb5b |
|
|
|
13bb5b |
// Hide the cancel button if the user list is disabled and we're asking for
|
|
|
13bb5b |
// a username
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING && this._disableUserList)
|
|
|
13bb5b |
cancelVisible = false;
|
|
|
13bb5b |
else
|
|
|
13bb5b |
cancelVisible = true;
|
|
|
13bb5b |
|
|
|
13bb5b |
this._authPrompt.cancelButton.visible = cancelVisible;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateBanner: function() {
|
|
|
13bb5b |
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
|
|
|
13bb5b |
let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (enabled && text) {
|
|
|
13bb5b |
this._bannerLabel.set_text(text);
|
|
|
13bb5b |
this._bannerLabel.show();
|
|
|
13bb5b |
} else {
|
|
|
13bb5b |
this._bannerLabel.hide();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
- _fadeInBannerView: function() {
|
|
|
13bb5b |
- Tweener.addTween(this._bannerView,
|
|
|
13bb5b |
- { opacity: 255,
|
|
|
13bb5b |
- time: _FADE_ANIMATION_TIME,
|
|
|
13bb5b |
- transition: 'easeOutQuad' });
|
|
|
13bb5b |
- },
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- _hideBannerView: function() {
|
|
|
13bb5b |
- Tweener.removeTweens(this._bannerView);
|
|
|
13bb5b |
- this._bannerView.opacity = 0;
|
|
|
13bb5b |
- },
|
|
|
13bb5b |
-
|
|
|
13bb5b |
_updateLogoTexture: function(cache, uri) {
|
|
|
13bb5b |
if (this._logoFileUri != uri)
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoBin.destroy_all_children();
|
|
|
13bb5b |
if (this._logoFileUri)
|
|
|
13bb5b |
this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri,
|
|
|
13bb5b |
-1, _LOGO_ICON_HEIGHT));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateLogo: function() {
|
|
|
13bb5b |
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
|
|
|
13bb5b |
this._updateLogoTexture(this._textureCache, this._logoFileUri);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onPrompted: function() {
|
|
|
13bb5b |
this._sessionMenuButton.updateSensitivity(true);
|
|
|
13bb5b |
- this._fadeInBannerView();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._shouldShowSessionMenuButton())
|
|
|
13bb5b |
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
13bb5b |
this._showPrompt();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onReset: function(authPrompt, beginRequest) {
|
|
|
13bb5b |
this._sessionMenuButton.updateSensitivity(true);
|
|
|
13bb5b |
- this._hideBannerView();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._user = null;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
|
|
|
13bb5b |
if (!this._disableUserList)
|
|
|
13bb5b |
this._showUserList();
|
|
|
13bb5b |
else
|
|
|
13bb5b |
this._hideUserListAskForUsernameAndBeginVerification();
|
|
|
13bb5b |
} else {
|
|
|
13bb5b |
this._hideUserListAndBeginVerification();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onDefaultSessionChanged: function(client, sessionId) {
|
|
|
13bb5b |
this._sessionMenuButton.setActiveSession(sessionId);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_shouldShowSessionMenuButton: function() {
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
|
|
|
13bb5b |
this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED)
|
|
|
13bb5b |
return false;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._user && this._user.is_loaded && this._user.is_logged_in())
|
|
|
13bb5b |
return false;
|
|
|
13bb5b |
|
|
|
13bb5b |
return true;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_showPrompt: function() {
|
|
|
13bb5b |
if (this._authPrompt.actor.visible)
|
|
|
13bb5b |
--
|
|
|
13bb5b |
2.1.0
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
From 4535550f8780b244f3e79a048c61eef3b2ed8cc8 Mon Sep 17 00:00:00 2001
|
|
|
13bb5b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
13bb5b |
Date: Mon, 10 Nov 2014 14:36:07 -0500
|
|
|
13bb5b |
Subject: [PATCH 3/5] loginDialog: allocate children manually
|
|
|
13bb5b |
|
|
|
13bb5b |
The login screen is pretty custom full screen container and the standard
|
|
|
13bb5b |
layout managers aren't really a good fit for the kind of layout that's
|
|
|
13bb5b |
happening. This will be even more problematic with upcoming changes
|
|
|
13bb5b |
to login banners, so we need to switch techniques.
|
|
|
13bb5b |
|
|
|
13bb5b |
This commit moves login dialog over to using a custom allocate handler
|
|
|
13bb5b |
that has specific domain knowledge of the parts of the login screen
|
|
|
13bb5b |
and where they go.
|
|
|
13bb5b |
---
|
|
|
13bb5b |
js/gdm/loginDialog.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
13bb5b |
1 file changed, 85 insertions(+), 9 deletions(-)
|
|
|
13bb5b |
|
|
|
13bb5b |
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
|
|
|
13bb5b |
index f35921c..4835199 100644
|
|
|
13bb5b |
--- a/js/gdm/loginDialog.js
|
|
|
13bb5b |
+++ b/js/gdm/loginDialog.js
|
|
|
13bb5b |
@@ -366,192 +366,268 @@ const SessionMenuButton = new Lang.Class({
|
|
|
13bb5b |
ids.sort();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (ids.length <= 1) {
|
|
|
13bb5b |
this._button.hide();
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
for (let i = 0; i < ids.length; i++) {
|
|
|
13bb5b |
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
|
|
|
13bb5b |
|
|
|
13bb5b |
let id = ids[i];
|
|
|
13bb5b |
let item = new PopupMenu.PopupMenuItem(sessionName);
|
|
|
13bb5b |
this._menu.addMenuItem(item);
|
|
|
13bb5b |
this._items[id] = item;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (!this._activeSessionId)
|
|
|
13bb5b |
this.setActiveSession(id);
|
|
|
13bb5b |
|
|
|
13bb5b |
item.connect('activate', Lang.bind(this, function() {
|
|
|
13bb5b |
this.setActiveSession(id);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}
|
|
|
13bb5b |
});
|
|
|
13bb5b |
Signals.addSignalMethods(SessionMenuButton.prototype);
|
|
|
13bb5b |
|
|
|
13bb5b |
const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
Name: 'LoginDialog',
|
|
|
13bb5b |
|
|
|
13bb5b |
_init: function(parentActor) {
|
|
|
13bb5b |
- this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW,
|
|
|
13bb5b |
- layout_manager: new Clutter.BinLayout(),
|
|
|
13bb5b |
- style_class: 'login-dialog',
|
|
|
13bb5b |
- visible: false });
|
|
|
13bb5b |
+ this.actor = new Shell.GenericContainer({ style_class: 'login-dialog',
|
|
|
13bb5b |
+ visible: false });
|
|
|
13bb5b |
+ this.actor.get_accessible().set_role(Atk.Role.WINDOW);
|
|
|
13bb5b |
|
|
|
13bb5b |
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
|
|
13bb5b |
+ this.actor.connect('allocate', Lang.bind(this, this._onAllocate));
|
|
|
13bb5b |
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
|
|
13bb5b |
parentActor.add_child(this.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userManager = AccountsService.UserManager.get_default()
|
|
|
13bb5b |
let gdmClient = new Gdm.Client();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
|
|
|
13bb5b |
this._greeter = gdmClient.get_greeter_sync(null);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._greeter.connect('default-session-name-changed',
|
|
|
13bb5b |
Lang.bind(this, this._onDefaultSessionChanged));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._greeter.connect('session-opened',
|
|
|
13bb5b |
Lang.bind(this, this._onSessionOpened));
|
|
|
13bb5b |
this._greeter.connect('timed-login-requested',
|
|
|
13bb5b |
Lang.bind(this, this._onTimedLoginRequested));
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateDisableUserList));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateLogo));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._textureCache = St.TextureCache.get_default();
|
|
|
13bb5b |
this._textureCache.connect('texture-file-changed',
|
|
|
13bb5b |
Lang.bind(this, this._updateLogoTexture));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
y_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
- x_expand: true,
|
|
|
13bb5b |
- y_expand: true,
|
|
|
13bb5b |
vertical: true,
|
|
|
13bb5b |
visible: false });
|
|
|
13bb5b |
this.actor.add_child(this._userSelectionBox);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
|
|
13bb5b |
text: '' });
|
|
|
13bb5b |
this._userSelectionBox.add(this._bannerLabel);
|
|
|
13bb5b |
this._updateBanner();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userList = new UserList();
|
|
|
13bb5b |
this._userSelectionBox.add(this._userList.actor,
|
|
|
13bb5b |
{ expand: true,
|
|
|
13bb5b |
x_fill: true,
|
|
|
13bb5b |
y_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
|
|
|
13bb5b |
this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted));
|
|
|
13bb5b |
this._authPrompt.connect('reset', Lang.bind(this, this._onReset));
|
|
|
13bb5b |
this._authPrompt.hide();
|
|
|
13bb5b |
this.actor.add_child(this._authPrompt.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
// translators: this message is shown below the user list on the
|
|
|
13bb5b |
// login screen. It can be activated to reveal an entry for
|
|
|
13bb5b |
// manually entering the username.
|
|
|
13bb5b |
let notListedLabel = new St.Label({ text: _("Not listed?"),
|
|
|
13bb5b |
style_class: 'login-dialog-not-listed-label' });
|
|
|
13bb5b |
this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
|
|
13bb5b |
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
|
|
13bb5b |
can_focus: true,
|
|
|
13bb5b |
child: notListedLabel,
|
|
|
13bb5b |
reactive: true,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.hide();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userSelectionBox.add(this._notListedButton,
|
|
|
13bb5b |
{ expand: false,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
- y_align: Clutter.ActorAlign.END,
|
|
|
13bb5b |
- x_expand: true,
|
|
|
13bb5b |
- y_expand: true });
|
|
|
13bb5b |
+ y_align: Clutter.ActorAlign.END });
|
|
|
13bb5b |
this.actor.add_child(this._logoBin);
|
|
|
13bb5b |
this._updateLogo();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (!this._userManager.is_loaded)
|
|
|
13bb5b |
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
|
|
13bb5b |
Lang.bind(this, function() {
|
|
|
13bb5b |
if (this._userManager.is_loaded) {
|
|
|
13bb5b |
this._loadUserList();
|
|
|
13bb5b |
this._userManager.disconnect(this._userManagerLoadedId);
|
|
|
13bb5b |
this._userManagerLoadedId = 0;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
else
|
|
|
13bb5b |
this._loadUserList();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userList.connect('activate',
|
|
|
13bb5b |
Lang.bind(this, function(userList, item) {
|
|
|
13bb5b |
this._onUserListActivated(item);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
this._sessionMenuButton = new SessionMenuButton();
|
|
|
13bb5b |
this._sessionMenuButton.connect('session-activated',
|
|
|
13bb5b |
Lang.bind(this, function(list, sessionId) {
|
|
|
13bb5b |
this._greeter.call_select_session_sync (sessionId, null);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
this._sessionMenuButton.actor.opacity = 0;
|
|
|
13bb5b |
this._sessionMenuButton.actor.show();
|
|
|
13bb5b |
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._disableUserList = undefined;
|
|
|
13bb5b |
this._userListLoaded = false;
|
|
|
13bb5b |
|
|
|
13bb5b |
// If the user list is enabled, it should take key focus; make sure the
|
|
|
13bb5b |
// screen shield is initialized first to prevent it from stealing the
|
|
|
13bb5b |
// focus later
|
|
|
13bb5b |
Main.layoutManager.connect('startup-complete',
|
|
|
13bb5b |
Lang.bind(this, this._updateDisableUserList));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
+ _getLogoBinAllocation: function (dialogBox) {
|
|
|
13bb5b |
+ let actorBox = new Clutter.ActorBox();
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
|
|
|
13bb5b |
+ let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ actorBox.x1 = centerX - natWidth / 2;
|
|
|
13bb5b |
+ actorBox.y1 = dialogBox.y2 - natHeight;
|
|
|
13bb5b |
+ actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
13bb5b |
+ actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ return actorBox;
|
|
|
13bb5b |
+ },
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ _getCenterActorAllocation: function (dialogBox, actor) {
|
|
|
13bb5b |
+ let actorBox = new Clutter.ActorBox();
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
|
|
|
13bb5b |
+ let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
13bb5b |
+ let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ actorBox.x1 = centerX - natWidth / 2;
|
|
|
13bb5b |
+ actorBox.y1 = centerY - natHeight / 2;
|
|
|
13bb5b |
+ actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
13bb5b |
+ actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ return actorBox;
|
|
|
13bb5b |
+ },
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ _onAllocate: function (actor, dialogBox, flags) {
|
|
|
13bb5b |
+ let dialogHeight = dialogBox.y2 - dialogBox.y1;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // First find out what space the children require
|
|
|
13bb5b |
+ let authPromptAllocation = null;
|
|
|
13bb5b |
+ if (this._authPrompt.actor.visible)
|
|
|
13bb5b |
+ authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let userSelectionAllocation = null;
|
|
|
13bb5b |
+ let userSelectionHeight = 0;
|
|
|
13bb5b |
+ if (this._userSelectionBox.visible) {
|
|
|
13bb5b |
+ userSelectionAllocation = this._getCenterActorAllocation(dialogBox, this._userSelectionBox);
|
|
|
13bb5b |
+ userSelectionHeight = userSelectionAllocation.y2 - userSelectionAllocation.y1;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let logoAllocation = null;
|
|
|
13bb5b |
+ let logoHeight = 0;
|
|
|
13bb5b |
+ if (this._logoBin.visible) {
|
|
|
13bb5b |
+ logoAllocation = this._getLogoBinAllocation(dialogBox);
|
|
|
13bb5b |
+ logoHeight = logoAllocation.y2 - logoAllocation.y1;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Then figure out what extra space we can hand out
|
|
|
13bb5b |
+ let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight;
|
|
|
13bb5b |
+ if (leftOverYSpace > 0) {
|
|
|
13bb5b |
+ if (userSelectionAllocation) {
|
|
|
13bb5b |
+ let topExpansion = leftOverYSpace / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Don't ever expand more than we have space for
|
|
|
13bb5b |
+ if (userSelectionAllocation.y1 - topExpansion < 0)
|
|
|
13bb5b |
+ topExpansion = userSelectionAllocation.y1;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Always expand the bottom the same as the top since it's centered
|
|
|
13bb5b |
+ let bottomExpansion = topExpansion;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ userSelectionAllocation.y1 -= topExpansion;
|
|
|
13bb5b |
+ userSelectionAllocation.y2 += bottomExpansion;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Finally hand out the allocations
|
|
|
13bb5b |
+ if (authPromptAllocation)
|
|
|
13bb5b |
+ this._authPrompt.actor.allocate(authPromptAllocation, flags);
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ if (userSelectionAllocation)
|
|
|
13bb5b |
+ this._userSelectionBox.allocate(userSelectionAllocation, flags);
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ if (logoAllocation)
|
|
|
13bb5b |
+ this._logoBin.allocate(logoAllocation, flags);
|
|
|
13bb5b |
+ },
|
|
|
13bb5b |
+
|
|
|
13bb5b |
_ensureUserListLoaded: function() {
|
|
|
13bb5b |
if (!this._userManager.is_loaded)
|
|
|
13bb5b |
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
|
|
13bb5b |
Lang.bind(this, function() {
|
|
|
13bb5b |
if (this._userManager.is_loaded) {
|
|
|
13bb5b |
this._loadUserList();
|
|
|
13bb5b |
this._userManager.disconnect(this._userManagerLoadedId);
|
|
|
13bb5b |
this._userManagerLoadedId = 0;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
else
|
|
|
13bb5b |
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateDisableUserList: function() {
|
|
|
13bb5b |
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (disableUserList != this._disableUserList) {
|
|
|
13bb5b |
this._disableUserList = disableUserList;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
|
|
13bb5b |
this._authPrompt.reset();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateCancelButton: function() {
|
|
|
13bb5b |
let cancelVisible;
|
|
|
13bb5b |
|
|
|
13bb5b |
// Hide the cancel button if the user list is disabled and we're asking for
|
|
|
13bb5b |
// a username
|
|
|
13bb5b |
--
|
|
|
13bb5b |
2.1.0
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
From f3b8445905e1b34140b5e903a81a27650d68230b Mon Sep 17 00:00:00 2001
|
|
|
13bb5b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
13bb5b |
Date: Tue, 11 Nov 2014 09:11:01 -0500
|
|
|
13bb5b |
Subject: [PATCH 4/5] loginDialog: display banner message when
|
|
|
13bb5b |
disable-user-list=true
|
|
|
13bb5b |
|
|
|
13bb5b |
The login screen supports showing a banner message which admins
|
|
|
13bb5b |
can use to mention login rules or disclaimers.
|
|
|
13bb5b |
|
|
|
13bb5b |
This message only shows up currently if the user list is enabled.
|
|
|
13bb5b |
Most people who want to show a banner message also want to disable
|
|
|
13bb5b |
the user list.
|
|
|
13bb5b |
|
|
|
13bb5b |
This commit moves the banner message to display when the user is
|
|
|
13bb5b |
prompted for login credentials instead of when showing the user
|
|
|
13bb5b |
list. It also adds a scrollbar if the message is too long.
|
|
|
13bb5b |
---
|
|
|
13bb5b |
data/theme/gnome-shell.css | 8 ++--
|
|
|
13bb5b |
js/gdm/loginDialog.js | 105 +++++++++++++++++++++++++++++++++++++++------
|
|
|
13bb5b |
2 files changed, 95 insertions(+), 18 deletions(-)
|
|
|
13bb5b |
|
|
|
13bb5b |
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
|
|
|
13bb5b |
index aa82632..90eb64f 100644
|
|
|
13bb5b |
--- a/data/theme/gnome-shell.css
|
|
|
13bb5b |
+++ b/data/theme/gnome-shell.css
|
|
|
13bb5b |
@@ -2187,67 +2187,67 @@ StScrollBar StButton#vhandle:active {
|
|
|
13bb5b |
.candidate-box:hover {
|
|
|
13bb5b |
border-radius: 4px;
|
|
|
13bb5b |
background-color: rgba(255,255,255,0.1);
|
|
|
13bb5b |
}
|
|
|
13bb5b |
.candidate-page-button-box {
|
|
|
13bb5b |
height: 2em;
|
|
|
13bb5b |
width: 80px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.vertical .candidate-page-button-box {
|
|
|
13bb5b |
padding-top: 0.5em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.horizontal .candidate-page-button-box {
|
|
|
13bb5b |
padding-left: 0.5em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-previous {
|
|
|
13bb5b |
border-radius: 4px 0px 0px 4px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-next {
|
|
|
13bb5b |
border-radius: 0px 4px 4px 0px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.candidate-page-button-icon {
|
|
|
13bb5b |
icon-size: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
/* Login Dialog */
|
|
|
13bb5b |
+.login-dialog-banner-view {
|
|
|
13bb5b |
+ padding-top: 24px;
|
|
|
13bb5b |
+ max-width: 23em;
|
|
|
13bb5b |
+}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-banner {
|
|
|
13bb5b |
- font-size: 10pt;
|
|
|
13bb5b |
- font-weight: bold;
|
|
|
13bb5b |
- text-align: center;
|
|
|
13bb5b |
color: #666666;
|
|
|
13bb5b |
- padding-bottom: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-title {
|
|
|
13bb5b |
font-size: 14pt;
|
|
|
13bb5b |
font-weight: bold;
|
|
|
13bb5b |
color: #666666;
|
|
|
13bb5b |
padding-bottom: 2em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog {
|
|
|
13bb5b |
/* Reset border and background */
|
|
|
13bb5b |
border: none;
|
|
|
13bb5b |
background-color: transparent;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-button-box {
|
|
|
13bb5b |
spacing: 5px;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list-view {
|
|
|
13bb5b |
-st-vfade-offset: 1em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list {
|
|
|
13bb5b |
spacing: 12px;
|
|
|
13bb5b |
padding: .2em;
|
|
|
13bb5b |
width: 23em;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
.login-dialog-user-list-item {
|
|
|
13bb5b |
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
|
|
|
13bb5b |
index 4835199..348798c 100644
|
|
|
13bb5b |
--- a/js/gdm/loginDialog.js
|
|
|
13bb5b |
+++ b/js/gdm/loginDialog.js
|
|
|
13bb5b |
@@ -1,60 +1,61 @@
|
|
|
13bb5b |
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
13bb5b |
/*
|
|
|
13bb5b |
* Copyright 2011 Red Hat, Inc
|
|
|
13bb5b |
*
|
|
|
13bb5b |
* This program is free software; you can redistribute it and/or modify
|
|
|
13bb5b |
* it under the terms of the GNU General Public License as published by
|
|
|
13bb5b |
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
13bb5b |
* any later version.
|
|
|
13bb5b |
*
|
|
|
13bb5b |
* This program is distributed in the hope that it will be useful,
|
|
|
13bb5b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
13bb5b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
13bb5b |
* GNU General Public License for more details.
|
|
|
13bb5b |
*
|
|
|
13bb5b |
* You should have received a copy of the GNU General Public License
|
|
|
13bb5b |
* along with this program; if not, write to the Free Software
|
|
|
13bb5b |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
13bb5b |
* 02111-1307, USA.
|
|
|
13bb5b |
*/
|
|
|
13bb5b |
|
|
|
13bb5b |
const AccountsService = imports.gi.AccountsService;
|
|
|
13bb5b |
const Atk = imports.gi.Atk;
|
|
|
13bb5b |
const Clutter = imports.gi.Clutter;
|
|
|
13bb5b |
const Gdm = imports.gi.Gdm;
|
|
|
13bb5b |
const Gio = imports.gi.Gio;
|
|
|
13bb5b |
const GLib = imports.gi.GLib;
|
|
|
13bb5b |
const Gtk = imports.gi.Gtk;
|
|
|
13bb5b |
const Lang = imports.lang;
|
|
|
13bb5b |
const Mainloop = imports.mainloop;
|
|
|
13bb5b |
const Meta = imports.gi.Meta;
|
|
|
13bb5b |
+const Pango = imports.gi.Pango;
|
|
|
13bb5b |
const Shell = imports.gi.Shell;
|
|
|
13bb5b |
const Signals = imports.signals;
|
|
|
13bb5b |
const St = imports.gi.St;
|
|
|
13bb5b |
|
|
|
13bb5b |
const AuthPrompt = imports.gdm.authPrompt;
|
|
|
13bb5b |
const Batch = imports.gdm.batch;
|
|
|
13bb5b |
const BoxPointer = imports.ui.boxpointer;
|
|
|
13bb5b |
const CtrlAltTab = imports.ui.ctrlAltTab;
|
|
|
13bb5b |
const GdmUtil = imports.gdm.util;
|
|
|
13bb5b |
const Layout = imports.ui.layout;
|
|
|
13bb5b |
const Main = imports.ui.main;
|
|
|
13bb5b |
const PopupMenu = imports.ui.popupMenu;
|
|
|
13bb5b |
const Realmd = imports.gdm.realmd;
|
|
|
13bb5b |
const Tweener = imports.ui.tweener;
|
|
|
13bb5b |
const UserMenu = imports.ui.userMenu;
|
|
|
13bb5b |
const UserWidget = imports.ui.userWidget;
|
|
|
13bb5b |
|
|
|
13bb5b |
const _FADE_ANIMATION_TIME = 0.25;
|
|
|
13bb5b |
const _SCROLL_ANIMATION_TIME = 0.5;
|
|
|
13bb5b |
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
|
|
13bb5b |
const _LOGO_ICON_HEIGHT = 48;
|
|
|
13bb5b |
|
|
|
13bb5b |
let _loginDialog = null;
|
|
|
13bb5b |
|
|
|
13bb5b |
const UserListItem = new Lang.Class({
|
|
|
13bb5b |
Name: 'UserListItem',
|
|
|
13bb5b |
|
|
|
13bb5b |
_init: function(user) {
|
|
|
13bb5b |
this.user = user;
|
|
|
13bb5b |
this._userChangedId = this.user.connect('changed',
|
|
|
13bb5b |
@@ -412,272 +413,346 @@ const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
Lang.bind(this, this._onDefaultSessionChanged));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._greeter.connect('session-opened',
|
|
|
13bb5b |
Lang.bind(this, this._onSessionOpened));
|
|
|
13bb5b |
this._greeter.connect('timed-login-requested',
|
|
|
13bb5b |
Lang.bind(this, this._onTimedLoginRequested));
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateBanner));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateDisableUserList));
|
|
|
13bb5b |
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
|
|
13bb5b |
Lang.bind(this, this._updateLogo));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._textureCache = St.TextureCache.get_default();
|
|
|
13bb5b |
this._textureCache.connect('texture-file-changed',
|
|
|
13bb5b |
Lang.bind(this, this._updateLogoTexture));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
y_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
vertical: true,
|
|
|
13bb5b |
visible: false });
|
|
|
13bb5b |
this.actor.add_child(this._userSelectionBox);
|
|
|
13bb5b |
|
|
|
13bb5b |
- this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
|
|
13bb5b |
- text: '' });
|
|
|
13bb5b |
- this._userSelectionBox.add(this._bannerLabel);
|
|
|
13bb5b |
- this._updateBanner();
|
|
|
13bb5b |
-
|
|
|
13bb5b |
this._userList = new UserList();
|
|
|
13bb5b |
this._userSelectionBox.add(this._userList.actor,
|
|
|
13bb5b |
{ expand: true,
|
|
|
13bb5b |
x_fill: true,
|
|
|
13bb5b |
y_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
|
|
|
13bb5b |
this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted));
|
|
|
13bb5b |
this._authPrompt.connect('reset', Lang.bind(this, this._onReset));
|
|
|
13bb5b |
this._authPrompt.hide();
|
|
|
13bb5b |
this.actor.add_child(this._authPrompt.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
// translators: this message is shown below the user list on the
|
|
|
13bb5b |
// login screen. It can be activated to reveal an entry for
|
|
|
13bb5b |
// manually entering the username.
|
|
|
13bb5b |
let notListedLabel = new St.Label({ text: _("Not listed?"),
|
|
|
13bb5b |
style_class: 'login-dialog-not-listed-label' });
|
|
|
13bb5b |
this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
|
|
13bb5b |
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
|
|
13bb5b |
can_focus: true,
|
|
|
13bb5b |
child: notListedLabel,
|
|
|
13bb5b |
reactive: true,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification));
|
|
|
13bb5b |
|
|
|
13bb5b |
this._notListedButton.hide();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userSelectionBox.add(this._notListedButton,
|
|
|
13bb5b |
{ expand: false,
|
|
|
13bb5b |
x_align: St.Align.START,
|
|
|
13bb5b |
x_fill: true });
|
|
|
13bb5b |
|
|
|
13bb5b |
+ this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
|
|
|
13bb5b |
+ opacity: 0,
|
|
|
13bb5b |
+ vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
|
|
13bb5b |
+ hscrollbar_policy: Gtk.PolicyType.NEVER });
|
|
|
13bb5b |
+ this.actor.add_child(this._bannerView);
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let bannerBox = new St.BoxLayout({ vertical: true });
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ this._bannerView.add_actor(bannerBox);
|
|
|
13bb5b |
+ this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
|
|
|
13bb5b |
+ text: '' });
|
|
|
13bb5b |
+ this._bannerLabel.clutter_text.line_wrap = true;
|
|
|
13bb5b |
+ this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
|
|
13bb5b |
+ bannerBox.add_child(this._bannerLabel);
|
|
|
13bb5b |
+ this._updateBanner();
|
|
|
13bb5b |
+
|
|
|
13bb5b |
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
|
|
|
13bb5b |
x_align: Clutter.ActorAlign.CENTER,
|
|
|
13bb5b |
y_align: Clutter.ActorAlign.END });
|
|
|
13bb5b |
this.actor.add_child(this._logoBin);
|
|
|
13bb5b |
this._updateLogo();
|
|
|
13bb5b |
|
|
|
13bb5b |
if (!this._userManager.is_loaded)
|
|
|
13bb5b |
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
|
|
13bb5b |
Lang.bind(this, function() {
|
|
|
13bb5b |
if (this._userManager.is_loaded) {
|
|
|
13bb5b |
this._loadUserList();
|
|
|
13bb5b |
this._userManager.disconnect(this._userManagerLoadedId);
|
|
|
13bb5b |
this._userManagerLoadedId = 0;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
else
|
|
|
13bb5b |
this._loadUserList();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._userList.connect('activate',
|
|
|
13bb5b |
Lang.bind(this, function(userList, item) {
|
|
|
13bb5b |
this._onUserListActivated(item);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
this._sessionMenuButton = new SessionMenuButton();
|
|
|
13bb5b |
this._sessionMenuButton.connect('session-activated',
|
|
|
13bb5b |
Lang.bind(this, function(list, sessionId) {
|
|
|
13bb5b |
this._greeter.call_select_session_sync (sessionId, null);
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
this._sessionMenuButton.actor.opacity = 0;
|
|
|
13bb5b |
this._sessionMenuButton.actor.show();
|
|
|
13bb5b |
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._disableUserList = undefined;
|
|
|
13bb5b |
this._userListLoaded = false;
|
|
|
13bb5b |
|
|
|
13bb5b |
// If the user list is enabled, it should take key focus; make sure the
|
|
|
13bb5b |
// screen shield is initialized first to prevent it from stealing the
|
|
|
13bb5b |
// focus later
|
|
|
13bb5b |
Main.layoutManager.connect('startup-complete',
|
|
|
13bb5b |
Lang.bind(this, this._updateDisableUserList));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
+ _getBannerAllocation: function (dialogBox) {
|
|
|
13bb5b |
+ let actorBox = new Clutter.ActorBox();
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let [minWidth, minHeight, natWidth, natHeight] = this._bannerView.get_preferred_size();
|
|
|
13bb5b |
+ let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ actorBox.x1 = centerX - natWidth / 2;
|
|
|
13bb5b |
+ actorBox.y1 = dialogBox.y1 + Main.layoutManager.panelBox.height;
|
|
|
13bb5b |
+ actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
13bb5b |
+ actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ return actorBox;
|
|
|
13bb5b |
+ },
|
|
|
13bb5b |
+
|
|
|
13bb5b |
_getLogoBinAllocation: function (dialogBox) {
|
|
|
13bb5b |
let actorBox = new Clutter.ActorBox();
|
|
|
13bb5b |
|
|
|
13bb5b |
let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
|
|
|
13bb5b |
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
13bb5b |
|
|
|
13bb5b |
actorBox.x1 = centerX - natWidth / 2;
|
|
|
13bb5b |
actorBox.y1 = dialogBox.y2 - natHeight;
|
|
|
13bb5b |
actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
13bb5b |
actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
13bb5b |
|
|
|
13bb5b |
return actorBox;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_getCenterActorAllocation: function (dialogBox, actor) {
|
|
|
13bb5b |
let actorBox = new Clutter.ActorBox();
|
|
|
13bb5b |
|
|
|
13bb5b |
let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
|
|
|
13bb5b |
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
13bb5b |
let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
|
|
|
13bb5b |
|
|
|
13bb5b |
actorBox.x1 = centerX - natWidth / 2;
|
|
|
13bb5b |
actorBox.y1 = centerY - natHeight / 2;
|
|
|
13bb5b |
actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
13bb5b |
actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
13bb5b |
|
|
|
13bb5b |
return actorBox;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onAllocate: function (actor, dialogBox, flags) {
|
|
|
13bb5b |
let dialogHeight = dialogBox.y2 - dialogBox.y1;
|
|
|
13bb5b |
|
|
|
13bb5b |
// First find out what space the children require
|
|
|
13bb5b |
+ let bannerAllocation = null;
|
|
|
13bb5b |
+ let bannerHeight = 0;
|
|
|
13bb5b |
+ let bannerWidth = 0;
|
|
|
13bb5b |
+ if (this._bannerView.visible) {
|
|
|
13bb5b |
+ bannerAllocation = this._getBannerAllocation(dialogBox, this._bannerView);
|
|
|
13bb5b |
+ bannerHeight = bannerAllocation.y2 - bannerAllocation.y1;
|
|
|
13bb5b |
+ bannerWidth = bannerAllocation.x2 - bannerAllocation.x1;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+
|
|
|
13bb5b |
let authPromptAllocation = null;
|
|
|
13bb5b |
- if (this._authPrompt.actor.visible)
|
|
|
13bb5b |
+ let authPromptHeight = 0;
|
|
|
13bb5b |
+ if (this._authPrompt.actor.visible) {
|
|
|
13bb5b |
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
|
|
|
13bb5b |
+ authPromptHeight = authPromptAllocation.y2 - authPromptAllocation.y1;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
|
|
|
13bb5b |
let userSelectionAllocation = null;
|
|
|
13bb5b |
let userSelectionHeight = 0;
|
|
|
13bb5b |
if (this._userSelectionBox.visible) {
|
|
|
13bb5b |
userSelectionAllocation = this._getCenterActorAllocation(dialogBox, this._userSelectionBox);
|
|
|
13bb5b |
userSelectionHeight = userSelectionAllocation.y2 - userSelectionAllocation.y1;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
let logoAllocation = null;
|
|
|
13bb5b |
let logoHeight = 0;
|
|
|
13bb5b |
if (this._logoBin.visible) {
|
|
|
13bb5b |
logoAllocation = this._getLogoBinAllocation(dialogBox);
|
|
|
13bb5b |
logoHeight = logoAllocation.y2 - logoAllocation.y1;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
// Then figure out what extra space we can hand out
|
|
|
13bb5b |
- let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight;
|
|
|
13bb5b |
- if (leftOverYSpace > 0) {
|
|
|
13bb5b |
- if (userSelectionAllocation) {
|
|
|
13bb5b |
- let topExpansion = leftOverYSpace / 2;
|
|
|
13bb5b |
+ if (bannerAllocation) {
|
|
|
13bb5b |
+ let leftOverYSpace = dialogHeight - bannerHeight - authPromptHeight - logoHeight;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ if (leftOverYSpace > 0) {
|
|
|
13bb5b |
+ // First figure out how much left over space is up top
|
|
|
13bb5b |
+ let leftOverTopSpace = leftOverYSpace / 2;
|
|
|
13bb5b |
|
|
|
13bb5b |
- // Don't ever expand more than we have space for
|
|
|
13bb5b |
- if (userSelectionAllocation.y1 - topExpansion < 0)
|
|
|
13bb5b |
- topExpansion = userSelectionAllocation.y1;
|
|
|
13bb5b |
+ // Then, shift the banner into the middle of that extra space
|
|
|
13bb5b |
+ let yShift = leftOverTopSpace / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ bannerAllocation.y1 += yShift;
|
|
|
13bb5b |
+ bannerAllocation.y2 += yShift;
|
|
|
13bb5b |
+ } else {
|
|
|
13bb5b |
+ // recompute banner height to be constrained if there's no room for its
|
|
|
13bb5b |
+ // requested height
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // First figure out how much space there is without the banner
|
|
|
13bb5b |
+ leftOverYSpace += bannerHeight;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Then figure out how much of that space is up top
|
|
|
13bb5b |
+ let availableTopSpace = leftOverYSpace / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Then give all of that space to the banner
|
|
|
13bb5b |
+ bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+ } else if (userSelectionAllocation) {
|
|
|
13bb5b |
+ // Grow the user list to fill the space
|
|
|
13bb5b |
+ let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight;
|
|
|
13bb5b |
|
|
|
13bb5b |
- // Always expand the bottom the same as the top since it's centered
|
|
|
13bb5b |
+ if (leftOverYSpace > 0) {
|
|
|
13bb5b |
+ let topExpansion = leftOverYSpace / 2;
|
|
|
13bb5b |
let bottomExpansion = topExpansion;
|
|
|
13bb5b |
|
|
|
13bb5b |
userSelectionAllocation.y1 -= topExpansion;
|
|
|
13bb5b |
userSelectionAllocation.y2 += bottomExpansion;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
// Finally hand out the allocations
|
|
|
13bb5b |
+ if (bannerAllocation) {
|
|
|
13bb5b |
+ this._bannerView.allocate(bannerAllocation, flags);
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
+
|
|
|
13bb5b |
if (authPromptAllocation)
|
|
|
13bb5b |
this._authPrompt.actor.allocate(authPromptAllocation, flags);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (userSelectionAllocation)
|
|
|
13bb5b |
this._userSelectionBox.allocate(userSelectionAllocation, flags);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (logoAllocation)
|
|
|
13bb5b |
this._logoBin.allocate(logoAllocation, flags);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_ensureUserListLoaded: function() {
|
|
|
13bb5b |
if (!this._userManager.is_loaded)
|
|
|
13bb5b |
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
|
|
13bb5b |
Lang.bind(this, function() {
|
|
|
13bb5b |
if (this._userManager.is_loaded) {
|
|
|
13bb5b |
this._loadUserList();
|
|
|
13bb5b |
this._userManager.disconnect(this._userManagerLoadedId);
|
|
|
13bb5b |
this._userManagerLoadedId = 0;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
else
|
|
|
13bb5b |
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateDisableUserList: function() {
|
|
|
13bb5b |
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (disableUserList != this._disableUserList) {
|
|
|
13bb5b |
this._disableUserList = disableUserList;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
|
|
13bb5b |
this._authPrompt.reset();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateCancelButton: function() {
|
|
|
13bb5b |
let cancelVisible;
|
|
|
13bb5b |
|
|
|
13bb5b |
// Hide the cancel button if the user list is disabled and we're asking for
|
|
|
13bb5b |
// a username
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING && this._disableUserList)
|
|
|
13bb5b |
cancelVisible = false;
|
|
|
13bb5b |
else
|
|
|
13bb5b |
cancelVisible = true;
|
|
|
13bb5b |
|
|
|
13bb5b |
this._authPrompt.cancelButton.visible = cancelVisible;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateBanner: function() {
|
|
|
13bb5b |
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
|
|
|
13bb5b |
let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (enabled && text) {
|
|
|
13bb5b |
this._bannerLabel.set_text(text);
|
|
|
13bb5b |
this._bannerLabel.show();
|
|
|
13bb5b |
} else {
|
|
|
13bb5b |
this._bannerLabel.hide();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
+ _fadeInBannerView: function() {
|
|
|
13bb5b |
+ Tweener.addTween(this._bannerView,
|
|
|
13bb5b |
+ { opacity: 255,
|
|
|
13bb5b |
+ time: _FADE_ANIMATION_TIME,
|
|
|
13bb5b |
+ transition: 'easeOutQuad' });
|
|
|
13bb5b |
+ },
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ _hideBannerView: function() {
|
|
|
13bb5b |
+ Tweener.removeTweens(this._bannerView);
|
|
|
13bb5b |
+ this._bannerView.opacity = 0;
|
|
|
13bb5b |
+ },
|
|
|
13bb5b |
+
|
|
|
13bb5b |
_updateLogoTexture: function(cache, uri) {
|
|
|
13bb5b |
if (this._logoFileUri != uri)
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoBin.destroy_all_children();
|
|
|
13bb5b |
if (this._logoFileUri)
|
|
|
13bb5b |
this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri,
|
|
|
13bb5b |
-1, _LOGO_ICON_HEIGHT));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_updateLogo: function() {
|
|
|
13bb5b |
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
|
|
|
13bb5b |
this._updateLogoTexture(this._textureCache, this._logoFileUri);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onPrompted: function() {
|
|
|
13bb5b |
this._sessionMenuButton.updateSensitivity(true);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._shouldShowSessionMenuButton())
|
|
|
13bb5b |
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
13bb5b |
this._showPrompt();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onReset: function(authPrompt, beginRequest) {
|
|
|
13bb5b |
this._sessionMenuButton.updateSensitivity(true);
|
|
|
13bb5b |
|
|
|
13bb5b |
this._user = null;
|
|
|
13bb5b |
|
|
|
13bb5b |
@@ -688,60 +763,61 @@ const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
this._hideUserListAskForUsernameAndBeginVerification();
|
|
|
13bb5b |
} else {
|
|
|
13bb5b |
this._hideUserListAndBeginVerification();
|
|
|
13bb5b |
}
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onDefaultSessionChanged: function(client, sessionId) {
|
|
|
13bb5b |
this._sessionMenuButton.setActiveSession(sessionId);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_shouldShowSessionMenuButton: function() {
|
|
|
13bb5b |
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
|
|
|
13bb5b |
this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED)
|
|
|
13bb5b |
return false;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (this._user && this._user.is_loaded && this._user.is_logged_in())
|
|
|
13bb5b |
return false;
|
|
|
13bb5b |
|
|
|
13bb5b |
return true;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_showPrompt: function() {
|
|
|
13bb5b |
if (this._authPrompt.actor.visible)
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
this._authPrompt.actor.opacity = 0;
|
|
|
13bb5b |
this._authPrompt.actor.show();
|
|
|
13bb5b |
Tweener.addTween(this._authPrompt.actor,
|
|
|
13bb5b |
{ opacity: 255,
|
|
|
13bb5b |
time: _FADE_ANIMATION_TIME,
|
|
|
13bb5b |
transition: 'easeOutQuad' });
|
|
|
13bb5b |
+ this._fadeInBannerView();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_showRealmLoginHint: function(realmManager, hint) {
|
|
|
13bb5b |
if (!hint)
|
|
|
13bb5b |
return;
|
|
|
13bb5b |
|
|
|
13bb5b |
hint = hint.replace(/%U/g, 'user');
|
|
|
13bb5b |
hint = hint.replace(/%D/g, 'DOMAIN');
|
|
|
13bb5b |
hint = hint.replace(/%[^UD]/g, '');
|
|
|
13bb5b |
|
|
|
13bb5b |
// Translators: this message is shown below the username entry field
|
|
|
13bb5b |
// to clue the user in on how to login to the local network realm
|
|
|
13bb5b |
this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), GdmUtil.MessageType.HINT);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_askForUsernameAndBeginVerification: function() {
|
|
|
13bb5b |
this._authPrompt.setPasswordChar('');
|
|
|
13bb5b |
this._authPrompt.setQuestion(_("Username: "));
|
|
|
13bb5b |
|
|
|
13bb5b |
let realmManager = new Realmd.Manager();
|
|
|
13bb5b |
let realmSignalId = realmManager.connect('login-format-changed',
|
|
|
13bb5b |
Lang.bind(this, this._showRealmLoginHint));
|
|
|
13bb5b |
this._showRealmLoginHint(realmManager.loginFormat);
|
|
|
13bb5b |
|
|
|
13bb5b |
let nextSignalId = this._authPrompt.connect('next',
|
|
|
13bb5b |
Lang.bind(this, function() {
|
|
|
13bb5b |
this._authPrompt.disconnect(nextSignalId);
|
|
|
13bb5b |
this._authPrompt.updateSensitivity(false);
|
|
|
13bb5b |
let answer = this._authPrompt.getAnswer();
|
|
|
13bb5b |
this._user = this._userManager.get_user(answer);
|
|
|
13bb5b |
@@ -909,60 +985,61 @@ const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
return false;
|
|
|
13bb5b |
}));
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_setUserListExpanded: function(expanded) {
|
|
|
13bb5b |
this._userList.updateStyle(expanded);
|
|
|
13bb5b |
this._userSelectionBox.visible = expanded;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_hideUserList: function() {
|
|
|
13bb5b |
this._setUserListExpanded(false);
|
|
|
13bb5b |
if (this._userSelectionBox.visible)
|
|
|
13bb5b |
GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_hideUserListAskForUsernameAndBeginVerification: function() {
|
|
|
13bb5b |
this._hideUserList();
|
|
|
13bb5b |
this._askForUsernameAndBeginVerification();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_hideUserListAndBeginVerification: function() {
|
|
|
13bb5b |
this._hideUserList();
|
|
|
13bb5b |
this._authPrompt.begin();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_showUserList: function() {
|
|
|
13bb5b |
this._ensureUserListLoaded();
|
|
|
13bb5b |
this._authPrompt.hide();
|
|
|
13bb5b |
+ this._hideBannerView();
|
|
|
13bb5b |
this._sessionMenuButton.close();
|
|
|
13bb5b |
this._setUserListExpanded(true);
|
|
|
13bb5b |
this._notListedButton.show();
|
|
|
13bb5b |
this._userList.actor.grab_key_focus();
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_beginVerificationForItem: function(item) {
|
|
|
13bb5b |
this._authPrompt.setUser(item.user);
|
|
|
13bb5b |
|
|
|
13bb5b |
let userName = item.user.get_user_name();
|
|
|
13bb5b |
let hold = new Batch.Hold();
|
|
|
13bb5b |
|
|
|
13bb5b |
this._authPrompt.begin({ userName: userName,
|
|
|
13bb5b |
hold: hold });
|
|
|
13bb5b |
return hold;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onUserListActivated: function(activatedItem) {
|
|
|
13bb5b |
let tasks = [function() {
|
|
|
13bb5b |
return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
function() {
|
|
|
13bb5b |
this._setUserListExpanded(false);
|
|
|
13bb5b |
}];
|
|
|
13bb5b |
|
|
|
13bb5b |
this._user = activatedItem.user;
|
|
|
13bb5b |
|
|
|
13bb5b |
this._updateCancelButton();
|
|
|
13bb5b |
|
|
|
13bb5b |
let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks),
|
|
|
13bb5b |
--
|
|
|
13bb5b |
2.1.0
|
|
|
13bb5b |
|
|
|
13bb5b |
|
|
|
13bb5b |
From 9bdce53329817e3453baa85cbc4d899511630154 Mon Sep 17 00:00:00 2001
|
|
|
13bb5b |
From: Ray Strode <rstrode@redhat.com>
|
|
|
13bb5b |
Date: Tue, 11 Nov 2014 09:11:01 -0500
|
|
|
13bb5b |
Subject: [PATCH 5/5] loginDialog: use two column view if banner message long
|
|
|
13bb5b |
|
|
|
13bb5b |
Frequently banner messages are longer than can reasonable
|
|
|
13bb5b |
fit in a one column view, which leads to a smooshed layout.
|
|
|
13bb5b |
|
|
|
13bb5b |
This commit changes the layout to a two column view, with the
|
|
|
13bb5b |
banner on the left and the prompt on the right, if the banner
|
|
|
13bb5b |
message is long enough that it can't fit well above the prompt.
|
|
|
13bb5b |
If there isn't enough space for two columns then we keep the
|
|
|
13bb5b |
one column layout but add scrollbars.
|
|
|
13bb5b |
---
|
|
|
13bb5b |
js/gdm/loginDialog.js | 67 ++++++++++++++++++++++++++++++++++++++++++---------
|
|
|
13bb5b |
1 file changed, 55 insertions(+), 12 deletions(-)
|
|
|
13bb5b |
|
|
|
13bb5b |
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
|
|
|
13bb5b |
index 348798c..9ee259f 100644
|
|
|
13bb5b |
--- a/js/gdm/loginDialog.js
|
|
|
13bb5b |
+++ b/js/gdm/loginDialog.js
|
|
|
13bb5b |
@@ -550,118 +550,161 @@ const LoginDialog = new Lang.Class({
|
|
|
13bb5b |
_getLogoBinAllocation: function (dialogBox) {
|
|
|
13bb5b |
let actorBox = new Clutter.ActorBox();
|
|
|
13bb5b |
|
|
|
13bb5b |
let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
|
|
|
13bb5b |
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
13bb5b |
|
|
|
13bb5b |
actorBox.x1 = centerX - natWidth / 2;
|
|
|
13bb5b |
actorBox.y1 = dialogBox.y2 - natHeight;
|
|
|
13bb5b |
actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
13bb5b |
actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
13bb5b |
|
|
|
13bb5b |
return actorBox;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_getCenterActorAllocation: function (dialogBox, actor) {
|
|
|
13bb5b |
let actorBox = new Clutter.ActorBox();
|
|
|
13bb5b |
|
|
|
13bb5b |
let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
|
|
|
13bb5b |
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
13bb5b |
let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
|
|
|
13bb5b |
|
|
|
13bb5b |
actorBox.x1 = centerX - natWidth / 2;
|
|
|
13bb5b |
actorBox.y1 = centerY - natHeight / 2;
|
|
|
13bb5b |
actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
13bb5b |
actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
13bb5b |
|
|
|
13bb5b |
return actorBox;
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_onAllocate: function (actor, dialogBox, flags) {
|
|
|
13bb5b |
+ let dialogWidth = dialogBox.x2 - dialogBox.x1;
|
|
|
13bb5b |
let dialogHeight = dialogBox.y2 - dialogBox.y1;
|
|
|
13bb5b |
|
|
|
13bb5b |
// First find out what space the children require
|
|
|
13bb5b |
let bannerAllocation = null;
|
|
|
13bb5b |
let bannerHeight = 0;
|
|
|
13bb5b |
let bannerWidth = 0;
|
|
|
13bb5b |
if (this._bannerView.visible) {
|
|
|
13bb5b |
bannerAllocation = this._getBannerAllocation(dialogBox, this._bannerView);
|
|
|
13bb5b |
bannerHeight = bannerAllocation.y2 - bannerAllocation.y1;
|
|
|
13bb5b |
bannerWidth = bannerAllocation.x2 - bannerAllocation.x1;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
let authPromptAllocation = null;
|
|
|
13bb5b |
let authPromptHeight = 0;
|
|
|
13bb5b |
+ let authPromptWidth = 0;
|
|
|
13bb5b |
if (this._authPrompt.actor.visible) {
|
|
|
13bb5b |
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
|
|
|
13bb5b |
authPromptHeight = authPromptAllocation.y2 - authPromptAllocation.y1;
|
|
|
13bb5b |
+ authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
let userSelectionAllocation = null;
|
|
|
13bb5b |
let userSelectionHeight = 0;
|
|
|
13bb5b |
if (this._userSelectionBox.visible) {
|
|
|
13bb5b |
userSelectionAllocation = this._getCenterActorAllocation(dialogBox, this._userSelectionBox);
|
|
|
13bb5b |
userSelectionHeight = userSelectionAllocation.y2 - userSelectionAllocation.y1;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
let logoAllocation = null;
|
|
|
13bb5b |
let logoHeight = 0;
|
|
|
13bb5b |
if (this._logoBin.visible) {
|
|
|
13bb5b |
logoAllocation = this._getLogoBinAllocation(dialogBox);
|
|
|
13bb5b |
logoHeight = logoAllocation.y2 - logoAllocation.y1;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
- // Then figure out what extra space we can hand out
|
|
|
13bb5b |
+ // Then figure out if we're overly constrained and need to
|
|
|
13bb5b |
+ // try a different layout, or if we have what extra space we
|
|
|
13bb5b |
+ // can hand out
|
|
|
13bb5b |
if (bannerAllocation) {
|
|
|
13bb5b |
let leftOverYSpace = dialogHeight - bannerHeight - authPromptHeight - logoHeight;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (leftOverYSpace > 0) {
|
|
|
13bb5b |
// First figure out how much left over space is up top
|
|
|
13bb5b |
let leftOverTopSpace = leftOverYSpace / 2;
|
|
|
13bb5b |
|
|
|
13bb5b |
// Then, shift the banner into the middle of that extra space
|
|
|
13bb5b |
let yShift = leftOverTopSpace / 2;
|
|
|
13bb5b |
|
|
|
13bb5b |
bannerAllocation.y1 += yShift;
|
|
|
13bb5b |
bannerAllocation.y2 += yShift;
|
|
|
13bb5b |
} else {
|
|
|
13bb5b |
- // recompute banner height to be constrained if there's no room for its
|
|
|
13bb5b |
- // requested height
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- // First figure out how much space there is without the banner
|
|
|
13bb5b |
- leftOverYSpace += bannerHeight;
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- // Then figure out how much of that space is up top
|
|
|
13bb5b |
- let availableTopSpace = leftOverYSpace / 2;
|
|
|
13bb5b |
-
|
|
|
13bb5b |
- // Then give all of that space to the banner
|
|
|
13bb5b |
- bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
|
|
|
13bb5b |
+ // Then figure out how much space there would be if we switched to a
|
|
|
13bb5b |
+ // wide layout with banner on one side and authprompt on the other.
|
|
|
13bb5b |
+ let leftOverXSpace = dialogWidth - authPromptWidth;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // In a wide view, half of the available space goes to the banner,
|
|
|
13bb5b |
+ // and the other half goes to the margins.
|
|
|
13bb5b |
+ let wideBannerWidth = leftOverXSpace / 2;
|
|
|
13bb5b |
+ let wideSpacing = leftOverXSpace - wideBannerWidth;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // If we do go with a wide layout, we need there to be at least enough
|
|
|
13bb5b |
+ // space for the banner and the auth prompt to be the same width,
|
|
|
13bb5b |
+ // so it doesn't look unbalanced.
|
|
|
13bb5b |
+ if (authPromptWidth > 0 && wideBannerWidth > authPromptWidth) {
|
|
|
13bb5b |
+ let centerX = dialogBox.x1 + dialogWidth / 2;
|
|
|
13bb5b |
+ let centerY = dialogBox.y1 + dialogHeight / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // A small portion of the spacing goes down the center of the
|
|
|
13bb5b |
+ // screen to help delimit the two columns of the wide view
|
|
|
13bb5b |
+ let centerGap = wideSpacing / 8;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // place the banner along the left edge of the center margin
|
|
|
13bb5b |
+ bannerAllocation.x2 = centerX - centerGap / 2;
|
|
|
13bb5b |
+ bannerAllocation.x1 = bannerAllocation.x2 - wideBannerWidth;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // figure out how tall it would like to be and try to accomodate
|
|
|
13bb5b |
+ // but don't let it get too close to the logo
|
|
|
13bb5b |
+ let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ let maxWideHeight = dialogHeight - 3 * logoHeight;
|
|
|
13bb5b |
+ wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight);
|
|
|
13bb5b |
+ bannerAllocation.y1 = centerY - wideBannerHeight / 2;
|
|
|
13bb5b |
+ bannerAllocation.y2 = bannerAllocation.y1 + wideBannerHeight;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // place the auth prompt along the right edge of the center margin
|
|
|
13bb5b |
+ authPromptAllocation.x1 = centerX + centerGap / 2;
|
|
|
13bb5b |
+ authPromptAllocation.x2 = authPromptAllocation.x1 + authPromptWidth;
|
|
|
13bb5b |
+ } else {
|
|
|
13bb5b |
+ // If we aren't going to do a wide view, then we need to limit
|
|
|
13bb5b |
+ // the height of the banner so it will present scrollbars
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // First figure out how much space there is without the banner
|
|
|
13bb5b |
+ leftOverYSpace += bannerHeight;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Then figure out how much of that space is up top
|
|
|
13bb5b |
+ let availableTopSpace = leftOverYSpace / 2;
|
|
|
13bb5b |
+
|
|
|
13bb5b |
+ // Then give all of that space to the banner
|
|
|
13bb5b |
+ bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
|
|
|
13bb5b |
+ }
|
|
|
13bb5b |
}
|
|
|
13bb5b |
} else if (userSelectionAllocation) {
|
|
|
13bb5b |
// Grow the user list to fill the space
|
|
|
13bb5b |
let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight;
|
|
|
13bb5b |
|
|
|
13bb5b |
if (leftOverYSpace > 0) {
|
|
|
13bb5b |
let topExpansion = leftOverYSpace / 2;
|
|
|
13bb5b |
let bottomExpansion = topExpansion;
|
|
|
13bb5b |
|
|
|
13bb5b |
userSelectionAllocation.y1 -= topExpansion;
|
|
|
13bb5b |
userSelectionAllocation.y2 += bottomExpansion;
|
|
|
13bb5b |
}
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
// Finally hand out the allocations
|
|
|
13bb5b |
if (bannerAllocation) {
|
|
|
13bb5b |
this._bannerView.allocate(bannerAllocation, flags);
|
|
|
13bb5b |
}
|
|
|
13bb5b |
|
|
|
13bb5b |
if (authPromptAllocation)
|
|
|
13bb5b |
this._authPrompt.actor.allocate(authPromptAllocation, flags);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (userSelectionAllocation)
|
|
|
13bb5b |
this._userSelectionBox.allocate(userSelectionAllocation, flags);
|
|
|
13bb5b |
|
|
|
13bb5b |
if (logoAllocation)
|
|
|
13bb5b |
this._logoBin.allocate(logoAllocation, flags);
|
|
|
13bb5b |
},
|
|
|
13bb5b |
|
|
|
13bb5b |
_ensureUserListLoaded: function() {
|
|
|
13bb5b |
--
|
|
|
13bb5b |
2.1.0
|
|
|
13bb5b |
|