[nautilus/antoniof/when-clicked-doesnt-actually-mean-clicked: 4/4] pathbar: Use gesture for context menus



commit 4a4451f80e843577a12c33ceb9a844ca3cbb1fd7
Author: António Fernandes <antoniof gnome org>
Date:   Thu Aug 23 20:31:38 2018 +0100

    pathbar: Use gesture for context menus
    
    Pathbar context menus for non-current location were reimplemented as
    popovers in commit ce3a5c721fdc9fab2179eb257f216c0757f4d920
    
    However, since then, we listen to GtkWidget::button-press-event"
    instead of GtkButton::clicked. However, despite its name, the later
    is emited whenever the GtkButton is activated, including using the
    keyboard. As a result, we lost the ability to change location with
    the keyboard.
    
    Reversely, we gained the (undesirable) ability to change location
    whenever a mouse button is pressed, even if that gesture would not
    be handled by GtkButton. Example: when dragging to move the window.
    
    Instead, partially revert these changes and use a GtkGesture to
    popup context menus, like we already do for middle click.
    
    Fixes https://gitlab.gnome.org/GNOME/nautilus/issues/568 and 
https://gitlab.gnome.org/GNOME/nautilus/issues/588

 src/nautilus-pathbar.c | 90 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 61 insertions(+), 29 deletions(-)
---
diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c
index 269360f73..90a7949a6 100644
--- a/src/nautilus-pathbar.c
+++ b/src/nautilus-pathbar.c
@@ -1099,9 +1099,8 @@ nautilus_path_bar_clear_buttons (NautilusPathBar *self)
     }
 }
 
-static gboolean
-button_clicked_cb (GtkWidget *button,
-                   GdkEvent *event,
+static void
+button_clicked_cb (GtkButton *button,
                    gpointer   data)
 {
     ButtonData *button_data;
@@ -1112,13 +1111,13 @@ button_clicked_cb (GtkWidget *button,
     button_data = BUTTON_DATA (data);
     if (button_data->ignore_changes)
     {
-        return GDK_EVENT_STOP;
+        return;
     }
 
     self = button_data->path_bar;
     priv = nautilus_path_bar_get_instance_private (self);
 
-    gdk_event_get_state (event, &state);
+    gtk_get_current_event_state (&state);
 
     if ((state & GDK_CONTROL_MASK) != 0)
     {
@@ -1132,11 +1131,6 @@ button_clicked_cb (GtkWidget *button,
         {
             gtk_popover_popup (priv->current_view_menu_popover);
         }
-        else if (((GdkEventButton *) event)->button == GDK_BUTTON_SECONDARY)
-        {
-            gtk_popover_set_relative_to (priv->button_menu_popover, button);
-            pop_up_pathbar_context_menu (self, button_data->file);
-        }
         else
         {
             g_signal_emit (self, path_bar_signals[OPEN_LOCATION], 0,
@@ -1144,8 +1138,6 @@ button_clicked_cb (GtkWidget *button,
                            0);
         }
     }
-
-    return GDK_EVENT_STOP;
 }
 
 static void
@@ -1245,31 +1237,70 @@ on_multi_press_gesture_pressed (GtkGestureMultiPress *gesture,
                                 gdouble               y,
                                 gpointer              user_data)
 {
-    GdkEventSequence *sequence;
-    const GdkEvent *event;
-    GdkModifierType state;
+    ButtonData *button_data;
+    NautilusPathBar *self;
+    guint current_button;
 
     if (n_press != 1)
     {
         return;
     }
 
-    sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
-    event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+    button_data = BUTTON_DATA (user_data);
+    self = button_data->path_bar;
+    current_button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
 
-    gdk_event_get_state (event, &state);
+    switch (current_button)
+    {
+        case GDK_BUTTON_MIDDLE:
+        {
+            GdkModifierType state;
 
-    state &= gtk_accelerator_get_default_mod_mask ();
+            gtk_get_current_event_state (&state);
+            state &= gtk_accelerator_get_default_mod_mask ();
+            if (state == 0)
+            {
+                g_signal_emit (self, path_bar_signals[OPEN_LOCATION], 0,
+                               button_data->path,
+                               GTK_PLACES_OPEN_NEW_TAB);
+            }
+        }
+        break;
 
-    if (state == 0)
-    {
-        ButtonData *button_data;
+        case GDK_BUTTON_SECONDARY:
+        {
+            NautilusPathBarPrivate *priv;
+            GdkEventSequence *sequence;
 
-        button_data = BUTTON_DATA (user_data);
+            /* Claim the event to prevent GtkWindow from popping up the window
+             * manager menu, since we are in the titlebar.
+             */
+            sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+            gtk_gesture_set_sequence_state (GTK_GESTURE (gesture),
+                                            sequence,
+                                            GTK_EVENT_SEQUENCE_CLAIMED);
 
-        g_signal_emit (button_data->path_bar, path_bar_signals[OPEN_LOCATION], 0,
-                       button_data->path,
-                       GTK_PLACES_OPEN_NEW_TAB);
+            priv = nautilus_path_bar_get_instance_private (self);
+            if (g_file_equal (button_data->path, priv->current_path))
+            {
+                gtk_popover_popup (priv->current_view_menu_popover);
+            }
+            else
+            {
+                gtk_popover_set_relative_to (priv->button_menu_popover,
+                                             button_data->button);
+                pop_up_pathbar_context_menu (self, button_data->file);
+            }
+        }
+        break;
+
+        default:
+        {
+            /* Ignore other buttons in this gesture. GtkButton will claim the
+             * primary button presses and emit the "clicked" signal.
+             */
+        }
+        break;
     }
 }
 
@@ -1695,13 +1726,14 @@ make_button_data (NautilusPathBar *self,
 
     button_data->path_bar = self;
 
-    g_signal_connect (button_data->button, "button-press-event", G_CALLBACK (button_clicked_cb), 
button_data);
+    g_signal_connect (button_data->button, "clicked", G_CALLBACK (button_clicked_cb), button_data);
 
-    /* A gesture is needed here, because GtkButton doesn’t react to middle-clicking.
+    /* A gesture is needed here, because GtkButton doesn’t react to middle- or
+     * secondary-clicking.
      */
     button_data->multi_press_gesture = gtk_gesture_multi_press_new (button_data->button);
 
-    gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (button_data->multi_press_gesture), GDK_BUTTON_MIDDLE);
+    gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (button_data->multi_press_gesture), 0);
 
     g_signal_connect (button_data->multi_press_gesture, "pressed",
                       G_CALLBACK (on_multi_press_gesture_pressed), button_data);


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