popupMenu: Propagate sensitivity to menu children

This way, if a parent is insensitive, all children will be, too.
Though PopupSubMenus will be forced closed, PopupMenuSection needs
the propagation.

https://bugzilla.gnome.org/show_bug.cgi?id=702539
This commit is contained in:
Jasper St. Pierre 2013-06-12 03:16:53 -04:00
parent bc317bf3f2
commit 86835db8f2

View File

@ -64,6 +64,8 @@ const PopupBaseMenuItem = new Lang.Class({
this._spacing = 0; this._spacing = 0;
this.active = false; this.active = false;
this._activatable = params.reactive && params.activate; this._activatable = params.reactive && params.activate;
this._sensitive = true;
this.parentSensitive = true;
if (!this._activatable) if (!this._activatable)
this.actor.add_style_class_name('popup-inactive-menu-item'); this.actor.add_style_class_name('popup-inactive-menu-item');
@ -133,17 +135,24 @@ const PopupBaseMenuItem = new Lang.Class({
} }
}, },
setSensitive: function(sensitive) { syncSensitive: function() {
if (!this._activatable) let sensitive = this.getSensitive();
return;
if (this.sensitive == sensitive)
return;
this.sensitive = sensitive;
this.actor.reactive = sensitive; this.actor.reactive = sensitive;
this.actor.can_focus = sensitive; this.actor.can_focus = sensitive;
this.emit('sensitive-changed');
return sensitive;
},
this.emit('sensitive-changed', sensitive); getSensitive: function() {
return this._activatable && this._sensitive && this.parentSensitive;
},
setSensitive: function(sensitive) {
if (this._sensitive == sensitive)
return;
this._sensitive = sensitive;
this.syncSensitive();
}, },
destroy: function() { destroy: function() {
@ -649,6 +658,9 @@ const PopupMenuBase = new Lang.Class({
this._activeMenuItem = null; this._activeMenuItem = null;
this._settingsActions = { }; this._settingsActions = { };
this._sensitive = true;
this.parentSensitive = true;
this._sessionUpdatedId = Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); this._sessionUpdatedId = Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
}, },
@ -659,6 +671,15 @@ const PopupMenuBase = new Lang.Class({
return this; return this;
}, },
getSensitive: function() {
return this._sensitive && this.parentSensitive;
},
setSensitive: function(sensitive) {
this._sensitive = sensitive;
this.emit('sensitive-changed');
},
_sessionUpdated: function() { _sessionUpdated: function() {
this._setSettingsVisibility(Main.sessionMode.allowSettings); this._setSettingsVisibility(Main.sessionMode.allowSettings);
}, },
@ -737,7 +758,8 @@ const PopupMenuBase = new Lang.Class({
this.emit('active-changed', null); 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 (!sensitive && this._activeMenuItem == menuItem) {
if (!this.actor.navigate_focus(menuItem.actor, if (!this.actor.navigate_focus(menuItem.actor,
Gtk.DirectionType.TAB_FORWARD, Gtk.DirectionType.TAB_FORWARD,
@ -752,6 +774,12 @@ const PopupMenuBase = new Lang.Class({
this.emit('activate', menuItem); this.emit('activate', menuItem);
this.itemActivated(BoxPointer.PopupAnimation.FULL); this.itemActivated(BoxPointer.PopupAnimation.FULL);
})); }));
menuItem._parentSensitiveChangeId = 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 weird name is to avoid a conflict with some random property
// the menuItem may have, called destroyId // the menuItem may have, called destroyId
// (FIXME: in the future it may make sense to have container objects // (FIXME: in the future it may make sense to have container objects
@ -761,6 +789,7 @@ const PopupMenuBase = new Lang.Class({
menuItem.disconnect(menuItem._activateId); menuItem.disconnect(menuItem._activateId);
menuItem.disconnect(menuItem._activeChangeId); menuItem.disconnect(menuItem._activeChangeId);
menuItem.disconnect(menuItem._sensitiveChangeId); menuItem.disconnect(menuItem._sensitiveChangeId);
this.disconnect(menuItem._parentSensitiveChangeId);
if (menuItem == this._activeMenuItem) if (menuItem == this._activeMenuItem)
this._activeMenuItem = null; this._activeMenuItem = null;
})); }));
@ -831,10 +860,15 @@ const PopupMenuBase = new Lang.Class({
let parentClosingId = this.connect('menu-closed', function() { let parentClosingId = this.connect('menu-closed', function() {
menuItem.emit('menu-closed'); menuItem.emit('menu-closed');
}); });
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.connect('destroy', Lang.bind(this, function() {
menuItem.disconnect(activateId); menuItem.disconnect(activateId);
menuItem.disconnect(activeChangeId); menuItem.disconnect(activeChangeId);
this.disconnect(subMenuSensitiveChangedId);
this.disconnect(parentOpenStateChangedId); this.disconnect(parentOpenStateChangedId);
this.disconnect(parentClosingId); this.disconnect(parentClosingId);
this.length--; this.length--;
@ -1109,6 +1143,10 @@ const PopupDummyMenu = new Lang.Class({
return false; return false;
}, },
getSensitive: function() {
return true;
},
open: function() { this.emit('open-state-changed', true); }, open: function() { this.emit('open-state-changed', true); },
close: function() { this.emit('open-state-changed', false); }, close: function() { this.emit('open-state-changed', false); },
toggle: function() {}, toggle: function() {},
@ -1151,6 +1189,10 @@ const PopupSubMenu = new Lang.Class({
return topMaxHeight >= 0 && topNaturalHeight >= topMaxHeight; return topMaxHeight >= 0 && topNaturalHeight >= topMaxHeight;
}, },
getSensitive: function() {
return this._sensitive && return this.sourceActor._delegate.getSensitive();
},
open: function(animate) { open: function(animate) {
if (this.isOpen) if (this.isOpen)
return; return;