From 933867107029e363a7b29d9e95979b934043ce46 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 19 Apr 2026 15:20:10 -0400 Subject: [PATCH] it works! --- rust/src/api/workspace_api.rs | 4 -- rust/src/internal/wayland.rs | 96 +++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/rust/src/api/workspace_api.rs b/rust/src/api/workspace_api.rs index 5104589..991a0d2 100644 --- a/rust/src/api/workspace_api.rs +++ b/rust/src/api/workspace_api.rs @@ -11,22 +11,18 @@ pub struct Workspace { pub fn listen_workspaces(sink: StreamSink>) -> Result<()> { std::thread::spawn(move || { - // Connect to Wayland let conn = Connection::connect_to_env().expect("Failed to connect to Wayland"); let mut event_queue: EventQueue = conn.new_event_queue(); let qh = event_queue.handle(); - // Initialize state let mut state = AppState { workspaces: HashMap::new(), sink, }; - // Get registry (this triggers wl_registry events → binds manager) conn.display().get_registry(&qh, ()); - // Main event loop loop { event_queue .blocking_dispatch(&mut state) diff --git a/rust/src/internal/wayland.rs b/rust/src/internal/wayland.rs index cee6d5e..c5622e6 100644 --- a/rust/src/internal/wayland.rs +++ b/rust/src/internal/wayland.rs @@ -1,21 +1,39 @@ use crate::{frb_generated::StreamSink, workspace_api::Workspace}; use std::collections::HashMap; -use wayland_protocols::ext::workspace::v1::client::{ - ext_workspace_manager_v1, - ext_workspace_handle_v1, +use wayland_client::{ + self, Connection, Dispatch, QueueHandle, backend::ObjectId, event_created_child, protocol::wl_registry +}; +use wayland_protocols::ext::workspace::v1::client::{ + ext_workspace_group_handle_v1, ext_workspace_handle_v1, ext_workspace_manager_v1, }; -use wayland_client::{self, Connection, Dispatch, QueueHandle, event_created_child, protocol::wl_registry}; pub struct AppState { - pub workspaces: HashMap, + pub workspaces: HashMap, pub sink: StreamSink>, } impl AppState { - // fn emit(&self) { - // let _ = self.sink.add(self.workspaces.values().cloned().collect()); - // } + fn emit(&self) { + let mut entries: Vec<(&ObjectId, &Workspace)> = self.workspaces.iter().collect(); + + entries.sort_by_key( + |entry: &(&ObjectId, &Workspace)| -> u32 { + entry.0.protocol_id() + }, + ); + + let sorted: Vec = entries + .into_iter() + .map( + |entry: (&ObjectId, &Workspace)| -> Workspace { + entry.1.clone() + }, + ) + .collect(); + + let _ = self.sink.add(sorted); + } } impl Dispatch for AppState { @@ -27,7 +45,7 @@ impl Dispatch for AppState { _conn: &Connection, qh: &QueueHandle, ) { - if let wl_registry::Event::Global { + if let wl_registry::Event::Global { name, interface, version, @@ -56,11 +74,15 @@ impl Dispatch for AppState ) { } - event_created_child!( + event_created_child!( AppState, ext_workspace_manager_v1::ExtWorkspaceManagerV1, [ - _workspace => ( + wayland_protocols::ext::workspace::v1::client::ext_workspace_manager_v1::EVT_WORKSPACE_GROUP_OPCODE => ( + ext_workspace_group_handle_v1::ExtWorkspaceGroupHandleV1, + () + ), + wayland_protocols::ext::workspace::v1::client::ext_workspace_manager_v1::EVT_WORKSPACE_OPCODE => ( ext_workspace_handle_v1::ExtWorkspaceHandleV1, () ) @@ -68,17 +90,59 @@ impl Dispatch for AppState ); } - +use wayland_client::Proxy; impl Dispatch for AppState { fn event( state: &mut Self, - _proxy: &ext_workspace_handle_v1::ExtWorkspaceHandleV1, + proxy: &ext_workspace_handle_v1::ExtWorkspaceHandleV1, event: ext_workspace_handle_v1::Event, _data: &(), _conn: &Connection, _qh: &QueueHandle, ) { - println!("workspace event: {:?}", event); - + match event { + ext_workspace_handle_v1::Event::Id { id: _ } => { + + state + .workspaces + .insert(proxy.id(), Workspace { activated: false }); + state.emit(); + } + + ext_workspace_handle_v1::Event::State { state: flags } => { + let active = matches!( + flags, + wayland_client::WEnum::Value(ext_workspace_handle_v1::State::Active) + ); + + let id = proxy.id(); + + if let Some(ws) = state.workspaces.get_mut(&id) { + ws.activated = active; + } + + state.emit(); + } + + ext_workspace_handle_v1::Event::Removed => { + state.workspaces.remove(&proxy.id()); + state.emit(); + } + + _ => {} + } } -} \ No newline at end of file +} + +impl Dispatch for AppState { + fn event( + _state: &mut Self, + _proxy: &ext_workspace_group_handle_v1::ExtWorkspaceGroupHandleV1, + _event: ext_workspace_group_handle_v1::Event, + _data: &(), + _conn: &Connection, + _qh: &QueueHandle, + ) { + // println!("workspace GROUP event: {:?}", event); + } +}