[nautilus] places: Align popover menu with mouse position



commit ba9fe119d8c5a16ea3ea6fe55a4855ca34a73736
Author: Corey Berla <corey berla me>
Date:   Thu Apr 21 12:34:23 2022 -0700

    places: Align popover menu with mouse position
    
    The popover menu always pops-up in the center of each
    row regardless of where the mouse cursor is currently positioned.
    
    Make the popover popup at the pointer click position. If the popover
    is triggered by the keyboard (i.e. SHIFT+F10), then align it with the
    start of the row.

 src/gtk/nautilusgtkplacesview.c | 52 +++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 10 deletions(-)
---
diff --git a/src/gtk/nautilusgtkplacesview.c b/src/gtk/nautilusgtkplacesview.c
index 4cac82e69..11d7323b8 100644
--- a/src/gtk/nautilusgtkplacesview.c
+++ b/src/gtk/nautilusgtkplacesview.c
@@ -1723,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));
 
@@ -1756,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);
     }
@@ -1767,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)
@@ -1781,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,
@@ -1788,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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]