Added WaitConfig, fix wait_until note in docs

This commit is contained in:
Noel 2024-04-09 17:07:00 -07:00 committed by ComplexSpaces
parent eabb191df0
commit 6cf324cc44
2 changed files with 62 additions and 35 deletions

View file

@ -154,9 +154,15 @@ impl<'clipboard> Set<'clipboard> {
pub(crate) fn text(self, text: Cow<'_, str>) -> Result<(), Error> {
match self.clipboard {
Clipboard::X11(clipboard) => {
clipboard.set_text(text, self.selection, self.wait, self.wait_until)
}
Clipboard::X11(clipboard) => clipboard.set_text(
text,
self.selection,
match (self.wait, self.wait_until) {
(_, Some(deadline)) => x11::WaitConfig::Until(deadline),
(true, None) => x11::WaitConfig::Forever,
(false, None) => x11::WaitConfig::None,
},
),
#[cfg(feature = "wayland-data-control")]
Clipboard::WlDataControl(clipboard) => clipboard.set_text(text, self.selection, self.wait),
@ -165,9 +171,16 @@ impl<'clipboard> Set<'clipboard> {
pub(crate) fn html(self, html: Cow<'_, str>, alt: Option<Cow<'_, str>>) -> Result<(), Error> {
match self.clipboard {
Clipboard::X11(clipboard) => {
clipboard.set_html(html, alt, self.selection, self.wait, self.wait_until)
}
Clipboard::X11(clipboard) => clipboard.set_html(
html,
alt,
self.selection,
match (self.wait, self.wait_until) {
(_, Some(deadline)) => x11::WaitConfig::Until(deadline),
(true, None) => x11::WaitConfig::Forever,
(false, None) => x11::WaitConfig::None,
},
),
#[cfg(feature = "wayland-data-control")]
Clipboard::WlDataControl(clipboard) => clipboard.set_html(html, alt, self.selection, self.wait),
@ -177,9 +190,15 @@ impl<'clipboard> Set<'clipboard> {
#[cfg(feature = "image-data")]
pub(crate) fn image(self, image: ImageData<'_>) -> Result<(), Error> {
match self.clipboard {
Clipboard::X11(clipboard) => {
clipboard.set_image(image, self.selection, self.wait, self.wait_until)
}
Clipboard::X11(clipboard) => clipboard.set_image(
image,
self.selection,
match (self.wait, self.wait_until) {
(_, Some(deadline)) => x11::WaitConfig::Until(deadline),
(true, None) => x11::WaitConfig::Forever,
(false, None) => x11::WaitConfig::None,
},
),
#[cfg(feature = "wayland-data-control")]
Clipboard::WlDataControl(clipboard) => clipboard.set_image(image, self.selection, self.wait),
@ -241,13 +260,11 @@ pub trait SetExtLinux: private::Sealed {
/// Whether or not to wait for the clipboard's content to be replaced after setting it. This waits until the
/// `deadline` has exceeded.
///
/// This is useful for short-lived programs so that it doesn't block until new contents on the clipboard
/// were added and will exit as so.
/// This is useful for short-lived programs so it won't block until new contents on the clipboard
/// were added.
///
/// For X11, this will wait until it either had new contents available in the clipboard or if the
/// `deadline` was exceeded. This isn't available for Wayland and will not do anything.
///
/// Note: this will call [`wait()`][SetExtLinux::wait] if it wasn't previously set.
/// Note: this is a superset of [`wait()`][SetExtLinux::wait] and will overwrite any state
/// that was previously set using it.
fn wait_until(self, deadline: Instant) -> Self;
}

View file

@ -205,6 +205,20 @@ enum ReadSelNotifyResult {
EventNotRecognized,
}
/// Configuration on how long to wait for a new X11 copy event is emitted.
#[derive(Default)]
pub enum WaitConfig {
/// Waits until the given [`Instant`] has reached.
Until(Instant),
/// Waits forever until a new event is reached.
Forever,
/// It shouldn't wait.
#[default]
None,
}
impl Inner {
fn new() -> Result<Self> {
let server = XContext::new()?;
@ -227,8 +241,7 @@ impl Inner {
&self,
data: Vec<ClipboardData>,
selection: LinuxClipboardKind,
wait: bool,
until: Option<Instant>,
wait: WaitConfig,
) -> Result<()> {
if self.serve_stopped.load(Ordering::Relaxed) {
return Err(Error::Unknown {
@ -261,16 +274,16 @@ impl Inner {
// It is important that the mutex is locked to prevent this notification getting lost.
selection.data_changed.notify_all();
if wait {
drop(data_guard);
match wait {
WaitConfig::None => {}
WaitConfig::Forever => {
drop(data_guard);
selection.data_changed.wait(&mut guard);
}
// Wait for the clipboard's content to be changed.
match until {
Some(deadline) => {
selection.data_changed.wait_until(&mut guard, deadline);
}
None => selection.data_changed.wait(&mut guard),
WaitConfig::Until(deadline) => {
drop(data_guard);
selection.data_changed.wait_until(&mut guard, deadline);
}
}
@ -882,14 +895,13 @@ impl Clipboard {
&self,
message: Cow<'_, str>,
selection: LinuxClipboardKind,
wait: bool,
until: Option<Instant>,
wait: WaitConfig,
) -> Result<()> {
let data = vec![ClipboardData {
bytes: message.into_owned().into_bytes(),
format: self.inner.atoms.UTF8_STRING,
}];
self.inner.write(data, selection, wait, until)
self.inner.write(data, selection, wait)
}
pub(crate) fn set_html(
@ -897,8 +909,7 @@ impl Clipboard {
html: Cow<'_, str>,
alt: Option<Cow<'_, str>>,
selection: LinuxClipboardKind,
wait: bool,
until: Option<Instant>,
wait: WaitConfig,
) -> Result<()> {
let mut data = vec![];
if let Some(alt_text) = alt {
@ -911,7 +922,7 @@ impl Clipboard {
bytes: html.into_owned().into_bytes(),
format: self.inner.atoms.HTML,
});
self.inner.write(data, selection, wait, until)
self.inner.write(data, selection, wait)
}
#[cfg(feature = "image-data")]
@ -937,12 +948,11 @@ impl Clipboard {
&self,
image: ImageData,
selection: LinuxClipboardKind,
wait: bool,
until: Option<Instant>,
wait: WaitConfig,
) -> Result<()> {
let encoded = encode_as_png(&image)?;
let data = vec![ClipboardData { bytes: encoded, format: self.inner.atoms.PNG_MIME }];
self.inner.write(data, selection, wait, until)
self.inner.write(data, selection, wait)
}
}