Skip to content

Commit a9f61b4

Browse files
committed
fix(wayland): allow for one active dnd offer per device
1 parent 8937e18 commit a9f61b4

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

src/platform_impl/linux/wayland/seat/data_device/mod.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use wayland_client::protocol::wl_data_device::WlDataDevice;
66
use wayland_client::protocol::wl_data_device_manager::DndAction;
77
use wayland_client::protocol::wl_data_source::WlDataSource;
88
use wayland_client::protocol::wl_surface::WlSurface;
9-
use wayland_client::{Connection, QueueHandle};
9+
use wayland_client::{Connection, Proxy, QueueHandle};
1010

1111
use crate::event::WindowEvent;
1212
use crate::platform_impl::wayland::state::WinitState;
@@ -44,11 +44,12 @@ impl DataDeviceHandler for WinitState {
4444
offer.set_actions(DndAction::Copy, DndAction::Copy);
4545

4646
if let Ok(read_pipe) = offer.receive(mime_type) {
47+
let data_device_id = data_device.inner().id();
4748
let surface = offer.surface;
4849
let window_id = wayland::make_wid(&surface);
4950

5051
self.read_file_paths(read_pipe, move |state, path| {
51-
state.dnd_offer = Some(DndOfferState {
52+
state.dnd_offers.insert(data_device_id.clone(), DndOfferState {
5253
surface: surface.clone(),
5354
path: path.clone(),
5455
});
@@ -63,10 +64,14 @@ impl DataDeviceHandler for WinitState {
6364
}
6465
}
6566

66-
fn leave(&mut self, _: &Connection, _: &QueueHandle<Self>, _: &WlDataDevice) {
67-
if let Some(dnd_offer) = self.dnd_offer.take() {
68-
let window_id = wayland::make_wid(&dnd_offer.surface);
69-
self.events_sink.push_window_event(WindowEvent::HoveredFileCancelled, window_id);
67+
fn leave(&mut self, _: &Connection, _: &QueueHandle<Self>, wl_data_device: &WlDataDevice) {
68+
let data_device = self.get_data_device(wl_data_device);
69+
70+
if let Some(data_device) = data_device {
71+
if let Some(dnd_offer) = self.dnd_offers.remove(&data_device.inner().id()) {
72+
let window_id = wayland::make_wid(&dnd_offer.surface);
73+
self.events_sink.push_window_event(WindowEvent::HoveredFileCancelled, window_id);
74+
}
7075
}
7176
}
7277

@@ -84,7 +89,7 @@ impl DataDeviceHandler for WinitState {
8489
if let Some(offer) = data_device.data().drag_offer() {
8590
let window_id = wayland::make_wid(&offer.surface);
8691

87-
if let Some(dnd_offer) = self.dnd_offer.as_ref() {
92+
if let Some(dnd_offer) = self.dnd_offers.get(&data_device.inner().id()) {
8893
self.events_sink.push_window_event(
8994
WindowEvent::HoveredFile(dnd_offer.path.to_path_buf()),
9095
window_id,
@@ -108,7 +113,7 @@ impl DataDeviceHandler for WinitState {
108113
if let Some(offer) = data_device.data().drag_offer() {
109114
let window_id = wayland::make_wid(&offer.surface);
110115

111-
if let Some(dnd_offer) = self.dnd_offer.take() {
116+
if let Some(dnd_offer) = self.dnd_offers.remove(&data_device.inner().id()) {
112117
self.events_sink
113118
.push_window_event(WindowEvent::DroppedFile(dnd_offer.path), window_id);
114119

src/platform_impl/linux/wayland/state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub struct WinitState {
5757
pub seat_state: SeatState,
5858

5959
pub data_device_manager_state: DataDeviceManagerState,
60-
pub dnd_offer: Option<DndOfferState>,
60+
pub dnd_offers: AHashMap<ObjectId, DndOfferState>,
6161

6262
/// The shm for software buffers, such as cursors.
6363
pub shm: Shm,
@@ -174,7 +174,7 @@ impl WinitState {
174174
seat_state,
175175

176176
data_device_manager_state,
177-
dnd_offer: None,
177+
dnd_offers: AHashMap::default(),
178178

179179
shm,
180180
custom_cursor_pool,

0 commit comments

Comments
 (0)