Introduce IPC socket
This commit is contained in:
parent
8959cce9f9
commit
a31baa3670
@ -21,6 +21,7 @@ toml = "0.9.8"
|
||||
popcorn-conf = { path = "../popcorn-conf" }
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
popcorn-proto = { path = "../popcorn-proto" }
|
||||
bincode = "1.3.3"
|
||||
|
||||
[build-dependencies]
|
||||
slint-build = "1.14.1"
|
||||
|
||||
56
crates/popcorn-d/src/ipc.rs
Normal file
56
crates/popcorn-d/src/ipc.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use std::fs;
|
||||
use std::io::Read;
|
||||
use std::os::unix::net::{UnixListener, UnixStream};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use dirs::runtime_dir;
|
||||
use popcorn_proto::OsdArgs;
|
||||
|
||||
/// Start a Unix socket server and forward received messages to the UI thread.
|
||||
pub fn start_ipc(tx: Sender<OsdArgs>) -> std::io::Result<()> {
|
||||
let sock_path = socket_path();
|
||||
|
||||
// Remove leftover socket from a previous run.
|
||||
let _ = fs::remove_file(&sock_path);
|
||||
|
||||
// Create parent directory if missing.
|
||||
if let Some(parent) = sock_path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
// Bind the Unix domain socket.
|
||||
let listener = UnixListener::bind(&sock_path)?;
|
||||
|
||||
// Run the IPC accept loop in a background thread.
|
||||
std::thread::spawn(move || {
|
||||
// Accept short-lived connections.
|
||||
for stream in listener.incoming() {
|
||||
if let Ok(stream) = stream {
|
||||
// Read one message per connection.
|
||||
if let Ok(args) = read_message(stream) {
|
||||
// Forward to UI thread via channel.
|
||||
let _ = tx.send(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read a single serialized OsdArgs message from a socket.
|
||||
fn read_message(mut stream: UnixStream) -> bincode::Result<OsdArgs> {
|
||||
let mut buf = Vec::new();
|
||||
// Read until client closes the connection.
|
||||
stream.read_to_end(&mut buf)?;
|
||||
// Deserialize binary message.
|
||||
bincode::deserialize(&buf)
|
||||
}
|
||||
|
||||
/// Compute the per-user runtime socket path.
|
||||
fn socket_path() -> PathBuf {
|
||||
// Prefer XDG runtime dir. Fallback to /tmp.
|
||||
let base = runtime_dir().unwrap_or_else(|| PathBuf::from("/tmp"));
|
||||
base.join("candywidgets").join("popcorn.sock")
|
||||
}
|
||||
@ -1,18 +1,38 @@
|
||||
mod ipc;
|
||||
mod osd;
|
||||
|
||||
use osd::OsdUi;
|
||||
use popcorn_conf::PopcornConfig;
|
||||
use popcorn_proto::OsdArgs;
|
||||
|
||||
use std::sync::mpsc;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Load configuration once at startup.
|
||||
let cfg = PopcornConfig::load_or_default();
|
||||
|
||||
// Create the OSD UI on the main (UI) thread.
|
||||
let osd = OsdUi::new(&cfg)?;
|
||||
|
||||
// start IPC loop here
|
||||
// for each message:
|
||||
// osd.update(&args, &cfg)
|
||||
// reset timer
|
||||
// Channel used to send IPC messages to the UI thread.
|
||||
let (tx, rx) = mpsc::channel::<OsdArgs>();
|
||||
|
||||
let _ = slint::run_event_loop();
|
||||
// Start IPC server in a background thread.
|
||||
ipc::start_ipc(tx)?;
|
||||
|
||||
// Poll IPC messages on the UI thread.
|
||||
slint::Timer::default().start(
|
||||
slint::TimerMode::Repeated,
|
||||
std::time::Duration::from_millis(16),
|
||||
move || {
|
||||
// Process all pending messages.
|
||||
while let Ok(args) = rx.try_recv() {
|
||||
let _ = osd.update(&args, &cfg);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Run the Slint event loop.
|
||||
slint::run_event_loop();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -12,5 +12,6 @@ keywords = ["OSD", "popup", "desktop", "cli"]
|
||||
license = "GPL-3+"
|
||||
|
||||
[dependencies]
|
||||
bincode = "1.3.3"
|
||||
clap = { version = "4.5.53", features = ["derive"] }
|
||||
popcorn-proto = { path = "../popcorn-proto" }
|
||||
@ -1,8 +1,8 @@
|
||||
mod args;
|
||||
|
||||
use args::CliArgs;
|
||||
use popcorn_proto::OsdArgs;
|
||||
use clap::Parser;
|
||||
use popcorn_proto::OsdArgs;
|
||||
|
||||
fn main() {
|
||||
let cli = CliArgs::parse();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user