[gnome-shell/wip/aggregate-menu: 70/99] popupMenu: Propagate sensitivity to menu children



commit 7096503129c19d8cb857246e9cb4fe3387f4062c
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Jun 12 03:16:53 2013 -0400

    popupMenu: Propagate sensitivity to menu children
    
    This way, if a parent is insensitive, all children will be, too.

 js/ui/popupMenu.js |   65 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 55 insertions(+), 10 deletions(-)
---
diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js
index 8514a5c..6588bb3 100644
--- a/js/ui/popupMenu.js
+++ b/js/ui/popupMenu.js
@@ -64,6 +64,8 @@ const PopupBaseMenuItem = new Lang.Class({
         this._spacing = 0;
         this.active = false;
         this._activatable = params.reactive && params.activate;
+        this._sensitive = true;
+        this.parentSensitive = true;
 
         if (!this._activatable)
             this.actor.add_style_class_name('popup-inactive-menu-item');
@@ -133,17 +135,24 @@ const PopupBaseMenuItem = new Lang.Class({
         }
     },
 
-    setSensitive: function(sensitive) {
-        if (!this._activatable)
-            return;
-        if (this.sensitive == sensitive)
-            return;
-
-        this.sensitive = sensitive;
+    syncSensitive: function() {
+        let sensitive = this.getSensitive();
         this.actor.reactive = sensitive;
         this.actor.can_focus = sensitive;
+        this.emit('sensitive-changed');
+        return sensitive;
+    },
+
+    getSensitive: function() {
+        return this._activatable && this._sensitive && this.parentSensitive;
+    },
+
+    setSensitive: function(sensitive) {
+        if (this._sensitive == sensitive)
+            return;
 
-        this.emit('sensitive-changed', sensitive);
+        this._sensitive = sensitive;
+        this.syncSensitive();
     },
 
     destroy: function() {
@@ -698,6 +707,18 @@ const PopupMenuBase = new Lang.Class({
         this._settingsActions = { };
 
         this._sessionUpdatedId = Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
+
+        this._sensitive = true;
+        this.parentSensitive = true;
+    },
+
+    getSensitive: function() {
+        return this._sensitive && this.parentSensitive;
+    },
+
+    setSensitive: function(sensitive) {
+        this._sensitive = sensitive;
+        this.emit('sensitive-changed');
     },
 
     _sessionUpdated: function() {
@@ -772,7 +793,8 @@ const PopupMenuBase = new Lang.Class({
                 this.emit('active-changed', null);
             }
         }));
-        menuItem._sensitiveChangeId = menuItem.connect('sensitive-changed', Lang.bind(this, 
function(menuItem, sensitive) {
+        menuItem._sensitiveChangeId = menuItem.connect('sensitive-changed', Lang.bind(this, function() {
+            let sensitive = menuItem.getSensitive();
             if (!sensitive && this._activeMenuItem == menuItem) {
                 if (!this.actor.navigate_focus(menuItem.actor,
                                                Gtk.DirectionType.TAB_FORWARD,
@@ -787,6 +809,12 @@ const PopupMenuBase = new Lang.Class({
             this.emit('activate', menuItem);
             this.close(BoxPointer.PopupAnimation.FULL);
         }));
+
+        menuItem._parentSensitiveChangedId = this.connect('sensitive-changed', Lang.bind(this, function() {
+            menuItem.parentSensitive = this.getSensitive();
+            menuItem.syncSensitive();
+        }));
+
         // the weird name is to avoid a conflict with some random property
         // the menuItem may have, called destroyId
         // (FIXME: in the future it may make sense to have container objects
@@ -795,7 +823,7 @@ const PopupMenuBase = new Lang.Class({
             menuItem.disconnect(menuItem._popupMenuDestroyId);
             menuItem.disconnect(menuItem._activateId);
             menuItem.disconnect(menuItem._activeChangeId);
-            menuItem.disconnect(menuItem._sensitiveChangeId);
+            this.disconnect(menuItem._parentSensitiveChangedId);
             if (menuItem == this._activeMenuItem)
                 this._activeMenuItem = null;
         }));
@@ -867,11 +895,16 @@ const PopupMenuBase = new Lang.Class({
             let subMenuOpenStateChangedId = menuItem.connect('submenu-open-state-changed', Lang.bind(this, 
function(menuItem, submenu, open) {
                 this.emit('submenu-open-state-changed', submenu, open);
             }));
+            let subMenuSensitiveChangedId = this.connect('sensitive-changed', Lang.bind(this, function() {
+                menuItem.parentSensitive = this.getSensitive();
+                menuItem.emit('sensitive-changed');
+            }));
 
             menuItem.connect('destroy', Lang.bind(this, function() {
                 menuItem.disconnect(activateId);
                 menuItem.disconnect(activeChangeId);
                 menuItem.disconnect(subMenuOpenStateChangedId);
+                this.disconnect(subMenuSensitiveChangedId);
                 this.disconnect(parentOpenStateChangedId);
                 this.disconnect(parentClosingId);
                 this.length--;
@@ -891,11 +924,13 @@ const PopupMenuBase = new Lang.Class({
             let subMenuOpenStateChangedId = menuItem.connect('submenu-open-state-changed', Lang.bind(this, 
function(menuItem, submenu, open) {
                 this.emit('submenu-open-state-changed', submenu, open);
             }));
+
             menuItem.connect('destroy', Lang.bind(this, function() {
                 menuItem.menu.disconnect(subMenuActivateId);
                 menuItem.menu.disconnect(subMenuActiveChangeId);
                 menuItem.disconnect(subMenuOpenStateChangedId);
                 this.disconnect(closingId);
+                this.disconnect(sensitiveChangedId);
             }));
         } else if (menuItem instanceof PopupSeparatorMenuItem) {
             this._connectItemSignals(menuItem);
@@ -1120,6 +1155,9 @@ const PopupDummyMenu = new Lang.Class({
         this.actor._delegate = this;
     },
 
+    getSensitive: function() {
+        return true;
+    },
     open: function() { this.emit('open-state-changed', true); },
     close: function() { this.emit('open-state-changed', false); },
     toggle: function() {},
@@ -1174,6 +1212,13 @@ const PopupSubMenu = new Lang.Class({
         return topMaxHeight >= 0 && topNaturalHeight >= topMaxHeight;
     },
 
+    getSensitive: function() {
+        if (!this._sensitive)
+            return false;
+
+        return this.sourceActor._delegate.getSensitive();
+    },
+
     open: function(animate) {
         if (this.isOpen)
             return;


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