diff options
-rw-r--r-- | scrollarea.c | 80 | ||||
-rw-r--r-- | scrollarea.h | 4 |
2 files changed, 46 insertions, 38 deletions
diff --git a/scrollarea.c b/scrollarea.c index d5187b9..622a402 100644 --- a/scrollarea.c +++ b/scrollarea.c @@ -83,6 +83,10 @@ struct FooScrollAreaPrivate guint32 motion_notify_time; gboolean in_size_allocate; + + /* Last emitted event went here - used to generate enters and leaves */ + FooScrollAreaEventFunc last_func; + gpointer last_data; }; enum @@ -927,31 +931,42 @@ emit_input (FooScrollArea *scroll_area, { FooScrollAreaEvent event; - if (!func) - return; - -#if 0 - if (type != FOO_MOTION) - emit_input (scroll_area, FOO_MOTION, x, y, button, func, data); -#endif - -#if 0 - x += scroll_area->priv->x_offset; - y += scroll_area->priv->y_offset; -#endif - - event.type = type; event.x = x; event.y = y; event.button = button; - if (event.type == FOO_BUTTON_PRESS) - begin_grab_internal (scroll_area, TRUE, func, data); + if (scroll_area->priv->last_func != func || + scroll_area->priv->last_data != data) + { + if (scroll_area->priv->last_func) + { + event.type = FOO_LEAVE; + scroll_area->priv->last_func (scroll_area, &event, + scroll_area->priv->last_data); + } - func (scroll_area, &event, data); + if (func) + { + event.type = FOO_ENTER; + func (scroll_area, &event, data); + } + } + + event.type = type; + + if (func) + { + if (event.type == FOO_BUTTON_PRESS) + begin_grab_internal (scroll_area, TRUE, func, data); + + func (scroll_area, &event, data); + + if (event.type == FOO_BUTTON_RELEASE) + end_grab_internal (scroll_area, TRUE); + } - if (event.type == FOO_BUTTON_RELEASE) - end_grab_internal (scroll_area, TRUE); + scroll_area->priv->last_func = func; + scroll_area->priv->last_data = data; } #if 0 @@ -1010,25 +1025,10 @@ process_event (FooScrollArea *scroll_area, return; } - -#if 0 - x += widget->allocation.x; - y += widget->allocation.y; -#endif - -#if 0 - g_print ("number of input regions: %d\n", scroll_area->priv->input_regions->len); -#endif - for (i = 0; i < scroll_area->priv->input_regions->len; ++i) { InputRegion *region = scroll_area->priv->input_regions->pdata[i]; -#if 0 - g_print ("%d ", i); - print_region ("region:", region->region); -#endif - if (gdk_region_point_in (region->region, x, y)) { InputPath *path; @@ -1070,9 +1070,15 @@ process_event (FooScrollArea *scroll_area, * sort the regions, but so far I have been unable to * make this loop show up on a profile. */ - return; + break; } } + + /* If we got here, no event was emitted, so we emit + * a "nothing" event, that will just cause some internal bookkeeping + * be updated + */ + emit_input (scroll_area, FOO_NONE, 0, 0, 0, NULL, NULL); } static void @@ -1081,7 +1087,7 @@ process_gdk_event (FooScrollArea *scroll_area, int y, GdkEvent *event) { - FooScrollAreaEventType input_type = FOO_INVALID; + FooScrollAreaEventType input_type = FOO_NONE; int button = 0; if (event->type == GDK_BUTTON_PRESS) @@ -1102,7 +1108,7 @@ process_gdk_event (FooScrollArea *scroll_area, button = 0; } - if (input_type != FOO_INVALID) + if (input_type != FOO_NONE) process_event (scroll_area, input_type, x, y, button); } diff --git a/scrollarea.h b/scrollarea.h index e571fbb..57b0eaf 100644 --- a/scrollarea.h +++ b/scrollarea.h @@ -18,9 +18,11 @@ typedef struct FooScrollAreaEvent FooScrollAreaEvent; typedef enum { - FOO_INVALID, + FOO_NONE, FOO_BUTTON_PRESS, FOO_BUTTON_RELEASE, + FOO_ENTER, + FOO_LEAVE, FOO_MOTION } FooScrollAreaEventType; |