From b7c65c877df0180b96579a1ba395212de78057bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 May 2024 12:25:44 +0200 Subject: [PATCH] Toggle the Comet when pressing `F12` --- Cargo.toml | 4 ++-- beacon/src/client.rs | 32 +++++++++++++++++++++++++++-- beacon/src/lib.rs | 36 +++++++++++++++++++++++++++++---- debug/src/lib.rs | 19 ++++++++++++++++- winit/Cargo.toml | 2 ++ winit/src/application.rs | 20 ++++++++++++++++++ winit/src/application/state.rs | 13 ------------ winit/src/multi_window.rs | 21 +++++++++++++++++++ winit/src/multi_window/state.rs | 13 ------------ 9 files changed, 125 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3874b403..046e92ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ qr_code = ["iced_widget/qr_code"] # Enables lazy widgets lazy = ["iced_widget/lazy"] # Enables a debug view in native platforms (press F12) -debug = ["iced_debug/enable"] +debug = ["iced_winit/debug"] # Enables `tokio` as the `executor::Default` on native platforms tokio = ["iced_futures/tokio"] # Enables `async-std` as the `executor::Default` on native platforms @@ -62,8 +62,8 @@ fira-sans = ["iced_renderer/fira-sans"] auto-detect-theme = ["iced_core/auto-detect-theme"] [dependencies] -iced_core.workspace = true iced_debug.workspace = true +iced_core.workspace = true iced_futures.workspace = true iced_renderer.workspace = true iced_widget.workspace = true diff --git a/beacon/src/client.rs b/beacon/src/client.rs index 28cb2eeb..44f6af52 100644 --- a/beacon/src/client.rs +++ b/beacon/src/client.rs @@ -9,6 +9,7 @@ use tokio::net; use tokio::sync::mpsc; use tokio::time; +use std::sync::atomic::{self, AtomicBool}; use std::sync::Arc; use std::thread; @@ -17,6 +18,7 @@ pub const SERVER_ADDRESS: &str = "127.0.0.1:9167"; #[derive(Debug, Clone)] pub struct Client { sender: mpsc::Sender, + is_connected: Arc, _handle: Arc>, } @@ -31,6 +33,9 @@ pub enum Message { at: SystemTime, event: Event, }, + Quit { + at: SystemTime, + }, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -47,28 +52,50 @@ impl Client { event, }); } + + pub fn is_connected(&self) -> bool { + self.is_connected.load(atomic::Ordering::Relaxed) + } + + pub fn quit(&self) { + let _ = self.sender.try_send(Message::Quit { + at: SystemTime::now(), + }); + } } #[must_use] pub fn connect(name: String) -> Client { let (sender, receiver) = mpsc::channel(100); + let is_connected = Arc::new(AtomicBool::new(false)); - let handle = std::thread::spawn(move || run(name, receiver)); + let handle = { + let is_connected = is_connected.clone(); + + std::thread::spawn(move || run(name, is_connected.clone(), receiver)) + }; Client { sender, + is_connected, _handle: Arc::new(handle), } } #[tokio::main] -async fn run(name: String, mut receiver: mpsc::Receiver) { +async fn run( + name: String, + is_connected: Arc, + mut receiver: mpsc::Receiver, +) { let version = semver::Version::parse(env!("CARGO_PKG_VERSION")) .expect("Parse package version"); loop { match _connect().await { Ok(mut stream) => { + is_connected.store(true, atomic::Ordering::Relaxed); + let _ = send( &mut stream, Message::Connected { @@ -92,6 +119,7 @@ async fn run(name: String, mut receiver: mpsc::Receiver) { } } Err(_) => { + is_connected.store(false, atomic::Ordering::Relaxed); time::sleep(time::Duration::from_secs(2)).await; } } diff --git a/beacon/src/lib.rs b/beacon/src/lib.rs index 3149d8b5..ff2f36b0 100644 --- a/beacon/src/lib.rs +++ b/beacon/src/lib.rs @@ -35,6 +35,12 @@ pub enum Event { duration: Duration, span: Span, }, + QuitRequested { + at: SystemTime, + }, + AlreadyRunning { + at: SystemTime, + }, } impl Event { @@ -43,19 +49,36 @@ impl Event { Self::Connected { at, .. } | Self::Disconnected { at, .. } | Self::ThemeChanged { at, .. } - | Self::SpanFinished { at, .. } => *at, + | Self::SpanFinished { at, .. } + | Self::QuitRequested { at } + | Self::AlreadyRunning { at } => *at, } } } +pub fn is_running() -> bool { + std::net::TcpListener::bind(client::SERVER_ADDRESS).is_err() +} + pub fn run() -> impl Stream { stream::channel(|mut output| async move { let mut buffer = Vec::new(); loop { - let Ok(mut stream) = connect().await else { - delay().await; - continue; + let mut stream = match connect().await { + Ok(stream) => stream, + Err(error) => { + if error.kind() == io::ErrorKind::AddrInUse { + let _ = output + .send(Event::AlreadyRunning { + at: SystemTime::now(), + }) + .await; + } + + delay().await; + continue; + } }; loop { @@ -124,6 +147,11 @@ pub fn run() -> impl Stream { } } } + client::Message::Quit { at } => { + let _ = output + .send(Event::QuitRequested { at }) + .await; + } }; } Err(Error::IOFailed(_)) => { diff --git a/debug/src/lib.rs b/debug/src/lib.rs index 779cbb2c..125499e4 100644 --- a/debug/src/lib.rs +++ b/debug/src/lib.rs @@ -9,7 +9,9 @@ pub fn init(name: &str) { internal::init(name); } -pub fn open_comet() {} +pub fn toggle_comet() { + internal::toggle_comet(); +} pub fn log_message(_message: &impl std::fmt::Debug) {} @@ -65,6 +67,7 @@ mod internal { use beacon::span; use once_cell::sync::Lazy; + use std::process; use std::sync::atomic::{self, AtomicBool}; use std::sync::RwLock; @@ -72,6 +75,18 @@ mod internal { name.clone_into(&mut NAME.write().expect("Write application name")); } + pub fn toggle_comet() { + if BEACON.is_connected() { + BEACON.quit(); + } else { + let _ = process::Command::new("iced_comet") + .stdin(process::Stdio::null()) + .stdout(process::Stdio::null()) + .stderr(process::Stdio::null()) + .spawn(); + } + } + pub fn theme_changed(f: impl FnOnce() -> Option) { let Some(palette) = f() else { return; @@ -166,6 +181,8 @@ mod internal { pub fn init(_name: &str) {} + pub fn toggle_comet() {} + pub fn theme_changed(_f: impl FnOnce() -> Option) {} pub fn boot() -> Span { diff --git a/winit/Cargo.toml b/winit/Cargo.toml index c06afeeb..bb1a8321 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -15,6 +15,7 @@ workspace = true [features] default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] +debug = ["iced_debug/enable"] system = ["sysinfo"] application = [] x11 = ["winit/x11"] @@ -24,6 +25,7 @@ wayland-csd-adwaita = ["winit/wayland-csd-adwaita"] multi-window = ["iced_runtime/multi-window"] [dependencies] +iced_debug.workspace = true iced_futures.workspace = true iced_graphics.workspace = true iced_runtime.workspace = true diff --git a/winit/src/application.rs b/winit/src/application.rs index 49ccb61c..d7949b9e 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -716,6 +716,26 @@ async fn run_instance( break; } + #[cfg(feature = "debug")] + match window_event { + winit::event::WindowEvent::KeyboardInput { + event: + winit::event::KeyEvent { + logical_key: + winit::keyboard::Key::Named( + winit::keyboard::NamedKey::F12, + ), + state: winit::event::ElementState::Pressed, + repeat: false, + .. + }, + .. + } => { + crate::debug::toggle_comet(); + } + _ => {} + } + state.update(&window, &window_event); if let Some(event) = conversion::window_event( diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index da9519ee..e51f5348 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -161,19 +161,6 @@ where WindowEvent::ModifiersChanged(new_modifiers) => { self.modifiers = new_modifiers.state(); } - #[cfg(feature = "debug")] - WindowEvent::KeyboardInput { - event: - winit::event::KeyEvent { - logical_key: - winit::keyboard::Key::Named( - winit::keyboard::NamedKey::F12, - ), - state: winit::event::ElementState::Pressed, - .. - }, - .. - } => crate::debug::open_axe(), _ => {} } } diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index 473913bc..54208412 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -777,6 +777,27 @@ async fn run_instance( event: window_event, window_id, } => { + #[cfg(feature = "debug")] + match window_event { + winit::event::WindowEvent::KeyboardInput { + event: + winit::event::KeyEvent { + logical_key: + winit::keyboard::Key::Named( + winit::keyboard::NamedKey::F12, + ), + state: + winit::event::ElementState::Pressed, + repeat: false, + .. + }, + .. + } => { + crate::debug::toggle_comet(); + } + _ => {} + } + let Some((id, window)) = window_manager.get_mut_alias(window_id) else { diff --git a/winit/src/multi_window/state.rs b/winit/src/multi_window/state.rs index bc88c04b..5368b849 100644 --- a/winit/src/multi_window/state.rs +++ b/winit/src/multi_window/state.rs @@ -173,19 +173,6 @@ where WindowEvent::ModifiersChanged(new_modifiers) => { self.modifiers = new_modifiers.state(); } - #[cfg(feature = "debug")] - WindowEvent::KeyboardInput { - event: - winit::event::KeyEvent { - logical_key: - winit::keyboard::Key::Named( - winit::keyboard::NamedKey::F12, - ), - state: winit::event::ElementState::Pressed, - .. - }, - .. - } => _debug.toggle(), _ => {} } }