diff --git a/src/server/frontend_wayland/wl_data_device.cpp b/src/server/frontend_wayland/wl_data_device.cpp index 6bd476a688..00435d0e9d 100644 --- a/src/server/frontend_wayland/wl_data_device.cpp +++ b/src/server/frontend_wayland/wl_data_device.cpp @@ -87,7 +87,13 @@ class mf::WlDataDevice::Offer : public wayland::DataOffer void set_actions(uint32_t dnd_actions, uint32_t preferred_action) override { - send_action_event_if_supported(source->offer_set_actions(dnd_actions, preferred_action)); + const auto action = source->offer_set_actions(dnd_actions, preferred_action); + + if (!dnd_action || dnd_action.value() != action) + { + dnd_action = action; + send_action_event_if_supported(action); + } } private: @@ -95,6 +101,7 @@ class mf::WlDataDevice::Offer : public wayland::DataOffer wayland::Weak const device; std::shared_ptr const source; std::optional accepted_mime_type; + std::optional dnd_action; }; mf::WlDataDevice::Offer::Offer(WlDataDevice* device, std::shared_ptr const& source) : diff --git a/src/server/frontend_wayland/wl_data_source.cpp b/src/server/frontend_wayland/wl_data_source.cpp index aee9d392a5..be3eb01171 100644 --- a/src/server/frontend_wayland/wl_data_source.cpp +++ b/src/server/frontend_wayland/wl_data_source.cpp @@ -340,7 +340,11 @@ uint32_t mf::WlDataSource::drag_n_drop_set_actions(uint32_t dnd_actions, uint32_ { if (action | acceptable_options) { - send_action_event_if_supported(action); + if (!dnd_action || dnd_action.value() != action) + { + dnd_action = action; + send_action_event_if_supported(action); + } return action; } } diff --git a/src/server/frontend_wayland/wl_data_source.h b/src/server/frontend_wayland/wl_data_source.h index 084f50cf1e..ec47ffd2ce 100644 --- a/src/server/frontend_wayland/wl_data_source.h +++ b/src/server/frontend_wayland/wl_data_source.h @@ -88,6 +88,7 @@ class WlDataSource : public wayland::DataSource std::weak_ptr dnd_source; bool dnd_source_source_is_ours{false}; uint32_t dnd_actions; + std::optional dnd_action; std::optional drag_surface; }; }