From a90fb8a4d9c9c21507917cbaa7b4b050c50092be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20K=C3=BCmmerlin?= <rgcjonas@gmail.com> Date: Wed, 19 Aug 2015 15:45:42 +0200 Subject: [PATCH] thunar-location-buttons: Modernize No more deprecated APIs (modulo GtkAction) and now looking gorgeous using linked buttons. --- thunar/thunar-location-button.c | 351 +++++++++++-------------------- thunar/thunar-location-button.h | 6 - thunar/thunar-location-buttons.c | 261 +++++++++++++++++------ 3 files changed, 330 insertions(+), 288 deletions(-) diff --git a/thunar/thunar-location-button.c b/thunar/thunar-location-button.c index e143cec41..b843adbab 100644 --- a/thunar/thunar-location-button.c +++ b/thunar/thunar-location-button.c @@ -40,11 +40,14 @@ +#define THUNAR_LOCATION_BUTTON_MAX_WIDTH 250 + + + /* Property identifiers */ enum { PROP_0, - PROP_ACTIVE, PROP_FILE, }; @@ -52,7 +55,6 @@ enum enum { CLICKED, - CONTEXT_MENU, GONE, LAST_SIGNAL, }; @@ -68,68 +70,59 @@ static void thunar_location_button_set_property (GObject guint prop_id, const GValue *value, GParamSpec *pspec); -static void thunar_location_button_style_set (GtkWidget *widget, - GtkStyle *previous_style); static GdkDragAction thunar_location_button_get_dest_actions (ThunarLocationButton *location_button, GdkDragContext *context, GtkWidget *button, guint timestamp); +static void thunar_location_button_active_changed (ThunarLocationButton *location_button); static void thunar_location_button_file_changed (ThunarLocationButton *location_button, ThunarFile *file); static void thunar_location_button_file_destroy (ThunarLocationButton *location_button, ThunarFile *file); -static void thunar_location_button_align_size_request (GtkWidget *align, - GtkRequisition *requisition, - ThunarLocationButton *location_button); +static void thunar_location_button_apply_label_size (ThunarLocationButton *location_button); static gboolean thunar_location_button_button_press_event (GtkWidget *button, - GdkEventButton *event, - ThunarLocationButton *location_button); + GdkEventButton *event); static gboolean thunar_location_button_button_release_event (GtkWidget *button, - GdkEventButton *event, - ThunarLocationButton *location_button); + GdkEventButton *event); static gboolean thunar_location_button_drag_drop (GtkWidget *button, GdkDragContext *context, gint x, gint y, - guint timestamp, - ThunarLocationButton *location_button); + guint timestamp); static void thunar_location_button_drag_data_get (GtkWidget *button, GdkDragContext *context, GtkSelectionData *selection_data, guint info, - guint timestamp, - ThunarLocationButton *location_button); + guint timestamp); static void thunar_location_button_drag_data_received (GtkWidget *button, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, - guint timestamp, - ThunarLocationButton *location_button); + guint timestamp); static void thunar_location_button_drag_leave (GtkWidget *button, GdkDragContext *context, - guint timestamp, - ThunarLocationButton *location_button); + guint timestamp); static gboolean thunar_location_button_drag_motion (GtkWidget *button, GdkDragContext *context, gint x, gint y, - guint timestamp, - ThunarLocationButton *location_button); + guint timestamp); static gboolean thunar_location_button_enter_timeout (gpointer user_data); static void thunar_location_button_enter_timeout_destroy (gpointer user_data); +static void thunar_location_button_clicked (ThunarLocationButton *button); struct _ThunarLocationButtonClass { - GtkAlignmentClass __parent__; + GtkToggleButtonClass __parent__; }; struct _ThunarLocationButton { - GtkAlignment __parent__; + GtkToggleButton __parent__; GtkWidget *image; GtkWidget *label; @@ -146,7 +139,6 @@ struct _ThunarLocationButton guint drop_occurred : 1; /* public properties */ - guint active : 1; ThunarFile *file; }; @@ -161,7 +153,7 @@ static guint location_button_signals[LAST_SIGNAL]; -G_DEFINE_TYPE (ThunarLocationButton, thunar_location_button, GTK_TYPE_ALIGNMENT) +G_DEFINE_TYPE (ThunarLocationButton, thunar_location_button, GTK_TYPE_TOGGLE_BUTTON) @@ -176,22 +168,6 @@ thunar_location_button_class_init (ThunarLocationButtonClass *klass) gobject_class->get_property = thunar_location_button_get_property; gobject_class->set_property = thunar_location_button_set_property; - gtkwidget_class = GTK_WIDGET_CLASS (klass); - gtkwidget_class->style_set = thunar_location_button_style_set; - - /** - * ThunarLocationButton:active: - * - * Whether the location button is currently active. - **/ - g_object_class_install_property (gobject_class, - PROP_ACTIVE, - g_param_spec_boolean ("active", - "active", - "active", - FALSE, - EXO_PARAM_READWRITE)); - /** * ThunarLocationButton:file: * @@ -206,15 +182,14 @@ thunar_location_button_class_init (ThunarLocationButtonClass *klass) EXO_PARAM_READWRITE)); /** - * ThunarLocationButton::clicked: + * ThunarLocationButton::location-button-clicked: * @location_button : a #ThunarLocationButton. * * Emitted by @location_button when the user clicks on the - * @location_button or thunar_location_button_clicked() is - * called. + * @location_button or gtk_button_clicked() is called. **/ location_button_signals[CLICKED] = - g_signal_new (I_("clicked"), + g_signal_new (I_("location-button-clicked"), G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, @@ -222,22 +197,6 @@ thunar_location_button_class_init (ThunarLocationButtonClass *klass) G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - /** - * ThunarLocationButton::context-menu: - * @location_button : a #ThunarLocationButton. - * @event : a #GdkEventButton. - * - * Emitted by @location_button when the user requests to open - * the context menu for @location_button. - **/ - location_button_signals[CONTEXT_MENU] = - g_signal_new (I_("context-menu"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, GDK_TYPE_EVENT); - /** * ThunarLocationButton::gone: * @location_button : a #ThunarLocationButton. @@ -257,52 +216,40 @@ thunar_location_button_class_init (ThunarLocationButtonClass *klass) static void -thunar_location_button_init (ThunarLocationButton *location_button) +thunar_location_button_init (ThunarLocationButton *button) { - GtkWidget *align; - GtkWidget *button; GtkWidget *hbox; - /* create the toggle button */ - button = gtk_toggle_button_new (); - gtk_widget_set_can_focus (button, FALSE); - g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (thunar_location_button_clicked), location_button); - exo_mutual_binding_new (G_OBJECT (location_button), "active", G_OBJECT (button), "active"); - gtk_container_add (GTK_CONTAINER (location_button), button); - gtk_widget_show (button); + /* initialize the toggle button */ + g_signal_connect (button, "notify::active", G_CALLBACK (thunar_location_button_active_changed), NULL); + g_signal_connect (button, "clicked", G_CALLBACK (thunar_location_button_clicked), NULL); /* setup drag support for the button */ gtk_drag_source_set (GTK_WIDGET (button), GDK_BUTTON1_MASK, drag_targets, G_N_ELEMENTS (drag_targets), GDK_ACTION_LINK); gtk_drag_dest_set (GTK_WIDGET (button), GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_MOTION, drag_targets, G_N_ELEMENTS (drag_targets), GDK_ACTION_ASK | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE); - g_signal_connect (G_OBJECT (button), "button-press-event", G_CALLBACK (thunar_location_button_button_press_event), location_button); - g_signal_connect (G_OBJECT (button), "button-release-event", G_CALLBACK (thunar_location_button_button_release_event), location_button); - g_signal_connect (G_OBJECT (button), "drag-drop", G_CALLBACK (thunar_location_button_drag_drop), location_button); - g_signal_connect (G_OBJECT (button), "drag-data-get", G_CALLBACK (thunar_location_button_drag_data_get), location_button); - g_signal_connect (G_OBJECT (button), "drag-data-received", G_CALLBACK (thunar_location_button_drag_data_received), location_button); - g_signal_connect (G_OBJECT (button), "drag-leave", G_CALLBACK (thunar_location_button_drag_leave), location_button); - g_signal_connect (G_OBJECT (button), "drag-motion", G_CALLBACK (thunar_location_button_drag_motion), location_button); + g_signal_connect (G_OBJECT (button), "button-press-event", G_CALLBACK (thunar_location_button_button_press_event), NULL); + g_signal_connect (G_OBJECT (button), "button-release-event", G_CALLBACK (thunar_location_button_button_release_event), NULL); + g_signal_connect (G_OBJECT (button), "drag-drop", G_CALLBACK (thunar_location_button_drag_drop), NULL); + g_signal_connect (G_OBJECT (button), "drag-data-get", G_CALLBACK (thunar_location_button_drag_data_get), NULL); + g_signal_connect (G_OBJECT (button), "drag-data-received", G_CALLBACK (thunar_location_button_drag_data_received), NULL); + g_signal_connect (G_OBJECT (button), "drag-leave", G_CALLBACK (thunar_location_button_drag_leave), NULL); + g_signal_connect (G_OBJECT (button), "drag-motion", G_CALLBACK (thunar_location_button_drag_motion), NULL); /* create the horizontal box */ - hbox = gtk_hbox_new (FALSE, 2); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); gtk_container_add (GTK_CONTAINER (button), hbox); gtk_widget_show (hbox); /* create the button image */ - location_button->image = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (hbox), location_button->image, TRUE, FALSE, 0); - gtk_widget_show (location_button->image); - - /* create the button label alignment */ - align = gtk_alignment_new (0.5f, 0.5f, 1.0f, 1.0f); - g_signal_connect (G_OBJECT (align), "size-request", G_CALLBACK (thunar_location_button_align_size_request), location_button); - gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, 0); - gtk_widget_show (align); + button->image = gtk_image_new (); + gtk_box_pack_start (GTK_BOX (hbox), button->image, TRUE, FALSE, 0); + gtk_widget_show (button->image); /* create the button label */ - location_button->label = g_object_new (GTK_TYPE_LABEL, NULL); - gtk_container_add (GTK_CONTAINER (align), location_button->label); - gtk_widget_show (location_button->label); + button->label = g_object_new (GTK_TYPE_LABEL, "xalign", 0.5f, "yalign", 0.5f, NULL); + gtk_box_pack_start (GTK_BOX (hbox), button->label, TRUE, TRUE, 0); + gtk_widget_show (button->label); } @@ -337,10 +284,6 @@ thunar_location_button_get_property (GObject *object, switch (prop_id) { - case PROP_ACTIVE: - g_value_set_boolean (value, thunar_location_button_get_active (location_button)); - break; - case PROP_FILE: g_value_set_object (value, thunar_location_button_get_file (location_button)); break; @@ -363,10 +306,6 @@ thunar_location_button_set_property (GObject *object, switch (prop_id) { - case PROP_ACTIVE: - thunar_location_button_set_active (location_button, g_value_get_boolean (value)); - break; - case PROP_FILE: thunar_location_button_set_file (location_button, g_value_get_object (value)); break; @@ -379,21 +318,6 @@ thunar_location_button_set_property (GObject *object, -static void -thunar_location_button_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - ThunarLocationButton *location_button = THUNAR_LOCATION_BUTTON (widget); - - /* update the user interface if we have a file */ - if (G_LIKELY (location_button->file != NULL)) - thunar_location_button_file_changed (location_button, location_button->file); - - (*GTK_WIDGET_CLASS (thunar_location_button_parent_class)->style_set) (widget, previous_style); -} - - - static GdkDragAction thunar_location_button_get_dest_actions (ThunarLocationButton *location_button, GdkDragContext *context, @@ -442,22 +366,25 @@ thunar_location_button_file_changed (ThunarLocationButton *location_button, /* update and show the label widget (hide for the local root folder) */ if (thunar_file_is_local (file) && thunar_file_is_root (file)) { - /* hide the alignment in which the label would otherwise show up */ - gtk_widget_hide (gtk_widget_get_parent (location_button->label)); + /* hide the label would otherwise show up */ + gtk_widget_hide (location_button->label); } else { - /* set label to the file's display name and show the alignment (and thereby the label) */ + /* set label to the file's display name and show the label */ gtk_label_set_text (GTK_LABEL (location_button->label), thunar_file_get_display_name (file)); - gtk_widget_show (gtk_widget_get_parent (location_button->label)); + + /* set the label's size request in such a way that a bold label will not change the button size */ + thunar_location_button_apply_label_size (location_button); + + gtk_widget_show (location_button->label); } /* the image is only visible for certain special paths */ if (thunar_file_is_home (file) || thunar_file_is_desktop (file) || thunar_file_is_root (file)) { /* determine the icon size for menus (to be compatible with GtkPathBar) */ - settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (location_button))); - if (gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &width, &height)) + if (gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height)) size = MAX (width, height); else size = 16; @@ -485,12 +412,12 @@ thunar_location_button_file_changed (ThunarLocationButton *location_button, custom_icon = thunar_file_get_custom_icon (file); if (custom_icon != NULL) { - gtk_drag_source_set_icon_name (gtk_bin_get_child (GTK_BIN (location_button)), custom_icon); + gtk_drag_source_set_icon_name (GTK_WIDGET (location_button), custom_icon); } else { icon_name = thunar_file_get_icon_name (file, location_button->file_icon_state, icon_theme); - gtk_drag_source_set_icon_name (gtk_bin_get_child (GTK_BIN (location_button)), icon_name); + gtk_drag_source_set_icon_name (GTK_WIDGET (location_button), icon_name); } } @@ -511,45 +438,57 @@ thunar_location_button_file_destroy (ThunarLocationButton *location_button, static void -thunar_location_button_align_size_request (GtkWidget *align, - GtkRequisition *requisition, - ThunarLocationButton *location_button) +thunar_location_button_apply_label_size (ThunarLocationButton *location_button) { - PangoLayout *layout; - gint normal_height; - gint normal_width; - gint bold_height; - gint bold_width; + GtkRequisition normal_size; + GtkRequisition bold_size; + gint width, height; + PangoAttrList *original_attrs; + + original_attrs = pango_attr_list_ref (gtk_label_get_attributes (GTK_LABEL (location_button->label))); - /* allocate a pango layout for the label text */ - layout = gtk_widget_create_pango_layout (location_button->label, gtk_label_get_text (GTK_LABEL (location_button->label))); + /* determine the normal size */ + gtk_label_set_attributes (GTK_LABEL (location_button->label), NULL); + gtk_widget_get_preferred_size (location_button->label, NULL, &normal_size); - /* determine the normal pixel size */ - pango_layout_get_pixel_size (layout, &normal_width, &normal_height); + /* determine the bold size */ + gtk_label_set_attributes (GTK_LABEL (location_button->label), thunar_pango_attr_list_bold()); + gtk_widget_get_preferred_size (location_button->label, NULL, &bold_size); - /* determine the bold pixel size */ - pango_layout_set_attributes (layout, thunar_pango_attr_list_bold ()); - pango_layout_get_pixel_size (layout, &bold_width, &bold_height); + /* restore original attributes */ + gtk_label_set_attributes (GTK_LABEL (location_button->label), original_attrs); + pango_attr_list_unref (original_attrs); /* request the maximum of the pixel sizes, to make sure * the button always requests the same size, no matter if * the label is bold or not. */ - requisition->width = MAX (bold_width, normal_width); - requisition->height = MAX (bold_height, normal_height); + width = MAX (normal_size.width, bold_size.width); + height = MAX (normal_size.height, bold_size.height); - /* cleanup */ - g_object_unref (G_OBJECT (layout)); + if (width >= THUNAR_LOCATION_BUTTON_MAX_WIDTH) + { + /* if the size is too big, enable ellipsizing */ + gtk_label_set_ellipsize (GTK_LABEL (location_button->label), PANGO_ELLIPSIZE_MIDDLE); + gtk_widget_set_size_request (GTK_WIDGET (location_button->label), THUNAR_LOCATION_BUTTON_MAX_WIDTH, height); + } + else + { + /* don't enable ellipsizing: In some borderline cases, the size calculated + * is actually off by 1 or 2 pixels and the label will ellipsize unnecessarily + * TODO: check what we did wrong */ + gtk_widget_set_size_request (GTK_WIDGET (location_button->label), width, height); + } } static gboolean thunar_location_button_button_press_event (GtkWidget *button, - GdkEventButton *event, - ThunarLocationButton *location_button) + GdkEventButton *event) { - _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (button), FALSE); + gboolean popup_menu_return; /* check if we can handle the button event */ if (G_UNLIKELY (event->button == 2)) @@ -559,8 +498,8 @@ thunar_location_button_button_press_event (GtkWidget *button, } else if (event->button == 3) { - /* emit the "context-menu" signal and let the surrounding ThunarLocationButtons popup a menu */ - g_signal_emit (G_OBJECT (location_button), location_button_signals[CONTEXT_MENU], 0, event); + /* emit the "popup-menu" signal and let the surrounding ThunarLocationButtons popup a menu */ + g_signal_emit_by_name (G_OBJECT (button), "popup-menu", &popup_menu_return); return TRUE; } @@ -571,14 +510,13 @@ thunar_location_button_button_press_event (GtkWidget *button, static gboolean thunar_location_button_button_release_event (GtkWidget *button, - GdkEventButton *event, - ThunarLocationButton *location_button) + GdkEventButton *event) { ThunarApplication *application; ThunarPreferences *preferences; gboolean open_in_tab; - _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (button), FALSE); /* reset inconsistent button state after releasing the middle-mouse-button */ if (G_UNLIKELY (event->button == 2)) @@ -587,7 +525,7 @@ thunar_location_button_button_release_event (GtkWidget *button, gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), FALSE); /* verify that we still have a valid file */ - if (G_LIKELY (location_button->file != NULL)) + if (G_LIKELY (THUNAR_LOCATION_BUTTON (button)->file != NULL)) { preferences = thunar_preferences_get (); g_object_get (preferences, "misc-middle-click-in-tab", &open_in_tab, NULL); @@ -596,13 +534,13 @@ thunar_location_button_button_release_event (GtkWidget *button, if (open_in_tab) { /* open in tab */ - g_signal_emit (G_OBJECT (location_button), location_button_signals[CLICKED], 0, TRUE); + g_signal_emit_by_name (G_OBJECT (button), "location-button-clicked", 0, TRUE); } else { /* open a new window for the folder */ application = thunar_application_get (); - thunar_application_open_window (application, location_button->file, gtk_widget_get_screen (GTK_WIDGET (location_button)), NULL); + thunar_application_open_window (application, THUNAR_LOCATION_BUTTON (button)->file, gtk_widget_get_screen (button), NULL); g_object_unref (G_OBJECT (application)); } } @@ -618,13 +556,12 @@ thunar_location_button_drag_drop (GtkWidget *button, GdkDragContext *context, gint x, gint y, - guint timestamp, - ThunarLocationButton *location_button) + guint timestamp) { GdkAtom target; _thunar_return_val_if_fail (GTK_IS_WIDGET (button), FALSE); - _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (button), FALSE); /* determine the DnD target and see if we can handle it */ target = gtk_drag_dest_find_target (button, context, NULL); @@ -634,7 +571,7 @@ thunar_location_button_drag_drop (GtkWidget *button, /* set state so drag-data-received knows that * this is really a drop this time. */ - location_button->drop_occurred = TRUE; + THUNAR_LOCATION_BUTTON (button)->drop_occurred = TRUE; /* request the drag data from the source */ gtk_drag_get_data (button, context, target, timestamp); @@ -650,21 +587,20 @@ thunar_location_button_drag_data_get (GtkWidget *button, GdkDragContext *context, GtkSelectionData *selection_data, guint info, - guint timestamp, - ThunarLocationButton *location_button) + guint timestamp) { gchar **uris; GList path_list; _thunar_return_if_fail (GTK_IS_WIDGET (button)); - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button)); + _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button)); /* verify that we have a valid file */ - if (G_LIKELY (location_button->file != NULL)) + if (G_LIKELY (THUNAR_LOCATION_BUTTON (button)->file != NULL)) { /* transform the path into an uri list string */ path_list.next = path_list.prev = NULL; - path_list.data = thunar_file_get_file (location_button->file); + path_list.data = thunar_file_get_file (THUNAR_LOCATION_BUTTON (button)->file); /* set the uri list for the drag selection */ uris = thunar_g_file_list_to_stringv (&path_list); @@ -682,12 +618,12 @@ thunar_location_button_drag_data_received (GtkWidget *button, gint y, GtkSelectionData *selection_data, guint info, - guint timestamp, - ThunarLocationButton *location_button) + guint timestamp) { - GdkDragAction actions; - GdkDragAction action; - gboolean succeed = FALSE; + GdkDragAction actions; + GdkDragAction action; + gboolean succeed = FALSE; + ThunarLocationButton *location_button = THUNAR_LOCATION_BUTTON (button); /* check if we don't already know the drop data */ if (G_LIKELY (!location_button->drop_data_ready)) @@ -724,7 +660,7 @@ thunar_location_button_drag_data_received (GtkWidget *button, gtk_drag_finish (context, succeed, FALSE, timestamp); /* disable the highlighting and release the drag data */ - thunar_location_button_drag_leave (button, context, timestamp, location_button); + thunar_location_button_drag_leave (button, context, timestamp); } } @@ -733,11 +669,12 @@ thunar_location_button_drag_data_received (GtkWidget *button, static void thunar_location_button_drag_leave (GtkWidget *button, GdkDragContext *context, - guint timestamp, - ThunarLocationButton *location_button) + guint timestamp) { _thunar_return_if_fail (GTK_IS_BUTTON (button)); - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button)); + _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button)); + + ThunarLocationButton *location_button = THUNAR_LOCATION_BUTTON (button); /* reset the file icon state to default appearance */ if (G_LIKELY (location_button->file_icon_state != THUNAR_FILE_ICON_STATE_DEFAULT)) @@ -770,14 +707,14 @@ thunar_location_button_drag_motion (GtkWidget *button, GdkDragContext *context, gint x, gint y, - guint timestamp, - ThunarLocationButton *location_button) + guint timestamp) { - ThunarFileIconState file_icon_state; - GdkDragAction actions; - GtkSettings *settings; - GdkAtom target; - gint delay; + ThunarFileIconState file_icon_state; + ThunarLocationButton *location_button = THUNAR_LOCATION_BUTTON (button); + GdkDragAction actions; + GtkSettings *settings; + GdkAtom target; + gint delay; _thunar_return_val_if_fail (GTK_IS_BUTTON (button), FALSE); _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button), FALSE); @@ -785,13 +722,15 @@ thunar_location_button_drag_motion (GtkWidget *button, /* schedule the enter timeout if not already done */ if (G_UNLIKELY (location_button->enter_timeout_id == 0)) { - /* we use the gtk-menu-popdown-delay here, which seems to be sane for our purpose */ - settings = gtk_settings_get_for_screen (gtk_widget_get_screen (button)); - g_object_get (G_OBJECT (settings), "gtk-menu-popdown-delay", &delay, NULL); + /* we used to use gtk-menu-popdown-delay here, but this was never right and is now deprecated */ + /* therefore, we hardcode the value instead. */ + delay = 1000; /* schedule the timeout */ - location_button->enter_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, delay, thunar_location_button_enter_timeout, - location_button, thunar_location_button_enter_timeout_destroy); + location_button->enter_timeout_id = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT, delay, + thunar_location_button_enter_timeout, + location_button, + thunar_location_button_enter_timeout_destroy); } /* request the drop on-demand (if we don't have it already) */ @@ -838,8 +777,6 @@ thunar_location_button_enter_timeout (gpointer user_data) { ThunarLocationButton *location_button = THUNAR_LOCATION_BUTTON (user_data); - GDK_THREADS_ENTER (); - /* We emulate a "clicked" event here, because else the buttons * would be destroyed and replaced by new buttons, which causes * the Gtk DND code to dump core once the mouse leaves the area @@ -848,9 +785,7 @@ thunar_location_button_enter_timeout (gpointer user_data) * Besides that, handling this as "clicked" event allows the user * to go back to the initial directory. */ - thunar_location_button_clicked (location_button); - - GDK_THREADS_LEAVE (); + gtk_button_clicked (GTK_BUTTON (location_button)); return FALSE; } @@ -880,44 +815,15 @@ thunar_location_button_new (void) -/** - * thunar_location_button_get_active: - * @location_button : a #ThunarLocationButton. - * - * Returns %TRUE if @location_button is currently active. - * - * Return value: %TRUE if @location_button is currently active. - **/ -gboolean -thunar_location_button_get_active (ThunarLocationButton *location_button) -{ - _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button), FALSE); - return location_button->active; -} - - - -/** - * thunar_location_button_set_active: - * @location_button : a #ThunarLocationButton. - * @active : %TRUE if @location_button should be active. - * - * Sets the active state of @location_button to @active. - **/ -void -thunar_location_button_set_active (ThunarLocationButton *location_button, - gboolean active) +static void +thunar_location_button_active_changed (ThunarLocationButton *location_button) { _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (location_button)); - /* apply the new state */ - location_button->active = active; + gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (location_button)); /* use a bold label for active location buttons */ gtk_label_set_attributes (GTK_LABEL (location_button->label), active ? thunar_pango_attr_list_bold () : NULL); - - /* notify listeners */ - g_object_notify (G_OBJECT (location_button), "active"); } @@ -985,9 +891,8 @@ thunar_location_button_set_file (ThunarLocationButton *location_button, g_signal_connect_swapped (G_OBJECT (file), "changed", G_CALLBACK (thunar_location_button_file_changed), location_button); g_signal_connect_swapped (G_OBJECT (file), "destroy", G_CALLBACK (thunar_location_button_file_destroy), location_button); - /* update our internal state for the new file (if realized) */ - if (gtk_widget_get_realized (GTK_WIDGET (location_button))) - thunar_location_button_file_changed (location_button, file); + /* update our internal state for the new file */ + thunar_location_button_file_changed (location_button, file); } /* notify listeners */ @@ -1000,7 +905,7 @@ thunar_location_button_set_file (ThunarLocationButton *location_button, * thunar_location_button_clicked: * @location_button : a #ThunarLocationButton. * - * Emits the ::clicked signal on @location_button. + * Emits the ::location-button-clicked signal on @location_button. **/ void thunar_location_button_clicked (ThunarLocationButton *location_button) diff --git a/thunar/thunar-location-button.h b/thunar/thunar-location-button.h index f00d4b6e1..adecf9a49 100644 --- a/thunar/thunar-location-button.h +++ b/thunar/thunar-location-button.h @@ -38,16 +38,10 @@ GType thunar_location_button_get_type (void) G_GNUC_CONST; GtkWidget *thunar_location_button_new (void) G_GNUC_MALLOC; -gboolean thunar_location_button_get_active (ThunarLocationButton *location_button); -void thunar_location_button_set_active (ThunarLocationButton *location_button, - gboolean active); - ThunarFile *thunar_location_button_get_file (ThunarLocationButton *location_button); void thunar_location_button_set_file (ThunarLocationButton *location_button, ThunarFile *file); -void thunar_location_button_clicked (ThunarLocationButton *location_button); - G_END_DECLS; #endif /* !__THUNAR_LOCATION_BUTTON_H__ */ diff --git a/thunar/thunar-location-buttons.c b/thunar/thunar-location-buttons.c index 057b91afa..86a063a5b 100644 --- a/thunar/thunar-location-buttons.c +++ b/thunar/thunar-location-buttons.c @@ -79,6 +79,9 @@ static void thunar_location_buttons_get_preferred_width (GtkWidg 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, @@ -97,6 +100,8 @@ static GtkWidget *thunar_location_buttons_make_button (ThunarL 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); @@ -114,8 +119,7 @@ static void thunar_location_buttons_scroll_right (GtkWidg static void thunar_location_buttons_clicked (ThunarLocationButton *button, gboolean open_in_tab, ThunarLocationButtons *buttons); -static void thunar_location_buttons_context_menu (ThunarLocationButton *button, - GdkEventButton *event, +static gboolean thunar_location_buttons_context_menu (ThunarLocationButton *button, ThunarLocationButtons *buttons); static void thunar_location_buttons_gone (ThunarLocationButton *button, ThunarLocationButtons *buttons); @@ -207,6 +211,7 @@ thunar_location_buttons_class_init (ThunarLocationButtonsClass *klass) gobject_class->set_property = thunar_location_buttons_set_property; gtkwidget_class = GTK_WIDGET_CLASS (klass); + gtkwidget_class->draw = thunar_location_buttons_draw; gtkwidget_class->unmap = thunar_location_buttons_unmap; gtkwidget_class->get_preferred_width = thunar_location_buttons_get_preferred_width; gtkwidget_class->get_preferred_height = thunar_location_buttons_get_preferred_height; @@ -218,6 +223,7 @@ thunar_location_buttons_class_init (ThunarLocationButtonsClass *klass) gtkcontainer_class->add = thunar_location_buttons_add; gtkcontainer_class->remove = thunar_location_buttons_remove; gtkcontainer_class->forall = thunar_location_buttons_forall; + gtkcontainer_class->get_path_for_child = thunar_location_buttons_get_path_for_child; /* Override ThunarNavigator's properties */ g_object_class_override_property (gobject_class, PROP_CURRENT_DIRECTORY, "current-directory"); @@ -292,7 +298,7 @@ thunar_location_buttons_init (ThunarLocationButtons *buttons) gtk_container_add (GTK_CONTAINER (buttons), buttons->left_slider); gtk_widget_show (buttons->left_slider); - arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_OUT); + arrow = gtk_image_new_from_icon_name ("pan-start-symbolic", GTK_ICON_SIZE_BUTTON); gtk_container_add (GTK_CONTAINER (buttons->left_slider), arrow); gtk_widget_show (arrow); @@ -303,9 +309,15 @@ thunar_location_buttons_init (ThunarLocationButtons *buttons) gtk_container_add (GTK_CONTAINER (buttons), buttons->right_slider); gtk_widget_show (buttons->right_slider); - arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT); + arrow = gtk_image_new_from_icon_name ("pan-end-symbolic", GTK_ICON_SIZE_BUTTON); gtk_container_add (GTK_CONTAINER (buttons->right_slider), arrow); gtk_widget_show (arrow); + + /* setup style classes */ + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (buttons)), + GTK_STYLE_CLASS_LINKED); + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (buttons)), + "path-bar"); } @@ -479,7 +491,7 @@ thunar_location_buttons_set_current_directory (ThunarNavigator *navigator, if (G_UNLIKELY (lp != NULL)) { /* fake a "clicked" event for that button */ - thunar_location_button_clicked (THUNAR_LOCATION_BUTTON (lp->data)); + gtk_button_clicked (GTK_BUTTON (lp->data)); } else { @@ -503,8 +515,6 @@ thunar_location_buttons_set_current_directory (ThunarNavigator *navigator, { g_object_ref (G_OBJECT (current_directory)); - gtk_widget_push_composite_child (); - /* add the new buttons */ for (file = current_directory; file != NULL; file = file_parent) { @@ -523,8 +533,6 @@ thunar_location_buttons_set_current_directory (ThunarNavigator *navigator, if (G_LIKELY (file != current_directory)) g_object_unref (G_OBJECT (file)); } - - gtk_widget_pop_composite_child (); } } @@ -594,6 +602,108 @@ thunar_location_buttons_get_preferred_height (GtkWidget *widget, +static GtkWidgetPath * +thunar_location_buttons_get_path_for_child (GtkContainer *container, + GtkWidget *child) +{ + ThunarLocationButtons *path_bar = THUNAR_LOCATION_BUTTONS (container); + GtkWidgetPath *path; + + path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (path_bar))); + + if (gtk_widget_get_visible (child) && + gtk_widget_get_child_visible (child)) + { + GtkWidgetPath *sibling_path; + GList *visible_children; + GList *l; + int pos; + + /* 1. Build the list of visible children, in visually left-to-right order + * (i.e. independently of the widget's direction). Note that our + * list is stored in innermost-to-outermost path order! + */ + visible_children = NULL; + + if (gtk_widget_get_visible (path_bar->right_slider) && + gtk_widget_get_child_visible (path_bar->right_slider)) + { + visible_children = g_list_prepend (visible_children, path_bar->right_slider); + } + + for (l = path_bar->list; l; l = l->next) + { + if (gtk_widget_get_visible (GTK_WIDGET (l->data)) && + gtk_widget_get_child_visible (GTK_WIDGET (l->data))) + visible_children = g_list_prepend (visible_children, l->data); + } + + if (gtk_widget_get_visible (path_bar->left_slider) && + gtk_widget_get_child_visible (path_bar->left_slider)) + { + visible_children = g_list_prepend (visible_children, path_bar->left_slider); + } + + if (gtk_widget_get_direction (GTK_WIDGET (path_bar)) == GTK_TEXT_DIR_RTL) + { + visible_children = g_list_reverse (visible_children); + } + + /* 2. Find the index of the child within that list */ + pos = 0; + + for (l = visible_children; l; l = l->next) + { + GtkWidget *button = l->data; + + if (button == child) + break; + + pos++; + } + + /* 3. Build the path */ + sibling_path = gtk_widget_path_new (); + + for (l = visible_children; l; l = l->next) + { + gtk_widget_path_append_for_widget (sibling_path, l->data); + } + + gtk_widget_path_append_with_siblings (path, sibling_path, pos); + + g_list_free (visible_children); + gtk_widget_path_unref (sibling_path); + } + else + { + gtk_widget_path_append_for_widget (path, child); + } + + return path; +} + + + +static void +thunar_location_buttons_child_ordering_changed (ThunarLocationButtons *location_buttons) +{ + GList *lp; + + if (gtk_widget_get_visible (location_buttons->left_slider) && + gtk_widget_get_child_visible (location_buttons->left_slider)) + gtk_widget_reset_style (location_buttons->right_slider); + + if (gtk_widget_get_visible (location_buttons->right_slider) && + gtk_widget_get_child_visible (location_buttons->right_slider)) + gtk_widget_reset_style (location_buttons->right_slider); + + for (lp = location_buttons->list; lp; lp = lp->next) + gtk_widget_reset_style (GTK_WIDGET (lp->data)); +} + + + static void thunar_location_buttons_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -603,6 +713,7 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, GtkAllocation child_allocation; GtkWidget *child; gboolean need_sliders = FALSE; + gboolean need_reorder = FALSE; gboolean reached_end; GList *first_button; GList *lp; @@ -611,8 +722,8 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, gint allocation_width; gint border_width; gint slider_space; - gint spacing; gint width; + GtkRequisition child_requisition; gtk_widget_set_allocation (widget, allocation); @@ -620,21 +731,20 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, if (G_UNLIKELY (buttons->list == NULL)) return; - gtk_widget_style_get (GTK_WIDGET (buttons), "spacing", &spacing, NULL); - direction = gtk_widget_get_direction (widget); border_width = gtk_container_get_border_width (GTK_CONTAINER (buttons)); allocation_width = allocation->width - 2 * border_width; /* check if we need to display the sliders */ if (G_LIKELY (buttons->fake_root_button != NULL)) - width = buttons->slider_width + spacing; + width = buttons->slider_width; else width = 0; for (lp = buttons->list; lp != NULL; lp = lp->next) { - width += thunar_gtk_widget_get_requisition_width (GTK_WIDGET (lp->data)) + spacing; + gtk_widget_get_preferred_size (GTK_WIDGET (lp->data), &child_requisition, NULL); + width += child_requisition.width; if (lp == buttons->fake_root_button) break; } @@ -645,10 +755,13 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, first_button = buttons->fake_root_button; else first_button = g_list_last (buttons->list); + + /* reset the scroll position */ + buttons->first_scrolled_button = NULL; } else { - slider_space = 2 * (spacing + buttons->slider_width); + slider_space = 2 * buttons->slider_width; if (buttons->first_scrolled_button != NULL) first_button = buttons->first_scrolled_button; @@ -660,30 +773,35 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, * We start at the first button, count forward until hit the new * button, then count backwards. */ - width = thunar_gtk_widget_get_requisition_width (GTK_WIDGET (first_button->data)); + gtk_widget_get_preferred_size (GTK_WIDGET (first_button->data), &child_requisition, NULL); + width = child_requisition.width; for (lp = first_button->prev, reached_end = FALSE; lp != NULL && !reached_end; lp = lp->prev) { child = lp->data; - if (width + thunar_gtk_widget_get_requisition_width (child) + spacing + slider_space > allocation_width) + gtk_widget_get_preferred_size (GTK_WIDGET (child), &child_requisition, NULL); + + if (width + child_requisition.width + slider_space > allocation_width) reached_end = TRUE; else if (lp == buttons->fake_root_button) break; else - width += thunar_gtk_widget_get_requisition_width (child) + spacing; + width += child_requisition.width; } while (first_button->next != NULL && !reached_end) { child = first_button->data; - if (width + thunar_gtk_widget_get_requisition_width (child) + spacing + slider_space > allocation_width) + gtk_widget_get_preferred_size (GTK_WIDGET (child), &child_requisition, NULL); + + if (width + child_requisition.width + slider_space > allocation_width) { reached_end = TRUE; } else { - width += thunar_gtk_widget_get_requisition_width (child) + spacing; + width += child_requisition.width; if (first_button == buttons->fake_root_button) break; first_button = first_button->next; @@ -700,7 +818,7 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, child_allocation.x = allocation->x + allocation->width - border_width; if (need_sliders || buttons->fake_root_button != NULL) { - child_allocation.x -= spacing + buttons->slider_width; + child_allocation.x -= buttons->slider_width; left_slider_offset = allocation->width - border_width - buttons->slider_width; } } @@ -710,18 +828,14 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, if (need_sliders || buttons->fake_root_button != NULL) { left_slider_offset = border_width; - child_allocation.x += spacing + buttons->slider_width; + child_allocation.x += buttons->slider_width; } } for (lp = first_button; lp != NULL; lp = lp->prev) { - GtkRequisition child_requisition; - GtkAllocation widget_allocation; - child = lp->data; - gtk_widget_get_requisition (child, &child_requisition); - gtk_widget_get_allocation (widget, &widget_allocation); + gtk_widget_get_preferred_size (child, &child_requisition, NULL); child_allocation.width = child_requisition.width; if (G_UNLIKELY (direction == GTK_TEXT_DIR_RTL)) @@ -730,41 +844,48 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, /* check to see if we don't have any more space to allocate buttons */ if (need_sliders && direction == GTK_TEXT_DIR_RTL) { - if (child_allocation.x - spacing - buttons->slider_width < widget_allocation.x + border_width) + if (child_allocation.x - buttons->slider_width < allocation->x + border_width) break; } else if (need_sliders && direction == GTK_TEXT_DIR_LTR) { - if (child_allocation.x + child_allocation.width + spacing + buttons->slider_width > widget_allocation.x + border_width + allocation_width) + if (child_allocation.x + child_allocation.width + buttons->slider_width > allocation->x + border_width + allocation_width) break; } + need_reorder |= gtk_widget_get_child_visible (GTK_WIDGET (lp->data)) == FALSE; gtk_widget_set_child_visible (GTK_WIDGET (lp->data), TRUE); gtk_widget_size_allocate (child, &child_allocation); if (direction == GTK_TEXT_DIR_RTL) { - child_allocation.x -= spacing; right_slider_offset = border_width; } else { - child_allocation.x += child_allocation.width + spacing; + child_allocation.x += child_allocation.width; right_slider_offset = allocation->width - border_width - buttons->slider_width; } } /* now we go hide all the buttons that don't fit */ for (; lp != NULL; lp = lp->prev) - gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE); + { + need_reorder |= gtk_widget_get_child_visible (GTK_WIDGET (lp->data)) == TRUE; + gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE); + } for (lp = first_button->next; lp != NULL; lp = lp->next) - gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE); + { + need_reorder |= gtk_widget_get_child_visible (GTK_WIDGET (lp->data)) == TRUE; + gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE); + } if (need_sliders || buttons->fake_root_button != NULL) { child_allocation.width = buttons->slider_width; child_allocation.x = left_slider_offset + allocation->x; gtk_widget_size_allocate (buttons->left_slider, &child_allocation); + need_reorder |= gtk_widget_get_child_visible (buttons->left_slider) == FALSE; gtk_widget_set_child_visible (buttons->left_slider, TRUE); gtk_widget_show_all (buttons->left_slider); @@ -772,6 +893,7 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, } else { + need_reorder |= gtk_widget_get_child_visible (buttons->left_slider) == TRUE; gtk_widget_set_child_visible (buttons->left_slider, FALSE); } @@ -780,6 +902,7 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, child_allocation.width = buttons->slider_width; child_allocation.x = right_slider_offset + allocation->x; gtk_widget_size_allocate (buttons->right_slider, &child_allocation); + need_reorder |= gtk_widget_get_child_visible (buttons->right_slider) == FALSE; gtk_widget_set_child_visible (buttons->right_slider, TRUE); gtk_widget_show_all (buttons->right_slider); @@ -787,8 +910,30 @@ thunar_location_buttons_size_allocate (GtkWidget *widget, } else { + need_reorder |= gtk_widget_get_child_visible (buttons->right_slider) == TRUE; gtk_widget_set_child_visible (buttons->right_slider, FALSE); } + + if (need_reorder) + thunar_location_buttons_child_ordering_changed (buttons); +} + + + +static gboolean +thunar_location_buttons_draw (GtkWidget *widget, + cairo_t *cr) +{ + GtkStyleContext *context; + GtkAllocation alloc; + + context = gtk_widget_get_style_context (widget); + gtk_widget_get_allocation (widget, &alloc); + + gtk_render_background (context, cr, 0, 0, alloc.width, alloc.height); + gtk_render_frame (context, cr, 0, 0, alloc.width, alloc.height); + + return GTK_WIDGET_CLASS (thunar_location_buttons_parent_class)->draw (widget, cr); } @@ -899,12 +1044,12 @@ thunar_location_buttons_make_button (ThunarLocationButtons *buttons, thunar_location_button_set_file (THUNAR_LOCATION_BUTTON (button), file); /* the current directory is active */ - thunar_location_button_set_active (THUNAR_LOCATION_BUTTON (button), (file == buttons->current_directory)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), (file == buttons->current_directory)); /* connect signal handlers */ - g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (thunar_location_buttons_clicked), buttons); + g_signal_connect (G_OBJECT (button), "location-button-clicked", G_CALLBACK (thunar_location_buttons_clicked), buttons); g_signal_connect (G_OBJECT (button), "gone", G_CALLBACK (thunar_location_buttons_gone), buttons); - g_signal_connect (G_OBJECT (button), "context-menu", G_CALLBACK (thunar_location_buttons_context_menu), buttons); + g_signal_connect (G_OBJECT (button), "popup-menu", G_CALLBACK (thunar_location_buttons_context_menu), buttons); return button; } @@ -928,15 +1073,11 @@ thunar_location_buttons_scroll_timeout (gpointer user_data) { ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (user_data); - GDK_THREADS_ENTER (); - if (gtk_widget_has_focus (buttons->left_slider)) thunar_location_buttons_scroll_left (buttons->left_slider, buttons); else if (gtk_widget_has_focus (buttons->right_slider)) thunar_location_buttons_scroll_right (buttons->right_slider, buttons); - GDK_THREADS_LEAVE (); - return TRUE; } @@ -1012,9 +1153,10 @@ thunar_location_buttons_slider_button_press (GtkWidget *button, if (G_LIKELY (buttons->scroll_timeout_id == 0)) { - buttons->scroll_timeout_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_LOCATION_BUTTONS_SCROLL_TIMEOUT, - thunar_location_buttons_scroll_timeout, buttons, - thunar_location_buttons_scroll_timeout_destroy); + buttons->scroll_timeout_id = gdk_threads_add_timeout_full (G_PRIORITY_LOW, + THUNAR_LOCATION_BUTTONS_SCROLL_TIMEOUT, + thunar_location_buttons_scroll_timeout, buttons, + thunar_location_buttons_scroll_timeout_destroy); } return FALSE; @@ -1075,7 +1217,6 @@ thunar_location_buttons_scroll_right (GtkWidget *button, gint space_available; gint space_needed; gint border_width; - gint spacing; if (G_UNLIKELY (buttons->ignore_click)) { @@ -1083,10 +1224,6 @@ thunar_location_buttons_scroll_right (GtkWidget *button, return; } - gtk_widget_style_get (GTK_WIDGET (buttons), - "spacing", &spacing, - NULL); - gtk_widget_queue_resize (GTK_WIDGET (buttons)); border_width = gtk_container_get_border_width (GTK_CONTAINER (buttons)); @@ -1111,15 +1248,18 @@ thunar_location_buttons_scroll_right (GtkWidget *button, break; } - space_needed = thunar_gtk_widget_get_allocation_width (GTK_WIDGET (right_button->data)) + spacing; + space_needed = thunar_gtk_widget_get_allocation_width (GTK_WIDGET (right_button->data)); if (direction == GTK_TEXT_DIR_RTL) { - space_available = thunar_gtk_widget_get_allocation_x (buttons->right_slider) - thunar_gtk_widget_get_allocation_x (GTK_WIDGET (buttons)); + space_available = thunar_gtk_widget_get_allocation_x (right_button->next->data) - + thunar_gtk_widget_get_allocation_x (buttons->right_slider) - + thunar_gtk_widget_get_allocation_width (buttons->right_slider); } else { - space_available = (thunar_gtk_widget_get_allocation_x (GTK_WIDGET (buttons)) + thunar_gtk_widget_get_allocation_width (GTK_WIDGET (buttons)) - border_width) - - (thunar_gtk_widget_get_allocation_x (buttons->right_slider) + thunar_gtk_widget_get_allocation_width (buttons->right_slider)); + space_available = thunar_gtk_widget_get_allocation_x (buttons->right_slider) - + thunar_gtk_widget_get_allocation_x (right_button->next->data) - + thunar_gtk_widget_get_allocation_width (right_button->next->data); } if (G_UNLIKELY (left_button == NULL)) @@ -1132,7 +1272,7 @@ thunar_location_buttons_scroll_right (GtkWidget *button, */ while (space_available < space_needed) { - space_available += thunar_gtk_widget_get_allocation_width (GTK_WIDGET (left_button->data)) + spacing; + space_available += thunar_gtk_widget_get_allocation_width (GTK_WIDGET (left_button->data)); left_button = left_button->prev; buttons->first_scrolled_button = left_button; } @@ -1202,7 +1342,7 @@ thunar_location_buttons_clicked (ThunarLocationButton *button, /* update the location button state (making sure to not recurse with the "clicked" handler) */ g_signal_handlers_block_by_func (G_OBJECT (button), thunar_location_buttons_clicked, buttons); - thunar_location_button_set_active (button, directory == buttons->current_directory); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), directory == buttons->current_directory); g_signal_handlers_unblock_by_func (G_OBJECT (button), thunar_location_buttons_clicked, buttons); } @@ -1230,9 +1370,8 @@ thunar_location_buttons_gone (ThunarLocationButton *button, -static void +static gboolean thunar_location_buttons_context_menu (ThunarLocationButton *button, - GdkEventButton *event, ThunarLocationButtons *buttons) { ThunarClipboardManager *clipboard; @@ -1301,13 +1440,17 @@ thunar_location_buttons_context_menu (ThunarLocationButton *button, /* run the menu on the screen on the buttons' screen */ menu = gtk_ui_manager_get_widget (buttons->ui_manager, "/location-buttons-context-menu"); - thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (buttons), NULL, NULL, event->button, event->time); + thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (buttons), NULL, NULL, 0, gtk_get_current_event_time ()); /* cleanup */ g_object_unref (G_OBJECT (buttons)); g_object_unref (G_OBJECT (clipboard)); + + return TRUE; } } + + return FALSE; } @@ -1366,13 +1509,13 @@ thunar_location_buttons_action_down_folder (GtkAction *action, /* lookup the active button */ for (lp = buttons->list; lp != NULL; lp = lp->next) - if (thunar_location_button_get_active (lp->data)) + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lp->data))) { /* check if we have a folder below that one */ if (G_LIKELY (lp->prev != NULL)) { /* enter that folder */ - thunar_location_button_clicked (lp->prev->data); + gtk_button_clicked (GTK_BUTTON (lp->prev->data)); } break; -- GitLab