diff --git a/Cargo.toml b/Cargo.toml index 585ef56..8f0a167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,8 @@ edition = "2021" [dependencies] cctk = { package = "cosmic-client-toolkit", git = "https://github.com/pop-os/cosmic-protocols" } futures-channel = "0.3.25" -# iced = { git = "https://github.com/pop-os/libcosmic", features = ["tokio"] } -# iced_native = { git = "https://github.com/pop-os/libcosmic" } -# iced_sctk = { git = "https://github.com/pop-os/libcosmic" } -# libcosmic = { git = "https://github.com/pop-os/libcosmic" } -iced = { path = "/home/ian/src/pop/libcosmic/iced", features = ["tokio"] } -iced_native = { path = "/home/ian/src/pop/libcosmic/iced/native" } -iced_sctk = { path = "/home/ian/src/pop/libcosmic/iced/sctk" } -libcosmic = { path = "/home/ian/src/pop/libcosmic" } +iced = { git = "https://github.com/pop-os/libcosmic", features = ["tokio", "wayland"] } +iced_native = { git = "https://github.com/pop-os/libcosmic" } +iced_sctk = { git = "https://github.com/pop-os/libcosmic" } +libcosmic = { git = "https://github.com/pop-os/libcosmic" } tokio = "1.23.0" diff --git a/src/main.rs b/src/main.rs index 8a37aff..3c11dc5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,15 @@ use cctk::{ cosmic_protocols::{ toplevel_info::v1::client::zcosmic_toplevel_handle_v1, - workspace::v1::client::zcosmic_workspace_handle_v1, + workspace::v1::client::{zcosmic_workspace_handle_v1, zcosmic_workspace_manager_v1}, }, sctk::shell::layer::{Anchor, KeyboardInteractivity, Layer}, toplevel_info::ToplevelInfo, - wayland_client::protocol::wl_output, + wayland_client::{protocol::wl_output, Connection, QueueHandle, WEnum}, }; use iced::{ event::wayland::{Event as WaylandEvent, OutputEvent}, keyboard::KeyCode, - sctk_settings::InitialSurface, widget, Application, Command, Element, Subscription, }; use iced_native::{ @@ -20,8 +19,9 @@ use iced_native::{ use iced_sctk::{ application::SurfaceIdWrapper, commands::layer_surface::{destroy_layer_surface, get_layer_surface}, + settings::InitialSurface, }; -use std::{collections::HashMap, process}; +use std::{collections::HashMap, mem, process}; mod wayland; @@ -63,6 +63,10 @@ struct App { layer_surfaces: HashMap, workspaces: Vec, toplevels: Vec, + workspace_manager: Option<( + Connection, + zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1, + )>, } impl App { @@ -84,6 +88,18 @@ impl App { ) -> Option<&mut Toplevel> { self.toplevels.iter_mut().find(|i| &i.handle == handle) } + + fn layer_surface_for_output_name( + &mut self, + output_name: Option<&str>, + ) -> Option<&mut LayerSurface> { + for surface in self.layer_surfaces.values_mut() { + if surface.output_name.as_deref() == output_name { + return Some(surface); + } + } + None + } } impl Application for App { @@ -148,16 +164,36 @@ impl Application for App { }, Msg::Wayland(evt) => { match evt { + wayland::Event::WorkspaceManager(conn, manager) => { + self.workspace_manager = Some((conn, manager)); + } wayland::Event::Workspaces(workspaces) => { - // XXX efficiency - // XXX removal + let old_workspaces = mem::take(&mut self.workspaces); self.workspaces = Vec::new(); for (output_name, workspace) in workspaces { + let is_active = workspace.state.contains(&WEnum::Value( + zcosmic_workspace_handle_v1::State::Active, + )); + if is_active { + // XXX + if let Some(surface) = + self.layer_surface_for_output_name(output_name.as_deref()) + { + surface.active_workspace = Some(workspace.handle.clone()); + } + } + + // XXX efficiency + let img = old_workspaces + .iter() + .find(|i| &i.handle == &workspace.handle) + .and_then(|i| i.img.clone()); + self.workspaces.push(Workspace { name: workspace.name, handle: workspace.handle, output_name, - img: None, + img, }); } } @@ -187,18 +223,11 @@ impl Application for App { } Msg::Closed(_) => {} Msg::ActivateWorkspace(workspace_handle) => { - // XXX - for workspace in &self.workspaces { - if &workspace.handle == &workspace_handle { - for surface in self.layer_surfaces.values_mut() { - if &surface.output_name == &workspace.output_name { - surface.active_workspace = Some(workspace_handle); - break; - } - } - break; - } - } + println!("Activate: {:?}", workspace_handle); + let (conn, workspace_manager) = self.workspace_manager.as_ref().unwrap(); + workspace_handle.activate(); + workspace_manager.commit(); + conn.flush(); } } diff --git a/src/wayland.rs b/src/wayland.rs index 447f7fd..3017e26 100644 --- a/src/wayland.rs +++ b/src/wayland.rs @@ -10,7 +10,7 @@ use cctk::{ cosmic_protocols::{ screencopy::v1::client::{zcosmic_screencopy_manager_v1, zcosmic_screencopy_session_v1}, toplevel_info::v1::client::zcosmic_toplevel_handle_v1, - workspace::v1::client::zcosmic_workspace_handle_v1, + workspace::v1::client::{zcosmic_workspace_handle_v1, zcosmic_workspace_manager_v1}, }, screencopy::{BufferInfo, ScreencopyHandler, ScreencopyState}, sctk::{ @@ -39,6 +39,10 @@ use std::{collections::HashMap, thread}; #[derive(Clone, Debug)] pub enum Event { + WorkspaceManager( + Connection, + zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1, + ), // XXX Output name rather than `WlOutput` Workspaces(Vec<(Option, cctk::workspace::Workspace)>), WorkspaceCapture( @@ -70,7 +74,7 @@ struct Frame { first_frame: bool, } -struct AppData { +pub struct AppData { qh: QueueHandle, output_state: OutputState, registry_state: RegistryState, @@ -265,6 +269,7 @@ impl ScreencopyHandler for AppData { session.commit(zcosmic_screencopy_session_v1::Options::empty()); } else { session.commit(zcosmic_screencopy_session_v1::Options::OnDamage); + // TODO } conn.flush().unwrap(); @@ -336,6 +341,10 @@ fn start() -> mpsc::Receiver { output_names: HashMap::new(), }; + if let Ok(manager) = app_data.workspace_state.workspace_manager().get() { + app_data.send_event(Event::WorkspaceManager(conn, manager.clone())); + } + thread::spawn(move || loop { event_queue.blocking_dispatch(&mut app_data).unwrap(); });