From: Daniel Boles Date: Tue, 27 Jun 2023 20:03:10 +0000 (+0100) Subject: DropTarget: Fix critical if reject drop pre-enter X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~1^2~89^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=dfa6591675c0c319161c5a725b7999eef6aba48b;p=gtk4.git DropTarget: Fix critical if reject drop pre-enter Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5922 The docs of `Gtk.DropTarget::accept` say this: > If the decision whether the drop will be accepted or rejected depends > on the data, [`::accept`] should return `TRUE`, [`:preload`] should be > set and the value should be inspected via the `::notify:value` signal, > calling `gtk_drop_target_reject()` if required. But this pattern causes a CRITICAL, given these steps: * Create a `DragSource` and `DropTarget` * Keep the default `::accept` handler and set `:preload` to `TRUE` * Connect to `notify::value` and therein call `DropTarget.reject()` * CRITICAL at `DropTarget.enter()`→`Drop.get_actions()` on NULL instance We should let the documented case work without a CRITICAL or worse, null deref. And per @otte on the bug, we should bail earlier before `::enter` & setting `GTK_STATE_FLAG_DROP_ACTIVE`; neither should occur if rejected This fixes that, by checking after `start_drop()` when notifications are thawed, whether any handler has `reject()`ed & set our `drop` to `NULL`. --- diff --git a/gtk/gtkdroptarget.c b/gtk/gtkdroptarget.c index f99c476ac4..c4871f106e 100644 --- a/gtk/gtkdroptarget.c +++ b/gtk/gtkdroptarget.c @@ -507,7 +507,12 @@ gtk_drop_target_handle_crossing (GtkEventController *controller, graphene_point_init (&self->coords, x, y); gtk_drop_target_start_drop (self, crossing->drop); - g_signal_emit (self, signals[ENTER], 0, x, y, &preferred); + /* start_drop ends w/ thaw_notify, where handler may reject, so recheck */ + if (self->drop != NULL) + g_signal_emit (self, signals[ENTER], 0, x, y, &preferred); + else + preferred = 0; + if (!gdk_drag_action_is_unique (preferred)) { g_critical ("Handler for GtkDropTarget::enter on %s %p did not return a unique preferred action",