forked from AuroraMiddleware/gtk
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
This commit is contained in:
parent
42da600eb1
commit
852d4d618c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user