This is an automated email from the git hooks/post-receive script. a l e x p u s h e d a c o m m i t t o b r a n c h m a s t e r in repository xfce/thunar.
commit a63b1732d5846652151649073ebe15ac8b0ab2cb Author: Alexander Schwinn <ac...@gmx.de> Date: Tue Nov 14 23:02:58 2017 +0100 Segfault when pressing "folder up" on pathbar (Bug #13987) --- thunar/thunar-location-buttons.c | 318 ++++++++++++++++++++++----------------- 1 file changed, 183 insertions(+), 135 deletions(-) diff --git a/thunar/thunar-location-buttons.c b/thunar/thunar-location-buttons.c index 36847a8..e240039 100644 --- a/thunar/thunar-location-buttons.c +++ b/thunar/thunar-location-buttons.c @@ -51,87 +51,93 @@ enum -static void thunar_location_buttons_navigator_init (ThunarNavigatorIface *iface); -static void thunar_location_buttons_finalize (GObject *object); -static void thunar_location_buttons_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_location_buttons_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static ThunarFile *thunar_location_buttons_get_current_directory (ThunarNavigator *navigator); -static void thunar_location_buttons_set_current_directory (ThunarNavigator *navigator, - ThunarFile *current_directory); -static void thunar_location_buttons_unmap (GtkWidget *widget); -static void thunar_location_buttons_on_filler_clicked (ThunarLocationButtons *buttons); -static void thunar_location_buttons_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural); -static void thunar_location_buttons_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural); -static GtkWidgetPath *thunar_location_buttons_get_path_for_child (GtkContainer *container, - GtkWidget *child); -static void thunar_location_buttons_child_ordering_changed (ThunarLocationButtons *buttons); -static void thunar_location_buttons_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void thunar_location_buttons_state_changed (GtkWidget *widget, - GtkStateType previous_state); -static void thunar_location_buttons_grab_notify (GtkWidget *widget, - gboolean was_grabbed); -static void thunar_location_buttons_add (GtkContainer *container, - GtkWidget *widget); -static void thunar_location_buttons_remove (GtkContainer *container, - GtkWidget *widget); -static void thunar_location_buttons_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); -static GtkWidget *thunar_location_buttons_make_button (ThunarLocationButtons *buttons, - ThunarFile *file); -static void thunar_location_buttons_remove_1 (GtkContainer *container, - GtkWidget *widget); -static gboolean thunar_location_buttons_draw (GtkWidget *buttons, - cairo_t *cr); -static gboolean thunar_location_buttons_scroll_timeout (gpointer user_data); -static void thunar_location_buttons_scroll_timeout_destroy (gpointer user_data); -static void thunar_location_buttons_stop_scrolling (ThunarLocationButtons *buttons); -static void thunar_location_buttons_update_sliders (ThunarLocationButtons *buttons); -static gboolean thunar_location_buttons_slider_button_press (GtkWidget *button, - GdkEventButton *event, - ThunarLocationButtons *buttons); -static gboolean thunar_location_buttons_slider_button_release (GtkWidget *button, - GdkEventButton *event, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_scroll_left (GtkWidget *button, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_scroll_right (GtkWidget *button, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_clicked (ThunarLocationButton *button, - gboolean open_in_tab, - ThunarLocationButtons *buttons); -static gboolean thunar_location_buttons_context_menu (ThunarLocationButton *button, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_gone (ThunarLocationButton *button, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_create_folder (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_down_folder (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_empty_trash (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_open (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_open_in_new_tab (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_open_in_new_window (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_paste_into_folder (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_properties (GtkAction *action, - ThunarLocationButtons *buttons); +static void thunar_location_buttons_navigator_init (ThunarNavigatorIface *iface); +static void thunar_location_buttons_finalize (GObject *object); +static void thunar_location_buttons_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_location_buttons_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static ThunarFile *thunar_location_buttons_get_current_directory (ThunarNavigator *navigator); +static void thunar_location_buttons_set_current_directory (ThunarNavigator *navigator, + ThunarFile *current_directory); +static void thunar_location_buttons_unmap (GtkWidget *widget); +static void thunar_location_buttons_on_filler_clicked (ThunarLocationButtons *buttons); +static void thunar_location_buttons_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural); +static void thunar_location_buttons_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural); +static GtkWidgetPath *thunar_location_buttons_get_path_for_child (GtkContainer *container, + GtkWidget *child); +static void thunar_location_buttons_child_ordering_changed (ThunarLocationButtons *buttons); +static GList *thunar_location_buttons_detect_first_visible_button (ThunarLocationButtons *buttons, + gint available_width, + gint *resulting_occupied_width); +static GList *thunar_location_buttons_detect_last_visible_button (ThunarLocationButtons *buttons, + gint available_width, + gint *resulting_occupied_width); +static void thunar_location_buttons_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static void thunar_location_buttons_state_changed (GtkWidget *widget, + GtkStateType previous_state); +static void thunar_location_buttons_grab_notify (GtkWidget *widget, + gboolean was_grabbed); +static void thunar_location_buttons_add (GtkContainer *container, + GtkWidget *widget); +static void thunar_location_buttons_remove (GtkContainer *container, + GtkWidget *widget); +static void thunar_location_buttons_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); +static GtkWidget *thunar_location_buttons_make_button (ThunarLocationButtons *buttons, + ThunarFile *file); +static void thunar_location_buttons_remove_1 (GtkContainer *container, + GtkWidget *widget); +static gboolean thunar_location_buttons_draw (GtkWidget *buttons, + cairo_t *cr); +static gboolean thunar_location_buttons_scroll_timeout (gpointer user_data); +static void thunar_location_buttons_scroll_timeout_destroy (gpointer user_data); +static void thunar_location_buttons_stop_scrolling (ThunarLocationButtons *buttons); +static void thunar_location_buttons_update_sliders (ThunarLocationButtons *buttons); +static gboolean thunar_location_buttons_slider_button_press (GtkWidget *button, + GdkEventButton *event, + ThunarLocationButtons *buttons); +static gboolean thunar_location_buttons_slider_button_release (GtkWidget *button, + GdkEventButton *event, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_scroll_left (GtkWidget *button, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_scroll_right (GtkWidget *button, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_clicked (ThunarLocationButton *button, + gboolean open_in_tab, + ThunarLocationButtons *buttons); +static gboolean thunar_location_buttons_context_menu (ThunarLocationButton *button, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_gone (ThunarLocationButton *button, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_create_folder (GtkAction *action, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_down_folder (GtkAction *action, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_empty_trash (GtkAction *action, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_open (GtkAction *action, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_open_in_new_tab (GtkAction *action, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_open_in_new_window (GtkAction *action, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_paste_into_folder (GtkAction *action, + ThunarLocationButtons *buttons); +static void thunar_location_buttons_action_properties (GtkAction *action, + ThunarLocationButtons *buttons); @@ -159,7 +165,8 @@ struct _ThunarLocationButtons GList *list; GList *fake_root_button; - guint scroll_count; + GList *first_visible_button; + GList *last_visible_button; guint scroll_timeout_id; }; @@ -434,8 +441,9 @@ thunar_location_buttons_set_current_directory (ThunarNavigator *navigator, while (buttons->list != NULL) gtk_container_remove (GTK_CONTAINER (buttons), buttons->list->data); - /* clear scroll count and fake root buttons */ - buttons->scroll_count = 0; + /* clear scroll positions and fake root button */ + buttons->first_visible_button = NULL; + buttons->last_visible_button = NULL; buttons->fake_root_button = NULL; } @@ -618,6 +626,58 @@ thunar_location_buttons_child_ordering_changed (ThunarLocationButtons *location_ +static GList* +thunar_location_buttons_detect_first_visible_button (ThunarLocationButtons *buttons, + gint available_width, + gint *resulting_occupied_width) +{ + GList *lp; + gint button_width = 0; + gint resulting_width = 0; + + /* walk all buttons starting by last, until no space is left */ + for (lp = buttons->last_visible_button; lp != NULL; lp = lp->next) + { + gtk_widget_get_preferred_width (GTK_WIDGET (lp->data), &button_width, NULL); + if (resulting_width + button_width > available_width) + { + return lp->prev; + } + resulting_width += button_width; + if(resulting_occupied_width != NULL) + *resulting_occupied_width = resulting_width; + } + return g_list_last (buttons->list); +} + + + +static GList* +thunar_location_buttons_detect_last_visible_button (ThunarLocationButtons *buttons, + gint available_width, + gint *resulting_occupied_width) +{ + GList *lp; + gint button_width = 0; + gint resulting_width = 0; + + /* walk all buttons starting by first, until no space is left */ + for (lp = buttons->first_visible_button; lp != NULL; lp = lp->prev) + { + gtk_widget_get_preferred_width (GTK_WIDGET (lp->data), &button_width, NULL); + if (resulting_width + button_width > available_width) + { + return lp->next; + } + resulting_width += button_width; + if(resulting_occupied_width != NULL) + *resulting_occupied_width = resulting_width; + } + return buttons->list; +} + + + static void thunar_location_buttons_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -629,13 +689,10 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, GtkAllocation first_slider_allocation; /* left slider if direction is LTR */ GtkAllocation second_slider_allocation; /* right slider if direction is LTR */ GtkAllocation filler_allocation; - GList *first_button = g_list_last (buttons->list); - GList *last_button = buttons->list; GList *lp; gint required_width_total = 0; gint border_width; gint temp_width; - guint scroll_index; gboolean need_reorder = FALSE; gtk_widget_set_allocation (widget, allocation); @@ -674,10 +731,6 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, filler_allocation.height = available_space.height; filler_allocation.y = available_space.y; - /* set default for first button */ - if (G_LIKELY (buttons->fake_root_button != NULL)) - first_button = buttons->fake_root_button; - for (lp = buttons->list; lp != NULL; lp = lp->next) { gtk_widget_get_preferred_width (GTK_WIDGET (lp->data), &temp_width, NULL); @@ -688,41 +741,38 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, if ( required_width_total <= available_space.width ) { - /* reset the scroll position */ - buttons->scroll_count = 0; + /* Show full list of buttons, starting by fake root, if available */ + if (buttons->fake_root_button == NULL) + buttons->first_visible_button = g_list_last (buttons->list); + else + buttons->first_visible_button = buttons->fake_root_button; + buttons->last_visible_button = buttons->list; } else { /* reset calculation for required_width_total .. we need to cut off some folders */ required_width_total = first_slider_allocation.width + second_slider_allocation.width + filler_allocation.width; - if (G_UNLIKELY (buttons->scroll_count != 0)) - { - for (scroll_index = 0; scroll_index < buttons->scroll_count ; scroll_index++) - last_button = last_button->next; - } + /* No scrolling defined ? Use last button as fixed start! */ + if(buttons->last_visible_button == NULL && buttons->first_visible_button == NULL) + buttons->last_visible_button = buttons->list; - /* find last button for available width */ - for (lp = last_button; lp != NULL; lp = lp->next) - { - gtk_widget_get_preferred_width (GTK_WIDGET (lp->data), &temp_width, NULL); - if ( required_width_total + temp_width > available_space.width) - { - first_button = lp->prev; - break; - } - required_width_total += temp_width; - } + if(buttons->first_visible_button == NULL) /* last button is fixed defined */ + buttons->first_visible_button = thunar_location_buttons_detect_first_visible_button(buttons, available_space.width - required_width_total, &temp_width); + else /* first button is fixed defined */ + buttons->last_visible_button = thunar_location_buttons_detect_last_visible_button(buttons, available_space.width - required_width_total, &temp_width); + + required_width_total += temp_width; } - /* hide buttons before first_button */ - for (lp = first_button->next; lp != NULL; lp = lp->next) + /* hide buttons before first_visible_button */ + for (lp = buttons->first_visible_button->next; lp != NULL; lp = lp->next) { need_reorder |= gtk_widget_get_child_visible (GTK_WIDGET (lp->data)) == TRUE; gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE); } - /* hide buttons after last button */ - for (lp = last_button->prev; lp != NULL; lp = lp->prev) + /* hide buttons after last visible_button */ + for (lp = buttons->last_visible_button->prev; lp != NULL; lp = lp->prev) { need_reorder |= gtk_widget_get_child_visible (GTK_WIDGET (lp->data)) == TRUE; gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE); @@ -741,7 +791,7 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, folder_button_allocation.x = first_slider_allocation.x; } - for (lp = first_button; lp != NULL; lp = lp->prev) + for (lp = buttons->first_visible_button; lp != NULL; lp = lp->prev) { gtk_widget_get_preferred_width (GTK_WIDGET (lp->data), &folder_button_allocation.width, NULL); @@ -755,7 +805,7 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, if (G_LIKELY (direction == GTK_TEXT_DIR_LTR)) folder_button_allocation.x += folder_button_allocation.width; - if( lp == last_button ) + if( lp == buttons->last_visible_button ) break; } @@ -1051,8 +1101,6 @@ static void thunar_location_buttons_scroll_left (GtkWidget *button, ThunarLocationButtons *buttons) { - GList *lp; - if (G_UNLIKELY (buttons->ignore_click)) { buttons->ignore_click = FALSE; @@ -1060,15 +1108,13 @@ thunar_location_buttons_scroll_left (GtkWidget *button, } gtk_widget_queue_resize (GTK_WIDGET (buttons)); - - for (lp = g_list_last (buttons->list); lp != NULL; lp = lp->prev) - if (lp->prev != NULL && gtk_widget_get_child_visible (GTK_WIDGET (lp->prev->data))) - { - if (lp->prev == buttons->fake_root_button) - buttons->fake_root_button = NULL; - buttons->scroll_count ++; - break; - } + if (buttons->first_visible_button->next != NULL) + { + if (buttons->first_visible_button == buttons->fake_root_button) + buttons->fake_root_button = NULL; + buttons->first_visible_button = buttons->first_visible_button->next; + buttons->last_visible_button = NULL; + } } @@ -1084,8 +1130,11 @@ thunar_location_buttons_scroll_right (GtkWidget *button, } gtk_widget_queue_resize (GTK_WIDGET (buttons)); - if ( buttons->scroll_count > 0 ) - buttons->scroll_count--; + if (buttons->last_visible_button->prev != NULL) + { + buttons->last_visible_button = buttons->last_visible_button->prev; + buttons->first_visible_button = NULL; + } } @@ -1125,13 +1174,12 @@ thunar_location_buttons_clicked (ThunarLocationButton *button, /* check if the button is visible on the button bar */ if (!gtk_widget_get_child_visible (GTK_WIDGET (button))) { -// ########## -// FIXME: The auto-scroll feature currently is disabled, since on horizontal small windows it can produce graphical glitches and even seg.faults. To be fixed. -// ########## -// buttons->scroll_count = 0; -// /* scroll left till the button is visible */ -// while(!gtk_widget_get_child_visible (GTK_WIDGET (button)) && buttons->scroll_count < g_list_length(buttons->list) ) -// thunar_location_buttons_scroll_left (buttons->left_slider, buttons); + for (lp = buttons->list; lp != NULL; lp = lp->next) + { + if( lp->data == button ) + buttons->first_visible_button = lp; + } + buttons->last_visible_button = NULL; } /* update all buttons */ -- To stop receiving notification emails like this one, please contact the administrator of this repository. _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org https://mail.xfce.org/mailman/listinfo/xfce4-commits