diff --git a/src/core/seat/keyboard.cpp b/src/core/seat/keyboard.cpp index 19d5127eb..9ff1c8a33 100644 --- a/src/core/seat/keyboard.cpp +++ b/src/core/seat/keyboard.cpp @@ -11,6 +11,7 @@ #include "touch.hpp" #include "input-manager.hpp" #include "input-method-relay.hpp" +#include "seat-impl.hpp" #include "wayfire/signal-definitions.hpp" #include @@ -111,6 +112,27 @@ void wf::keyboard_t::setup_listeners() wlr_seat_keyboard_send_modifiers(seat, &kbd->modifiers); } + auto& seat_priv = wf::get_core().seat->priv; + if (seat_priv->active_drag && seat_priv->active_drag->source) + { + uint32_t mods = wlr_keyboard_get_modifiers(kbd); + bool ctrl = mods & WLR_MODIFIER_CTRL; + bool shift = mods & WLR_MODIFIER_SHIFT; + uint32_t action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; + if (ctrl && shift) + { + action = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; + } else if (ctrl) + { + action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + } else if (shift) + { + action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; + } + + seat_priv->active_drag->source->compositor_action = action; + } + wf::get_core().seat->notify_activity(); emit_device_post_event_signal(&event, &handle->base); }); diff --git a/src/core/seat/pointer.cpp b/src/core/seat/pointer.cpp index 82dc5c0a7..90c001aed 100644 --- a/src/core/seat/pointer.cpp +++ b/src/core/seat/pointer.cpp @@ -246,7 +246,7 @@ void wf::pointer_t::grab_surface(wf::scene::node_ptr node) if (node) { - set_grab(node, seat->priv->drag_active ? input_grab_kind_t::DND : input_grab_kind_t::IMPLICIT); + set_grab(node, seat->priv->is_drag_active() ? input_grab_kind_t::DND : input_grab_kind_t::IMPLICIT); return; } @@ -268,7 +268,7 @@ wf::input_grab_kind_t wf::pointer_t::get_current_grab_kind() const return input_grab_kind_t::NONE; } - if ((current_grab_kind == input_grab_kind_t::IMPLICIT) && seat->priv->drag_active) + if ((current_grab_kind == input_grab_kind_t::IMPLICIT) && seat->priv->is_drag_active()) { return input_grab_kind_t::DND; } diff --git a/src/core/seat/seat-impl.hpp b/src/core/seat/seat-impl.hpp index 5c2ac40ed..7739695d3 100644 --- a/src/core/seat/seat-impl.hpp +++ b/src/core/seat/seat-impl.hpp @@ -91,8 +91,15 @@ struct seat_t::impl // Current drag icon std::unique_ptr drag_icon; + // The active drag, or NULL if no drag is in progress. Note we can have a + // drag without a drag icon, and active_drag->source may be NULL. + wlr_drag *active_drag = nullptr; + // Is dragging active. Note we can have a drag without a drag icon. - bool drag_active = false; + bool is_drag_active() const + { + return active_drag != nullptr; + } /** Update the position of the drag icon, if it exists */ void update_drag_icon(); diff --git a/src/core/seat/seat.cpp b/src/core/seat/seat.cpp index 32e88ea46..f32f1167b 100644 --- a/src/core/seat/seat.cpp +++ b/src/core/seat/seat.cpp @@ -289,10 +289,10 @@ wf::seat_t::seat_t(wl_display *display, std::string name) : seat(wlr_seat_create this->priv->drag_icon = std::make_unique(d->icon); } - this->priv->drag_active = true; + this->priv->active_drag = d; priv->end_drag.set_callback([&] (void*) { - this->priv->drag_active = false; + this->priv->active_drag = nullptr; priv->end_drag.disconnect(); }); priv->end_drag.connect(&d->events.destroy); @@ -325,7 +325,7 @@ wf::seat_t::seat_t(wl_display *display, std::string name) : seat(wlr_seat_create priv->on_wlr_pointer_grab_end.set_callback([&] (void*) { - if (priv->drag_active) + if (priv->is_drag_active()) { // Drag is handled separately. return; diff --git a/src/core/seat/touch.cpp b/src/core/seat/touch.cpp index 61dc39af8..a75e09ea4 100644 --- a/src/core/seat/touch.cpp +++ b/src/core/seat/touch.cpp @@ -150,7 +150,7 @@ wf::input_grab_kind_t wf::touch_interface_t::get_current_grab_kind(int32_t id) c return input_grab_kind_t::NONE; } - if ((it->second == input_grab_kind_t::NONE) && wf::get_core_impl().seat->priv->drag_active) + if ((it->second == input_grab_kind_t::NONE) && wf::get_core_impl().seat->priv->is_drag_active()) { return input_grab_kind_t::DND; } diff --git a/src/view/wlr-surface-touch-interaction.cpp b/src/view/wlr-surface-touch-interaction.cpp index f269ffe98..facca67d7 100644 --- a/src/view/wlr-surface-touch-interaction.cpp +++ b/src/view/wlr-surface-touch-interaction.cpp @@ -28,7 +28,7 @@ class wlr_surface_touch_interaction_t final : public wf::touch_interaction_t seat->priv->last_press_release_serial = wlr_seat_touch_notify_down(seat->seat, surface, time_ms, finger_id, local.x, local.y); - if ((grab == input_grab_kind_t::NONE) && !seat->priv->drag_active) + if ((grab == input_grab_kind_t::NONE) && !seat->priv->is_drag_active()) { wf::xwayland_bring_to_front(surface); }