Skip to content

Commit

Permalink
Move pasted items to front
Browse files Browse the repository at this point in the history
The reason I didn't do this initially is because I was going to implement updating the deduplicator functionality through the broadcast API and put the MoveToFront call on the client side. Realistically, I'm not going to get around to build the broadcast API anytime soon because the current hacks I have in place work 99% of the time. So just add one more hack to implement moving to front in the watcher.
  • Loading branch information
Alex Saveau committed Nov 23, 2024
1 parent 58adb8a commit 42fa7f1
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
1 change: 1 addition & 0 deletions client-sdk/api.golden
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub unsafe fn clipboard_history_client_sdk::api::MoveToFrontRequest::drop(ptr: u
pub unsafe fn clipboard_history_client_sdk::api::MoveToFrontRequest::init(init: <T as crossbeam_epoch::atomic::Pointable>::Init) -> usize
impl<T> either::into_either::IntoEither for clipboard_history_client_sdk::api::MoveToFrontRequest
#[repr(C)] pub struct clipboard_history_client_sdk::api::PasteCommand
pub clipboard_history_client_sdk::api::PasteCommand::id: u64
pub clipboard_history_client_sdk::api::PasteCommand::mime: clipboard_history_core::protocol::MimeType
pub clipboard_history_client_sdk::api::PasteCommand::trigger_paste: bool
impl clipboard_history_core::utils::AsBytes for clipboard_history_client_sdk::api::PasteCommand
Expand Down
4 changes: 3 additions & 1 deletion client-sdk/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,14 @@ pub fn connect_to_paste_server(addr: &SocketAddrUnix) -> Result<OwnedFd, ClientE
Ok(sock)
}

pub const PASTE_SERVER_PROTOCOL_VERSION: u8 = 1;
pub const PASTE_SERVER_PROTOCOL_VERSION: u8 = 2;

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct PasteCommand {
version: u8,
pub trigger_paste: bool,
pub id: u64,
pub mime: MimeType,
}

Expand All @@ -128,6 +129,7 @@ pub fn send_paste_buffer(
let cmd = PasteCommand {
version: PASTE_SERVER_PROTOCOL_VERSION,
trigger_paste,
id: entry.id(),
mime,
};
sendmsg(
Expand Down
51 changes: 47 additions & 4 deletions x11/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ use ringboard_sdk::{
Error, IoErr, create_tmp_file,
dirs::{paste_socket_file, socket_file},
init_unix_server,
protocol::{AddResponse, IdNotFoundError, MimeType, MoveToFrontResponse, RingKind},
protocol::{
AddResponse, IdNotFoundError, MimeType, MoveToFrontResponse, Response, RingKind,
},
ring::Mmap,
},
};
Expand All @@ -39,7 +41,7 @@ use rustix::{
fs::{CWD, MemfdFlags, Mode, OFlags, memfd_create},
io::{Errno, read_uninit},
net::{
RecvAncillaryBuffer, RecvAncillaryMessage::ScmRights, RecvFlags, SocketAddrUnix,
RecvAncillaryBuffer, RecvAncillaryMessage::ScmRights, RecvFlags, SendFlags, SocketAddrUnix,
SocketType, recvmsg,
},
path::Arg,
Expand Down Expand Up @@ -433,6 +435,8 @@ fn run() -> Result<(), CliError> {
&conn,
&atoms,
root,
&server,
&mut deduplicator,
paste_window,
&paste_socket,
&mut ancillary_buf,
Expand Down Expand Up @@ -1052,7 +1056,7 @@ fn handle_x11_event(
State::FastPathPendingSelection
| State::TargetsRequest { .. }
| State::PendingSelection { .. } => {
trace!("Ignoring already processed property.");
trace!("Ignoring property to be processed in selection notification.");
}
State::Free => {
error!(
Expand All @@ -1075,13 +1079,47 @@ fn handle_paste_event(
conn: &RustConnection,
atoms: &Atoms,
root: Window,
server: impl AsFd,
deduplicator: &mut CopyDeduplication,
paste_window: Window,
paste_socket: impl AsFd,
ancillary_buf: &mut [u8; rustix::cmsg_space!(ScmRights(1))],
last_paste: &mut Option<(PasteFile, PasteAtom)>,
clear_selection_mask: &mut u8,
auto_paste: bool,
) -> Result<(), CliError> {
struct MoveToFrontGuard<'a, 'b, Server: AsFd>(
Server,
&'a mut Option<(PasteFile, PasteAtom)>,
&'b mut CopyDeduplication,
);

impl<Server: AsFd> Drop for MoveToFrontGuard<'_, '_, Server> {
fn drop(&mut self) {
let Ok(MoveToFrontResponse::Success { id }) =
unsafe { MoveToFrontRequest::recv(&self.0, RecvFlags::empty()) }.map(
|Response {
sequence_number: _,
value,
}| value,
)
else {
return;
};
let Some((file, _)) = self.1 else {
return;
};

let data = match file {
PasteFile::Small(mmap) => mmap,
PasteFile::Large(mmap) => &**mmap,
};
let data_hash =
CopyDeduplication::hash(CopyData::Slice(data), u64::try_from(data.len()).unwrap());
self.2.remember(data_hash, id);
}
}

let mut buf = [0; size_of::<PasteCommand>()];
let mut ancillary = RecvAncillaryBuffer::new(ancillary_buf);
let msg = recvmsg(
Expand Down Expand Up @@ -1110,9 +1148,13 @@ fn handle_paste_event(
let PasteCommand {
trigger_paste,
mime,
id,
..
} = *unsafe { &buf.as_ptr().cast::<PasteCommand>().read_unaligned() };

MoveToFrontRequest::send(&server, id, None, SendFlags::empty())?;
let move_to_front_guard = MoveToFrontGuard(server, last_paste, deduplicator);

let mut mime_atom_req = if mime.is_empty() {
None
} else {
Expand All @@ -1127,7 +1169,7 @@ fn handle_paste_event(
for fd in received_fds {
let data = Mmap::from(fd).map_io_err(|| "Failed to mmap paste file.")?;
info!("Received paste buffer of length {}.", data.len());
*last_paste = Some((
*move_to_front_guard.1 = Some((
if data.len() > MAX_TRANSFER_SIZE {
PasteFile::Large(Rc::new(data))
} else {
Expand Down Expand Up @@ -1209,6 +1251,7 @@ fn do_paste(conn: &RustConnection, root: Window) -> Result<(), CliError> {
key(KEY_PRESS_EVENT, 118)?;
key(KEY_RELEASE_EVENT, 118)?;
key(KEY_RELEASE_EVENT, 50)?;
conn.flush()?;
info!("Sent paste command.");

Ok(())
Expand Down

0 comments on commit 42fa7f1

Please sign in to comment.