diff --git a/Cargo.toml b/Cargo.toml index 0ba6419..db233a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ debug = ["iced/debug"] softbuffer = ["iced/softbuffer", "iced_softbuffer"] wayland = ["iced/wayland", "iced/glow"] wgpu = ["iced/wgpu", "iced_wgpu"] -tokio = ["iced/tokio"] +tokio = ["dep:tokio", "iced/tokio"] winit = ["iced/winit", "iced_winit"] applet = ["cosmic-panel-config", "sctk", "wayland"] winit_softbuffer = ["winit", "softbuffer"] @@ -23,6 +23,7 @@ apply = "0.3.0" derive_setters = "0.1.5" lazy_static = "1.4.0" palette = "0.6.1" +tokio = { version = "1.24.2", optional = true } cosmic-panel-config = {git = "https://github.com/pop-os/cosmic-panel", optional = true } sctk = { package = "smithay-client-toolkit", git = "https://github.com/Smithay/client-toolkit", optional = true, rev = "3776d4a" } slotmap = "1.0.6" diff --git a/src/lib.rs b/src/lib.rs index 97b337f..fa454d4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,11 @@ pub mod keyboard_nav; pub mod theme; pub mod widget; +#[cfg(feature = "tokio")] +mod single_thread_executor; +#[cfg(feature = "tokio")] +pub use single_thread_executor::SingleThreadExecutor; + pub mod settings; pub use settings::settings; diff --git a/src/single_thread_executor.rs b/src/single_thread_executor.rs new file mode 100644 index 0000000..e9ee318 --- /dev/null +++ b/src/single_thread_executor.rs @@ -0,0 +1,28 @@ +use std::{future::Future, thread}; + +#[cfg(feature = "tokio")] +pub struct SingleThreadExecutor(tokio::runtime::Runtime); + +#[cfg(feature = "tokio")] +impl iced_native::Executor for SingleThreadExecutor { + fn new() -> Result { + // Current thread executor requires calling `block_on` to actually run + // futures. Main thread is busy with things other than running futures, + // so spawn a single worker thread. + Ok(Self( + tokio::runtime::Builder::new_multi_thread() + .worker_threads(1) + .enable_all() + .build()?, + )) + } + + fn spawn(&self, future: impl Future + Send + 'static) { + let _ = self.0.spawn(future); + } + + fn enter(&self, f: impl FnOnce() -> R) -> R { + let _guard = self.0.enter(); + f() + } +}