From 75bbdf160b744d405af85f0209fac1ec2e3e6309 Mon Sep 17 00:00:00 2001 From: Arecsu Date: Thu, 13 Aug 2026 13:43:53 -0300 Subject: [PATCH] fix: don't treat a relayed gesture cancel as a click in thumbtable/culling The event-controller migration converted the thumbtable's button-release-event signal to a GtkGestureMultiPress and inherited the cancel->release bridge: on every gesture cancel the bridge fakes a released(1,0,0), and the release handler interpreted that as a click. A cancel is not a click: GTK3 cancels gestures on grab-notify/controller resets, and a press whose release never arrived (e.g. the second press of a double-click that switched to darkroom on press) keeps a stale point in the gesture that a later hover crossing can cancel. Moving the mouse over the lighttable thumbtable then silently ran select_single() on the hovered image (issue #21813). Restore the pre-gesture semantics: the release handler only acts on a real GDK button release -- exactly what the old button-release-event handler received -- while the cancel->release relay stays for the pressed-state cleanup the bauhaus handlers rely on. --- src/dtgtk/culling.c | 11 +++++++++++ src/dtgtk/thumbtable.c | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/dtgtk/culling.c b/src/dtgtk/culling.c index df01c3a407e..ce5b3a1e1b4 100644 --- a/src/dtgtk/culling.c +++ b/src/dtgtk/culling.c @@ -1061,6 +1061,17 @@ static void _event_button_release_cb(GtkGestureSingle *gesture, { table->panning = FALSE; + /* A gesture cancel is relayed to this handler so widgets can clean up + * their pressed state, but it is not a click (issue #21813). Only a + * real GDK button release may toggle the culling selection. */ + GdkEvent *release_event = gtk_get_current_event(); + if(!release_event || release_event->type != GDK_BUTTON_RELEASE) + { + gdk_event_free(release_event); + return; + } + gdk_event_free(release_event); + const dt_imgid_t overid = dt_control_get_mouse_over_id(); // if the act_on algorithm need a specific culling "selection", // we use a very simple culling-specific selection diff --git a/src/dtgtk/thumbtable.c b/src/dtgtk/thumbtable.c index 9d042cb1ebf..54287eb1f6a 100644 --- a/src/dtgtk/thumbtable.c +++ b/src/dtgtk/thumbtable.c @@ -1621,6 +1621,20 @@ static void _event_button_release_cb(GtkGestureSingle *gesture, && cv != DT_VIEW_PRINT) return; + /* A gesture cancel is relayed to this handler so widgets can clean up + * their pressed state, but it is not a click: cancels can also fire for + * a long-dead press while merely hovering (issue #21813 -- the thumbtable + * re-selected the hovered image). Only a real GDK button release may + * select/toggle, exactly like the pre-gesture button-release-event + * handler. */ + GdkEvent *release_event = gtk_get_current_event(); + if(!release_event || release_event->type != GDK_BUTTON_RELEASE) + { + gdk_event_free(release_event); + return; + } + gdk_event_free(release_event); + dt_set_backthumb_time(0.0); const dt_imgid_t id = dt_control_get_mouse_over_id();