mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
Fix copy mode on Wayland
On Wayland, copy mode often doesn't actually update the clipboard. Specifically, it only works one time after a pointer enter or pointer button event, then doesn't work again until the next event. This is because the Wayland protocol serial number in CopyAndPaste::last_serial is only updated by pointer enter and pointer button events. So, subsequent copies using only the keyboard reuse the same serial number and get ignored. last_serial used to be updated for keyboard events, too, but that was (accidentally?) dropped in commit0a00ffe98b
. Commit0a00ffe98b
also added another last_serial to WaylandConnection which is updated for keyboard events but isn't used anywhere as far as I can tell. So, to fix this bug, let's get rid of CopyAndPaste::last_serial and replace it with WaylandConnection::last_serial, which is now updated for pointer and keyboard events. closes: #3843
This commit is contained in:
parent
f376468f46
commit
7373a4990b
@ -16,13 +16,11 @@ use crate::Clipboard;
|
||||
#[derive(Default)]
|
||||
pub struct CopyAndPaste {
|
||||
data_offer: Option<WlDataOffer>,
|
||||
pub(crate) last_serial: u32,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for CopyAndPaste {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
fmt.debug_struct("CopyAndPaste")
|
||||
.field("last_serial", &self.last_serial)
|
||||
.field("data_offer", &self.data_offer.is_some())
|
||||
.finish()
|
||||
}
|
||||
@ -35,12 +33,6 @@ impl CopyAndPaste {
|
||||
Arc::new(Mutex::new(Default::default()))
|
||||
}
|
||||
|
||||
pub fn update_last_serial(&mut self, serial: u32) {
|
||||
if serial != 0 {
|
||||
self.last_serial = serial;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_clipboard_data(&mut self, clipboard: Clipboard) -> anyhow::Result<FileDescriptor> {
|
||||
let conn = crate::Connection::get().unwrap().wayland();
|
||||
let pointer = conn.pointer.borrow();
|
||||
@ -75,6 +67,7 @@ impl CopyAndPaste {
|
||||
|
||||
pub fn set_clipboard_data(&mut self, clipboard: Clipboard, data: String) {
|
||||
let conn = crate::Connection::get().unwrap().wayland();
|
||||
let last_serial = *conn.last_serial.borrow();
|
||||
let pointer = conn.pointer.borrow();
|
||||
let primary_selection = if let Clipboard::PrimarySelection = clipboard {
|
||||
conn.environment
|
||||
@ -105,7 +98,7 @@ impl CopyAndPaste {
|
||||
}
|
||||
},
|
||||
);
|
||||
device.set_selection(&Some(source), self.last_serial)
|
||||
device.set_selection(&Some(source), last_serial)
|
||||
}
|
||||
None => {
|
||||
let source = conn
|
||||
@ -122,7 +115,7 @@ impl CopyAndPaste {
|
||||
conn.pointer
|
||||
.borrow()
|
||||
.data_device
|
||||
.set_selection(Some(&source), self.last_serial);
|
||||
.set_selection(Some(&source), last_serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,12 +123,14 @@ impl CopyAndPaste {
|
||||
pub fn handle_data_offer(&mut self, event: DataOfferEvent, offer: WlDataOffer) {
|
||||
match event {
|
||||
DataOfferEvent::Offer { mime_type } => {
|
||||
let conn = crate::Connection::get().unwrap().wayland();
|
||||
let last_serial = *conn.last_serial.borrow();
|
||||
if mime_type == TEXT_MIME_TYPE {
|
||||
offer.accept(self.last_serial, Some(mime_type));
|
||||
offer.accept(last_serial, Some(mime_type));
|
||||
self.data_offer.replace(offer);
|
||||
} else {
|
||||
// Refuse other mime types
|
||||
offer.accept(self.last_serial, None);
|
||||
offer.accept(last_serial, None);
|
||||
}
|
||||
}
|
||||
DataOfferEvent::SourceActions { .. } | DataOfferEvent::Action { .. } => {
|
||||
|
@ -141,10 +141,8 @@ impl PendingMouse {
|
||||
pub fn queue(&mut self, evt: PointerEvent) -> bool {
|
||||
match evt {
|
||||
PointerEvent::Enter { serial, .. } => {
|
||||
self.copy_and_paste
|
||||
.lock()
|
||||
.unwrap()
|
||||
.update_last_serial(serial);
|
||||
let conn = WaylandConnection::get().unwrap().wayland();
|
||||
*conn.last_serial.borrow_mut() = serial;
|
||||
self.in_window = true;
|
||||
false
|
||||
}
|
||||
@ -169,10 +167,8 @@ impl PendingMouse {
|
||||
serial,
|
||||
..
|
||||
} => {
|
||||
self.copy_and_paste
|
||||
.lock()
|
||||
.unwrap()
|
||||
.update_last_serial(serial);
|
||||
let conn = WaylandConnection::get().unwrap().wayland();
|
||||
*conn.last_serial.borrow_mut() = serial;
|
||||
fn linux_button(b: u32) -> Option<MousePress> {
|
||||
// See BTN_LEFT and friends in <linux/input-event-codes.h>
|
||||
match b {
|
||||
|
@ -1176,8 +1176,8 @@ impl WaylandWindowInner {
|
||||
|
||||
fn request_drag_move(&self) {
|
||||
if let Some(window) = self.window.as_ref() {
|
||||
let serial = self.copy_and_paste.lock().unwrap().last_serial;
|
||||
let conn = Connection::get().unwrap().wayland();
|
||||
let serial = *conn.last_serial.borrow();
|
||||
window.start_interactive_move(&conn.pointer.borrow().seat, serial);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user