mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-08-17 14:51:04 +02:00
refactor(wayland): update to 0.30.0
This is pretty much a rewrite of the Wayland client code for `wayland-client` and `wayland-protocols` v0.30.0, and `smithay-client-toolkit` v0.17.0
This commit is contained in:
parent
5c18ec8ba0
commit
7f46cb4976
23 changed files with 1779 additions and 1338 deletions
|
@ -1,74 +1,182 @@
|
|||
use super::manager::DataControlDeviceManagerState;
|
||||
use crate::lock;
|
||||
use nix::fcntl::OFlag;
|
||||
use nix::unistd::{close, pipe2};
|
||||
use smithay_client_toolkit::data_device::ReadPipe;
|
||||
use std::io;
|
||||
use smithay_client_toolkit::data_device_manager::data_offer::DataOfferError;
|
||||
use smithay_client_toolkit::data_device_manager::ReadPipe;
|
||||
use std::ops::DerefMut;
|
||||
use std::os::fd::FromRawFd;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tracing::warn;
|
||||
use wayland_client::Main;
|
||||
use wayland_protocols::wlr::unstable::data_control::v1::client::zwlr_data_control_offer_v1::{
|
||||
use wayland_client::{Connection, Dispatch, Proxy, QueueHandle};
|
||||
use wayland_protocols_wlr::data_control::v1::client::zwlr_data_control_offer_v1::{
|
||||
Event, ZwlrDataControlOfferV1,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Inner {
|
||||
mime_types: Vec<String>,
|
||||
pub struct UndeterminedOffer {
|
||||
pub(crate) data_offer: Option<ZwlrDataControlOfferV1>,
|
||||
}
|
||||
|
||||
impl PartialEq for UndeterminedOffer {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.data_offer == other.data_offer
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DataControlOffer {
|
||||
inner: Arc<Mutex<Inner>>,
|
||||
pub(crate) offer: ZwlrDataControlOfferV1,
|
||||
pub struct SelectionOffer {
|
||||
pub data_offer: ZwlrDataControlOfferV1,
|
||||
}
|
||||
|
||||
impl DataControlOffer {
|
||||
pub(crate) fn new(offer: &Main<ZwlrDataControlOfferV1>) -> Self {
|
||||
let inner = Arc::new(Mutex::new(Inner {
|
||||
mime_types: Vec::new(),
|
||||
}));
|
||||
|
||||
{
|
||||
let inner = inner.clone();
|
||||
|
||||
offer.quick_assign(move |_, event, _| {
|
||||
let mut inner = lock!(inner);
|
||||
if let Event::Offer { mime_type } = event {
|
||||
inner.mime_types.push(mime_type);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
offer: offer.detach(),
|
||||
inner,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_mime_types<F, T>(&self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&[String]) -> T,
|
||||
{
|
||||
let inner = lock!(self.inner);
|
||||
f(&inner.mime_types)
|
||||
}
|
||||
|
||||
pub fn receive(&self, mime_type: String) -> io::Result<ReadPipe> {
|
||||
// create a pipe
|
||||
let (readfd, writefd) = pipe2(OFlag::O_CLOEXEC)?;
|
||||
|
||||
self.offer.receive(mime_type, writefd);
|
||||
|
||||
if let Err(err) = close(writefd) {
|
||||
warn!("Failed to close write pipe: {}", err);
|
||||
}
|
||||
|
||||
Ok(unsafe { FromRawFd::from_raw_fd(readfd) })
|
||||
impl PartialEq for SelectionOffer {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.data_offer == other.data_offer
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DataControlOffer {
|
||||
fn drop(&mut self) {
|
||||
self.offer.destroy();
|
||||
impl SelectionOffer {
|
||||
pub fn receive(&self, mime_type: String) -> Result<ReadPipe, DataOfferError> {
|
||||
receive(&self.data_offer, mime_type).map_err(DataOfferError::Io)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum DataControlDeviceOffer {
|
||||
Selection(SelectionOffer),
|
||||
Undetermined(UndeterminedOffer),
|
||||
}
|
||||
|
||||
impl Default for DataControlDeviceOffer {
|
||||
fn default() -> Self {
|
||||
Self::Undetermined(UndeterminedOffer { data_offer: None })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct DataControlOfferData {
|
||||
pub(crate) inner: Arc<Mutex<DataControlDeviceOfferInner>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct DataControlDeviceOfferInner {
|
||||
pub(crate) offer: DataControlDeviceOffer,
|
||||
pub(crate) mime_types: Vec<String>,
|
||||
}
|
||||
|
||||
impl DataControlOfferData {
|
||||
pub(crate) fn push_mime_type(&self, mime_type: String) {
|
||||
lock!(self.inner).mime_types.push(mime_type);
|
||||
}
|
||||
|
||||
pub(crate) fn to_selection_offer(&self) {
|
||||
let mut inner = lock!(self.inner);
|
||||
match &mut inner.deref_mut().offer {
|
||||
DataControlDeviceOffer::Selection(_) => {}
|
||||
DataControlDeviceOffer::Undetermined(o) => {
|
||||
inner.offer = DataControlDeviceOffer::Selection(SelectionOffer {
|
||||
data_offer: o.data_offer.clone().expect("Missing current data offer"),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn init_undetermined_offer(&self, offer: &ZwlrDataControlOfferV1) {
|
||||
let mut inner = lock!(self.inner);
|
||||
match &mut inner.deref_mut().offer {
|
||||
DataControlDeviceOffer::Selection(_) => {
|
||||
inner.offer = DataControlDeviceOffer::Undetermined(UndeterminedOffer {
|
||||
data_offer: Some(offer.clone()),
|
||||
});
|
||||
}
|
||||
DataControlDeviceOffer::Undetermined(o) => {
|
||||
o.data_offer = Some(offer.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DataControlOfferDataExt {
|
||||
fn data_control_offer_data(&self) -> &DataControlOfferData;
|
||||
fn mime_types(&self) -> Vec<String>;
|
||||
fn as_selection_offer(&self) -> Option<SelectionOffer>;
|
||||
}
|
||||
|
||||
impl DataControlOfferDataExt for DataControlOfferData {
|
||||
fn data_control_offer_data(&self) -> &DataControlOfferData {
|
||||
self
|
||||
}
|
||||
|
||||
fn mime_types(&self) -> Vec<String> {
|
||||
lock!(self.inner).mime_types.clone()
|
||||
}
|
||||
|
||||
fn as_selection_offer(&self) -> Option<SelectionOffer> {
|
||||
match &lock!(self.inner).offer {
|
||||
DataControlDeviceOffer::Selection(o) => Some(o.clone()),
|
||||
DataControlDeviceOffer::Undetermined(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler trait for `DataOffer` events.
|
||||
///
|
||||
/// The functions defined in this trait are called as `DataOffer` events are received from the compositor.
|
||||
pub trait DataControlOfferHandler: Sized {
|
||||
// Called for each mime type the data offer advertises.
|
||||
fn offer(
|
||||
&mut self,
|
||||
conn: &Connection,
|
||||
qh: &QueueHandle<Self>,
|
||||
offer: &mut DataControlDeviceOffer,
|
||||
mime_type: String,
|
||||
);
|
||||
}
|
||||
|
||||
impl<D, U> Dispatch<ZwlrDataControlOfferV1, U, D> for DataControlDeviceManagerState
|
||||
where
|
||||
D: Dispatch<ZwlrDataControlOfferV1, U> + DataControlOfferHandler,
|
||||
U: DataControlOfferDataExt,
|
||||
{
|
||||
fn event(
|
||||
state: &mut D,
|
||||
_offer: &ZwlrDataControlOfferV1,
|
||||
event: <ZwlrDataControlOfferV1 as Proxy>::Event,
|
||||
data: &U,
|
||||
conn: &Connection,
|
||||
qh: &QueueHandle<D>,
|
||||
) {
|
||||
let data = data.data_control_offer_data();
|
||||
|
||||
if let Event::Offer { mime_type } = event {
|
||||
data.push_mime_type(mime_type.clone());
|
||||
state.offer(conn, qh, &mut lock!(data.inner).offer, mime_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Request to receive the data of a given mime type.
|
||||
///
|
||||
/// You can do this several times, as a reaction to motion of
|
||||
/// the dnd cursor, or to inspect the data in order to choose your
|
||||
/// response.
|
||||
///
|
||||
/// Note that you should *not* read the contents right away in a
|
||||
/// blocking way, as you may deadlock your application doing so.
|
||||
/// At least make sure you flush your events to the server before
|
||||
/// doing so.
|
||||
///
|
||||
/// Fails if too many file descriptors were already open and a pipe
|
||||
/// could not be created.
|
||||
pub fn receive(offer: &ZwlrDataControlOfferV1, mime_type: String) -> std::io::Result<ReadPipe> {
|
||||
// create a pipe
|
||||
let (readfd, writefd) = pipe2(OFlag::O_CLOEXEC)?;
|
||||
|
||||
offer.receive(mime_type, writefd);
|
||||
|
||||
if let Err(err) = close(writefd) {
|
||||
warn!("Failed to close write pipe: {}", err);
|
||||
}
|
||||
|
||||
Ok(unsafe { FromRawFd::from_raw_fd(readfd) })
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue