[gnome-shell] panel: make ActivitiesButton a PanelMenu.Button
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] panel: make ActivitiesButton a PanelMenu.Button
- Date: Thu, 14 Jul 2011 19:31:46 +0000 (UTC)
commit 50f248ec5b2a0ac7d3b6d70b7844563bb34c620f
Author: Dan Winship <danw gnome org>
Date: Thu Jul 14 08:56:14 2011 -0400
panel: make ActivitiesButton a PanelMenu.Button
The fact that everything in the top bar except the activities button
was a menu made various things difficult. Simplify this by making the
activities button be a menu too, but just hack it up a bit so that the
menu associated with the button never actually appears.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=645759 (Clicking on
Activities with menu up leaves a funny state) and its semi-dup 641253
(panel keynav between Activities and menus is quirky).
data/theme/gnome-shell.css | 4 +-
js/ui/panel.js | 109 +++++++++++++++++++++++++++++++++----------
2 files changed, 85 insertions(+), 28 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 98771db..edbd023 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -264,7 +264,7 @@ StTooltip StLabel {
}
.panel-corner:active,
-.panel-corner:checked,
+.panel-corner:overview,
.panel-corner:focus {
-panel-corner-inner-border-color: rgba(255,255,255,0.8);
}
@@ -301,7 +301,7 @@ StTooltip StLabel {
}
.panel-button:active,
-.panel-button:checked,
+.panel-button:overview,
.panel-button:focus {
border-image: url("panel-button-border.svg") 10 10 0 2;
background-image: url("panel-button-highlight-wide.svg");
diff --git a/js/ui/panel.js b/js/ui/panel.js
index d679cd6..86e83db 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -544,37 +544,41 @@ AppMenuButton.prototype = {
Signals.addSignalMethods(AppMenuButton.prototype);
-// Activities button.
+// Activities button. Because everything else in the top bar is a
+// PanelMenu.Button, it simplifies some things to make this be one too.
+// We just hack it up to not actually have a menu attached to it.
function ActivitiesButton() {
this._init.apply(this, arguments);
}
ActivitiesButton.prototype = {
+ __proto__: PanelMenu.Button.prototype,
+
_init: function() {
+ PanelMenu.Button.prototype._init.call(this, 0.0);
+
/* Translators: If there is no suitable word for "Activities"
in your language, you can use the word for "Overview". */
let label = new St.Label({ text: _("Activities") });
- this.actor = new St.Button({ name: 'panelActivities',
- style_class: 'panel-button',
- reactive: true,
- can_focus: true });
- this.actor.set_child(label);
- this.actor._delegate = this;
+ this.actor.child = label;
+ this.actor.name = 'panelActivities';
- this.actor.connect('clicked', Lang.bind(this, function(b) {
- if (!Main.overview.animationInProgress) {
- this._hotCorner.maybeToggleOverviewOnClick();
- return true;
- } else {
- return false;
- }
- }));
+ // Hack up our menu...
+ this.menu.open = Lang.bind(this, this._onMenuOpenRequest);
+ this.menu.close = Lang.bind(this, this._onMenuCloseRequest);
+ this.menu.toggle = Lang.bind(this, this._onMenuToggleRequest);
+
+ 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));
Main.overview.connect('showing', Lang.bind(this, function() {
- this.actor.checked = true;
+ this.actor.add_style_pseudo_class('overview');
+ this._escapeMenuGrab();
}));
Main.overview.connect('hiding', Lang.bind(this, function() {
- this.actor.checked = false;
+ this.actor.remove_style_pseudo_class('overview');
+ this._escapeMenuGrab();
}));
this._hotCorner = null;
@@ -595,6 +599,50 @@ ActivitiesButton.prototype = {
Lang.bind(this, this._xdndShowOverview, actor));
},
+ _escapeMenuGrab: function() {
+ if (this.menu.isOpen)
+ this.menu.close();
+ },
+
+ _onCapturedEvent: function(actor, event) {
+ if (event.type() == Clutter.EventType.BUTTON_PRESS) {
+ if (!this._hotCorner.shouldToggleOverviewOnClick())
+ return true;
+ }
+ return false;
+ },
+
+ _onMenuOpenRequest: function() {
+ this.menu.isOpen = true;
+ this.menu.emit('open-state-changed', true);
+ },
+
+ _onMenuCloseRequest: function() {
+ this.menu.isOpen = false;
+ this.menu.emit('open-state-changed', false);
+ },
+
+ _onMenuToggleRequest: function() {
+ this.menu.isOpen = !this.menu.isOpen;
+ this.menu.emit('open-state-changed', this.menu.isOpen);
+ },
+
+ _onButtonRelease: function() {
+ if (this.menu.isOpen) {
+ this.menu.close();
+ Main.overview.toggle();
+ }
+ },
+
+ _onKeyRelease: function(actor, event) {
+ let symbol = event.get_key_symbol();
+ if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
+ if (this.menu.isOpen)
+ this.menu.close();
+ Main.overview.toggle();
+ }
+ },
+
_xdndShowOverview: function(actor) {
let [x, y, mask] = global.get_pointer();
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
@@ -841,9 +889,9 @@ HotCorner.prototype = {
},
_onCornerClicked : function() {
- if (!Main.overview.animationInProgress)
- this.maybeToggleOverviewOnClick();
- return true;
+ if (this.shouldToggleOverviewOnClick())
+ Main.overview.toggle();
+ return true;
},
_onCornerLeft : function(actor, event) {
@@ -862,13 +910,18 @@ HotCorner.prototype = {
return false;
},
- // Toggles the overview unless this is the first click on the Activities button within the HOT_CORNER_ACTIVATION_TIMEOUT time
- // of the hot corner being triggered. This check avoids opening and closing the overview if the user both triggered the hot corner
- // and clicked the Activities button.
- maybeToggleOverviewOnClick: function() {
+ // 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)
- Main.overview.toggle();
- this._activationTime = 0;
+ return true;
+ return false;
}
}
@@ -980,6 +1033,10 @@ Panel.prototype = {
this._activities = this.button = this._activitiesButton.actor;
this._leftBox.add(this._activities);
+ // The activities button has a pretend menu, so as to integrate
+ // more cleanly with the rest of the panel
+ this._menus.addMenu(this._activitiesButton.menu);
+
// Synchronize the button's pseudo classes with its corner
this.button.connect('style-changed', Lang.bind(this,
function(actor) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]