diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2012-09-19 20:56:26 -0400 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2012-10-22 18:39:37 -0400 |
commit | 852d4d618c46238228220f6f311ea4e764c0e6d8 (patch) | |
tree | 810998997831cb0a960c68744b8d92c4aaaa9fa2 /gtk/gtknotebook.c | |
parent | 42da600eb193e3423ab7810380ae39bac95d47fd (diff) | |
download | gtk+-852d4d618c46238228220f6f311ea4e764c0e6d8.tar.gz |
notebook: return TRUE for drag-motion event when over tabs
The GtkNotebook drag-motion event handler may install a timeout when
hovering over a tab, in order to switch to it.
On the other hand it's desirable for applications to use the empty tab
area as a drop target, so the drag-motion handler returns FALSE
(also in case it installs the switch tab timeout), as explained in
https://bugzilla.gnome.org/show_bug.cgi?id=350665.
Unfortunately, applications can use the tab label widget (or a child
of it) as a different drop target area, and install their own
drag-motion handler there.
In this scenario, the timeout will still be installed by GtkNotebook's
handler, but since it returns FALSE, it will never get the matching
drag-leave event, causing it to trigger also when the mouse pointer
moved elsewhere before it expired.
Fix this by returning TRUE from drag-motion when the event is over a
tab. Note that this makes automatic tab switching not work anymore when
drag and drop is handled in the tab label widget; applications are
expected to also handle tab switching if desired in such a case.
https://bugzilla.gnome.org/show_bug.cgi?id=684415
Diffstat (limited to 'gtk/gtknotebook.c')
-rw-r--r-- | gtk/gtknotebook.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index a1469ef129..4d495c7321 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -150,6 +150,7 @@ struct _GtkNotebookPrivate guint dnd_timer; guint switch_tab_timer; + GList *switch_tab; guint32 timer; guint32 timestamp; @@ -3696,20 +3697,20 @@ gtk_notebook_switch_tab_timeout (gpointer data) { GtkNotebook *notebook = GTK_NOTEBOOK (data); GtkNotebookPrivate *priv = notebook->priv; - GList *tab; - gint x, y; + GList *switch_tab; priv->switch_tab_timer = 0; - x = priv->mouse_x; - y = priv->mouse_y; - if ((tab = get_tab_at_pos (notebook, x, y)) != NULL) + switch_tab = priv->switch_tab; + priv->switch_tab = NULL; + + if (switch_tab) { /* FIXME: hack, we don't want the * focus to move fom the source widget */ priv->child_has_focus = FALSE; - gtk_notebook_switch_focus_tab (notebook, tab); + gtk_notebook_switch_focus_tab (notebook, switch_tab); } return FALSE; @@ -3730,6 +3731,8 @@ gtk_notebook_drag_motion (GtkWidget *widget, GtkNotebookArrow arrow; guint timeout; GdkAtom target, tab_target; + GList *tab; + gboolean retval = FALSE; gtk_widget_get_allocation (widget, &allocation); @@ -3741,7 +3744,9 @@ gtk_notebook_drag_motion (GtkWidget *widget, priv->click_child = arrow; gtk_notebook_set_scroll_timer (notebook); gdk_drag_status (context, 0, time); - return TRUE; + + retval = TRUE; + goto out; } stop_scrolling (notebook); @@ -3754,6 +3759,8 @@ gtk_notebook_drag_motion (GtkWidget *widget, GtkNotebook *source; GtkWidget *source_child; + retval = TRUE; + source = GTK_NOTEBOOK (gtk_drag_get_source_widget (context)); source_child = source->priv->cur_page->child; @@ -3765,7 +3772,7 @@ gtk_notebook_drag_motion (GtkWidget *widget, gtk_widget_is_ancestor (widget, source_child))) { gdk_drag_status (context, GDK_ACTION_MOVE, time); - return TRUE; + goto out; } else { @@ -3780,11 +3787,19 @@ gtk_notebook_drag_motion (GtkWidget *widget, if (gtk_notebook_get_event_window_position (notebook, &position) && x >= position.x && x <= position.x + position.width && - y >= position.y && y <= position.y + position.height) + y >= position.y && y <= position.y + position.height && + (tab = get_tab_at_pos (notebook, x, y))) { priv->mouse_x = x; priv->mouse_y = y; + retval = TRUE; + + if (tab != priv->switch_tab) + remove_switch_tab_timer (notebook); + + priv->switch_tab = tab; + if (!priv->switch_tab_timer) { settings = gtk_widget_get_settings (widget); @@ -3800,7 +3815,8 @@ gtk_notebook_drag_motion (GtkWidget *widget, remove_switch_tab_timer (notebook); } - return (target == tab_target) ? TRUE : FALSE; + out: + return retval; } static void @@ -3809,7 +3825,6 @@ gtk_notebook_drag_leave (GtkWidget *widget, guint time) { GtkNotebook *notebook = GTK_NOTEBOOK (widget); - GtkNotebookPrivate *priv = notebook->priv; remove_switch_tab_timer (notebook); stop_scrolling (notebook); @@ -4977,6 +4992,8 @@ gtk_notebook_real_remove (GtkNotebook *notebook, if (priv->detached_tab == list->data) priv->detached_tab = NULL; + if (priv->switch_tab == list) + priv->switch_tab = NULL; if (list == priv->first_tab) priv->first_tab = next_list; |