[nautilus/wip/antoniof/new-list-view: 6/12] view-icon-controller: Select single item on specific cases




commit 29bc55071e263c5a0b3f0a50bbfe4414e3e94b1c
Author: António Fernandes <antoniof gnome org>
Date:   Sun May 22 17:52:33 2022 +0100

    view-icon-controller: Select single item on specific cases
    
    We've been changing the selection to the clicked item (if unselected) in
    all cases except when SHIFT or CTRL are pressed, because the default
    GtkGridView behavior does it only for primary click and only after
    release.
    
    But this causes duplicate selection events in some cases, interferes
    with drag-and-drop (work in progress in another branch) and misses some
    corner cases (e.g. middle click while holding CTRL).
    
    Instead, factor out that block into a helper function to be called in
    the specific situations where we need it:
    
        - before activating with middle click;
        - before opening context menu;
        - before activating with single click.
    
    Double-click doesn't need it because the item is selected by the release
    handler of the first click.

 src/nautilus-view-icon-controller.c | 51 ++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 21 deletions(-)
---
diff --git a/src/nautilus-view-icon-controller.c b/src/nautilus-view-icon-controller.c
index eae7584cf..a9c009573 100644
--- a/src/nautilus-view-icon-controller.c
+++ b/src/nautilus-view-icon-controller.c
@@ -760,6 +760,24 @@ real_click_policy_changed (NautilusFilesView *files_view)
     set_click_mode_from_settings (self);
 }
 
+/* GtkGridView changes selection only with the primary button, and only after
+ * release. But we need to select the clicked item earlier to activate it or
+ * open its context menu. This helper should be used in these situations.
+ * Does nothing if already selected, to preserve multiple selections. */
+static void
+select_single_item_if_not_selected (NautilusViewIconController *self,
+                                    NautilusViewItemModel      *item)
+{
+    GtkSelectionModel *selection_model = GTK_SELECTION_MODEL (self->model);
+    guint position;
+
+    position = nautilus_view_model_get_index (self->model, item);
+    if (!gtk_selection_model_is_selected (selection_model, position))
+    {
+        gtk_selection_model_select_item (selection_model, position, TRUE);
+    }
+}
+
 static void
 activate_selection_on_click (NautilusViewIconController *self,
                              gboolean                    open_in_new_tab)
@@ -786,6 +804,7 @@ on_item_click_pressed (GtkGestureClick *gesture,
 {
     NautilusViewIconController *self;
     GtkWidget *event_widget;
+    NautilusViewItemModel *item_model;
     guint button;
     GdkModifierType modifiers;
     gboolean selection_mode;
@@ -794,6 +813,7 @@ on_item_click_pressed (GtkGestureClick *gesture,
 
     self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
     event_widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
+    item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (event_widget));
     button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
     modifiers = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (gesture));
 
@@ -809,27 +829,6 @@ on_item_click_pressed (GtkGestureClick *gesture,
                                  n_press == 1 &&
                                  !selection_mode);
 
-    /* GtkGridView changes selection only with the primary button, but we
-     * need that to happen with all buttons, otherwise e.g. opening context
-     * menus would require two clicks: a primary click to select the item,
-     * followed by a secondary click to open the menu.
-     * When holding Ctrl and Shift, GtkGridView does a good job, let's not
-     * interfere in that case. */
-    if (!selection_mode)
-    {
-        GtkSelectionModel *selection_model = GTK_SELECTION_MODEL (self->model);
-        NautilusViewItemModel *item_model;
-        guint position;
-
-        item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (event_widget));
-        position = nautilus_view_model_get_index (self->model, item_model);
-
-        if (!gtk_selection_model_is_selected (selection_model, position))
-        {
-            gtk_selection_model_select_item (selection_model, position, TRUE);
-        }
-    }
-
     /* It's safe to claim event sequence on press in the following cases because
      * they don't interfere with touch scrolling. */
     if (button == GDK_BUTTON_PRIMARY && n_press == 2 && !self->single_click_mode)
@@ -840,11 +839,13 @@ on_item_click_pressed (GtkGestureClick *gesture,
     }
     else if (button == GDK_BUTTON_MIDDLE && n_press == 1)
     {
+        select_single_item_if_not_selected (self, item_model);
         activate_selection_on_click (self, TRUE);
         gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
     }
     else if (button == GDK_BUTTON_SECONDARY && n_press == 1)
     {
+        select_single_item_if_not_selected (self, item_model);
         nautilus_files_view_pop_up_selection_context_menu (NAUTILUS_FILES_VIEW (self),
                                                            view_x, view_y);
         gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
@@ -862,9 +863,17 @@ on_item_click_released (GtkGestureClick *gesture,
 
     if (self->activate_on_release)
     {
+        GtkWidget *event_widget;
+        NautilusViewItemModel *item_model;
+
+        event_widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
+        item_model = nautilus_view_icon_item_ui_get_model (NAUTILUS_VIEW_ICON_ITEM_UI (event_widget));
+
+        select_single_item_if_not_selected (self, item_model);
         activate_selection_on_click (self, FALSE);
         gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
     }
+
     self->activate_on_release = FALSE;
     self->deny_background_click = FALSE;
 }


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