diff options
-rw-r--r-- | gtk/gtkdnd.c | 104 | ||||
-rw-r--r-- | gtk/gtkdndprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkmain.c | 67 | ||||
-rw-r--r-- | gtk/gtkmain.h | 2 | ||||
-rw-r--r-- | gtk/gtkprivate.h | 2 |
5 files changed, 68 insertions, 111 deletions
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 1ebbf9666a..5bb5b45190 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -62,23 +62,19 @@ * Drop API makes use of signals in the #GtkWidget class. */ - -/* Forward declarations */ -static gboolean gtk_drop_find_widget (GtkWidget *widget, - GdkEvent *event); - - /* - * _gtk_drag_dest_handle_event: + * gtk_drag_dest_handle_event: * @toplevel: Toplevel widget that received the event * @event: the event to handle * * Called from widget event handling code on Drag events - * for destinations. + * for destinations. For drag-motion and drop-start events, + * this function is only called if no event handler has + * handled the event. */ void -_gtk_drag_dest_handle_event (GtkWidget *toplevel, - GdkEvent *event) +gtk_drag_dest_handle_event (GtkWidget *toplevel, + GdkEvent *event) { GtkDropTarget *dest; GdkDrop *drop; @@ -107,10 +103,7 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel, case GDK_DRAG_MOTION: case GDK_DROP_START: - { - if (!gtk_drop_find_widget (toplevel, event)) - gdk_drop_status (drop, 0); - } + gdk_drop_status (drop, 0); break; default: @@ -118,89 +111,6 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel, } } -static gboolean -gtk_drop_find_widget (GtkWidget *event_widget, - GdkEvent *event) -{ - GtkWidget *widget; - double x, y; - int wx, wy; - - if (!gtk_widget_get_mapped (event_widget) || - !gtk_widget_get_sensitive (event_widget)) - return FALSE; - - gdk_event_get_coords (event, &x, &y); - - widget = gtk_widget_pick (event_widget, x, y, GTK_PICK_DEFAULT); - - if (!widget) - return FALSE; - - gtk_widget_translate_coordinates (event_widget, widget, x, y, &wx, &wy); - - while (widget) - { - GtkWidget *parent; - GList *hierarchy = NULL; - gboolean found = FALSE; - - if (!gtk_widget_get_mapped (widget)) - return FALSE; - - if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_INSENSITIVE) - { - widget = gtk_widget_get_parent (widget); - continue; - } - - /* need to reference the entire hierarchy temporarily in case the - * ::drag-motion/::drag-drop callbacks change the widget hierarchy. - */ - for (parent = widget; - parent; - parent = gtk_widget_get_parent (parent)) - { - hierarchy = g_list_prepend (hierarchy, g_object_ref (parent)); - } - - gdk_event_set_coords (event, wx, wy); - found = gtk_widget_run_controllers (widget, event, GTK_PHASE_BUBBLE); - gdk_event_set_coords (event, x, y); - - if (!found) - { - /* Get the parent before unreffing the hierarchy because - * invoking the callback might have destroyed the widget - */ - parent = gtk_widget_get_parent (widget); - - /* The parent might be going away when unreffing the - * hierarchy, so also protect againt that - */ - if (parent) - g_object_add_weak_pointer (G_OBJECT (parent), (gpointer *) &parent); - } - - g_list_free_full (hierarchy, g_object_unref); - - if (found) - return TRUE; - - if (parent) - g_object_remove_weak_pointer (G_OBJECT (parent), (gpointer *) &parent); - else - return FALSE; - - if (!gtk_widget_translate_coordinates (widget, parent, wx, wy, &wx, &wy)) - return FALSE; - - widget = parent; - } - - return FALSE; -} - static void clear_current_dest (gpointer data, GObject *former_object) { diff --git a/gtk/gtkdndprivate.h b/gtk/gtkdndprivate.h index a520b1cf08..4de9a173d5 100644 --- a/gtk/gtkdndprivate.h +++ b/gtk/gtkdndprivate.h @@ -25,8 +25,8 @@ G_BEGIN_DECLS -void _gtk_drag_dest_handle_event (GtkWidget *toplevel, - GdkEvent *event); +void gtk_drag_dest_handle_event (GtkWidget *toplevel, + GdkEvent *event); void gtk_drop_set_current_dest (GdkDrop *drop, GtkDropTarget *dest); diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index fe5868a95d..504fe53382 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1676,6 +1676,20 @@ is_focus_event (GdkEvent *event) } } +static gboolean +is_dnd_event (GdkEvent *event) +{ + switch ((guint) event->any.type) + { + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DROP_START: + return TRUE; + default: + return FALSE; + } +} static inline void set_widget_active_state (GtkWidget *target, @@ -1818,6 +1832,25 @@ handle_key_event (GdkEvent *event) return focus_widget ? focus_widget : event_widget; } +static GtkWidget * +handle_dnd_event (GdkEvent *event) +{ + GtkWidget *event_widget; + GtkWidget *target; + gdouble x, y; + GtkWidget *native; + + event_widget = gtk_get_event_widget (event); + + if (!gdk_event_get_coords (event, &x, &y)) + return event_widget; + + native = GTK_WIDGET (gtk_widget_get_native (event_widget)); + target = gtk_widget_pick (native, x, y, GTK_PICK_DEFAULT); + + return target; +} + /** * gtk_main_do_event: * @event: An event to process (normally passed by GDK) @@ -1914,6 +1947,8 @@ gtk_main_do_event (GdkEvent *event) goto cleanup; } } + else if (is_dnd_event (event)) + target_widget = handle_dnd_event (event); if (!target_widget) goto cleanup; @@ -2028,12 +2063,17 @@ gtk_main_do_event (GdkEvent *event) /* Crossing event propagation happens during picking */ break; - case GDK_DRAG_ENTER: - case GDK_DRAG_LEAVE: case GDK_DRAG_MOTION: case GDK_DROP_START: - _gtk_drag_dest_handle_event (target_widget, event); + if (gtk_propagate_event (target_widget, event)) + break; + G_GNUC_FALLTHROUGH; + + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + gtk_drag_dest_handle_event (target_widget, event); break; + case GDK_EVENT_LAST: default: g_assert_not_reached (); @@ -2623,14 +2663,19 @@ propagate_event_down (GtkWidget *widget, return handled_event; } -void +gboolean gtk_propagate_event_internal (GtkWidget *widget, GdkEvent *event, GtkWidget *topmost) { /* Propagate the event down and up */ - if (!propagate_event_down (widget, event, topmost)) - propagate_event_up (widget, event, topmost); + if (propagate_event_down (widget, event, topmost)) + return TRUE; + + if (propagate_event_up (widget, event, topmost)) + return TRUE; + + return FALSE; } /** @@ -2657,8 +2702,10 @@ gtk_propagate_event_internal (GtkWidget *widget, * certainly better ways to achieve your goals. For example, use * gtk_widget_queue_draw() instead * of making up expose events. + * + * Returns: %TRUE if the event was handled */ -void +gboolean gtk_propagate_event (GtkWidget *widget, GdkEvent *event) { @@ -2666,8 +2713,8 @@ gtk_propagate_event (GtkWidget *widget, GtkWidget *event_widget, *topmost = NULL; GdkDevice *device; - g_return_if_fail (GTK_IS_WIDGET (widget)); - g_return_if_fail (event != NULL); + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); event_widget = gtk_get_event_widget (event); window_group = gtk_main_get_window_group (event_widget); @@ -2679,5 +2726,5 @@ gtk_propagate_event (GtkWidget *widget, if (!topmost) topmost = gtk_window_group_get_current_grab (window_group); - gtk_propagate_event_internal (widget, event, topmost); + return gtk_propagate_event_internal (widget, event, topmost); } diff --git a/gtk/gtkmain.h b/gtk/gtkmain.h index 81c1e574ad..0009c4d90e 100644 --- a/gtk/gtkmain.h +++ b/gtk/gtkmain.h @@ -160,7 +160,7 @@ GtkWidget *gtk_get_event_target_with_type (GdkEvent *event, GType type); GDK_AVAILABLE_IN_ALL -void gtk_propagate_event (GtkWidget *widget, +gboolean gtk_propagate_event (GtkWidget *widget, GdkEvent *event); diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index 2732f064c8..38dfe92a31 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -90,7 +90,7 @@ gboolean _gtk_translate_keyboard_accel_state (GdkKeymap *keymap, gint *level, GdkModifierType *consumed_modifiers); -void gtk_propagate_event_internal (GtkWidget *widget, +gboolean gtk_propagate_event_internal (GtkWidget *widget, GdkEvent *event, GtkWidget *topmost); |