diff --git a/src/ifs/ipc.rs b/src/ifs/ipc.rs index 7ef8c41f..50d5fdb0 100644 --- a/src/ifs/ipc.rs +++ b/src/ifs/ipc.rs @@ -63,6 +63,7 @@ pub trait IpcVtable: Sized { fn send_send(src: &Rc, mime_type: &str, fd: Rc); fn remove_from_seat(device: &Self::Device); fn get_offer_seat(offer: &Self::Offer) -> Rc; + fn source_eq(left: &Self::Source, right: &Self::Source) -> bool; } pub struct DeviceData { diff --git a/src/ifs/ipc/wl_data_device.rs b/src/ifs/ipc/wl_data_device.rs index 958c2e2a..ff66848a 100644 --- a/src/ifs/ipc/wl_data_device.rs +++ b/src/ifs/ipc/wl_data_device.rs @@ -280,6 +280,10 @@ impl IpcVtable for ClipboardIpc { fn get_offer_seat(offer: &Self::Offer) -> Rc { offer.device.seat.clone() } + + fn source_eq(left: &Self::Source, right: &Self::Source) -> bool { + left as *const _ == right as *const _ + } } object_base! { diff --git a/src/ifs/ipc/zwp_primary_selection_device_v1.rs b/src/ifs/ipc/zwp_primary_selection_device_v1.rs index 7d699ecb..a75112e8 100644 --- a/src/ifs/ipc/zwp_primary_selection_device_v1.rs +++ b/src/ifs/ipc/zwp_primary_selection_device_v1.rs @@ -224,6 +224,10 @@ impl IpcVtable for PrimarySelectionIpc { fn get_offer_seat(offer: &Self::Offer) -> Rc { offer.seat.clone() } + + fn source_eq(left: &Self::Source, right: &Self::Source) -> bool { + left as *const _ == right as *const _ + } } object_base! { diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 0ff04a8d..391edb89 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -673,6 +673,11 @@ impl WlSeatGlobal { field: &CloneCell>>, src: Option>, ) -> Result<(), WlSeatError> { + if let (Some(new), Some(old)) = (&src, &field.get()) { + if T::source_eq(old, new) { + return Ok(()); + } + } if let Some(new) = &src { ipc::attach_seat::(new, self, ipc::Role::Selection)?; }