StScrollbar: clean up properly when unmapped during scroll

If we're unmapped (or destroyed) during a scroll, we want to clean
up the changes we've made to Clutter's event handling, remove our
signal handler, and emit ::scroll-stop.

https://bugzilla.gnome.org/show_bug.cgi?id=646825
This commit is contained in:
Owen W. Taylor 2011-04-05 10:54:28 -04:00
parent d6c3868a7c
commit b9828bf5de

View File

@ -110,6 +110,8 @@ handle_button_press_event_cb (ClutterActor *actor,
ClutterButtonEvent *event, ClutterButtonEvent *event,
StScrollBar *bar); StScrollBar *bar);
static void stop_scrolling (StScrollBar *bar);
static void static void
st_scroll_bar_get_property (GObject *gobject, st_scroll_bar_get_property (GObject *gobject,
guint prop_id, guint prop_id,
@ -271,6 +273,8 @@ st_scroll_bar_unmap (ClutterActor *actor)
CLUTTER_ACTOR_CLASS (st_scroll_bar_parent_class)->unmap (actor); CLUTTER_ACTOR_CLASS (st_scroll_bar_parent_class)->unmap (actor);
stop_scrolling (ST_SCROLL_BAR (actor));
clutter_actor_unmap (priv->bw_stepper); clutter_actor_unmap (priv->bw_stepper);
clutter_actor_unmap (priv->fw_stepper); clutter_actor_unmap (priv->fw_stepper);
clutter_actor_unmap (priv->trough); clutter_actor_unmap (priv->trough);
@ -806,6 +810,22 @@ move_slider (StScrollBar *bar,
st_adjustment_set_value (priv->adjustment, position); st_adjustment_set_value (priv->adjustment, position);
} }
static void
stop_scrolling (StScrollBar *bar)
{
ClutterActor *stage;
if (!bar->priv->capture_handler)
return;
stage = clutter_actor_get_stage (bar->priv->trough);
g_signal_handler_disconnect (stage, bar->priv->capture_handler);
bar->priv->capture_handler = 0;
clutter_set_motion_events_enabled (TRUE);
g_signal_emit (bar, signals[SCROLL_STOP], 0);
}
static gboolean static gboolean
handle_capture_event_cb (ClutterActor *trough, handle_capture_event_cb (ClutterActor *trough,
ClutterEvent *event, ClutterEvent *event,
@ -822,19 +842,11 @@ handle_capture_event_cb (ClutterActor *trough,
{ {
ClutterActor *stage, *target; ClutterActor *stage, *target;
stage = clutter_actor_get_stage(bar->priv->trough); stop_scrolling (bar);
if (bar->priv->capture_handler)
{
g_signal_handler_disconnect (stage, bar->priv->capture_handler);
bar->priv->capture_handler = 0;
}
clutter_set_motion_events_enabled (TRUE);
g_signal_emit (bar, signals[SCROLL_STOP], 0);
/* check if the mouse pointer has left the handle during the drag and /* check if the mouse pointer has left the handle during the drag and
* remove the hover state if it has */ * remove the hover state if it has */
stage = clutter_actor_get_stage (bar->priv->trough);
target = clutter_stage_get_actor_at_pos ((ClutterStage*) stage, target = clutter_stage_get_actor_at_pos ((ClutterStage*) stage,
CLUTTER_PICK_REACTIVE, CLUTTER_PICK_REACTIVE,
((ClutterButtonEvent*) event)->x, ((ClutterButtonEvent*) event)->x,
@ -843,8 +855,6 @@ handle_capture_event_cb (ClutterActor *trough,
{ {
st_widget_remove_style_pseudo_class ((StWidget*) bar->priv->handle, "hover"); st_widget_remove_style_pseudo_class ((StWidget*) bar->priv->handle, "hover");
} }
} }
return TRUE; return TRUE;