Make popdown,popup methods idempotent; remove 'popdown' for 'cancelled'

Callers will generally expect _popup and _popdown to be a no-op if
the menu is already in that state; make it so.

Also change the 'popdown' signal to be 'cancelled'; this is
clearer and allows us to avoid having activate also call popdown.

https://bugzilla.gnome.org/show_bug.cgi?id=594699
This commit is contained in:
Colin Walters 2009-09-11 17:16:49 -04:00
parent 05c99241d6
commit 7ac9fb2dd0
2 changed files with 42 additions and 15 deletions

View File

@ -502,9 +502,9 @@ WellMenu.prototype = {
padding: 4, padding: 4,
corner_radius: WELL_MENU_CORNER_RADIUS, corner_radius: WELL_MENU_CORNER_RADIUS,
width: Main.overview._dash.actor.width * 0.75 }); width: Main.overview._dash.actor.width * 0.75 });
this._windowContainer.connect('popdown', Lang.bind(this, this._onPopdown));
this._windowContainer.connect('unselected', Lang.bind(this, this._onWindowUnselected)); this._windowContainer.connect('unselected', Lang.bind(this, this._onWindowUnselected));
this._windowContainer.connect('selected', Lang.bind(this, this._onWindowSelected)); this._windowContainer.connect('selected', Lang.bind(this, this._onWindowSelected));
this._windowContainer.connect('cancelled', Lang.bind(this, this._onWindowSelectionCancelled));
this._windowContainer.connect('activate', Lang.bind(this, this._onWindowActivate)); this._windowContainer.connect('activate', Lang.bind(this, this._onWindowActivate));
this.actor.add_actor(this._windowContainer); this.actor.add_actor(this._windowContainer);
@ -655,9 +655,11 @@ WellMenu.prototype = {
_onWindowActivate: function (actor, child) { _onWindowActivate: function (actor, child) {
let window = child._window; let window = child._window;
Main.overview.activateWindow(window, Clutter.get_current_event_time()); Main.overview.activateWindow(window, Clutter.get_current_event_time());
this.emit('popup', false);
this.actor.hide();
}, },
_onPopdown: function () { _onWindowSelectionCancelled: function () {
this.emit('highlight-window', null); this.emit('highlight-window', null);
this.emit('popup', false); this.emit('popup', false);
this.actor.hide(); this.actor.hide();

View File

@ -13,6 +13,7 @@
G_DEFINE_TYPE(ShellMenu, shell_menu, BIG_TYPE_BOX); G_DEFINE_TYPE(ShellMenu, shell_menu, BIG_TYPE_BOX);
struct _ShellMenuPrivate { struct _ShellMenuPrivate {
gboolean popped_up;
gboolean have_grab; gboolean have_grab;
ClutterActor *selected; ClutterActor *selected;
@ -24,7 +25,7 @@ enum
UNSELECTED, UNSELECTED,
SELECTED, SELECTED,
ACTIVATE, ACTIVATE,
POPDOWN, CANCELLED,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -41,6 +42,15 @@ shell_menu_contains (ShellMenu *box,
return actor != NULL; return actor != NULL;
} }
static void
shell_menu_popdown_nosignal (ShellMenu *box)
{
box->priv->popped_up = FALSE;
if (box->priv->have_grab)
clutter_ungrab_pointer ();
clutter_actor_hide (CLUTTER_ACTOR (box));
}
static void static void
on_selected_destroy (ClutterActor *actor, on_selected_destroy (ClutterActor *actor,
ShellMenu *box) ShellMenu *box)
@ -107,13 +117,19 @@ shell_menu_button_release_event (ClutterActor *actor,
if (event->button != 1) if (event->button != 1)
return FALSE; return FALSE;
shell_menu_popdown (box); shell_menu_popdown_nosignal (box);
if (!shell_menu_contains (box, event->source)) if (!shell_menu_contains (CLUTTER_CONTAINER (box), event->source))
{
g_signal_emit (G_OBJECT (box), shell_menu_signals[CANCELLED], 0);
return FALSE; return FALSE;
}
if (box->priv->selected == NULL) if (box->priv->selected == NULL)
{
g_signal_emit (G_OBJECT (box), shell_menu_signals[CANCELLED], 0);
return FALSE; return FALSE;
}
g_signal_emit (G_OBJECT (box), shell_menu_signals[ACTIVATE], 0, box->priv->selected); g_signal_emit (G_OBJECT (box), shell_menu_signals[ACTIVATE], 0, box->priv->selected);
@ -125,17 +141,26 @@ shell_menu_popup (ShellMenu *box,
guint button, guint button,
guint32 activate_time) guint32 activate_time)
{ {
if (box->priv->popped_up)
return;
box->priv->popped_up = TRUE;
box->priv->have_grab = TRUE; box->priv->have_grab = TRUE;
clutter_grab_pointer (CLUTTER_ACTOR (box)); clutter_grab_pointer (CLUTTER_ACTOR (box));
} }
/**
* shell_menu_popdown:
* @box:
*
* If the menu is currently active, hide it, emitting the 'cancelled' signal.
*/
void void
shell_menu_popdown (ShellMenu *box) shell_menu_popdown (ShellMenu *box)
{ {
if (box->priv->have_grab) if (!box->priv->popped_up)
clutter_ungrab_pointer (); return;
clutter_actor_hide (CLUTTER_ACTOR (box)); shell_menu_popdown_nosignal (box);
g_signal_emit (G_OBJECT (box), shell_menu_signals[POPDOWN], 0); g_signal_emit (G_OBJECT (box), shell_menu_signals[CANCELLED], 0);
} }
/** /**
@ -218,13 +243,13 @@ shell_menu_class_init (ShellMenuClass *klass)
G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR); G_TYPE_NONE, 1, CLUTTER_TYPE_ACTOR);
/** /**
* ShellMenu::popdown * ShellMenu::cancelled
* @box: The #ShellMenu * @box: The #ShellMenu
* *
* This signal is emitted when the menu is removed from the display. * This signal is emitted when the menu is closed without an option selected.
*/ */
shell_menu_signals[POPDOWN] = shell_menu_signals[CANCELLED] =
g_signal_new ("popdown", g_signal_new ("cancelled",
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
0, 0,