refactor: change ipc channel to iced subscription

This commit is contained in:
ByteAtATime 2025-11-29 12:47:55 -08:00
parent ae23c71705
commit c863b0d7c9
No known key found for this signature in database
4 changed files with 44 additions and 28 deletions

View file

@ -1,6 +1,11 @@
use iced::futures::channel::mpsc;
use iced::futures::{SinkExt, Stream};
use iced::{Subscription, stream};
use std::io::{Read, Write};
use std::os::unix::net::{UnixListener, UnixStream};
use std::os::unix::net::UnixStream;
use std::path::PathBuf;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::UnixListener;
const IPC_COMMAND_TOGGLE: &[u8] = b"toggle";
const IPC_COMMAND_OAUTH_PREFIX: &[u8] = b"oauth:";
@ -50,39 +55,49 @@ pub fn is_daemon_running() -> bool {
UnixStream::connect(&path).is_ok()
}
pub fn start_listener<F>(on_toggle: F) -> Result<(), Box<dyn std::error::Error>>
where
F: Fn() + Send + 'static,
{
let path = socket_path();
fn listener() -> impl Stream<Item = crate::Message> {
stream::channel(100, |mut output: mpsc::Sender<crate::Message>| async move {
let path = socket_path();
if path.exists() {
std::fs::remove_file(&path)?;
}
if path.exists() {
let _ = std::fs::remove_file(&path);
}
let listener = UnixListener::bind(&path)?;
let listener = match UnixListener::bind(&path) {
Ok(l) => l,
Err(e) => {
eprintln!("Failed to bind IPC socket: {}", e);
std::future::pending::<()>().await;
return;
}
};
std::thread::spawn(move || {
for stream in listener.incoming() {
if let Ok(mut stream) = stream {
loop {
if let Ok((mut stream, _)) = listener.accept().await {
let mut buf = [0u8; 2048];
if let Ok(n) = stream.read(&mut buf) {
if let Ok(n) = stream.read(&mut buf).await {
let data = &buf[..n];
if data == IPC_COMMAND_TOGGLE {
on_toggle();
let _ = stream.write_all(IPC_RESPONSE_OK);
let _ = output.send(crate::Message::ToggleWindow).await;
let _ = stream.write_all(IPC_RESPONSE_OK).await;
} else if data.starts_with(IPC_COMMAND_OAUTH_PREFIX) {
let url = std::str::from_utf8(&data[IPC_COMMAND_OAUTH_PREFIX.len()..])
.unwrap_or("");
crate::deep_link::handle_oauth_redirect(url);
let _ = stream.write_all(IPC_RESPONSE_OK);
if let Ok(url) =
std::str::from_utf8(&data[IPC_COMMAND_OAUTH_PREFIX.len()..])
{
let _ = output
.send(crate::Message::HandleOAuthRedirect(url.to_string()))
.await;
let _ = stream.write_all(IPC_RESPONSE_OK).await;
}
}
}
}
}
});
})
}
Ok(())
pub fn subscription() -> Subscription<crate::Message> {
Subscription::run(listener)
}
pub fn cleanup() {

View file

@ -148,12 +148,15 @@ fn subscription(state: &State) -> Subscription<Message> {
None
});
let ipc_sub = ipc::subscription();
let mut subs = vec![
message_sub,
sidecar_sub,
window_close_sub,
animation_sub,
escape_sub,
ipc_sub,
];
if state.window_id.is_some() {
@ -305,12 +308,6 @@ fn run_daemon() -> Result<(), Box<dyn std::error::Error>> {
setup_channels();
ipc::start_listener(|| {
if let Some(mut sender) = globals::SENDER.lock().unwrap().clone() {
let _ = iced::futures::executor::block_on(sender.send(Message::ToggleWindow));
}
})?;
let result = iced::daemon(boot, update, daemon_view)
.subscription(subscription)
.title("Flare")

View file

@ -38,6 +38,7 @@ pub enum Message {
Settings(crate::screens::settings::SettingsMessage),
OpenUrl(String),
HandleOAuthRedirect(String),
Tick(Instant),

View file

@ -227,6 +227,9 @@ pub fn update(state: &mut State, message: Message) -> Task<Message> {
Message::OpenUrl(url) => {
let _ = crate::utils::open_url(&url);
}
Message::HandleOAuthRedirect(url) => {
crate::deep_link::handle_oauth_redirect(&url);
}
Message::SidecarMessage(response) => {
return handle_sidecar_response(state, response);