use gdk_window_get_pointer() to get pointer coordinates, but limit its
2006-06-15 Carlos Garnacho <carlosg@gnome.org> * gtk/gtknotebook.c (gtk_notebook_motion_notify): use gdk_window_get_pointer() to get pointer coordinates, but limit its calls to a maximum of 45 times per second for not being too CPU/network abusive. stop drag operation if (event->state & GDK_BUTTON1_MASK) is FALSE to prevent tabs from "adhering" to the pointer. Fixes bug #341571 (gtk_notebook_calculate_tabs_allocation), (gtk_notebook_button_press): get rid of the "tab jumps to pointer" sensation when beginning a drag by using the pointer offset in the tab when the drag begins as an anchor. (gtk_notebook_redraw_tabs_union): remove, it wasn't worth the little performance gain and could draw artifacts under some circumstances. (gtk_notebook_drag_end): do not reparent the detached tab label until the animation has ended.
This commit is contained in:
committed by
Carlos Garnacho
parent
a2972ec488
commit
664b8c7b47
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
2006-06-15 Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
|
||||||
|
* gtk/gtknotebook.c (gtk_notebook_motion_notify): use
|
||||||
|
gdk_window_get_pointer() to get pointer coordinates, but limit its
|
||||||
|
calls to a maximum of 45 times per second for not being too
|
||||||
|
CPU/network abusive. stop drag operation if (event->state &
|
||||||
|
GDK_BUTTON1_MASK) is FALSE to prevent tabs from "adhering" to the
|
||||||
|
pointer. Fixes bug #341571
|
||||||
|
(gtk_notebook_calculate_tabs_allocation), (gtk_notebook_button_press):
|
||||||
|
get rid of the "tab jumps to pointer" sensation when beginning a drag
|
||||||
|
by using the pointer offset in the tab when the drag begins as an
|
||||||
|
anchor.
|
||||||
|
(gtk_notebook_redraw_tabs_union): remove, it wasn't worth the little
|
||||||
|
performance gain and could draw artifacts under some circumstances.
|
||||||
|
(gtk_notebook_drag_end): do not reparent the detached tab label until
|
||||||
|
the animation has ended.
|
||||||
|
|
||||||
2006-06-15 Bastien Nocera <hadess@hadess.net>
|
2006-06-15 Bastien Nocera <hadess@hadess.net>
|
||||||
|
|
||||||
* configure.in: Update the Cairo requirements (#345008)
|
* configure.in: Update the Cairo requirements (#345008)
|
||||||
|
|||||||
@ -1,3 +1,20 @@
|
|||||||
|
2006-06-15 Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
|
||||||
|
* gtk/gtknotebook.c (gtk_notebook_motion_notify): use
|
||||||
|
gdk_window_get_pointer() to get pointer coordinates, but limit its
|
||||||
|
calls to a maximum of 45 times per second for not being too
|
||||||
|
CPU/network abusive. stop drag operation if (event->state &
|
||||||
|
GDK_BUTTON1_MASK) is FALSE to prevent tabs from "adhering" to the
|
||||||
|
pointer. Fixes bug #341571
|
||||||
|
(gtk_notebook_calculate_tabs_allocation), (gtk_notebook_button_press):
|
||||||
|
get rid of the "tab jumps to pointer" sensation when beginning a drag
|
||||||
|
by using the pointer offset in the tab when the drag begins as an
|
||||||
|
anchor.
|
||||||
|
(gtk_notebook_redraw_tabs_union): remove, it wasn't worth the little
|
||||||
|
performance gain and could draw artifacts under some circumstances.
|
||||||
|
(gtk_notebook_drag_end): do not reparent the detached tab label until
|
||||||
|
the animation has ended.
|
||||||
|
|
||||||
2006-06-15 Bastien Nocera <hadess@hadess.net>
|
2006-06-15 Bastien Nocera <hadess@hadess.net>
|
||||||
|
|
||||||
* configure.in: Update the Cairo requirements (#345008)
|
* configure.in: Update the Cairo requirements (#345008)
|
||||||
|
|||||||
@ -43,6 +43,8 @@
|
|||||||
#define SCROLL_DELAY_FACTOR 5
|
#define SCROLL_DELAY_FACTOR 5
|
||||||
#define SCROLL_THRESHOLD 12
|
#define SCROLL_THRESHOLD 12
|
||||||
#define DND_THRESHOLD_MULTIPLIER 4
|
#define DND_THRESHOLD_MULTIPLIER 4
|
||||||
|
#define FRAMES_PER_SECOND 45
|
||||||
|
#define MSECS_BETWEEN_UPDATES (1000 / FRAMES_PER_SECOND)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SWITCH_PAGE,
|
SWITCH_PAGE,
|
||||||
@ -161,6 +163,13 @@ struct _GtkNotebookPrivate
|
|||||||
guint dnd_timer;
|
guint dnd_timer;
|
||||||
guint switch_tab_timer;
|
guint switch_tab_timer;
|
||||||
|
|
||||||
|
gint drag_begin_x;
|
||||||
|
gint drag_begin_y;
|
||||||
|
|
||||||
|
gint drag_offset_x;
|
||||||
|
gint drag_offset_y;
|
||||||
|
|
||||||
|
GtkWidget *dnd_window;
|
||||||
GtkTargetList *source_targets;
|
GtkTargetList *source_targets;
|
||||||
GtkNotebookDragOperation operation;
|
GtkNotebookDragOperation operation;
|
||||||
GdkWindow *drag_window;
|
GdkWindow *drag_window;
|
||||||
@ -168,8 +177,11 @@ struct _GtkNotebookPrivate
|
|||||||
gint drag_window_y;
|
gint drag_window_y;
|
||||||
GtkNotebookPage *detached_tab;
|
GtkNotebookPage *detached_tab;
|
||||||
|
|
||||||
gboolean during_detach : 1;
|
guint32 timestamp;
|
||||||
gboolean has_scrolled : 1;
|
|
||||||
|
gboolean during_reorder : 1;
|
||||||
|
gboolean during_detach : 1;
|
||||||
|
gboolean has_scrolled : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const GtkTargetEntry notebook_source_targets [] = {
|
static const GtkTargetEntry notebook_source_targets [] = {
|
||||||
@ -254,6 +266,8 @@ static void gtk_notebook_style_set (GtkWidget *widget,
|
|||||||
/*** Drag and drop Methods ***/
|
/*** Drag and drop Methods ***/
|
||||||
static void gtk_notebook_drag_begin (GtkWidget *widget,
|
static void gtk_notebook_drag_begin (GtkWidget *widget,
|
||||||
GdkDragContext *context);
|
GdkDragContext *context);
|
||||||
|
static void gtk_notebook_drag_end (GtkWidget *widget,
|
||||||
|
GdkDragContext *context);
|
||||||
static gboolean gtk_notebook_drag_motion (GtkWidget *widget,
|
static gboolean gtk_notebook_drag_motion (GtkWidget *widget,
|
||||||
GdkDragContext *context,
|
GdkDragContext *context,
|
||||||
gint x,
|
gint x,
|
||||||
@ -483,6 +497,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
|
|||||||
widget_class->focus = gtk_notebook_focus;
|
widget_class->focus = gtk_notebook_focus;
|
||||||
widget_class->style_set = gtk_notebook_style_set;
|
widget_class->style_set = gtk_notebook_style_set;
|
||||||
widget_class->drag_begin = gtk_notebook_drag_begin;
|
widget_class->drag_begin = gtk_notebook_drag_begin;
|
||||||
|
widget_class->drag_end = gtk_notebook_drag_end;
|
||||||
widget_class->drag_motion = gtk_notebook_drag_motion;
|
widget_class->drag_motion = gtk_notebook_drag_motion;
|
||||||
widget_class->drag_leave = gtk_notebook_drag_leave;
|
widget_class->drag_leave = gtk_notebook_drag_leave;
|
||||||
widget_class->drag_drop = gtk_notebook_drag_drop;
|
widget_class->drag_drop = gtk_notebook_drag_drop;
|
||||||
@ -1435,6 +1450,7 @@ gtk_notebook_get_property (GObject *object,
|
|||||||
* gtk_notebook_draw_focus
|
* gtk_notebook_draw_focus
|
||||||
* gtk_notebook_style_set
|
* gtk_notebook_style_set
|
||||||
* gtk_notebook_drag_begin
|
* gtk_notebook_drag_begin
|
||||||
|
* gtk_notebook_drag_end
|
||||||
* gtk_notebook_drag_motion
|
* gtk_notebook_drag_motion
|
||||||
* gtk_notebook_drag_drop
|
* gtk_notebook_drag_drop
|
||||||
* gtk_notebook_drag_data_get
|
* gtk_notebook_drag_data_get
|
||||||
@ -1581,7 +1597,7 @@ gtk_notebook_realize (GtkWidget *widget)
|
|||||||
attributes.event_mask = gtk_widget_get_events (widget);
|
attributes.event_mask = gtk_widget_get_events (widget);
|
||||||
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
|
||||||
GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK |
|
GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK |
|
||||||
GDK_BUTTON1_MOTION_MASK |
|
GDK_POINTER_MOTION_MASK |
|
||||||
GDK_SCROLL_MASK);
|
GDK_SCROLL_MASK);
|
||||||
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
||||||
|
|
||||||
@ -2326,21 +2342,29 @@ gtk_notebook_button_press (GtkWidget *widget,
|
|||||||
page = tab->data;
|
page = tab->data;
|
||||||
page_changed = page != notebook->cur_page;
|
page_changed = page != notebook->cur_page;
|
||||||
was_focus = gtk_widget_is_focus (widget);
|
was_focus = gtk_widget_is_focus (widget);
|
||||||
|
|
||||||
gtk_notebook_switch_focus_tab (notebook, tab);
|
gtk_notebook_switch_focus_tab (notebook, tab);
|
||||||
gtk_widget_grab_focus (widget);
|
gtk_widget_grab_focus (widget);
|
||||||
|
|
||||||
if (page_changed && !was_focus)
|
if (page_changed && !was_focus)
|
||||||
gtk_widget_child_focus (page->child, GTK_DIR_TAB_FORWARD);
|
gtk_widget_child_focus (page->child, GTK_DIR_TAB_FORWARD);
|
||||||
|
|
||||||
/* save press to possibly begin a drag */
|
/* save press to possibly begin a drag */
|
||||||
if (page->reorderable || page->detachable)
|
if (page->reorderable || page->detachable)
|
||||||
{
|
{
|
||||||
priv->during_detach = FALSE;
|
priv->during_detach = FALSE;
|
||||||
|
priv->during_reorder = FALSE;
|
||||||
priv->pressed_button = event->button;
|
priv->pressed_button = event->button;
|
||||||
|
|
||||||
priv->mouse_x = x - widget->allocation.x;
|
gdk_window_get_pointer (widget->window,
|
||||||
priv->mouse_y = y - widget->allocation.y;
|
&priv->mouse_x,
|
||||||
|
&priv->mouse_y,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
priv->drag_begin_x = priv->mouse_x;
|
||||||
|
priv->drag_begin_y = priv->mouse_y;
|
||||||
|
priv->drag_offset_x = priv->drag_begin_x - page->allocation.x;
|
||||||
|
priv->drag_offset_y = priv->drag_begin_y - page->allocation.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2425,8 +2449,8 @@ get_drop_position (GtkNotebook *notebook,
|
|||||||
gint x, y;
|
gint x, y;
|
||||||
|
|
||||||
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
||||||
x = priv->mouse_x + GTK_WIDGET (notebook)->allocation.x;
|
x = priv->mouse_x;
|
||||||
y = priv->mouse_y + GTK_WIDGET (notebook)->allocation.y;
|
y = priv->mouse_y;
|
||||||
|
|
||||||
is_rtl = gtk_widget_get_direction ((GtkWidget *) notebook) == GTK_TEXT_DIR_RTL;
|
is_rtl = gtk_widget_get_direction ((GtkWidget *) notebook) == GTK_TEXT_DIR_RTL;
|
||||||
children = notebook->children;
|
children = notebook->children;
|
||||||
@ -2556,33 +2580,25 @@ hide_drag_window (GtkNotebook *notebook,
|
|||||||
gdk_window_hide (priv->drag_window);
|
gdk_window_hide (priv->drag_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static void
|
||||||
gtk_notebook_button_release (GtkWidget *widget,
|
gtk_notebook_stop_reorder (GtkNotebook *notebook)
|
||||||
GdkEventButton *event)
|
|
||||||
{
|
{
|
||||||
GtkNotebook *notebook;
|
|
||||||
GtkNotebookPrivate *priv;
|
GtkNotebookPrivate *priv;
|
||||||
GtkNotebookPage *page;
|
GtkNotebookPage *page;
|
||||||
GList *element;
|
|
||||||
gint old_page_num, page_num;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
|
|
||||||
g_return_val_if_fail (event != NULL, FALSE);
|
|
||||||
|
|
||||||
if (event->type != GDK_BUTTON_RELEASE)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
notebook = GTK_NOTEBOOK (widget);
|
|
||||||
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
||||||
page = notebook->cur_page;
|
page = notebook->cur_page;
|
||||||
|
|
||||||
if (page->reorderable &&
|
if (!page)
|
||||||
event->button == priv->pressed_button)
|
return;
|
||||||
{
|
|
||||||
priv->pressed_button = -1;
|
|
||||||
|
|
||||||
|
if (page->reorderable || page->detachable)
|
||||||
|
{
|
||||||
if (!priv->during_detach)
|
if (!priv->during_detach)
|
||||||
{
|
{
|
||||||
|
gint old_page_num, page_num;
|
||||||
|
GList *element;
|
||||||
|
|
||||||
element = get_drop_position (notebook, page->pack);
|
element = get_drop_position (notebook, page->pack);
|
||||||
old_page_num = g_list_position (notebook->children, notebook->focus_tab);
|
old_page_num = g_list_position (notebook->children, notebook->focus_tab);
|
||||||
page_num = reorder_tab (notebook, element, notebook->focus_tab);
|
page_num = reorder_tab (notebook, element, notebook->focus_tab);
|
||||||
@ -2607,6 +2623,33 @@ gtk_notebook_button_release (GtkWidget *widget,
|
|||||||
priv->dnd_timer = 0;
|
priv->dnd_timer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
gtk_notebook_button_release (GtkWidget *widget,
|
||||||
|
GdkEventButton *event)
|
||||||
|
{
|
||||||
|
GtkNotebook *notebook;
|
||||||
|
GtkNotebookPrivate *priv;
|
||||||
|
GtkNotebookPage *page;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
|
||||||
|
g_return_val_if_fail (event != NULL, FALSE);
|
||||||
|
|
||||||
|
if (event->type != GDK_BUTTON_RELEASE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
notebook = GTK_NOTEBOOK (widget);
|
||||||
|
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
||||||
|
page = notebook->cur_page;
|
||||||
|
|
||||||
|
if (!priv->during_detach &&
|
||||||
|
page->reorderable &&
|
||||||
|
event->button == priv->pressed_button)
|
||||||
|
{
|
||||||
|
priv->pressed_button = -1;
|
||||||
|
gtk_notebook_stop_reorder (notebook);
|
||||||
|
}
|
||||||
|
|
||||||
if (event->button == notebook->button)
|
if (event->button == notebook->button)
|
||||||
{
|
{
|
||||||
@ -2679,20 +2722,26 @@ get_pointer_position (GtkNotebook *notebook)
|
|||||||
if (notebook->tab_pos == GTK_POS_TOP ||
|
if (notebook->tab_pos == GTK_POS_TOP ||
|
||||||
notebook->tab_pos == GTK_POS_BOTTOM)
|
notebook->tab_pos == GTK_POS_BOTTOM)
|
||||||
{
|
{
|
||||||
is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
|
gint x;
|
||||||
|
|
||||||
if (priv->mouse_x > widget->allocation.width - 2 * container->border_width - SCROLL_THRESHOLD)
|
is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
|
||||||
|
x = priv->mouse_x - widget->allocation.x;
|
||||||
|
|
||||||
|
if (x > widget->allocation.width - 2 * container->border_width - SCROLL_THRESHOLD)
|
||||||
return (is_rtl) ? POINTER_BEFORE : POINTER_AFTER;
|
return (is_rtl) ? POINTER_BEFORE : POINTER_AFTER;
|
||||||
else if (priv->mouse_x < SCROLL_THRESHOLD + container->border_width)
|
else if (x < SCROLL_THRESHOLD + container->border_width)
|
||||||
return (is_rtl) ? POINTER_AFTER : POINTER_BEFORE;
|
return (is_rtl) ? POINTER_AFTER : POINTER_BEFORE;
|
||||||
else
|
else
|
||||||
return POINTER_BETWEEN;
|
return POINTER_BETWEEN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (priv->mouse_y > widget->allocation.height - 2 * container->border_width - SCROLL_THRESHOLD)
|
gint y;
|
||||||
|
|
||||||
|
y = priv->mouse_y - widget->allocation.y;
|
||||||
|
if (y > widget->allocation.height - 2 * container->border_width - SCROLL_THRESHOLD)
|
||||||
return POINTER_AFTER;
|
return POINTER_AFTER;
|
||||||
else if (priv->mouse_y < SCROLL_THRESHOLD + container->border_width)
|
else if (y < SCROLL_THRESHOLD + container->border_width)
|
||||||
return POINTER_BEFORE;
|
return POINTER_BEFORE;
|
||||||
else
|
else
|
||||||
return POINTER_BETWEEN;
|
return POINTER_BETWEEN;
|
||||||
@ -2707,6 +2756,8 @@ scroll_notebook_timer (gpointer data)
|
|||||||
GtkNotebookPointerPosition pointer_position;
|
GtkNotebookPointerPosition pointer_position;
|
||||||
GList *element, *first_tab;
|
GList *element, *first_tab;
|
||||||
|
|
||||||
|
GDK_THREADS_ENTER ();
|
||||||
|
|
||||||
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
||||||
pointer_position = get_pointer_position (notebook);
|
pointer_position = get_pointer_position (notebook);
|
||||||
|
|
||||||
@ -2728,6 +2779,8 @@ scroll_notebook_timer (gpointer data)
|
|||||||
gdk_window_raise (priv->drag_window);
|
gdk_window_raise (priv->drag_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GDK_THREADS_LEAVE ();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2773,22 +2826,33 @@ gtk_notebook_motion_notify (GtkWidget *widget,
|
|||||||
GtkSettings *settings;
|
GtkSettings *settings;
|
||||||
guint timeout;
|
guint timeout;
|
||||||
|
|
||||||
|
page = notebook->cur_page;
|
||||||
|
|
||||||
|
if (!page)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(event->state & GDK_BUTTON1_MASK) &&
|
||||||
|
priv->pressed_button != -1)
|
||||||
|
{
|
||||||
|
priv->pressed_button = -1;
|
||||||
|
gtk_notebook_stop_reorder (notebook);
|
||||||
|
stop_scrolling (notebook);
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->pressed_button == -1)
|
if (priv->pressed_button == -1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!notebook->cur_page)
|
if (event->time < priv->timestamp + MSECS_BETWEEN_UPDATES)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
page = notebook->cur_page;
|
priv->timestamp = event->time;
|
||||||
|
gdk_window_get_pointer (widget->window,
|
||||||
get_widget_coordinates (widget, (GdkEvent*) event, &priv->mouse_x, &priv->mouse_y);
|
&priv->mouse_x,
|
||||||
priv->mouse_x -= widget->allocation.x;
|
&priv->mouse_y,
|
||||||
priv->mouse_y -= widget->allocation.y;
|
NULL);
|
||||||
|
|
||||||
if (page->detachable &&
|
if (page->detachable &&
|
||||||
check_threshold (notebook,
|
check_threshold (notebook, priv->mouse_x, priv->mouse_y))
|
||||||
priv->mouse_x + widget->allocation.x,
|
|
||||||
priv->mouse_y + widget->allocation.y))
|
|
||||||
{
|
{
|
||||||
priv->detached_tab = notebook->cur_page;
|
priv->detached_tab = notebook->cur_page;
|
||||||
priv->during_detach = TRUE;
|
priv->during_detach = TRUE;
|
||||||
@ -2798,8 +2862,11 @@ gtk_notebook_motion_notify (GtkWidget *widget,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page->reorderable)
|
if (page->reorderable &&
|
||||||
|
(priv->during_reorder ||
|
||||||
|
gtk_drag_check_threshold (widget, priv->drag_begin_x, priv->drag_begin_y, priv->mouse_x, priv->mouse_y)))
|
||||||
{
|
{
|
||||||
|
priv->during_reorder = TRUE;
|
||||||
pointer_position = get_pointer_position (notebook);
|
pointer_position = get_pointer_position (notebook);
|
||||||
|
|
||||||
if (event->window == priv->drag_window &&
|
if (event->window == priv->drag_window &&
|
||||||
@ -2833,8 +2900,8 @@ gtk_notebook_motion_notify (GtkWidget *widget,
|
|||||||
/* the drag operation is beginning, create the window */
|
/* the drag operation is beginning, create the window */
|
||||||
if (priv->operation != DRAG_OPERATION_REORDER)
|
if (priv->operation != DRAG_OPERATION_REORDER)
|
||||||
{
|
{
|
||||||
show_drag_window (notebook, priv, page);
|
|
||||||
priv->operation = DRAG_OPERATION_REORDER;
|
priv->operation = DRAG_OPERATION_REORDER;
|
||||||
|
show_drag_window (notebook, priv, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_notebook_pages_allocate (notebook);
|
gtk_notebook_pages_allocate (notebook);
|
||||||
@ -2970,8 +3037,7 @@ gtk_notebook_drag_begin (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
|
GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
|
||||||
GtkNotebook *notebook = (GtkNotebook*) widget;
|
GtkNotebook *notebook = (GtkNotebook*) widget;
|
||||||
GtkWidget *tab_label, *window;
|
GtkWidget *tab_label;
|
||||||
gint width, height;
|
|
||||||
|
|
||||||
if (priv->dnd_timer)
|
if (priv->dnd_timer)
|
||||||
{
|
{
|
||||||
@ -2979,25 +3045,42 @@ gtk_notebook_drag_begin (GtkWidget *widget,
|
|||||||
priv->dnd_timer = 0;
|
priv->dnd_timer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->operation = DRAG_OPERATION_DETACH;
|
||||||
|
gtk_notebook_pages_allocate (notebook);
|
||||||
|
|
||||||
tab_label = priv->detached_tab->tab_label;
|
tab_label = priv->detached_tab->tab_label;
|
||||||
gdk_drawable_get_size (priv->drag_window, &width, &height);
|
|
||||||
|
|
||||||
hide_drag_window (notebook, priv, notebook->cur_page);
|
hide_drag_window (notebook, priv, notebook->cur_page);
|
||||||
g_object_ref (tab_label);
|
g_object_ref (tab_label);
|
||||||
gtk_widget_unparent (tab_label);
|
gtk_widget_unparent (tab_label);
|
||||||
|
|
||||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
priv->dnd_window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||||
gtk_container_add (GTK_CONTAINER (window), tab_label);
|
gtk_container_add (GTK_CONTAINER (priv->dnd_window), tab_label);
|
||||||
gtk_widget_set_size_request (window, width, height);
|
gtk_widget_set_size_request (priv->dnd_window,
|
||||||
|
priv->detached_tab->allocation.width,
|
||||||
|
priv->detached_tab->allocation.height);
|
||||||
g_object_unref (tab_label);
|
g_object_unref (tab_label);
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (window), "expose-event",
|
g_signal_connect (G_OBJECT (priv->dnd_window), "expose-event",
|
||||||
G_CALLBACK (on_drag_icon_expose), notebook);
|
G_CALLBACK (on_drag_icon_expose), notebook);
|
||||||
|
|
||||||
gtk_drag_set_icon_widget (context, window, -2, -2);
|
gtk_drag_set_icon_widget (context, priv->dnd_window, -2, -2);
|
||||||
|
}
|
||||||
|
|
||||||
priv->operation = DRAG_OPERATION_DETACH;
|
static void
|
||||||
gtk_notebook_pages_allocate (notebook);
|
gtk_notebook_drag_end (GtkWidget *widget,
|
||||||
|
GdkDragContext *context)
|
||||||
|
{
|
||||||
|
GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
|
||||||
|
|
||||||
|
priv->pressed_button = -1;
|
||||||
|
gtk_notebook_stop_reorder (GTK_NOTEBOOK (widget));
|
||||||
|
|
||||||
|
GTK_BIN (priv->dnd_window)->child = NULL;
|
||||||
|
gtk_widget_destroy (priv->dnd_window);
|
||||||
|
priv->dnd_window = NULL;
|
||||||
|
|
||||||
|
priv->operation = DRAG_OPERATION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -3008,6 +3091,8 @@ gtk_notebook_switch_tab_timeout (gpointer data)
|
|||||||
GList *tab;
|
GList *tab;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
|
||||||
|
GDK_THREADS_ENTER ();
|
||||||
|
|
||||||
notebook = GTK_NOTEBOOK (data);
|
notebook = GTK_NOTEBOOK (data);
|
||||||
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
||||||
|
|
||||||
@ -3024,6 +3109,8 @@ gtk_notebook_switch_tab_timeout (gpointer data)
|
|||||||
gtk_notebook_switch_focus_tab (notebook, tab);
|
gtk_notebook_switch_focus_tab (notebook, tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GDK_THREADS_LEAVE ();
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3190,8 +3277,8 @@ do_detach_tab (GtkNotebook *from,
|
|||||||
gtk_container_remove (GTK_CONTAINER (from), child);
|
gtk_container_remove (GTK_CONTAINER (from), child);
|
||||||
|
|
||||||
priv = GTK_NOTEBOOK_GET_PRIVATE (to);
|
priv = GTK_NOTEBOOK_GET_PRIVATE (to);
|
||||||
priv->mouse_x = x;
|
priv->mouse_x = x + GTK_WIDGET (to)->allocation.x;
|
||||||
priv->mouse_y = y;
|
priv->mouse_y = y + GTK_WIDGET (to)->allocation.y;
|
||||||
|
|
||||||
element = get_drop_position (to, tab_pack);
|
element = get_drop_position (to, tab_pack);
|
||||||
page_num = g_list_position (to->children, element);
|
page_num = g_list_position (to->children, element);
|
||||||
@ -3948,68 +4035,6 @@ gtk_notebook_redraw_tabs (GtkNotebook *notebook)
|
|||||||
gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
|
gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_notebook_redraw_tabs_union (GtkNotebook *notebook)
|
|
||||||
{
|
|
||||||
GtkWidget *widget;
|
|
||||||
GtkNotebookPage *page;
|
|
||||||
GdkRectangle redraw_rect;
|
|
||||||
gint border;
|
|
||||||
gint tab_pos = get_effective_tab_pos (notebook);
|
|
||||||
|
|
||||||
widget = GTK_WIDGET (notebook);
|
|
||||||
border = GTK_CONTAINER (notebook)->border_width;
|
|
||||||
|
|
||||||
if (!GTK_WIDGET_MAPPED (notebook) || !notebook->first_tab)
|
|
||||||
return;
|
|
||||||
|
|
||||||
page = GTK_NOTEBOOK_PAGE (notebook->first_tab);
|
|
||||||
|
|
||||||
redraw_rect.x = border;
|
|
||||||
redraw_rect.y = border;
|
|
||||||
|
|
||||||
switch (tab_pos)
|
|
||||||
{
|
|
||||||
case GTK_POS_TOP:
|
|
||||||
redraw_rect.x = border;
|
|
||||||
redraw_rect.y = page->allocation.height + border;
|
|
||||||
break;
|
|
||||||
case GTK_POS_BOTTOM:
|
|
||||||
redraw_rect.x = border;
|
|
||||||
redraw_rect.y = widget->allocation.height - border -
|
|
||||||
page->allocation.height - widget->style->ythickness;
|
|
||||||
break;
|
|
||||||
case GTK_POS_RIGHT:
|
|
||||||
redraw_rect.x = widget->allocation.width - border -
|
|
||||||
page->allocation.width - widget->style->xthickness;
|
|
||||||
redraw_rect.y = border;
|
|
||||||
break;
|
|
||||||
case GTK_POS_LEFT:
|
|
||||||
redraw_rect.x = page->allocation.width + border;
|
|
||||||
redraw_rect.y = border;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tab_pos)
|
|
||||||
{
|
|
||||||
case GTK_POS_TOP:
|
|
||||||
case GTK_POS_BOTTOM:
|
|
||||||
redraw_rect.width = widget->allocation.width - 2 * border;
|
|
||||||
redraw_rect.height = widget->style->ythickness;
|
|
||||||
break;
|
|
||||||
case GTK_POS_RIGHT:
|
|
||||||
case GTK_POS_LEFT:
|
|
||||||
redraw_rect.width = widget->style->xthickness;
|
|
||||||
redraw_rect.height = widget->allocation.height - 2 * border;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
redraw_rect.x += widget->allocation.x;
|
|
||||||
redraw_rect.y += widget->allocation.y;
|
|
||||||
|
|
||||||
gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_notebook_redraw_arrows (GtkNotebook *notebook)
|
gtk_notebook_redraw_arrows (GtkNotebook *notebook)
|
||||||
{
|
{
|
||||||
@ -4133,12 +4158,14 @@ static void
|
|||||||
gtk_notebook_real_remove (GtkNotebook *notebook,
|
gtk_notebook_real_remove (GtkNotebook *notebook,
|
||||||
GList *list)
|
GList *list)
|
||||||
{
|
{
|
||||||
|
GtkNotebookPrivate *priv;
|
||||||
GtkNotebookPage *page;
|
GtkNotebookPage *page;
|
||||||
GList * next_list;
|
GList * next_list;
|
||||||
gint need_resize = FALSE;
|
gint need_resize = FALSE;
|
||||||
|
|
||||||
gboolean destroying;
|
gboolean destroying;
|
||||||
|
|
||||||
|
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
|
||||||
destroying = GTK_OBJECT_FLAGS (notebook) & GTK_IN_DESTRUCTION;
|
destroying = GTK_OBJECT_FLAGS (notebook) & GTK_IN_DESTRUCTION;
|
||||||
|
|
||||||
next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE);
|
next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE);
|
||||||
@ -4152,6 +4179,9 @@ gtk_notebook_real_remove (GtkNotebook *notebook,
|
|||||||
gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1);
|
gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->detached_tab == list->data)
|
||||||
|
priv->detached_tab = NULL;
|
||||||
|
|
||||||
if (list == notebook->first_tab)
|
if (list == notebook->first_tab)
|
||||||
notebook->first_tab = next_list;
|
notebook->first_tab = next_list;
|
||||||
if (list == notebook->focus_tab && !destroying)
|
if (list == notebook->focus_tab && !destroying)
|
||||||
@ -4884,16 +4914,21 @@ gtk_notebook_calculate_shown_tabs (GtkNotebook *notebook,
|
|||||||
{
|
{
|
||||||
*last_child = NULL;
|
*last_child = NULL;
|
||||||
children = NULL;
|
children = NULL;
|
||||||
|
|
||||||
gtk_notebook_calc_tabs (notebook,
|
gtk_notebook_calc_tabs (notebook,
|
||||||
gtk_notebook_search_page (notebook,
|
gtk_notebook_search_page (notebook,
|
||||||
notebook->first_tab,
|
notebook->first_tab,
|
||||||
STEP_PREV,
|
STEP_PREV,
|
||||||
TRUE),
|
TRUE),
|
||||||
&children, remaining_space, STEP_PREV);
|
&children, remaining_space, STEP_PREV);
|
||||||
notebook->first_tab = gtk_notebook_search_page(notebook,
|
|
||||||
children,
|
if (*remaining_space == 0)
|
||||||
STEP_NEXT,
|
notebook->first_tab = children;
|
||||||
TRUE);
|
else
|
||||||
|
notebook->first_tab = gtk_notebook_search_page(notebook,
|
||||||
|
children,
|
||||||
|
STEP_NEXT,
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5050,9 +5085,9 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook *notebook,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
left_x = CLAMP (widget->allocation.x + priv->mouse_x - notebook->cur_page->allocation.width / 2,
|
left_x = CLAMP (priv->mouse_x - priv->drag_offset_x,
|
||||||
min, max - notebook->cur_page->allocation.width);
|
min, max - notebook->cur_page->allocation.width);
|
||||||
top_y = CLAMP (widget->allocation.y + priv->mouse_y - notebook->cur_page->allocation.height / 2,
|
top_y = CLAMP (priv->mouse_y - priv->drag_offset_y,
|
||||||
min, max - notebook->cur_page->allocation.height);
|
min, max - notebook->cur_page->allocation.height);
|
||||||
right_x = left_x + notebook->cur_page->allocation.width;
|
right_x = left_x + notebook->cur_page->allocation.width;
|
||||||
bottom_y = top_y + notebook->cur_page->allocation.height;
|
bottom_y = top_y + notebook->cur_page->allocation.height;
|
||||||
@ -5206,8 +5241,9 @@ gtk_notebook_calculate_tabs_allocation (GtkNotebook *notebook,
|
|||||||
|
|
||||||
page->allocation = child_allocation;
|
page->allocation = child_allocation;
|
||||||
|
|
||||||
if (priv->operation == DRAG_OPERATION_REORDER &&
|
if (page == notebook->cur_page &&
|
||||||
page == notebook->cur_page)
|
(priv->operation == DRAG_OPERATION_REORDER ||
|
||||||
|
priv->operation == DRAG_OPERATION_DETACH))
|
||||||
{
|
{
|
||||||
/* needs to be allocated at 0,0
|
/* needs to be allocated at 0,0
|
||||||
* to be shown in the drag window */
|
* to be shown in the drag window */
|
||||||
@ -5317,7 +5353,6 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook)
|
|||||||
gboolean showarrow = FALSE;
|
gboolean showarrow = FALSE;
|
||||||
gint tab_space, min, max, remaining_space;
|
gint tab_space, min, max, remaining_space;
|
||||||
gint expanded_tabs, operation;
|
gint expanded_tabs, operation;
|
||||||
gboolean changed;
|
|
||||||
|
|
||||||
if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
|
if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
|
||||||
return;
|
return;
|
||||||
@ -5333,15 +5368,15 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook)
|
|||||||
&expanded_tabs, &remaining_space);
|
&expanded_tabs, &remaining_space);
|
||||||
|
|
||||||
children = notebook->first_tab;
|
children = notebook->first_tab;
|
||||||
changed = gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
|
gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
|
||||||
showarrow, STEP_NEXT,
|
showarrow, STEP_NEXT,
|
||||||
&remaining_space, &expanded_tabs, min, max);
|
&remaining_space, &expanded_tabs, min, max);
|
||||||
if (children && children != last_child)
|
if (children && children != last_child)
|
||||||
{
|
{
|
||||||
children = notebook->children;
|
children = notebook->children;
|
||||||
changed |= gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
|
gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
|
||||||
showarrow, STEP_PREV,
|
showarrow, STEP_PREV,
|
||||||
&remaining_space, &expanded_tabs, min, max);
|
&remaining_space, &expanded_tabs, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
children = notebook->children;
|
children = notebook->children;
|
||||||
@ -5357,10 +5392,7 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook)
|
|||||||
if (!notebook->first_tab)
|
if (!notebook->first_tab)
|
||||||
notebook->first_tab = notebook->children;
|
notebook->first_tab = notebook->children;
|
||||||
|
|
||||||
if (changed || operation != DRAG_OPERATION_REORDER)
|
gtk_notebook_redraw_tabs (notebook);
|
||||||
gtk_notebook_redraw_tabs (notebook);
|
|
||||||
else if (!changed)
|
|
||||||
gtk_notebook_redraw_tabs_union (notebook);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
Reference in New Issue
Block a user