X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtknotebook.c;h=5f0ce009a8a72123c2ff8dc185c1e7b4c492a163;hb=3c8e1c92a85b2e41161698f141747ced2c574f32;hp=32cdee71ee714d783f7f3547f20384b56c679f85;hpb=cf172a5873ce89a115f39dd9cbb5c49e2545b3db;p=~andy%2Fgtk diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index 32cdee71e..5f0ce009a 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /* @@ -43,6 +41,8 @@ #include "gtkdnd.h" #include "gtkbuildable.h" #include "gtktypebuiltins.h" +#include "gtkwidgetpath.h" +#include "gtkwidgetprivate.h" #include "a11y/gtknotebookaccessible.h" @@ -150,6 +150,7 @@ struct _GtkNotebookPrivate guint dnd_timer; guint switch_tab_timer; + GList *switch_tab; guint32 timer; guint32 timestamp; @@ -1069,7 +1070,7 @@ gtk_notebook_class_init (GtkNotebookClass *class) * a notebook where the tab will be attached. It is also * responsible for moving/resizing the window and adding the * necessary properties to the notebook (e.g. the - * #GtkNotebook:group ). + * #GtkNotebook:group-name ). * * Returns: (transfer none): a #GtkNotebook that @page should be * added to, or %NULL. @@ -1674,6 +1675,18 @@ gtk_notebook_get_property (GObject *object, * gtk_notebook_drag_data_get * gtk_notebook_drag_data_received */ +static void +remove_switch_tab_timer (GtkNotebook *notebook) +{ + GtkNotebookPrivate *priv = notebook->priv; + + if (priv->switch_tab_timer) + { + g_source_remove (priv->switch_tab_timer); + priv->switch_tab_timer = 0; + } +} + static void gtk_notebook_destroy (GtkWidget *widget) { @@ -1701,11 +1714,7 @@ gtk_notebook_destroy (GtkWidget *widget) priv->source_targets = NULL; } - if (priv->switch_tab_timer) - { - g_source_remove (priv->switch_tab_timer); - priv->switch_tab_timer = 0; - } + remove_switch_tab_timer (notebook); GTK_WIDGET_CLASS (gtk_notebook_parent_class)->destroy (widget); } @@ -1899,7 +1908,7 @@ gtk_notebook_realize (GtkWidget *widget) priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gdk_window_set_user_data (priv->event_window, notebook); + gtk_widget_register_window (widget, priv->event_window); } static void @@ -1908,13 +1917,13 @@ gtk_notebook_unrealize (GtkWidget *widget) GtkNotebook *notebook = GTK_NOTEBOOK (widget); GtkNotebookPrivate *priv = notebook->priv; - gdk_window_set_user_data (priv->event_window, NULL); + gtk_widget_unregister_window (widget, priv->event_window); gdk_window_destroy (priv->event_window); priv->event_window = NULL; if (priv->drag_window) { - gdk_window_set_user_data (priv->drag_window, NULL); + gtk_widget_unregister_window (widget, priv->drag_window); gdk_window_destroy (priv->drag_window); priv->drag_window = NULL; } @@ -2033,6 +2042,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook *notebook, gint tab_overlap; gint tab_curvature; gint arrow_spacing; + gint initial_gap; gint scroll_arrow_hlength; gint scroll_arrow_vlength; @@ -2042,6 +2052,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook *notebook, gtk_widget_style_get (widget, "focus-line-width", &focus_width, "focus-padding", &focus_pad, + "initial-gap", &initial_gap, "tab-overlap", &tab_overlap, "tab-curvature", &tab_curvature, "arrow-spacing", &arrow_spacing, @@ -2145,7 +2156,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook *notebook, action_width += action_widget_requisition[ACTION_WIDGET_START].width; action_width += action_widget_requisition[ACTION_WIDGET_END].width; - requisition->width = tab_width + tab_overlap + action_width; + requisition->width = tab_width + tab_overlap + action_width + initial_gap; requisition->height = tab_height; break; @@ -2184,7 +2195,7 @@ gtk_notebook_get_preferred_tabs_size (GtkNotebook *notebook, action_height += action_widget_requisition[ACTION_WIDGET_START].height; action_height += action_widget_requisition[ACTION_WIDGET_END].height; - requisition->height = tab_height + tab_overlap + action_height; + requisition->height = tab_height + tab_overlap + action_height + initial_gap; requisition->height = MAX (requisition->height, tab_max + tab_overlap); @@ -2493,6 +2504,7 @@ gtk_notebook_size_allocate (GtkWidget *widget, { case GTK_POS_TOP: child_allocation.y += priv->cur_page->requisition.height; + /* fall thru */ case GTK_POS_BOTTOM: child_allocation.height = MAX (1, child_allocation.height - @@ -2500,6 +2512,7 @@ gtk_notebook_size_allocate (GtkWidget *widget, break; case GTK_POS_LEFT: child_allocation.x += priv->cur_page->requisition.width; + /* fall thru */ case GTK_POS_RIGHT: child_allocation.width = MAX (1, child_allocation.width - @@ -2807,14 +2820,14 @@ gtk_notebook_arrow_button_press (GtkNotebook *notebook, priv->button = button; priv->click_child = arrow; - if (button == 1) + if (button == GDK_BUTTON_PRIMARY) { gtk_notebook_do_arrow (notebook, arrow); gtk_notebook_set_scroll_timer (notebook); } - else if (button == 2) + else if (button == GDK_BUTTON_MIDDLE) gtk_notebook_page_select (notebook, TRUE); - else if (button == 3) + else if (button == GDK_BUTTON_SECONDARY) gtk_notebook_switch_focus_tab (notebook, gtk_notebook_search_page (notebook, NULL, @@ -2914,7 +2927,7 @@ gtk_notebook_button_press (GtkWidget *widget, return TRUE; } - if (event->button != 1) + if (event->button != GDK_BUTTON_PRIMARY) return FALSE; priv->button = event->button; @@ -3113,7 +3126,7 @@ show_drag_window (GtkNotebook *notebook, priv->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gdk_window_set_user_data (priv->drag_window, widget); + gtk_widget_register_window (widget, priv->drag_window); gdk_window_set_background_rgba (priv->drag_window, &transparent); } @@ -3148,11 +3161,8 @@ hide_drag_window (GtkNotebook *notebook, { g_object_ref (page->tab_label); - if (GTK_IS_WINDOW (parent)) - { - /* parent widget is the drag window */ - gtk_container_remove (GTK_CONTAINER (parent), page->tab_label); - } + if (GTK_IS_WINDOW (parent)) /* parent widget is the drag window */ + gtk_container_remove (GTK_CONTAINER (parent), page->tab_label); else gtk_widget_unparent (page->tab_label); @@ -3185,7 +3195,7 @@ gtk_notebook_stop_reorder (GtkNotebook *notebook) { if (priv->during_reorder) { - gint old_page_num, page_num; + gint old_page_num, page_num, i; GList *element; element = get_drop_position (notebook); @@ -3194,9 +3204,16 @@ gtk_notebook_stop_reorder (GtkNotebook *notebook) gtk_notebook_child_reordered (notebook, page); if (priv->has_scrolled || old_page_num != page_num) - g_signal_emit (notebook, - notebook_signals[PAGE_REORDERED], 0, - page->child, page_num); + { + for (element = priv->children, i = 0; element; element = element->next, i++) + { + if (MIN (old_page_num, page_num) <= i && i <= MAX (old_page_num, page_num)) + gtk_widget_child_notify (((GtkNotebookPage *) element->data)->child, "position"); + } + g_signal_emit (notebook, + notebook_signals[PAGE_REORDERED], 0, + page->child, page_num); + } priv->has_scrolled = FALSE; priv->during_reorder = FALSE; @@ -3682,20 +3699,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; @@ -3716,6 +3733,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); @@ -3727,7 +3746,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); @@ -3740,6 +3761,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; @@ -3751,7 +3774,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 { @@ -3766,11 +3789,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); @@ -3783,14 +3814,11 @@ gtk_notebook_drag_motion (GtkWidget *widget, } else { - if (priv->switch_tab_timer) - { - g_source_remove (priv->switch_tab_timer); - priv->switch_tab_timer = 0; - } + remove_switch_tab_timer (notebook); } - return (target == tab_target) ? TRUE : FALSE; + out: + return retval; } static void @@ -3799,15 +3827,9 @@ gtk_notebook_drag_leave (GtkWidget *widget, guint time) { GtkNotebook *notebook = GTK_NOTEBOOK (widget); - GtkNotebookPrivate *priv = notebook->priv; - - if (priv->switch_tab_timer) - { - g_source_remove (priv->switch_tab_timer); - priv->switch_tab_timer = 0; - } - stop_scrolling (GTK_NOTEBOOK (widget)); + remove_switch_tab_timer (notebook); + stop_scrolling (notebook); } static gboolean @@ -4097,7 +4119,7 @@ gtk_notebook_remove (GtkContainer *container, GtkNotebook *notebook = GTK_NOTEBOOK (container); GtkNotebookPrivate *priv = notebook->priv; GtkNotebookPage *page; - GList *children; + GList *children, *list; gint page_num = 0; children = priv->children; @@ -4117,8 +4139,15 @@ gtk_notebook_remove (GtkContainer *container, g_object_ref (widget); + list = children->next; gtk_notebook_real_remove (notebook, children); + while (list) + { + gtk_widget_child_notify (((GtkNotebookPage *)list->data)->child, "position"); + list = list->next; + } + g_signal_emit (notebook, notebook_signals[PAGE_REMOVED], 0, @@ -4136,7 +4165,7 @@ focus_tabs_in (GtkNotebook *notebook) if (priv->show_tabs && priv->cur_page) { gtk_widget_grab_focus (GTK_WIDGET (notebook)); - + gtk_notebook_set_focus_child (GTK_CONTAINER (notebook), NULL); gtk_notebook_switch_focus_tab (notebook, g_list_find (priv->children, priv->cur_page)); @@ -4566,6 +4595,7 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook, GtkNotebookPrivate *priv = notebook->priv; GtkNotebookPage *page; gint nchildren; + GList *list; gtk_widget_freeze_child_notify (child); @@ -4648,7 +4678,14 @@ gtk_notebook_real_insert_page (GtkNotebook *notebook, gtk_widget_child_notify (child, "tab-fill"); gtk_widget_child_notify (child, "tab-label"); gtk_widget_child_notify (child, "menu-label"); - gtk_widget_child_notify (child, "position"); + + list = g_list_nth (priv->children, position); + while (list) + { + gtk_widget_child_notify (((GtkNotebookPage *)list->data)->child, "position"); + list = list->next; + } + gtk_widget_thaw_child_notify (child); /* The page-added handler might have reordered the pages, re-get the position */ @@ -4908,7 +4945,23 @@ gtk_notebook_remove_tab_label (GtkNotebook *notebook, page->mnemonic_activate_signal = 0; gtk_widget_set_state_flags (page->tab_label, 0, TRUE); - gtk_widget_unparent (page->tab_label); + if (gtk_widget_get_window (page->tab_label) != gtk_widget_get_window (GTK_WIDGET (notebook)) || + !NOTEBOOK_IS_TAB_LABEL_PARENT (notebook, page)) + { + GtkWidget *parent; + + /* we hit this condition during dnd of a detached tab */ + parent = gtk_widget_get_parent (page->tab_label); + if (GTK_IS_WINDOW (parent)) + gtk_container_remove (GTK_CONTAINER (parent), page->tab_label); + else + gtk_widget_unparent (page->tab_label); + } + else + { + gtk_widget_unparent (page->tab_label); + } + page->tab_label = NULL; } } @@ -4941,6 +4994,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; @@ -6508,11 +6563,6 @@ gtk_notebook_update_tab_states (GtkNotebook *notebook) { GtkRegionFlags current_flags; - if (page == priv->cur_page) - gtk_widget_set_state_flags (page->tab_label, GTK_STATE_FLAG_ACTIVE, FALSE); - else - gtk_widget_unset_state_flags (page->tab_label, GTK_STATE_FLAG_ACTIVE); - /* FIXME: We should store these flags somewhere instead of poking * the widget's path */ if (!gtk_widget_path_iter_has_region (gtk_widget_get_path (page->tab_label), @@ -6520,7 +6570,7 @@ gtk_notebook_update_tab_states (GtkNotebook *notebook) GTK_STYLE_REGION_TAB, ¤t_flags) || current_flags != _gtk_notebook_get_tab_flags (notebook, page)) - gtk_widget_reset_style (page->tab_label); + _gtk_widget_invalidate_style_context (page->tab_label, GTK_CSS_CHANGE_PARENT_STATE); } } } @@ -7985,6 +8035,7 @@ gtk_notebook_reorder_child (GtkNotebook *notebook, GtkNotebookPage *page; gint old_pos; gint max_pos; + gint i; g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); g_return_if_fail (GTK_IS_WIDGET (child)); @@ -8020,7 +8071,12 @@ gtk_notebook_reorder_child (GtkNotebook *notebook, /* Move around the menu items if necessary */ gtk_notebook_child_reordered (notebook, page); - gtk_widget_child_notify (child, "position"); + + for (list = priv->children, i = 0; list; list = list->next, i++) + { + if (MIN (old_pos, position) <= i && i <= MAX (old_pos, position)) + gtk_widget_child_notify (((GtkNotebookPage *) list->data)->child, "position"); + } if (priv->show_tabs) gtk_notebook_pages_allocate (notebook);