working perfectly, refactored to use calloop

This commit is contained in:
Henry Hiles 2026-04-20 22:25:26 -04:00
commit 1fa6c3e790
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
3 changed files with 123 additions and 72 deletions

86
rust/Cargo.lock generated
View file

@ -126,6 +126,31 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 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]] [[package]]
name = "cc" name = "cc"
version = "1.0.83" version = "1.0.83"
@ -141,6 +166,15 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 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]] [[package]]
name = "console_error_panic_hook" name = "console_error_panic_hook"
version = "0.1.7" version = "0.1.7"
@ -151,15 +185,6 @@ dependencies = [
"wasm-bindgen", "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]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.21" version = "0.8.21"
@ -404,6 +429,12 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]] [[package]]
name = "hex" name = "hex"
version = "0.4.3" version = "0.4.3"
@ -489,7 +520,7 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi 0.3.3",
"libc", "libc",
] ]
@ -550,6 +581,20 @@ version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" 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]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.13.1" version = "1.13.1"
@ -625,9 +670,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
name = "rust_lib_flight" name = "rust_lib_flight"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"crossbeam-channel", "calloop",
"calloop-wayland-source",
"flutter_rust_bridge", "flutter_rust_bridge",
"libc",
"serde", "serde",
"serde_json", "serde_json",
"wayland-client", "wayland-client",
@ -748,6 +793,23 @@ dependencies = [
"pin-project-lite", "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]] [[package]]
name = "typenum" name = "typenum"
version = "1.17.0" version = "1.17.0"

View file

@ -8,10 +8,12 @@ crate-type = ["cdylib", "staticlib"]
[dependencies] [dependencies]
flutter_rust_bridge = "=2.11.1" flutter_rust_bridge = "=2.11.1"
wayland-client = "0.31"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
wayland-client = "0.31"
wayland-protocols = { version = "0.32.12", features = ["client", "staging"] } 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"

View file

@ -1,9 +1,14 @@
use crate::{frb_generated::StreamSink, internal::wayland::AppState}; use crate::{frb_generated::StreamSink, internal::wayland::AppState};
use std::{collections::HashMap, sync::OnceLock};
use serde_json::Result; 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 wayland_client::Connection;
use std::sync::{OnceLock, mpsc::Sender};
use std::os::fd::AsRawFd;
static CONTROLLER: OnceLock<Sender<u32>> = OnceLock::new(); static CONTROLLER: OnceLock<Sender<u32>> = OnceLock::new();
@ -23,59 +28,41 @@ impl Workspace {
} }
pub fn listen_workspaces(sink: StreamSink<Vec<Vec<Workspace>>>) -> Result<()> { pub fn listen_workspaces(sink: StreamSink<Vec<Vec<Workspace>>>) -> Result<()> {
use std::sync::mpsc; let (tx, rx): (Sender<u32>, Channel<u32>) = channel();
CONTROLLER.set(tx).unwrap();
let (tx, rx) = mpsc::channel::<u32>(); 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 mut event_loop: EventLoop<AppState> = EventLoop::try_new().unwrap();
let conn = Connection::connect_to_env().expect("Failed to connect to Wayland"); let handle = event_loop.handle();
let mut event_queue = conn.new_event_queue(); WaylandSource::new(connection.clone(), event_queue)
let qh = event_queue.handle(); .insert(handle.clone())
.unwrap();
let mut state = AppState { handle
workspaces: HashMap::new(), .insert_source(rx, |event, _, state| {
workspace_groups: HashMap::new(), if let calloop::channel::Event::Msg(id) = event {
workspace_handles: HashMap::new(), if let Some(ws) = state.workspace_handles.get(&id) {
sink, ws.handle.activate();
}; ws.manager_handle.commit();
}
}
})
.unwrap();
conn.display().get_registry(&qh, ()); connection.display().get_registry(&qh, ());
while let Ok(_) = event_loop.dispatch(None, &mut state) {}
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();
}
}
}
});
Ok(()) Ok(())
} }