mirror of
https://github.com/NotAShelf/stash.git
synced 2026-04-12 22:17:41 +00:00
Merge pull request #49 from NotAShelf/notashelf/push-vootvqpuytyv
multicall: go back to forking solution
This commit is contained in:
commit
f838365314
5 changed files with 44 additions and 22 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1664,6 +1664,7 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"imagesize",
|
"imagesize",
|
||||||
"inquire",
|
"inquire",
|
||||||
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"notify-rust",
|
"notify-rust",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ imagesize = "0.14.0"
|
||||||
inquire = { default-features = false, version = "0.9.1", features = [
|
inquire = { default-features = false, version = "0.9.1", features = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
] }
|
] }
|
||||||
|
libc = "0.2.177"
|
||||||
log = "0.4.28"
|
log = "0.4.28"
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
thiserror = "2.0.17"
|
thiserror = "2.0.17"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@ pub trait QueryCommand {
|
||||||
|
|
||||||
impl QueryCommand for SqliteClipboardDb {
|
impl QueryCommand for SqliteClipboardDb {
|
||||||
fn query_delete(&self, query: &str) -> Result<usize, StashError> {
|
fn query_delete(&self, query: &str) -> Result<usize, StashError> {
|
||||||
<SqliteClipboardDb as ClipboardDb>::delete_query(self, query)
|
<Self as ClipboardDb>::delete_query(self, query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ impl ClipboardDb for SqliteClipboardDb {
|
||||||
.execute(
|
.execute(
|
||||||
"INSERT INTO clipboard (contents, mime, content_hash) VALUES (?1, ?2, \
|
"INSERT INTO clipboard (contents, mime, content_hash) VALUES (?1, ?2, \
|
||||||
?3)",
|
?3)",
|
||||||
params![buf, mime.map(|s| s.to_string()), content_hash],
|
params![buf, mime, content_hash],
|
||||||
)
|
)
|
||||||
.map_err(|e| StashError::Store(e.to_string().into()))?;
|
.map_err(|e| StashError::Store(e.to_string().into()))?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ fn handle_check_primary() {
|
||||||
std::process::exit(exit_code);
|
std::process::exit(exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_clipboard_type(primary: bool) -> CopyClipboardType {
|
const fn get_clipboard_type(primary: bool) -> CopyClipboardType {
|
||||||
if primary {
|
if primary {
|
||||||
CopyClipboardType::Primary
|
CopyClipboardType::Primary
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -213,21 +213,32 @@ fn handle_clear_clipboard(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fork_and_serve(prepared_copy: wl_clipboard_rs::copy::PreparedCopy) {
|
fn fork_and_serve(prepared_copy: wl_clipboard_rs::copy::PreparedCopy) {
|
||||||
// Use a simpler approach: serve in background thread instead of forking
|
// Use proper Unix fork() to create a child process that continues
|
||||||
// This avoids all the complexity and safety issues with fork()
|
// serving clipboard content after parent exits.
|
||||||
let handle = std::thread::spawn(move || {
|
// XXX: I wanted to choose and approach without fork, but we could not
|
||||||
if let Err(e) = prepared_copy.serve() {
|
// ensure persistence after the thread dies. Alas, we gotta fork.
|
||||||
log::error!("background clipboard service failed: {e}");
|
unsafe {
|
||||||
|
match libc::fork() {
|
||||||
|
0 => {
|
||||||
|
// Child process - serve clipboard content
|
||||||
|
if let Err(e) = prepared_copy.serve() {
|
||||||
|
log::error!("background clipboard service failed: {e}");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
std::process::exit(0);
|
||||||
|
},
|
||||||
|
-1 => {
|
||||||
|
// Fork failed
|
||||||
|
log::error!("failed to fork background process");
|
||||||
|
std::process::exit(1);
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
// Parent process - exit immediately
|
||||||
|
log::debug!("forked background process to serve clipboard content");
|
||||||
|
std::process::exit(0);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
// Give the background thread a moment to start
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
|
||||||
log::debug!("clipboard service started in background thread");
|
|
||||||
|
|
||||||
// Detach the thread to allow it to run independently
|
|
||||||
// The thread will be cleaned up when it completes or when the process exits
|
|
||||||
std::mem::forget(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wl_copy_main() -> Result<()> {
|
pub fn wl_copy_main() -> Result<()> {
|
||||||
|
|
@ -255,14 +266,23 @@ pub fn wl_copy_main() -> Result<()> {
|
||||||
|
|
||||||
// Handle foreground vs background mode
|
// Handle foreground vs background mode
|
||||||
if args.foreground {
|
if args.foreground {
|
||||||
// Foreground mode: copy and serve in current process
|
// Foreground mode: copy content and serve in current process
|
||||||
opts
|
// Use prepare_copy + serve to ensure proper clipboard registration
|
||||||
.copy(Source::Bytes(input.into()), mime_type)
|
let mut opts_fg = opts;
|
||||||
.context("failed to copy to clipboard")?;
|
opts_fg.foreground(true);
|
||||||
|
|
||||||
|
let prepared_copy = opts_fg
|
||||||
|
.prepare_copy(Source::Bytes(input.into()), mime_type)
|
||||||
|
.context("failed to prepare copy")?;
|
||||||
|
|
||||||
|
// Serve in foreground - blocks until interrupted (Ctrl+C, etc.)
|
||||||
|
prepared_copy
|
||||||
|
.serve()
|
||||||
|
.context("failed to serve clipboard content")?;
|
||||||
} else {
|
} else {
|
||||||
// Background mode: spawn child process to serve requests
|
// Background mode: spawn child process to serve requests
|
||||||
// First prepare to copy to validate before spawning
|
// First prepare to copy to validate before spawning
|
||||||
let mut opts_fg = opts.clone();
|
let mut opts_fg = opts;
|
||||||
opts_fg.foreground(true);
|
opts_fg.foreground(true);
|
||||||
|
|
||||||
let prepared_copy = opts_fg
|
let prepared_copy = opts_fg
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue