From 1fa6c3e790a9e1057129db03e6c1b798b227265b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 20 Apr 2026 22:25:26 -0400 Subject: [PATCH] working perfectly, refactored to use calloop --- rust/Cargo.lock | 86 +++++++++++++++++++++++++++++----- rust/Cargo.toml | 8 ++-- rust/src/api/workspace_api.rs | 87 +++++++++++++++-------------------- 3 files changed, 116 insertions(+), 65 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index fd84da8..a7c3dc2 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -126,6 +126,31 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "calloop" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" +dependencies = [ + "bitflags", + "polling", + "rustix", + "slab", + "tracing", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + [[package]] name = "cc" version = "1.0.83" @@ -141,6 +166,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -151,15 +185,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -404,6 +429,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hex" version = "0.4.3" @@ -489,7 +520,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.3", "libc", ] @@ -550,6 +581,20 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.5.2", + "pin-project-lite", + "rustix", + "windows-sys", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -625,9 +670,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" name = "rust_lib_flight" version = "0.1.0" dependencies = [ - "crossbeam-channel", + "calloop", + "calloop-wayland-source", "flutter_rust_bridge", - "libc", "serde", "serde_json", "wayland-client", @@ -748,6 +793,23 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" + [[package]] name = "typenum" version = "1.17.0" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index aa00f70..f0d324e 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -8,10 +8,12 @@ crate-type = ["cdylib", "staticlib"] [dependencies] flutter_rust_bridge = "=2.11.1" -wayland-client = "0.31" serde = { version = "1", features = ["derive"] } serde_json = "1" + +wayland-client = "0.31" wayland-protocols = { version = "0.32.12", features = ["client", "staging"] } -libc = "0.2.185" -crossbeam-channel = "0.5.15" + +calloop = "0.14.4" +calloop-wayland-source = "0.4.1" diff --git a/rust/src/api/workspace_api.rs b/rust/src/api/workspace_api.rs index d5dfee4..5913dae 100644 --- a/rust/src/api/workspace_api.rs +++ b/rust/src/api/workspace_api.rs @@ -1,9 +1,14 @@ use crate::{frb_generated::StreamSink, internal::wayland::AppState}; +use std::{collections::HashMap, sync::OnceLock}; use serde_json::Result; -use std::collections::HashMap; + +use calloop::{ + EventLoop, + channel::{Channel, Sender, channel}, +}; +use calloop_wayland_source::WaylandSource; + use wayland_client::Connection; -use std::sync::{OnceLock, mpsc::Sender}; -use std::os::fd::AsRawFd; static CONTROLLER: OnceLock> = OnceLock::new(); @@ -23,59 +28,41 @@ impl Workspace { } pub fn listen_workspaces(sink: StreamSink>>) -> Result<()> { - use std::sync::mpsc; + let (tx, rx): (Sender, Channel) = channel(); + CONTROLLER.set(tx).unwrap(); - let (tx, rx) = mpsc::channel::(); + let connection = Connection::connect_to_env().unwrap(); + let event_queue = connection.new_event_queue(); + let qh = event_queue.handle(); - CONTROLLER.set(tx).unwrap(); + let mut state = AppState { + workspaces: HashMap::new(), + workspace_groups: HashMap::new(), + workspace_handles: HashMap::new(), + sink, + }; - std::thread::spawn(move || { - let conn = Connection::connect_to_env().expect("Failed to connect to Wayland"); + let mut event_loop: EventLoop = EventLoop::try_new().unwrap(); + let handle = event_loop.handle(); - let mut event_queue = conn.new_event_queue(); - let qh = event_queue.handle(); + WaylandSource::new(connection.clone(), event_queue) + .insert(handle.clone()) + .unwrap(); - let mut state = AppState { - workspaces: HashMap::new(), - workspace_groups: HashMap::new(), - workspace_handles: HashMap::new(), - sink, - }; + handle + .insert_source(rx, |event, _, state| { + if let calloop::channel::Event::Msg(id) = event { + if let Some(ws) = state.workspace_handles.get(&id) { + ws.handle.activate(); + ws.manager_handle.commit(); + } + } + }) + .unwrap(); - conn.display().get_registry(&qh, ()); + connection.display().get_registry(&qh, ()); - -loop { - event_queue.flush().unwrap(); - - let read_guard = event_queue.prepare_read().unwrap(); - let fd = read_guard.connection_fd().as_raw_fd(); - - let mut fds = [libc::pollfd { - fd, - events: libc::POLLIN, - revents: 0, - }]; - - let timeout = 10; - - let res = unsafe { libc::poll(fds.as_mut_ptr(), 1, timeout) }; - - if res > 0 && (fds[0].revents & libc::POLLIN) != 0 { - read_guard.read().unwrap(); - event_queue.dispatch_pending(&mut state).unwrap(); - } else { - drop(read_guard); - } - - while let Ok(id) = rx.try_recv() { - if let Some(ws) = state.workspace_handles.get(&id) { - ws.handle.activate(); - ws.manager_handle.commit(); - } - } -} - }); + while let Ok(_) = event_loop.dispatch(None, &mut state) {} Ok(()) -} +} \ No newline at end of file