[gnome-shell] ui: Improve handling being headless



commit 5c37facc083078564faaeec4aa58084857c56ee1
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Apr 12 14:46:54 2017 +0800

    ui: Improve handling being headless
    
    Don't assume there will always be a primary (logical) monitor, or any
    (logical) monitor at all. This includes not allocating / layouting /
    styling correctly when being headless.
    
    The initial background loading will also be delayed until there are any
    (logical) monitors connected.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=730551

 js/ui/layout.js             |   29 ++++++++++++++++++++++++++---
 js/ui/overview.js           |    3 +++
 js/ui/panel.js              |   23 +++++++++++++++++------
 js/ui/workspaceThumbnail.js |   21 ++++++++++++++++++---
 4 files changed, 64 insertions(+), 12 deletions(-)
---
diff --git a/js/ui/layout.js b/js/ui/layout.js
index a2cb6e0..304c2a1 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -129,6 +129,9 @@ var MonitorConstraint = new Lang.Class({
         if (!this._primary && this._index < 0)
             return;
 
+        if (!Main.layoutManager.primaryMonitor)
+            return;
+
         let index;
         if (this._primary)
             index = Main.layoutManager.primaryIndex;
@@ -189,6 +192,7 @@ var LayoutManager = new Lang.Class({
         this._topActors = [];
         this._isPopupWindowVisible = false;
         this._startingUp = true;
+        this._pendingLoadBackground = false;
 
         // We don't want to paint the stage background color because either
         // the SystemBackground we create or the MetaBackgroundActor inside
@@ -323,7 +327,9 @@ var LayoutManager = new Lang.Class({
         for (let i = 0; i < nMonitors; i++)
             this.monitors.push(new Monitor(i, screen.get_monitor_geometry(i)));
 
-        if (nMonitors == 1) {
+        if (nMonitors == 0) {
+            this.primaryIndex = this.bottomIndex = -1;
+        } else if (nMonitors == 1) {
             this.primaryIndex = this.bottomIndex = 0;
         } else {
             // If there are monitors below the primary, then we need
@@ -337,8 +343,15 @@ var LayoutManager = new Lang.Class({
                 }
             }
         }
-        this.primaryMonitor = this.monitors[this.primaryIndex];
-        this.bottomMonitor = this.monitors[this.bottomIndex];
+        if (this.primaryIndex != -1) {
+            this.primaryMonitor = this.monitors[this.primaryIndex];
+            this.bottomMonitor = this.monitors[this.bottomIndex];
+
+            if (this._pendingLoadBackground) {
+                this._loadBackground();
+                this._pendingLoadBackground = false;
+            }
+        }
     },
 
     _updateHotCorners: function() {
@@ -458,6 +471,9 @@ var LayoutManager = new Lang.Class({
         this.screenShieldGroup.set_position(0, 0);
         this.screenShieldGroup.set_size(global.screen_width, global.screen_height);
 
+        if (!this.primaryMonitor)
+            return;
+
         this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
         this.panelBox.set_size(this.primaryMonitor.width, -1);
 
@@ -480,6 +496,9 @@ var LayoutManager = new Lang.Class({
             this._rightPanelBarrier = null;
         }
 
+        if (!this.primaryMonitor)
+            return;
+
         if (this.panelBox.height) {
             let primary = this.primaryMonitor;
 
@@ -549,6 +568,10 @@ var LayoutManager = new Lang.Class({
     },
 
     _loadBackground: function() {
+        if (!this.primaryMonitor) {
+            this._pendingLoadBackground = true;
+            return;
+        }
         this._systemBackground = new Background.SystemBackground();
         this._systemBackground.actor.hide();
 
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 1ac62a4..7eb2102 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -392,6 +392,9 @@ var Overview = new Lang.Class({
         // when it is next shown.
         this.hide();
 
+        if (!Main.layoutManager.primaryMonitor)
+            return;
+
         let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
 
         this._coverPane.set_position(0, workArea.y);
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 3056ac7..dc65366 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -839,8 +839,14 @@ var Panel = new Lang.Class({
     },
 
     _getPreferredWidth: function(actor, forHeight, alloc) {
+        let primaryMonitor = Main.layoutManager.primaryMonitor;
+
         alloc.min_size = -1;
-        alloc.natural_size = Main.layoutManager.primaryMonitor.width;
+
+        if (primaryMonitor)
+            alloc.natural_size = primaryMonitor.width;
+        else
+            alloc.natural_size = -1;
     },
 
     _getPreferredHeight: function(actor, forWidth, alloc) {
@@ -859,15 +865,16 @@ var Panel = new Lang.Class({
 
         let sideWidth, centerWidth;
         centerWidth = centerNaturalWidth;
-        sideWidth = (allocWidth - centerWidth) / 2;
+        sideWidth = Math.max(0, (allocWidth - centerWidth) / 2);
 
         let childBox = new Clutter.ActorBox();
 
         childBox.y1 = 0;
         childBox.y2 = allocHeight;
         if (this.actor.get_text_direction() == Clutter.TextDirection.RTL) {
-            childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
-                                                leftNaturalWidth);
+            childBox.x1 = Math.max(allocWidth - Math.min(Math.floor(sideWidth),
+                                                         leftNaturalWidth),
+                                   0);
             childBox.x2 = allocWidth;
         } else {
             childBox.x1 = 0;
@@ -889,8 +896,9 @@ var Panel = new Lang.Class({
             childBox.x2 = Math.min(Math.floor(sideWidth),
                                    rightNaturalWidth);
         } else {
-            childBox.x1 = allocWidth - Math.min(Math.floor(sideWidth),
-                                                rightNaturalWidth);
+            childBox.x1 = Math.max(allocWidth - Math.min(Math.floor(sideWidth),
+                                                         rightNaturalWidth),
+                                   0);
             childBox.x2 = allocWidth;
         }
         this._rightBox.allocate(childBox, flags);
@@ -1044,6 +1052,9 @@ var Panel = new Lang.Class({
             return;
         }
 
+        if (!Main.layoutManager.primaryMonitor)
+            return;
+
         /* Get all the windows in the active workspace that are in the primary monitor and visible */
         let activeWorkspace = global.screen.get_active_workspace();
         let windows = activeWorkspace.list_windows().filter(function(metaWindow) {
diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js
index 73a6088..f5f6913 100644
--- a/js/ui/workspaceThumbnail.js
+++ b/js/ui/workspaceThumbnail.js
@@ -937,7 +937,8 @@ var ThumbnailsBox = new Lang.Class({
     },
 
     addThumbnails: function(start, count) {
-        this._ensurePorthole();
+        if (!this._ensurePorthole())
+            return;
         for (let k = start; k < start + count; k++) {
             let metaWorkspace = global.screen.get_workspace_by_index(k);
             let thumbnail = new WorkspaceThumbnail(metaWorkspace);
@@ -1125,7 +1126,12 @@ var ThumbnailsBox = new Lang.Class({
         // the size request to our children because we know how big they are and know
         // that the actors aren't depending on the virtual functions being called.
 
-        this._ensurePorthole();
+        if (!this._ensurePorthole()) {
+            alloc.min_size = -1;
+            alloc.natural_size = -1;
+            return;
+        }
+
         let themeNode = this.actor.get_theme_node();
 
         let spacing = themeNode.get_length('spacing');
@@ -1137,7 +1143,11 @@ var ThumbnailsBox = new Lang.Class({
     },
 
     _getPreferredWidth: function(actor, forHeight, alloc) {
-        this._ensurePorthole();
+        if (!this._ensurePorthole()) {
+            alloc.min_size = -1;
+            alloc.natural_size = -1;
+            return;
+        }
 
         let themeNode = this.actor.get_theme_node();
 
@@ -1158,8 +1168,13 @@ var ThumbnailsBox = new Lang.Class({
     // The "porthole" is the portion of the screen that we show in the
     // workspaces
     _ensurePorthole: function() {
+        if (!Main.layoutManager.primaryMonitor)
+            return false;
+
         if (!this._porthole)
             this._porthole = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
+
+        return true;
     },
 
     _allocate: function(actor, box, flags) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]