summaryrefslogtreecommitdiff
path: root/gtk/gtknotebook.c
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimoc@gnome.org>2012-09-19 20:56:26 -0400
committerCosimo Cecchi <cosimoc@gnome.org>2012-10-22 18:39:37 -0400
commit852d4d618c46238228220f6f311ea4e764c0e6d8 (patch)
tree810998997831cb0a960c68744b8d92c4aaaa9fa2 /gtk/gtknotebook.c
parent42da600eb193e3423ab7810380ae39bac95d47fd (diff)
downloadgtk+-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.c39
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;