[nautilus/antonioffix-menus-and-popovers: 4/13] ui-utilities: Pop up context menu near selection



commit a327d42d31a34dfd9728d6064ac0659cbab510d2
Author: António Fernandes <antoniof gnome org>
Date:   Sun Jan 7 02:00:05 2018 +0000

    ui-utilities: Pop up context menu near selection
    
    Context menus pop up where the pointer is, which is at the
    selection if the pointing device is used to open the menu.
    
    However, if the <Menu> key or <Shift>+<F10> keyboard shortcut
    are used, context menus still shows up wherever the pointer is,
    which may not be near the selected item at all.
    
    Instead, show context menu near the 1st selected item (or at
    the edges if out of view) when the popup menu is activated from
    the keyboard.
    
    Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=102666

 src/nautilus-files-view.c   | 15 +++++++++++++--
 src/nautilus-pathbar.c      |  3 ++-
 src/nautilus-ui-utilities.c | 25 +++++++++++++++++++------
 src/nautilus-ui-utilities.h |  3 ++-
 4 files changed, 36 insertions(+), 10 deletions(-)
---
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index e14e10303..388475ee6 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -8114,6 +8114,7 @@ nautilus_files_view_pop_up_selection_context_menu  (NautilusFilesView *view,
                                                     GdkEventButton    *event)
 {
     NautilusFilesViewPrivate *priv;
+    g_autofree GdkRectangle *rectangle = NULL;
 
     g_assert (NAUTILUS_IS_FILES_VIEW (view));
 
@@ -8124,7 +8125,17 @@ nautilus_files_view_pop_up_selection_context_menu  (NautilusFilesView *view,
      */
     update_context_menus_if_pending (view);
 
-    nautilus_pop_up_context_menu (GTK_WIDGET (view), priv->selection_menu, event);
+    if (!event)
+    {
+        /* If triggered from the keyboard, popup at selection, not pointer */
+        rectangle = nautilus_files_view_get_rectangle_for_popup (view);
+        /* Don't popup from outside the view area */
+        rectangle->y = CLAMP (rectangle->y,
+                              0 - rectangle->height,
+                              gtk_widget_get_allocated_height (GTK_WIDGET (view)));
+    }
+
+    nautilus_pop_up_context_menu (GTK_WIDGET (view), priv->selection_menu, event, rectangle);
 }
 
 /**
@@ -8149,7 +8160,7 @@ nautilus_files_view_pop_up_background_context_menu (NautilusFilesView *view,
      */
     update_context_menus_if_pending (view);
 
-    nautilus_pop_up_context_menu (GTK_WIDGET (view), priv->background_menu, event);
+    nautilus_pop_up_context_menu (GTK_WIDGET (view), priv->background_menu, event, NULL);
 }
 
 static void
diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c
index dc8ee6dbe..09a74dd01 100644
--- a/src/nautilus-pathbar.c
+++ b/src/nautilus-pathbar.c
@@ -1628,7 +1628,8 @@ real_pop_up_pathbar_context_menu (NautilusPathBar *self)
 
     nautilus_pop_up_context_menu (GTK_WIDGET (self),
                                   priv->context_menu,
-                                  priv->context_menu_event);
+                                  priv->context_menu_event,
+                                  NULL);
 }
 
 static void
diff --git a/src/nautilus-ui-utilities.c b/src/nautilus-ui-utilities.c
index 58958e5e4..f782153f7 100644
--- a/src/nautilus-ui-utilities.c
+++ b/src/nautilus-ui-utilities.c
@@ -169,9 +169,10 @@ nautilus_gmenu_add_item_in_submodel (GMenu       *menu,
 }
 
 void
-nautilus_pop_up_context_menu (GtkWidget      *parent,
-                              GMenu          *menu,
-                              GdkEventButton *button_event)
+nautilus_pop_up_context_menu (GtkWidget            *parent,
+                              GMenu                *menu,
+                              const GdkEventButton *button_event,
+                              const GdkRectangle   *rectangle)
 {
     GtkWidget *gtk_menu;
 
@@ -181,9 +182,21 @@ nautilus_pop_up_context_menu (GtkWidget      *parent,
     gtk_menu = gtk_menu_new_from_model (G_MENU_MODEL (menu));
     gtk_menu_attach_to_widget (GTK_MENU (gtk_menu), parent, NULL);
 
-    gtk_menu_popup_at_pointer (GTK_MENU (gtk_menu),
-                               button_event ? (GdkEvent *) button_event :
-                               gtk_get_current_event ());
+    if (!button_event && rectangle)
+    {
+        gtk_menu_popup_at_rect (GTK_MENU (gtk_menu),
+                                gtk_widget_get_window (parent),
+                                rectangle,
+                                GDK_GRAVITY_SOUTH_WEST,
+                                GDK_GRAVITY_NORTH_WEST,
+                                NULL);
+    }
+    else
+    {
+        gtk_menu_popup_at_pointer (GTK_MENU (gtk_menu),
+                                   button_event ? (GdkEvent *) button_event :
+                                   gtk_get_current_event ());
+    }
 
     g_object_ref_sink (gtk_menu);
     g_object_unref (gtk_menu);
diff --git a/src/nautilus-ui-utilities.h b/src/nautilus-ui-utilities.h
index 0dfd31ca9..821df4d80 100644
--- a/src/nautilus-ui-utilities.h
+++ b/src/nautilus-ui-utilities.h
@@ -36,7 +36,8 @@ void nautilus_gmenu_merge                          (GMenu             *original,
                                                    gboolean           prepend);
 void nautilus_pop_up_context_menu                  (GtkWidget         *parent,
                                                     GMenu             *menu,
-                                                    GdkEventButton    *button_event);
+                                                    const GdkEventButton *button_event,
+                                                    const GdkRectangle   *rectangle);
 
 void   nautilus_ui_frame_image                     (GdkPixbuf        **pixbuf);
 void   nautilus_ui_frame_video                     (GdkPixbuf        **pixbuf);


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