File gnome-shell-875481-banner-message.patch of Package gnome-shell.1083
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index b27345a..085c717 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -2270,6 +2270,10 @@ StScrollBar StButton#vhandle:active {
}
/* Login Dialog */
+.login-dialog-banner-view {
+ padding-top: 24px;
+ max-width: 23em;
+}
.framed-user-icon {
border: 2px solid #8b8b8b;
@@ -2282,11 +2286,7 @@ StScrollBar StButton#vhandle:active {
}
.login-dialog-banner {
- font-size: 10pt;
- font-weight: bold;
- text-align: center;
color: #666666;
- padding-bottom: 1em;
}
.login-dialog-title {
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
index ae16214..40a2c3e 100644
--- a/js/gdm/loginDialog.js
+++ b/js/gdm/loginDialog.js
@@ -28,6 +28,7 @@ const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Meta = imports.gi.Meta;
+const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
@@ -399,12 +400,12 @@ const LoginDialog = new Lang.Class({
Name: 'LoginDialog',
_init: function(parentActor) {
- this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW,
- layout_manager: new Clutter.BinLayout(),
- style_class: 'login-dialog',
- visible: false });
+ this.actor = new Shell.GenericContainer({ style_class: 'login-dialog',
+ visible: false });
+ this.actor.get_accessible().set_role(Atk.Role.WINDOW);
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
+ this.actor.connect('allocate', Lang.bind(this, this._onAllocate));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
parentActor.add_child(this.actor);
@@ -440,17 +441,10 @@ const LoginDialog = new Lang.Class({
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
- x_expand: true,
- y_expand: true,
vertical: true,
visible: false });
this.actor.add_child(this._userSelectionBox);
- this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
- text: '' });
- this._userSelectionBox.add(this._bannerLabel);
- this._updateBanner();
-
this._userList = new UserList();
this._userSelectionBox.add(this._userList.actor,
{ expand: true,
@@ -507,11 +501,25 @@ const LoginDialog = new Lang.Class({
}
// domain end
+ this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
+ opacity: 0,
+ vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
+ hscrollbar_policy: Gtk.PolicyType.NEVER });
+ this.actor.add_child(this._bannerView);
+
+ let bannerBox = new St.BoxLayout({ vertical: true });
+
+ this._bannerView.add_actor(bannerBox);
+ this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner',
+ text: '' });
+ this._bannerLabel.clutter_text.line_wrap = true;
+ this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
+ bannerBox.add_child(this._bannerLabel);
+ this._updateBanner();
+
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
x_align: Clutter.ActorAlign.CENTER,
- y_align: Clutter.ActorAlign.END,
- x_expand: true,
- y_expand: true });
+ y_align: Clutter.ActorAlign.END });
this.actor.add_child(this._logoBin);
this._updateLogo();
@@ -555,6 +563,181 @@ const LoginDialog = new Lang.Class({
},
+ _getBannerAllocation: function (dialogBox) {
+ let actorBox = new Clutter.ActorBox();
+
+ let [minWidth, minHeight, natWidth, natHeight] = this._bannerView.get_preferred_size();
+ let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
+
+ actorBox.x1 = centerX - natWidth / 2;
+ actorBox.y1 = dialogBox.y1 + Main.layoutManager.panelBox.height;
+ actorBox.x2 = actorBox.x1 + natWidth;
+ actorBox.y2 = actorBox.y1 + natHeight;
+
+ return actorBox;
+ },
+
+ _getLogoBinAllocation: function (dialogBox) {
+ let actorBox = new Clutter.ActorBox();
+
+ let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
+ let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
+
+ actorBox.x1 = centerX - natWidth / 2;
+ actorBox.y1 = dialogBox.y2 - natHeight;
+ actorBox.x2 = actorBox.x1 + natWidth;
+ actorBox.y2 = actorBox.y1 + natHeight;
+
+ return actorBox;
+ },
+
+ _getCenterActorAllocation: function (dialogBox, actor) {
+ let actorBox = new Clutter.ActorBox();
+
+ let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
+ let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
+ let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
+
+ actorBox.x1 = centerX - natWidth / 2;
+ actorBox.y1 = centerY - natHeight / 2;
+ actorBox.x2 = actorBox.x1 + natWidth;
+ actorBox.y2 = actorBox.y1 + natHeight;
+
+ return actorBox;
+ },
+
+ _onAllocate: function (actor, dialogBox, flags) {
+ let dialogWidth = dialogBox.x2 - dialogBox.x1;
+ let dialogHeight = dialogBox.y2 - dialogBox.y1;
+
+ // First find out what space the children require
+ let bannerAllocation = null;
+ let bannerHeight = 0;
+ let bannerWidth = 0;
+ if (this._bannerView.visible) {
+ bannerAllocation = this._getBannerAllocation(dialogBox, this._bannerView);
+ bannerHeight = bannerAllocation.y2 - bannerAllocation.y1;
+ bannerWidth = bannerAllocation.x2 - bannerAllocation.x1;
+ }
+
+ let authPromptAllocation = null;
+ let authPromptHeight = 0;
+ let authPromptWidth = 0;
+ if (this._authPrompt.actor.visible) {
+ authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
+ authPromptHeight = authPromptAllocation.y2 - authPromptAllocation.y1;
+ authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
+ }
+
+ let userSelectionAllocation = null;
+ let userSelectionHeight = 0;
+ if (this._userSelectionBox.visible) {
+ userSelectionAllocation = this._getCenterActorAllocation(dialogBox, this._userSelectionBox);
+ userSelectionHeight = userSelectionAllocation.y2 - userSelectionAllocation.y1;
+ }
+
+ let logoAllocation = null;
+ let logoHeight = 0;
+ if (this._logoBin.visible) {
+ logoAllocation = this._getLogoBinAllocation(dialogBox);
+ logoHeight = logoAllocation.y2 - logoAllocation.y1;
+ }
+
+ // Then figure out if we're overly constrained and need to
+ // try a different layout, or if we have what extra space we
+ // can hand out
+ if (bannerAllocation > 0) {
+ let leftOverYSpace = dialogHeight - bannerHeight - authPromptHeight - logoHeight;
+
+ if (leftOverYSpace > 0) {
+ //First figure out how much left over space is up top
+ let leftOverTopSpace = leftOverYSpace / 2;
+
+ //Then, shift the banner into the middle of that extra space
+ let yShift = leftOverTopSpace / 2;
+
+ bannerAllocation.y1 += yShift;
+ bannerAllocation.y2 += yShift;
+ } else {
+ //Then figure out how much space there would be if we switched to a
+ // wide layout with banner on one side and authprompt on the other.
+ let leftOverXSpace = dialogWidth - authPromptWidth;
+
+ // In a wide view, half of the available space goes to the banner,
+ // and the other half goes to the margins.
+ let wideBannerWidth = leftOverXSpace / 2;
+ let wideSpacing = leftOverXSpace - wideBannerWidth;
+
+ // If we do go with a wide layout, we need there to be at least enough
+ // space for the banner and the auth prompt to be the same width,
+ // so it doesn't look unbalanced.
+ if (authPromptWidth > 0 && wideBannerWidth > authPromptWidth) {
+ let centerX = dialogBox.x1 + dialogWidth / 2;
+ let centerY = dialogBox.y1 + dialogHeight / 2;
+
+ // A small portion of the spacing goes down the center of the
+ // screen to help delimit the two columns of the wide view
+ let centerGap = wideSpacing / 8;
+
+ // place the banner along the left edge of the center margin
+ bannerAllocation.x2 = centerX - centerGap / 2;
+ bannerAllocation.x1 = bannerAllocation.x2 - wideBannerWidth;
+
+ // figure out how tall it would like to be and try to accomodate
+ // but don't let it get too close to the logo
+ let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
+
+ let maxWideHeight = dialogHeight - 3 * logoHeight;
+ wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight);
+ bannerAllocation.y1 = centerY - wideBannerHeight / 2;
+ bannerAllocation.y2 = bannerAllocation.y1 + wideBannerHeight;
+
+ // place the auth prompt along the right edge of the center margin
+ authPromptAllocation.x1 = centerX + centerGap / 2;
+ authPromptAllocation.x2 = authPromptAllocation.x1 + authPromptWidth;
+ } else {
+ // If we aren't going to do a wide view, then we need to limit
+ // the height of the banner so it will present scrollbars
+
+ // First figure out how much space there is without the banner
+ leftOverYSpace += bannerHeight;
+
+ // Then figure out how much of that space is up top
+ let availableTopSpace = leftOverYSpace / 2;
+
+ // Then give all of that space to the banner
+ bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
+ }
+ }
+ } else if (userSelectionAllocation) {
+ // Grow the user list to fill the space
+ let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight;
+
+ if (leftOverYSpace > 0) {
+ let topExpansion = leftOverYSpace / 2;
+ let bottomExpansion = topExpansion;
+
+ userSelectionAllocation.y1 -= topExpansion;
+ userSelectionAllocation.y2 += bottomExpansion;
+ }
+ }
+
+ // Finally hand out the allocations
+ if (bannerAllocation) {
+ this._bannerView.allocate(bannerAllocation, flags);
+ }
+
+ if (authPromptAllocation)
+ this._authPrompt.actor.allocate(authPromptAllocation, flags);
+
+ if (userSelectionAllocation)
+ this._userSelectionBox.allocate(userSelectionAllocation, flags);
+
+ if (logoAllocation)
+ this._logoBin.allocate(logoAllocation, flags);
+ },
+
+
_ensureUserListLoaded: function() {
if (!this._userManager.is_loaded)
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
@@ -618,6 +801,18 @@ const LoginDialog = new Lang.Class({
}
},
+ _fadeInBannerView: function() {
+ Tweener.addTween(this._bannerView,
+ { opacity: 255,
+ time: _FADE_ANIMATION_TIME,
+ transition: 'easeOutQuad' });
+ },
+
+ _hideBannerView: function() {
+ Tweener.removeTweens(this._bannerView);
+ this._bannerView.opacity = 0;
+ },
+
_updateLogoTexture: function(cache, uri) {
if (this._logoFileUri != uri)
return;
@@ -687,6 +882,7 @@ const LoginDialog = new Lang.Class({
{ opacity: 255,
time: _FADE_ANIMATION_TIME,
transition: 'easeOutQuad' });
+ this._fadeInBannerView();
},
_showRealmLoginHint: function(realmManager, hint) {
@@ -939,6 +1135,7 @@ const LoginDialog = new Lang.Class({
_showUserList: function() {
this._ensureUserListLoaded();
this._authPrompt.hide();
+ this._hideBannerView();
this._sessionMenuButton.close();
this._setUserListExpanded(true);
this._notListedButton.show();