[gnome-shell/wip/hot-corner-barriers: 6/11] layout: Construct the primary monitors's hot corner, too



commit a55e35bfee506fc48872534eebbbd3744ac7a50d
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Mar 1 16:00:37 2013 -0500

    layout: Construct the primary monitors's hot corner, too
    
    This cleans up the code considerably, and makes it so that
    one path creates all hot corners for all monitors. Why this
    wasn't done originally, I have no clue...
    
    The one complication is debouncing if the button and hot corner
    are triggered in rapid succession, so we just move this tracking
    to the overview.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=663661

 js/ui/layout.js      |  113 +++++++++++++++++---------------------------------
 js/ui/main.js        |    2 -
 js/ui/messageTray.js |   16 ++++---
 js/ui/overview.js    |   19 ++++++++
 js/ui/panel.js       |   51 +----------------------
 5 files changed, 68 insertions(+), 133 deletions(-)
---
diff --git a/js/ui/layout.js b/js/ui/layout.js
index 7fa982a..21f5ffd 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -18,7 +18,6 @@ const Main = imports.ui.main;
 const Params = imports.misc.params;
 const Tweener = imports.ui.tweener;
 
-const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
 const STARTUP_ANIMATION_TIME = 0.5;
 const KEYBOARD_ANIMATION_TIME = 0.15;
 const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
@@ -130,8 +129,9 @@ const LayoutManager = new Lang.Class({
         this.monitors = [];
         this.primaryMonitor = null;
         this.primaryIndex = -1;
+        this.hotCorners = [];
+
         this._keyboardIndex = -1;
-        this._hotCorners = [];
         this._leftPanelBarrier = null;
         this._rightPanelBarrier = null;
         this._trayBarrier = null;
@@ -276,56 +276,57 @@ const LayoutManager = new Lang.Class({
 
     _updateHotCorners: function() {
         // destroy old hot corners
-        for (let i = 0; i < this._hotCorners.length; i++)
-            this._hotCorners[i].destroy();
-        this._hotCorners = [];
+        for (let i = 0; i < this.hotCorners.length; i++)
+            this.hotCorners[i].destroy();
+        this.hotCorners = [];
 
         // build new hot corners
         for (let i = 0; i < this.monitors.length; i++) {
-            if (i == this.primaryIndex)
-                continue;
-
             let monitor = this.monitors[i];
             let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
             let cornerY = monitor.y;
 
-            let haveTopLeftCorner = true;
+            if (i != this.primaryIndex) {
+                let haveTopLeftCorner = true;
 
-            // Check if we have a top left (right for RTL) corner.
-            // I.e. if there is no monitor directly above or to the left(right)
-            let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
-            let besideY = cornerY;
-            let aboveX = cornerX;
-            let aboveY = cornerY - 1;
+                // Check if we have a top left (right for RTL) corner.
+                // I.e. if there is no monitor directly above or to the left(right)
+                let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
+                let besideY = cornerY;
+                let aboveX = cornerX;
+                let aboveY = cornerY - 1;
 
-            for (let j = 0; j < this.monitors.length; j++) {
-                if (i == j)
-                    continue;
-                let otherMonitor = this.monitors[j];
-                if (besideX >= otherMonitor.x &&
-                    besideX < otherMonitor.x + otherMonitor.width &&
-                    besideY >= otherMonitor.y &&
-                    besideY < otherMonitor.y + otherMonitor.height) {
-                    haveTopLeftCorner = false;
-                    break;
-                }
-                if (aboveX >= otherMonitor.x &&
-                    aboveX < otherMonitor.x + otherMonitor.width &&
-                    aboveY >= otherMonitor.y &&
-                    aboveY < otherMonitor.y + otherMonitor.height) {
-                    haveTopLeftCorner = false;
-                    break;
+                for (let j = 0; j < this.monitors.length; j++) {
+                    if (i == j)
+                        continue;
+                    let otherMonitor = this.monitors[j];
+                    if (besideX >= otherMonitor.x &&
+                        besideX < otherMonitor.x + otherMonitor.width &&
+                        besideY >= otherMonitor.y &&
+                        besideY < otherMonitor.y + otherMonitor.height) {
+                        haveTopLeftCorner = false;
+                        break;
+                    }
+                    if (aboveX >= otherMonitor.x &&
+                        aboveX < otherMonitor.x + otherMonitor.width &&
+                        aboveY >= otherMonitor.y &&
+                        aboveY < otherMonitor.y + otherMonitor.height) {
+                        haveTopLeftCorner = false;
+                        break;
+                    }
                 }
-            }
 
-            if (!haveTopLeftCorner)
-                continue;
+                if (!haveTopLeftCorner)
+                    continue;
+            }
 
             let corner = new HotCorner(this);
-            this._hotCorners.push(corner);
+            this.hotCorners.push(corner);
             corner.actor.set_position(cornerX, cornerY);
             this.addChrome(corner.actor);
         }
+
+        this.emit('hot-corners-changed');
     },
 
     _createBackground: function(monitorIndex) {
@@ -395,7 +396,6 @@ const LayoutManager = new Lang.Class({
     },
 
     _panelBoxChanged: function() {
-        this.emit('panel-box-changed');
         this._updatePanelBarriers();
     },
 
@@ -650,8 +650,6 @@ const LayoutManager = new Lang.Class({
         if (!Main.sessionMode.isGreeter)
             this._createSecondaryBackgrounds();
 
-        this.emit('panel-box-changed');
-
         this._queueUpdateRegions();
 
         this.emit('startup-complete');
@@ -1133,24 +1131,11 @@ const HotCorner = new Lang.Class({
             this._corner.set_position(0, 0);
         }
 
-        this._activationTime = 0;
-
         this.actor.connect('leave-event',
                            Lang.bind(this, this._onEnvironsLeft));
 
-        // Clicking on the hot corner environs should result in the
-        // same behavior as clicking on the hot corner.
-        this.actor.connect('button-release-event',
-                           Lang.bind(this, this._onCornerClicked));
-
-        // In addition to being triggered by the mouse enter event,
-        // the hot corner can be triggered by clicking on it. This is
-        // useful if the user wants to undo the effect of triggering
-        // the hot corner once in the hot corner.
         this._corner.connect('enter-event',
                              Lang.bind(this, this._onCornerEntered));
-        this._corner.connect('button-release-event',
-                             Lang.bind(this, this._onCornerClicked));
         this._corner.connect('leave-event',
                              Lang.bind(this, this._onCornerLeft));
 
@@ -1225,9 +1210,7 @@ const HotCorner = new Lang.Class({
     _onCornerEntered : function() {
         if (!this._entered) {
             this._entered = true;
-            if (!Main.overview.animationInProgress) {
-                this._activationTime = Date.now() / 1000;
-
+            if (Main.overview.shouldToggleByCornerOrButton()) {
                 this.rippleAnimation();
                 Main.overview.toggle();
             }
@@ -1235,12 +1218,6 @@ const HotCorner = new Lang.Class({
         return false;
     },
 
-    _onCornerClicked : function() {
-        if (this.shouldToggleOverviewOnClick())
-            Main.overview.toggle();
-        return true;
-    },
-
     _onCornerLeft : function(actor, event) {
         if (event.get_related() != this.actor)
             this._entered = false;
@@ -1252,20 +1229,6 @@ const HotCorner = new Lang.Class({
         if (event.get_related() != this._corner)
             this._entered = false;
         return false;
-    },
-
-    // Checks if the Activities button is currently sensitive to
-    // clicks. The first call to this function within the
-    // HOT_CORNER_ACTIVATION_TIMEOUT time of the hot corner being
-    // triggered will return false. This avoids opening and closing
-    // the overview if the user both triggered the hot corner and
-    // clicked the Activities button.
-    shouldToggleOverviewOnClick: function() {
-        if (Main.overview.animationInProgress)
-            return false;
-        if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > 
HOT_CORNER_ACTIVATION_TIMEOUT)
-            return true;
-        return false;
     }
 });
 
diff --git a/js/ui/main.js b/js/ui/main.js
index 4025bd7..e0c2dd7 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -148,8 +148,6 @@ function startSession() {
     else
         screenShield = new ScreenShield.ScreenShieldFallback();
 
-    // The message tray relies on being constructed
-    // after the panel.
     panel = new Panel.Panel();
     messageTray = new MessageTray.MessageTray();
     keyboard = new Keyboard.Keyboard();
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index 2df4abc..15629f5 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -1672,14 +1672,13 @@ const MessageTray = new Lang.Class({
         Main.layoutManager.trackChrome(this._closeButton);
 
         Main.layoutManager.connect('primary-fullscreen-changed', Lang.bind(this, this._onFullscreenChanged));
+        Main.layoutManager.connect('hot-corners-changed', Lang.bind(this, this._hotCornersChanged));
 
         // If the overview shows or hides while we're in
         // the message tray, revert back to normal mode.
         Main.overview.connect('showing', Lang.bind(this, this._escapeTray));
         Main.overview.connect('hiding', Lang.bind(this, this._escapeTray));
 
-        // Track if we've added the activities button
-        this._activitiesButtonAdded = false;
         Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
 
         Main.wm.addKeybinding('toggle-message-tray',
@@ -1703,6 +1702,7 @@ const MessageTray = new Lang.Class({
         this._trayDwellTimeoutId = 0;
         this._setupTrayDwellIfNeeded();
         this._sessionUpdated();
+        this._hotCornersChanged();
 
         this._noMessages = new St.Label({ text: _("No Messages"),
                                           style_class: 'no-messages-label',
@@ -1775,11 +1775,6 @@ const MessageTray = new Lang.Class({
     },
 
     _sessionUpdated: function() {
-        if (!this._activitiesButtonAdded && Main.panel.statusArea.activities) {
-            this._activitiesButtonAdded = true;
-            this._grabHelper.addActor(Main.panel.statusArea.activities.hotCorner.actor);
-        }
-
         if ((Main.sessionMode.isLocked || Main.sessionMode.isGreeter) && this._inCtrlAltTab) {
             Main.ctrlAltTabManager.removeGroup(this._summary);
             this._inCtrlAltTab = false;
@@ -2101,6 +2096,13 @@ const MessageTray = new Lang.Class({
         this._updateState();
     },
 
+    _hotCornersChanged: function() {
+        let primary = Main.layoutManager.primaryIndex;
+        let corner = Main.layoutManager.hotCorners[primary];
+        if (corner && corner.actor)
+            this._grabHelper.addActor(corner.actor);
+    },
+
     _onTrayHoverChanged: function() {
         if (this.actor.hover) {
             // No dwell inside notifications at the bottom of the screen
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 6f23608..35eb020 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -33,6 +33,8 @@ const SHADE_ANIMATION_TIME = .20;
 
 const DND_WINDOW_SWITCH_TIMEOUT = 1250;
 
+const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
+
 const ShellInfo = new Lang.Class({
     Name: 'ShellInfo',
 
@@ -146,6 +148,8 @@ const Overview = new Lang.Class({
         this._backgroundGroup.hide();
         this._bgManagers = [];
 
+        this._activationTime = 0;
+
         this.visible = false;           // animating to overview, in overview, animating out
         this._shown = false;            // show() and not hide()
         this._shownTemporarily = false; // showTemporarily() and not hideTemporarily()
@@ -536,6 +540,7 @@ const Overview = new Lang.Class({
         this.visible = true;
         this.animationInProgress = true;
         this.visibleTarget = true;
+        this._activationTime = Date.now() / 1000;
 
         // All the the actors in the window group are completely obscured,
         // hiding the group holding them while the Overview is displayed greatly
@@ -633,6 +638,20 @@ const Overview = new Lang.Class({
             this.show();
     },
 
+    // Checks if the Activities button is currently sensitive to
+    // clicks. The first call to this function within the
+    // OVERVIEW_ACTIVATION_TIMEOUT time of the hot corner being
+    // triggered will return false. This avoids opening and closing
+    // the overview if the user both triggered the hot corner and
+    // clicked the Activities button.
+    shouldToggleByCornerOrButton: function() {
+        if (this.animationInProgress)
+            return false;
+        if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > 
OVERVIEW_ACTIVATION_TIMEOUT)
+            return true;
+        return false;
+    },
+
     //// Private methods ////
 
     _syncInputMode: function() {
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 558ce67..2b1ed9b 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -18,7 +18,6 @@ const Atk = imports.gi.Atk;
 const Config = imports.misc.config;
 const CtrlAltTab = imports.ui.ctrlAltTab;
 const DND = imports.ui.dnd;
-const Layout = imports.ui.layout;
 const Overview = imports.ui.overview;
 const PopupMenu = imports.ui.popupMenu;
 const PanelMenu = imports.ui.panelMenu;
@@ -630,23 +629,15 @@ const ActivitiesButton = new Lang.Class({
         this.parent(0.0, null, true);
         this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON;
 
-        let container = new Shell.GenericContainer();
-        container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
-        container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
-        container.connect('allocate', Lang.bind(this, this._containerAllocate));
-        this.actor.add_actor(container);
         this.actor.name = 'panelActivities';
 
         /* Translators: If there is no suitable word for "Activities"
            in your language, you can use the word for "Overview". */
         this._label = new St.Label({ text: _("Activities") });
-        container.add_actor(this._label);
+        this.actor.add_actor(this._label);
 
         this.actor.label_actor = this._label;
 
-        this.hotCorner = new Layout.HotCorner(Main.layoutManager);
-        container.add_actor(this.hotCorner.actor);
-
         this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
         this.actor.connect_after('button-release-event', Lang.bind(this, this._onButtonRelease));
         this.actor.connect_after('key-release-event', Lang.bind(this, this._onKeyRelease));
@@ -661,44 +652,6 @@ const ActivitiesButton = new Lang.Class({
         }));
 
         this._xdndTimeOut = 0;
-
-        // Since the hot corner uses stage coordinates, Clutter won't
-        // queue relayouts for us when the panel moves. Queue a relayout
-        // when that happens.
-        Main.layoutManager.connect('panel-box-changed', Lang.bind(this, function() {
-            container.queue_relayout();
-        }));
-    },
-
-    _containerGetPreferredWidth: function(actor, forHeight, alloc) {
-        [alloc.min_size, alloc.natural_size] = this._label.get_preferred_width(forHeight);
-    },
-
-    _containerGetPreferredHeight: function(actor, forWidth, alloc) {
-        [alloc.min_size, alloc.natural_size] = this._label.get_preferred_height(forWidth);
-    },
-
-    _containerAllocate: function(actor, box, flags) {
-        this._label.allocate(box, flags);
-
-        // The hot corner needs to be outside any padding/alignment
-        // that has been imposed on us
-        let primary = Main.layoutManager.primaryMonitor;
-        let hotBox = new Clutter.ActorBox();
-        let ok, x, y;
-        if (actor.get_text_direction() == Clutter.TextDirection.LTR) {
-            [ok, x, y] = actor.transform_stage_point(primary.x, primary.y)
-        } else {
-            [ok, x, y] = actor.transform_stage_point(primary.x + primary.width, primary.y);
-            // hotCorner.actor has northeast gravity, so we don't need
-            // to adjust x for its width
-        }
-
-        hotBox.x1 = Math.round(x);
-        hotBox.x2 = hotBox.x1 + this.hotCorner.actor.width;
-        hotBox.y1 = Math.round(y);
-        hotBox.y2 = hotBox.y1 + this.hotCorner.actor.height;
-        this.hotCorner.actor.allocate(hotBox, flags);
     },
 
     handleDragOver: function(source, actor, x, y, time) {
@@ -715,7 +668,7 @@ const ActivitiesButton = new Lang.Class({
 
     _onCapturedEvent: function(actor, event) {
         if (event.type() == Clutter.EventType.BUTTON_PRESS) {
-            if (!this.hotCorner.shouldToggleOverviewOnClick())
+            if (!Main.overview.shouldToggleByCornerOrButton())
                 return true;
         }
         return false;


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