Expand description
§General Induction
By default, this library uses the ext-data-control-v1 protocol. This is the standard protocol
supported by modern compositors.
For legacy support, you can enable the wlr-data-control feature to use the older
wlr-data-control-unstable-v1 protocol. This handles the clipboard on sway, hyperland or kde
that implement the protocol.
You can view the protocol in wlr-data-control-unstable-v1. Here we simply explain it.
This protocol involves there register: WlSeat, ZwlrDataControlManagerV1, ZwlrDataControlDeviceV1, and zwlrDataControlOfferV1, seat is used to create a device, and the device will handle the copy and paste,
when you want to use this protocol, you need to init these first, then enter the eventloop, you
can view our code, part of init()
§Paste
Copy is mainly in the part of device dispatch and dataoffer one, there are two road to finished a copy event, this is decided by the time you send the receive request of ZwlrDataControlDeviceV1;
§Road 1
-
- First, the event enter to DataOffer event of zwlrDataControlOfferV1, it will send a zwlrDataControlOfferV1 object, this will include the data message of clipboard, if you send this time, you will not know the mimetype. In this time, the data includes the text selected and copied, here you can pass a file description to receive, and mimetype of TEXT, because at this time you do not know any mimetype of the data
-
- It will enter the event of zwlrDataControlOfferV1, there the mimetype be send, but before , you ignore the mimetype
-
- it enter the selection, follow the document of the protocol, you need to destroy the offer, if there is one,
-
- The main loop is end, then you need to run roundtrip, again, for the pipeline finished, then you will receive the text. Note, if in this routine, you need to check the mimetype in the end, because the data in pipeline maybe not text
§Road 2
it is similar with Road 1, but send receive request when receive selection event, this time you will receive mimetype. Here you can only receive the data which is by copy
§Copy
Paste with wlr-data-control-unstable-v1, need data provider alive, you can make an experiment, if you copy a text from firefox, and kill firefox, you will find, you cannot paste! It is amazing, doesn’t it? So the copy event need to keep alive if the data is still available. You will find that if you copy a text with wl-copy, it will always alive in htop, if you view the code, you will find it fork itself, and live in the backend, until you copy another text from other place, it will die.
Then the problem is, how to copy the data, and when to kill the progress?
Copy event involves ZwlrDataControlDeviceV1 and ZwlrDataControlSourceV1.
-
- if you want to send the data, you need to create a new ZwlrDataControlSourceV1, use the
create_data_source function of zwlr_data_control_manager_v1, create a new one, and set the
mimetype to it , use
offerrequest. You can set multi times,
- if you want to send the data, you need to create a new ZwlrDataControlSourceV1, use the
create_data_source function of zwlr_data_control_manager_v1, create a new one, and set the
mimetype to it , use
-
- start a never end loop of blocking_dispatch, but it is not never end loop, it should break when receive cancelled event of ZwlrDataControlSourceV1, this means another data is copied, the progress is not needed anymore
- 2.1. In blocking_dispatches at the beginning, you will receive some signals of send, with mimetype and a file description, write the data to the fd, then copy will finished, data will be in clipboard
- 2.2. when received cancelled, exit the progress
A simple example to create a clipboard listener is following:
use wayland_clipboard_listener::WlClipboardPasteStream;
use wayland_clipboard_listener::WlListenType;
fn main() {
let mut stream = WlClipboardPasteStream::init(WlListenType::ListenOnCopy).unwrap();
// Note: MIME type priority is ignored when WlListenType is ListenOnSelect
// stream.set_priority(vec![
// "image/jpeg".into(),
// "text/plain;charset=utf-8".into(),
// ]);
for context in stream.paste_stream().flatten() {
println!("{context:?}");
}
}
For using the legacy wlr protocol (with the wlr-data-control feature):
use wayland_clipboard_listener::WlClipboardPasteStreamWlr;
use wayland_clipboard_listener::WlListenType;
fn main() {
let mut stream = WlClipboardPasteStreamWlr::init(WlListenType::ListenOnCopy).unwrap();
for context in stream.paste_stream().flatten() {
println!("{context:?}");
}
}A simple example to create a wl-copy is following:
use wayland_clipboard_listener::{WlClipboardCopyStream, WlClipboardListenerError};
fn main() -> Result<(), WlClipboardListenerError> {
let args = std::env::args();
if args.len() != 2 {
println!("You need to pass a string to it");
return Ok(());
}
let context: &str = &args.last().unwrap();
let mut stream = WlClipboardCopyStream::init()?;
stream.copy_to_clipboard(context.as_bytes().to_vec(), vec!["TEXT"] ,false)?;
Ok(())
}Structs§
- Clip
Board Listen Context - context here describe two types of context
- Clip
Board Listen Message - WlClipboard
Copy Stream - copy stream, it can used to make a wl-copy
- WlClipboard
Listener Stream - Stream, provide a iter to listen to clipboard Note, the iter will loop very fast, you would better to use thread sleep or iter you self
- WlClipboard
Paste Stream - Paste stream it is used to handle paste event
Enums§
- WlClipboard
Listener Error - Error it describe three kind of error
- WlListen
Type - listentype if ListenOnHover, it will be useful for translation apps, but in dispatch, we cannot know the mime_types, it can only handle text