mirror of
https://github.com/rustdesk/qemu-display.git
synced 2025-08-17 16:25:39 +00:00
rdw: fix primary/clipboard serials
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
fb517a13db
commit
70c9e81515
@ -25,26 +25,29 @@ impl Handler {
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to listen to the clipboard");
|
.expect("Failed to listen to the clipboard");
|
||||||
let proxy = ctxt.proxy.clone();
|
let proxy = ctxt.proxy.clone();
|
||||||
let serial = Rc::new(Cell::new(0));
|
let serials = Rc::new([Cell::new(0), Cell::new(0)]);
|
||||||
let current_serial = serial.clone();
|
let current_serials = serials.clone();
|
||||||
let rx = rx.attach(None, move |evt| {
|
let rx = rx.attach(None, move |evt| {
|
||||||
use ClipboardEvent::*;
|
use ClipboardEvent::*;
|
||||||
|
|
||||||
log::debug!("Clipboard event: {:?}", evt);
|
log::debug!("Clipboard event: {:?}", evt);
|
||||||
match evt {
|
match evt {
|
||||||
Register | Unregister => {
|
Register | Unregister => {
|
||||||
current_serial.set(0);
|
current_serials[0].set(0);
|
||||||
}
|
current_serials[1].set(0);
|
||||||
Grab { serial, .. } if serial < current_serial.get() => {
|
|
||||||
log::debug!("Ignored peer grab: {} < {}", serial, current_serial.get());
|
|
||||||
}
|
}
|
||||||
Grab {
|
Grab {
|
||||||
selection,
|
selection,
|
||||||
serial,
|
serial,
|
||||||
mimes,
|
mimes,
|
||||||
} => {
|
} => {
|
||||||
current_serial.set(serial);
|
if let Some((clipboard, idx)) = clipboard_from_selection(selection) {
|
||||||
if let Some(clipboard) = clipboard_from_selection(selection) {
|
if serial < current_serials[idx].get() {
|
||||||
|
log::debug!("Ignored peer grab: {} < {}", serial, current_serials[idx].get());
|
||||||
|
return Continue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_serials[idx].set(serial);
|
||||||
let m: Vec<_> = mimes.iter().map(|s|s.as_str()).collect();
|
let m: Vec<_> = mimes.iter().map(|s|s.as_str()).collect();
|
||||||
let p = proxy.clone();
|
let p = proxy.clone();
|
||||||
let content = rdw::ContentProvider::new(&m, move |mime, stream, prio| {
|
let content = rdw::ContentProvider::new(&m, move |mime, stream, prio| {
|
||||||
@ -73,7 +76,7 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Release { selection } => {
|
Release { selection } => {
|
||||||
if let Some(clipboard) = clipboard_from_selection(selection) {
|
if let Some((clipboard, _)) = clipboard_from_selection(selection) {
|
||||||
// TODO: track if the outside/app changed the clipboard
|
// TODO: track if the outside/app changed the clipboard
|
||||||
if let Err(e) = clipboard.set_content(gdk::NONE_CONTENT_PROVIDER) {
|
if let Err(e) = clipboard.set_content(gdk::NONE_CONTENT_PROVIDER) {
|
||||||
log::warn!("Failed to release clipboard: {}", e);
|
log::warn!("Failed to release clipboard: {}", e);
|
||||||
@ -81,7 +84,7 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Request { selection, mimes, tx } => {
|
Request { selection, mimes, tx } => {
|
||||||
if let Some(clipboard) = clipboard_from_selection(selection) {
|
if let Some((clipboard, _)) = clipboard_from_selection(selection) {
|
||||||
glib::MainContext::default().spawn_local(async move {
|
glib::MainContext::default().spawn_local(async move {
|
||||||
let m: Vec<_> = mimes.iter().map(|s|s.as_str()).collect();
|
let m: Vec<_> = mimes.iter().map(|s|s.as_str()).collect();
|
||||||
let res = clipboard.read_async_future(&m, glib::Priority::default()).await;
|
let res = clipboard.read_async_future(&m, glib::Priority::default()).await;
|
||||||
@ -118,12 +121,12 @@ impl Handler {
|
|||||||
let cb_handler = watch_clipboard(
|
let cb_handler = watch_clipboard(
|
||||||
ctxt.proxy.clone(),
|
ctxt.proxy.clone(),
|
||||||
ClipboardSelection::Clipboard,
|
ClipboardSelection::Clipboard,
|
||||||
serial.clone(),
|
serials.clone(),
|
||||||
);
|
);
|
||||||
let cb_primary_handler = watch_clipboard(
|
let cb_primary_handler = watch_clipboard(
|
||||||
ctxt.proxy.clone(),
|
ctxt.proxy.clone(),
|
||||||
ClipboardSelection::Primary,
|
ClipboardSelection::Primary,
|
||||||
serial.clone(),
|
serials.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
ctxt.register().await?;
|
ctxt.register().await?;
|
||||||
@ -138,10 +141,10 @@ impl Handler {
|
|||||||
fn watch_clipboard(
|
fn watch_clipboard(
|
||||||
proxy: AsyncClipboardProxy<'static>,
|
proxy: AsyncClipboardProxy<'static>,
|
||||||
selection: ClipboardSelection,
|
selection: ClipboardSelection,
|
||||||
serial: Rc<Cell<u32>>,
|
serials: Rc<[Cell<u32>; 2]>,
|
||||||
) -> Option<SignalHandlerId> {
|
) -> Option<SignalHandlerId> {
|
||||||
let clipboard = match clipboard_from_selection(selection) {
|
let (clipboard, idx) = match clipboard_from_selection(selection) {
|
||||||
Some(clipboard) => clipboard,
|
Some(it) => it,
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,16 +156,16 @@ fn watch_clipboard(
|
|||||||
if let Some(formats) = clipboard.formats() {
|
if let Some(formats) = clipboard.formats() {
|
||||||
let types = formats.mime_types();
|
let types = formats.mime_types();
|
||||||
log::debug!(">clipboard-changed({:?}): {:?}", selection, types);
|
log::debug!(">clipboard-changed({:?}): {:?}", selection, types);
|
||||||
let proxy_clone = proxy.clone();
|
let proxy = proxy.clone();
|
||||||
let serial = serial.clone();
|
let serials = serials.clone();
|
||||||
glib::MainContext::default().spawn_local(async move {
|
glib::MainContext::default().spawn_local(async move {
|
||||||
if types.is_empty() {
|
if types.is_empty() {
|
||||||
let _ = proxy_clone.release(selection).await;
|
let _ = proxy.release(selection).await;
|
||||||
} else {
|
} else {
|
||||||
let mimes: Vec<_> = types.iter().map(|s| s.as_str()).collect();
|
let mimes: Vec<_> = types.iter().map(|s| s.as_str()).collect();
|
||||||
let ser = serial.get();
|
let ser = serials[idx].get();
|
||||||
let _ = proxy_clone.grab(selection, ser, &mimes).await;
|
let _ = proxy.grab(selection, ser, &mimes).await;
|
||||||
serial.set(ser + 1);
|
serials[idx].set(ser + 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -170,15 +173,15 @@ fn watch_clipboard(
|
|||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clipboard_from_selection(selection: ClipboardSelection) -> Option<gdk::Clipboard> {
|
fn clipboard_from_selection(selection: ClipboardSelection) -> Option<(gdk::Clipboard, usize)> {
|
||||||
let display = match gdk::Display::default() {
|
let display = match gdk::Display::default() {
|
||||||
Some(display) => display,
|
Some(display) => display,
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match selection {
|
match selection {
|
||||||
ClipboardSelection::Clipboard => Some(display.clipboard()),
|
ClipboardSelection::Clipboard => Some((display.clipboard(), 0)),
|
||||||
ClipboardSelection::Primary => Some(display.primary_clipboard()),
|
ClipboardSelection::Primary => Some((display.primary_clipboard(), 1)),
|
||||||
_ => {
|
_ => {
|
||||||
log::warn!("Unsupport clipboard selection: {:?}", selection);
|
log::warn!("Unsupport clipboard selection: {:?}", selection);
|
||||||
None
|
None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user