[nautilus/wip/coreyberla/dnd-threshold: 2/2] list-base: Prevent accidental hover-switch on slightest movement




commit 7e63981b782aee39c44e095ea3a231e6a0bb4529
Author: António Fernandes <antoniof gnome org>
Date:   Wed Aug 10 10:51:02 2022 +0100

    list-base: Prevent accidental hover-switch on slightest movement
    
    When switching to a new folder by hovering it during DND, there is a
    chance that a subfolder is going to appear right under the pointer.
    
    Since the pointer is likely still moving (because it's tied to human
    hand movement), the timeout for entering the subfolder starts right
    away, resulting in an accidental location switch.
    
    To prevent this, in the ::enter signal store the start coordinates
    without starting the timeout. The ::motion handler is then going to
    start the timeout only after significant pointer movement.
    
    This has the side effect of also making it harder to accidentally
    enter a folder by hovering only the edge of it, assuming that when
    a person intends to open the folder on hover they are going to target
    the center of the cell.

 src/nautilus-list-base.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
---
diff --git a/src/nautilus-list-base.c b/src/nautilus-list-base.c
index 9b283473d..2827220e1 100644
--- a/src/nautilus-list-base.c
+++ b/src/nautilus-list-base.c
@@ -570,10 +570,8 @@ on_item_drag_hover_enter (GtkDropControllerMotion *controller,
     NautilusListBase *self = nautilus_view_cell_get_view (cell);
     NautilusListBasePrivate *priv = nautilus_list_base_get_instance_private (self);
 
-    if (priv->hover_timer_id == 0)
-    {
-        priv->hover_timer_id = g_timeout_add (HOVER_TIMEOUT, hover_timer, cell);
-    }
+    priv->hover_start_point.x = x;
+    priv->hover_start_point.y = y;
 }
 
 static void
@@ -598,6 +596,12 @@ on_item_drag_hover_motion (GtkDropControllerMotion *controller,
     NautilusListBasePrivate *priv = nautilus_list_base_get_instance_private (self);
     graphene_point_t start = priv->hover_start_point;
 
+    /* This condition doubles in two roles:
+     *   - If the timeout hasn't started yet, to ensure the pointer has entered
+     *     deep enough into the cell before starting the timeout to switch;
+     *   - If the timeout has already started, to reset it if the pointer is
+     *     moving a lot.
+     * Both serve to prevent accidental triggering of switch-on-hover. */
     if (gtk_drag_check_threshold (GTK_WIDGET (cell), start.x, start.y, x, y))
     {
         g_clear_handle_id (&priv->hover_timer_id, g_source_remove);


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