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