From a4befeba5358d279453c1db8b030a1d0da14f1b1 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 10 Jun 2010 08:15:02 -0400 Subject: [PATCH] De-duplicate "actor contains actor" code Add _st_actor_contains() in st-private for use within St, and monkey-patch in a Clutter.Actor.contains() for use by javascript, and then replace all the duplicate implementations with one or the other of those. https://bugzilla.gnome.org/show_bug.cgi?id=621197 --- js/ui/chrome.js | 11 +---------- js/ui/dash.js | 11 +---------- js/ui/environment.js | 7 +++++++ js/ui/popupMenu.js | 17 +++-------------- js/ui/telepathyClient.js | 7 ++----- src/st/st-clickable.c | 17 ++++------------- src/st/st-entry.c | 14 +++----------- src/st/st-private.c | 9 +++++++++ src/st/st-private.h | 3 +++ src/st/st-widget.c | 23 +++++------------------ 10 files changed, 38 insertions(+), 81 deletions(-) diff --git a/js/ui/chrome.js b/js/ui/chrome.js index 9b920c899..cb913dd7c 100644 --- a/js/ui/chrome.js +++ b/js/ui/chrome.js @@ -65,15 +65,6 @@ Chrome.prototype = { children[i].allocate_preferred_size(flags); }, - _verifyAncestry: function(actor, ancestor) { - while (actor) { - if (actor == ancestor) - return true; - actor = actor.get_parent(); - } - return false; - }, - // addActor: // @actor: an actor to add to the chrome layer // @params: (optional) additional params @@ -195,7 +186,7 @@ Chrome.prototype = { }, _actorReparented: function(actor, oldParent) { - if (!this._verifyAncestry(actor, this.actor)) + if (!this.actor.contains(actor)) this._untrackActor(actor); }, diff --git a/js/ui/dash.js b/js/ui/dash.js index df0cc4beb..a26e6cf87 100644 --- a/js/ui/dash.js +++ b/js/ui/dash.js @@ -275,16 +275,7 @@ SearchEntry.prototype = { _onCapturedEvent: function(actor, event) { let source = event.get_source(); - let panelEvent = false; - - if (source) { - let parent = source; - do { - if (parent == Main.panel.actor) - break; - } while ((parent = parent.get_parent()) != null); - panelEvent = (parent != null); - } + let panelEvent = source && Main.panel.actor.contains(source); switch (event.type()) { case Clutter.EventType.BUTTON_PRESS: diff --git a/js/ui/environment.js b/js/ui/environment.js index 67682d8fe..27cce08ca 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -1,5 +1,6 @@ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ +const Clutter = imports.gi.Clutter;; const Shell = imports.gi.Shell; const St = imports.gi.St; const Gettext_gtk20 = imports.gettext.domain('gtk20'); @@ -70,6 +71,12 @@ function init() { _patchContainerClass(St.BoxLayout); _patchContainerClass(St.Table); + Clutter.Actor.prototype.contains = function(child) { + while (child != null && child != this) + child = child.get_parent(); + return child != null; + }; + _blockMethod('Clutter.Event.get_state', 'Shell.get_event_state', 'gjs\'s handling of Clutter.ModifierType is broken. See bug 597292.'); _blockMethod('Gdk.Display.get_pointer', 'global.get_pointer', diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index 22702f1c6..c907f316d 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -494,28 +494,17 @@ PopupMenuManager.prototype = { this.ungrab(); }, - _containsActor: function(container, actor) { - let parent = actor; - while (parent != null) { - if (parent == container) - return true; - parent = parent.get_parent(); - } - return false; - }, - _eventIsOnActiveMenu: function(event) { let src = event.get_source(); return this._activeMenu != null - && (this._containsActor(this._activeMenu.actor, src) || - this._containsActor(this._activeMenu.sourceActor, src)); + && (this._activeMenu.actor.contains(src) || + this._activeMenu.sourceActor.contains(src)); }, _eventIsOnAnyMenuSource: function(event) { let src = event.get_source(); for (let i = 0; i < this._menus.length; i++) { - let actor = this._menus[i].sourceActor; - if (this._containsActor(actor, src)) + if (this._menus[i].sourceActor.contains(src)) return true; } return false; diff --git a/js/ui/telepathyClient.js b/js/ui/telepathyClient.js index bf42663e9..70f52ced7 100644 --- a/js/ui/telepathyClient.js +++ b/js/ui/telepathyClient.js @@ -629,11 +629,8 @@ Notification.prototype = { return false; let source = event.get_source (); - while (source) { - if (source == notification) - return false; - source = source.get_parent(); - } + if (source && notification.contains(source)) + return false; // @source is outside @notification, which has to mean that // we have a pointer grab, and the user clicked outside the diff --git a/src/st/st-clickable.c b/src/st/st-clickable.c index 79192cfc5..abed5be26 100644 --- a/src/st/st-clickable.c +++ b/src/st/st-clickable.c @@ -11,6 +11,8 @@ #include "st-clickable.h" +#include "st-private.h" + G_DEFINE_TYPE (StClickable, st_clickable, ST_TYPE_BIN); struct _StClickablePrivate { @@ -69,17 +71,6 @@ set_pressed (StClickable *self, g_object_notify (G_OBJECT (self), "pressed"); } -static gboolean -st_clickable_contains (StClickable *self, - ClutterActor *actor) -{ - while (actor != NULL && actor != (ClutterActor*)self) - { - actor = clutter_actor_get_parent (actor); - } - return actor != NULL; -} - static gboolean st_clickable_enter_event (ClutterActor *actor, ClutterCrossingEvent *event) @@ -130,7 +121,7 @@ st_clickable_button_press_event (ClutterActor *actor, if (self->priv->held) return TRUE; - if (!st_clickable_contains (self, event->source)) + if (!_st_actor_contains (actor, event->source)) return FALSE; self->priv->held = TRUE; @@ -157,7 +148,7 @@ st_clickable_button_release_event (ClutterActor *actor, self->priv->held = FALSE; clutter_ungrab_pointer (); - if (!st_clickable_contains (self, event->source)) + if (!_st_actor_contains (actor, event->source)) return FALSE; set_pressed (self, FALSE); diff --git a/src/st/st-entry.c b/src/st/st-entry.c index 42a468709..7da288608 100644 --- a/src/st/st-entry.c +++ b/src/st/st-entry.c @@ -65,6 +65,7 @@ #include "st-texture-cache.h" #include "st-marshal.h" #include "st-clipboard.h" +#include "st-private.h" #define HAS_FOCUS(actor) (clutter_actor_get_stage (actor) && clutter_stage_get_key_focus ((ClutterStage *) clutter_actor_get_stage (actor)) == actor) @@ -577,22 +578,13 @@ st_entry_key_focus_in (ClutterActor *actor) clutter_actor_grab_key_focus (priv->entry); } -static gboolean -actor_contains (ClutterActor *widget, - ClutterActor *other) -{ - while (other != NULL && other != widget) - other = clutter_actor_get_parent (other); - return other != NULL; -} - static gboolean st_entry_enter_event (ClutterActor *actor, ClutterCrossingEvent *event) { StEntryPrivate *priv = ST_ENTRY_PRIV (actor); - if (actor_contains (actor, event->source) + if (_st_actor_contains (actor, event->source) && priv->hint && priv->hint_visible) { st_widget_set_hover (ST_WIDGET (actor), TRUE); @@ -605,7 +597,7 @@ static gboolean st_entry_leave_event (ClutterActor *actor, ClutterCrossingEvent *event) { - if (!actor_contains (actor, event->related)) + if (!_st_actor_contains (actor, event->related)) st_widget_set_hover (ST_WIDGET (actor), FALSE); return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->leave_event (actor, event); diff --git a/src/st/st-private.c b/src/st/st-private.c index dd64cb889..1ebadf654 100644 --- a/src/st/st-private.c +++ b/src/st/st-private.c @@ -310,3 +310,12 @@ _st_set_text_from_style (ClutterText *text, pango_attr_list_unref (attribs); } + +gboolean +_st_actor_contains (ClutterActor *actor, + ClutterActor *child) +{ + while (child != NULL && child != actor) + child = clutter_actor_get_parent (child); + return child != NULL; +} diff --git a/src/st/st-private.h b/src/st/st-private.h index 83686659c..eecd7fdaa 100644 --- a/src/st/st-private.h +++ b/src/st/st-private.h @@ -72,4 +72,7 @@ void _st_allocate_fill (StWidget *parent, void _st_set_text_from_style (ClutterText *text, StThemeNode *theme_node); +gboolean _st_actor_contains (ClutterActor *actor, + ClutterActor *child); + #endif /* __ST_PRIVATE_H__ */ diff --git a/src/st/st-widget.c b/src/st/st-widget.c index 2a0676687..16eceb0ff 100644 --- a/src/st/st-widget.c +++ b/src/st/st-widget.c @@ -557,15 +557,6 @@ st_widget_get_theme_node (StWidget *widget) return priv->theme_node; } -static gboolean -actor_contains (ClutterActor *widget, - ClutterActor *other) -{ - while (other != NULL && other != widget) - other = clutter_actor_get_parent (other); - return other != NULL; -} - static gboolean st_widget_enter (ClutterActor *actor, ClutterCrossingEvent *event) @@ -574,7 +565,7 @@ st_widget_enter (ClutterActor *actor, if (priv->track_hover) { - if (actor_contains (actor, event->source)) + if (_st_actor_contains (actor, event->source)) st_widget_set_hover (ST_WIDGET (actor), TRUE); else { @@ -600,7 +591,7 @@ st_widget_leave (ClutterActor *actor, if (priv->track_hover) { - if (!actor_contains (actor, event->related)) + if (!_st_actor_contains (actor, event->related)) st_widget_set_hover (ST_WIDGET (actor), FALSE); } @@ -1589,17 +1580,13 @@ st_widget_sync_hover (StWidget *widget) { ClutterDeviceManager *device_manager; ClutterInputDevice *pointer; - ClutterActor *actor; + ClutterActor *pointer_actor; device_manager = clutter_device_manager_get_default (); pointer = clutter_device_manager_get_core_device (device_manager, CLUTTER_POINTER_DEVICE); - actor = clutter_input_device_get_pointer_actor (pointer); - - while (actor && actor != (ClutterActor *)widget) - actor = clutter_actor_get_parent (actor); - - st_widget_set_hover (widget, actor == (ClutterActor *)widget); + pointer_actor = clutter_input_device_get_pointer_actor (pointer); + st_widget_set_hover (widget, _st_actor_contains (CLUTTER_ACTOR (widget), pointer_actor)); } /**