From ff84b96480dd965095a9e910443350dbc0e8d96a Mon Sep 17 00:00:00 2001 From: Corey Berla Date: Wed, 27 Apr 2022 12:16:11 -0700 Subject: places: Fix crash when disconnecting After disconnecting a network mount in places (when there's 2 or more mounts), right clicking another mount crashes the application. Set row_for_action to NULL when successfully unmounted. --- gtk/gtkplacesview.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gtk/gtkplacesview.c b/gtk/gtkplacesview.c index cb13276513..a8ac3613a4 100644 --- a/gtk/gtkplacesview.c +++ b/gtk/gtkplacesview.c @@ -1319,6 +1319,7 @@ volume_mount_ready_cb (GObject *source_volume, return; } + view->row_for_action = NULL; view->mounting_volume = FALSE; update_loading (view); -- cgit v1.2.1 From 7ed8a6ae3cba326980d247ad227f5bd107e67b06 Mon Sep 17 00:00:00 2001 From: Corey Berla Date: Thu, 21 Apr 2022 13:01:00 -0700 Subject: places: Fix crash when right clicking row After right clicking multiple rows, or after adding / removing rows (i.e. new network locations), right clicking the row will crash nautilus. This happens because the popover may become orphan but still expect a parent. Reposition the popover menu instead of reparenting it. --- gtk/gtkplacesview.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/gtk/gtkplacesview.c b/gtk/gtkplacesview.c index a8ac3613a4..4e2a2d82cb 100644 --- a/gtk/gtkplacesview.c +++ b/gtk/gtkplacesview.c @@ -1701,6 +1701,24 @@ 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, @@ -1736,6 +1754,7 @@ on_row_popup_menu (GtkWidget *widget, 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)); g_object_unref (model); } @@ -1743,10 +1762,7 @@ 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); + _popover_set_pointing_to_widget (GTK_POPOVER (view->popup_menu), GTK_WIDGET (row)); view->row_for_action = row; if (view->row_for_action) -- cgit v1.2.1 From 7df347d9a5927037803eaca8711e52305238c691 Mon Sep 17 00:00:00 2001 From: Corey Berla Date: Thu, 21 Apr 2022 13:17:34 -0700 Subject: places: Align popover menu with mouse position The popover menu previously always pops up in the center of each row regardless of where the mouse cursor is currently positioned. Make the popover popup at the current mouse position. If the popover is triggered by the keyboard (i.e. SHIFT+F10), then align it with the start of the row. --- gtk/gtkplacesview.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/gtk/gtkplacesview.c b/gtk/gtkplacesview.c index 4e2a2d82cb..223da9bb37 100644 --- a/gtk/gtkplacesview.c +++ b/gtk/gtkplacesview.c @@ -1720,15 +1720,16 @@ _popover_set_pointing_to_widget (GtkPopover *popover, } static gboolean -on_row_popup_menu (GtkWidget *widget, - GVariant *args, - gpointer user_data) +real_popup_menu (GtkWidget *widget, + double x, + double y) { GtkPlacesViewRow *row = GTK_PLACES_VIEW_ROW (widget); GtkPlacesView *view; GMount *mount; GFile *file; gboolean is_network; + double x_in_view, y_in_view; view = GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), GTK_TYPE_PLACES_VIEW)); @@ -1753,7 +1754,7 @@ on_row_popup_menu (GtkWidget *widget, 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_halign (view->popup_menu, GTK_ALIGN_START); gtk_widget_set_parent (view->popup_menu, GTK_WIDGET (view)); g_object_unref (model); @@ -1762,7 +1763,15 @@ on_row_popup_menu (GtkWidget *widget, if (view->row_for_action) g_object_set_data (G_OBJECT (view->row_for_action), "menu", NULL); - _popover_set_pointing_to_widget (GTK_POPOVER (view->popup_menu), GTK_WIDGET (row)); + if (x == -1 && y == -1) + _popover_set_pointing_to_widget (GTK_POPOVER (view->popup_menu), GTK_WIDGET (row)); + 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) @@ -1773,6 +1782,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, @@ -1780,7 +1797,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 -- cgit v1.2.1