diff options
author | António Fernandes <antoniof@gnome.org> | 2018-08-23 20:31:38 +0100 |
---|---|---|
committer | Ernestas Kulik <ernestas.kulik@gmail.com> | 2018-08-24 15:35:36 +0000 |
commit | 4a4451f80e843577a12c33ceb9a844ca3cbb1fd7 (patch) | |
tree | 8dac59cf34fa3ee97bb4658e5bb290ff2a6e2b02 /src | |
parent | ff5f4ea43c8a675e75b70ec36588a28df0f7a23d (diff) | |
download | nautilus-4a4451f80e843577a12c33ceb9a844ca3cbb1fd7.tar.gz |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/nautilus-pathbar.c | 90 |
1 files 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); |