diff --git a/src/gtk/nautilusgtkplacessidebar.c b/src/gtk/nautilusgtkplacessidebar.c index ad214d91f4648dcd84cf7de8690a2f1795b2c23c..f43278ddae02f557217044ce068520e271f1f9e9 100644 --- a/src/gtk/nautilusgtkplacessidebar.c +++ b/src/gtk/nautilusgtkplacessidebar.c @@ -403,6 +403,7 @@ add_place (NautilusGtkPlacesSidebar *sidebar, GtkWidget *row; GtkWidget *eject_button; GtkGesture *gesture; + char *eject_tooltip; check_unmount_and_eject (mount, volume, drive, &show_unmount, &show_eject); @@ -411,6 +412,12 @@ add_place (NautilusGtkPlacesSidebar *sidebar, g_assert (place_type != NAUTILUS_GTK_PLACES_BOOKMARK); show_eject_button = (show_unmount || show_eject); + if (mount != NULL && volume == NULL && drive == NULL) + eject_tooltip = _("Disconnect"); + else if (show_eject) + eject_tooltip = _("Eject"); + else + eject_tooltip = _("Unmount"); row = g_object_new (NAUTILUS_TYPE_GTK_SIDEBAR_ROW, "sidebar", sidebar, @@ -419,6 +426,7 @@ add_place (NautilusGtkPlacesSidebar *sidebar, "label", name, "tooltip", tooltip, "ejectable", show_eject_button, + "eject-tooltip", eject_tooltip, "order-index", index, "section-type", section_type, "place-type", place_type, @@ -2208,16 +2216,6 @@ rename_entry_changed (GtkEntry *entry, found ? _("This name is already taken") : ""); } -static void -reparent_popover (GtkWidget *widget, - GtkWidget *parent) -{ - g_object_ref (widget); - gtk_widget_unparent (widget); - gtk_widget_set_parent (widget, parent); - g_object_unref (widget); -} - static void do_rename (GtkButton *button, NautilusGtkPlacesSidebar *sidebar) @@ -2234,8 +2232,6 @@ do_rename (GtkButton *button, if (sidebar->rename_popover) { gtk_popover_popdown (GTK_POPOVER (sidebar->rename_popover)); - reparent_popover (sidebar->rename_popover, GTK_WIDGET (sidebar)); - reparent_popover (sidebar->popover, GTK_WIDGET (sidebar)); } _nautilus_gtk_bookmarks_manager_set_bookmark_label (sidebar->bookmarks_manager, file, new_text, NULL); @@ -2343,22 +2339,41 @@ update_popover_shadowing (GtkWidget *row, } static void -set_prelight (GtkPopover *popover) +set_prelight (NautilusGtkPlacesSidebar *sidebar) { - update_popover_shadowing (gtk_widget_get_parent (GTK_WIDGET (popover)), TRUE); + update_popover_shadowing (GTK_WIDGET (sidebar->context_row), TRUE); } static void -unset_prelight (GtkPopover *popover) +unset_prelight (NautilusGtkPlacesSidebar *sidebar) { - update_popover_shadowing (gtk_widget_get_parent (GTK_WIDGET (popover)), FALSE); + update_popover_shadowing (GTK_WIDGET (sidebar->context_row), FALSE); } static void -setup_popover_shadowing (GtkWidget *popover) +setup_popover_shadowing (GtkWidget *popover, + NautilusGtkPlacesSidebar *sidebar) { - g_signal_connect (popover, "map", G_CALLBACK (set_prelight), NULL); - g_signal_connect (popover, "unmap", G_CALLBACK (unset_prelight), NULL); + g_signal_connect_swapped (popover, "map", G_CALLBACK (set_prelight), sidebar); + g_signal_connect_swapped (popover, "unmap", G_CALLBACK (unset_prelight), sidebar); +} + +static void +_popover_set_pointing_to_widget (GtkPopover *popover, + GtkWidget *target) +{ + GtkWidget *parent; + double x, y, w, h; + + parent = gtk_widget_get_parent (GTK_WIDGET (popover)); + + if (!gtk_widget_translate_coordinates (target, parent, 0, 0, &x, &y)) + return; + + w = gtk_widget_get_allocated_width (GTK_WIDGET (target)); + h = gtk_widget_get_allocated_height (GTK_WIDGET (target)); + + gtk_popover_set_pointing_to (popover, &(GdkRectangle){x, y, w, h}); } static void @@ -2381,9 +2396,11 @@ show_rename_popover (NautilusGtkSidebarRow *row) sidebar->rename_uri = g_strdup (uri); gtk_editable_set_text (GTK_EDITABLE (sidebar->rename_entry), name); - reparent_popover (sidebar->rename_popover, GTK_WIDGET (row)); - setup_popover_shadowing (sidebar->rename_popover); + _popover_set_pointing_to_widget (GTK_POPOVER (sidebar->rename_popover), + GTK_WIDGET (row)); + + setup_popover_shadowing (sidebar->rename_popover, sidebar); gtk_popover_popup (GTK_POPOVER (sidebar->rename_popover)); gtk_widget_grab_focus (sidebar->rename_entry); @@ -2459,7 +2476,6 @@ remove_bookmark (NautilusGtkSidebarRow *row) if (type == NAUTILUS_GTK_PLACES_BOOKMARK) { - reparent_popover (sidebar->popover, GTK_WIDGET (sidebar)); file = g_file_new_for_uri (uri); _nautilus_gtk_bookmarks_manager_remove_bookmark (sidebar->bookmarks_manager, file, NULL); g_object_unref (file); @@ -3383,23 +3399,35 @@ create_row_popover (NautilusGtkPlacesSidebar *sidebar, sidebar->popover = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu)); g_object_unref (menu); + gtk_widget_set_parent (sidebar->popover, GTK_WIDGET (sidebar)); + gtk_widget_set_halign (sidebar->popover, GTK_ALIGN_START); + gtk_popover_set_has_arrow (GTK_POPOVER (sidebar->popover), FALSE); g_signal_connect (sidebar->popover, "destroy", G_CALLBACK (on_row_popover_destroy), sidebar); - setup_popover_shadowing (sidebar->popover); + setup_popover_shadowing (sidebar->popover, sidebar); } static void -show_row_popover (NautilusGtkSidebarRow *row) +show_row_popover (NautilusGtkSidebarRow *row, + double x, + double y) { NautilusGtkPlacesSidebar *sidebar; + double x_in_sidebar, y_in_sidebar; g_object_get (row, "sidebar", &sidebar, NULL); - g_clear_pointer (&sidebar->popover, gtk_widget_unparent); - create_row_popover (sidebar, row); - gtk_widget_set_parent (sidebar->popover, GTK_WIDGET (row)); + if (x == -1 && y == -1) + _popover_set_pointing_to_widget (GTK_POPOVER (sidebar->popover), GTK_WIDGET (row)); + else + { + gtk_widget_translate_coordinates (GTK_WIDGET (row), GTK_WIDGET (sidebar), + x, y, &x_in_sidebar, &y_in_sidebar); + gtk_popover_set_pointing_to (GTK_POPOVER (sidebar->popover), + &(GdkRectangle){x_in_sidebar, y_in_sidebar, 0, 0}); + } sidebar->context_row = row; gtk_popover_popup (GTK_POPOVER (sidebar->popover)); @@ -3490,7 +3518,7 @@ on_row_released (GtkGestureClick *gesture, else if (button == 3) { if (row_type != NAUTILUS_GTK_PLACES_CONNECT_TO_SERVER) - show_row_popover (NAUTILUS_GTK_SIDEBAR_ROW (row)); + show_row_popover (NAUTILUS_GTK_SIDEBAR_ROW (row), x, y); } } } @@ -3566,7 +3594,7 @@ popup_menu_cb (NautilusGtkSidebarRow *row) g_object_get (row, "place-type", &row_type, NULL); if (row_type != NAUTILUS_GTK_PLACES_CONNECT_TO_SERVER) - show_row_popover (row); + show_row_popover (row, -1, -1); } static void diff --git a/src/gtk/nautilusgtkplacesview.c b/src/gtk/nautilusgtkplacesview.c index fcd6d10f648d42753f1a6999521d0ba1ba40c7d3..11d7323b8573045f7524e8d0428a3cb82ca7b302 100644 --- a/src/gtk/nautilusgtkplacesview.c +++ b/src/gtk/nautilusgtkplacesview.c @@ -1372,6 +1372,7 @@ unmount_ready_cb (GObject *source_mount, return; } + view->row_for_action = NULL; view->unmounting_mount = FALSE; update_loading (view); @@ -1722,16 +1723,35 @@ get_menu_model (void) return G_MENU_MODEL (menu); } +static void +_popover_set_pointing_to_widget (GtkPopover *popover, + GtkWidget *target) +{ + GtkWidget *parent; + double x, y, w, h; + + parent = gtk_widget_get_parent (GTK_WIDGET (popover)); + + if (!gtk_widget_translate_coordinates (target, parent, 0, 0, &x, &y)) + return; + + w = gtk_widget_get_allocated_width (GTK_WIDGET (target)); + h = gtk_widget_get_allocated_height (GTK_WIDGET (target)); + + gtk_popover_set_pointing_to (popover, &(GdkRectangle){x, y, w, h}); +} + static gboolean -on_row_popup_menu (GtkWidget *widget, - GVariant *args, - gpointer user_data) +real_popup_menu (GtkWidget *widget, + double x, + double y) { NautilusGtkPlacesViewRow *row = NAUTILUS_GTK_PLACES_VIEW_ROW (widget); NautilusGtkPlacesView *view; GMount *mount; GFile *file; gboolean is_network; + double x_in_view, y_in_view; view = NAUTILUS_GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), NAUTILUS_TYPE_GTK_PLACES_VIEW)); @@ -1755,10 +1775,10 @@ on_row_popup_menu (GtkWidget *widget, GMenuModel *model = get_menu_model (); view->popup_menu = gtk_popover_menu_new_from_model (model); - gtk_popover_set_position (GTK_POPOVER (view->popup_menu), GTK_POS_BOTTOM); gtk_popover_set_has_arrow (GTK_POPOVER (view->popup_menu), FALSE); - gtk_widget_set_halign (view->popup_menu, GTK_ALIGN_CENTER); + gtk_widget_set_parent (view->popup_menu, GTK_WIDGET (view)); + gtk_widget_set_halign (view->popup_menu, GTK_ALIGN_START); g_object_unref (model); } @@ -1766,10 +1786,15 @@ on_row_popup_menu (GtkWidget *widget, if (view->row_for_action) g_object_set_data (G_OBJECT (view->row_for_action), "menu", NULL); - g_object_ref (view->popup_menu); - gtk_widget_unparent (view->popup_menu); - gtk_widget_set_parent (view->popup_menu, GTK_WIDGET (row)); - g_object_unref (view->popup_menu); + if (x == -1 && y == -1) + _popover_set_pointing_to_widget (GTK_POPOVER (view->popup_menu), widget); + else + { + gtk_widget_translate_coordinates (widget, GTK_WIDGET (view), + x, y, &x_in_view, &y_in_view); + gtk_popover_set_pointing_to (GTK_POPOVER (view->popup_menu), + &(GdkRectangle){x_in_view, y_in_view, 0, 0}); + } view->row_for_action = row; if (view->row_for_action) @@ -1780,6 +1805,14 @@ on_row_popup_menu (GtkWidget *widget, return TRUE; } +static gboolean +on_row_popup_menu (GtkWidget *widget, + GVariant *args, + gpointer user_data) +{ + return real_popup_menu (widget, -1, -1); +} + static void click_cb (GtkGesture *gesture, int n_press, @@ -1787,7 +1820,7 @@ click_cb (GtkGesture *gesture, double y, gpointer user_data) { - on_row_popup_menu (GTK_WIDGET (user_data), NULL, NULL); + real_popup_menu (GTK_WIDGET (user_data), x, y); } static gboolean diff --git a/src/gtk/nautilusgtksidebarrow.c b/src/gtk/nautilusgtksidebarrow.c index 0b0d6103ff8488090522c3fb10c5c5d843085fb5..f5d502995dcd272679a46a1061281b7a531cf13a 100644 --- a/src/gtk/nautilusgtksidebarrow.c +++ b/src/gtk/nautilusgtksidebarrow.c @@ -38,6 +38,7 @@ struct _NautilusGtkSidebarRow GtkWidget *end_icon_widget; char *label; char *tooltip; + char *eject_tooltip; GtkWidget *label_widget; gboolean ejectable; GtkWidget *eject_button; @@ -64,6 +65,7 @@ enum PROP_END_ICON, PROP_LABEL, PROP_TOOLTIP, + PROP_EJECT_TOOLTIP, PROP_EJECTABLE, PROP_SIDEBAR, PROP_ORDER_INDEX, @@ -155,6 +157,10 @@ nautilus_gtk_sidebar_row_get_property (GObject *object, g_value_set_string (value, self->tooltip); break; + case PROP_EJECT_TOOLTIP: + g_value_set_string (value, self->eject_tooltip); + break; + case PROP_EJECTABLE: g_value_set_boolean (value, self->ejectable); break; @@ -260,6 +266,12 @@ nautilus_gtk_sidebar_row_set_property (GObject *object, gtk_widget_set_tooltip_text (GTK_WIDGET (self), self->tooltip); break; + case PROP_EJECT_TOOLTIP: + g_free (self->eject_tooltip); + self->eject_tooltip = g_strdup (g_value_get_string (value)); + gtk_widget_set_tooltip_text (GTK_WIDGET (self->eject_button), self->eject_tooltip); + break; + case PROP_EJECTABLE: self->ejectable = g_value_get_boolean (value); if (self->ejectable) @@ -332,6 +344,7 @@ nautilus_gtk_sidebar_row_set_property (GObject *object, self->label = NULL; g_free (self->tooltip); self->tooltip = NULL; + self->eject_tooltip = NULL; gtk_widget_set_tooltip_text (GTK_WIDGET (self), NULL); self->ejectable = FALSE; self->section_type = NAUTILUS_GTK_PLACES_SECTION_BOOKMARKS; @@ -438,6 +451,8 @@ nautilus_gtk_sidebar_row_finalize (GObject *object) self->label = NULL; g_free (self->tooltip); self->tooltip = NULL; + g_free (self->eject_tooltip); + self->eject_tooltip = NULL; g_free (self->uri); self->uri = NULL; g_clear_object (&self->drive); @@ -511,6 +526,14 @@ nautilus_gtk_sidebar_row_class_init (NautilusGtkSidebarRowClass *klass) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + properties [PROP_EJECT_TOOLTIP] = + g_param_spec_string ("eject-tooltip", + "Eject Tooltip", + "Eject Tooltip", + NULL, + (G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + properties [PROP_EJECTABLE] = g_param_spec_boolean ("ejectable", "Ejectable", @@ -625,6 +648,7 @@ nautilus_gtk_sidebar_row_clone (NautilusGtkSidebarRow *self) "end-icon", self->end_icon, "label", self->label, "tooltip", self->tooltip, + "eject-tooltip", self->eject_tooltip, "ejectable", self->ejectable, "order-index", self->order_index, "section-type", self->section_type, diff --git a/src/gtk/nautilusgtksidebarrow.ui b/src/gtk/nautilusgtksidebarrow.ui index 956ea63cbd696a2debb25f1830d591d35f912038..95d91f900ba50f8ea376dedfdfaaa13aee86d57d 100644 --- a/src/gtk/nautilusgtksidebarrow.ui +++ b/src/gtk/nautilusgtksidebarrow.ui @@ -47,7 +47,6 @@ 3 4px media-eject-symbolic - Unmount