diff --git a/Cargo.lock b/Cargo.lock index a7da0fd..2b7b407 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -689,6 +689,15 @@ dependencies = [ "wayland-client 0.31.1", ] +[[package]] +name = "cosmic-comp-config" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-comp#92c16bd4adabbd00123284176a2e4cc52b5131c7" +dependencies = [ + "input", + "serde", +] + [[package]] name = "cosmic-config" version = "0.1.0" @@ -766,6 +775,8 @@ dependencies = [ "anyhow", "calloop", "cosmic-client-toolkit", + "cosmic-comp-config", + "cosmic-config", "env_logger", "futures-channel", "gbm", @@ -2047,6 +2058,29 @@ dependencies = [ "libc", ] +[[package]] +name = "input" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e74cd82cedcd66db78742a8337bdc48f188c4d2c12742cbc5cd85113f0b059" +dependencies = [ + "bitflags 1.3.2", + "input-sys", + "io-lifetimes 1.0.11", + "libc", + "log", + "udev", +] + +[[package]] +name = "input-sys" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f6c2a17e8aba7217660e32863af87b0febad811d4b8620ef76b386603fddc2" +dependencies = [ + "libc", +] + [[package]] name = "instant" version = "0.1.12" @@ -2249,6 +2283,16 @@ dependencies = [ "redox_syscall 0.4.1", ] +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -3892,6 +3936,17 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "udev" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebdbbd670373442a12fe9ef7aeb53aec4147a5a27a00bbc3ab639f08f48191a" +dependencies = [ + "libc", + "libudev-sys", + "pkg-config", +] + [[package]] name = "uds_windows" version = "1.0.2" diff --git a/Cargo.toml b/Cargo.toml index 61d417e..d407130 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,12 @@ edition = "2021" anyhow = "1.0.75" calloop = "0.12.3" cctk = { package = "cosmic-client-toolkit", git = "https://github.com/pop-os/cosmic-protocols" } +cosmic-comp-config = { git = "https://github.com/pop-os/cosmic-comp" } env_logger = "0.10.0" futures-channel = "0.3.25" gbm = "0.14.0" libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = false, features = ["tokio", "wayland"] } +cosmic-config = { git = "https://github.com/pop-os/libcosmic" } memmap2 = "0.9.0" tokio = "1.23.0" wayland-protocols = "0.31.0" diff --git a/src/main.rs b/src/main.rs index e66a662..092191a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,6 +35,7 @@ use cosmic::{ settings::InitialSurface, }, }; +use cosmic_config::ConfigGet; use std::{ collections::{HashMap, HashSet}, mem, @@ -117,6 +118,25 @@ enum DragSurface { }, } +struct Conf { + _cosmic_comp_config: cosmic_config::Config, + workspace_config: cosmic_comp_config::workspace::WorkspaceConfig, +} + +impl Default for Conf { + fn default() -> Self { + let cosmic_comp_config = cosmic_config::Config::new("com.system76.CosmicComp", 1).unwrap(); + let workspace_config = cosmic_comp_config.get("workspaces").unwrap_or_else(|err| { + eprintln!("Failed to read config 'worspaces': {}", err); + cosmic_comp_config::workspace::WorkspaceConfig::default() + }); + Self { + _cosmic_comp_config: cosmic_comp_config, + workspace_config, + } + } +} + #[derive(Default)] struct App { max_surface_id: u128, @@ -131,6 +151,7 @@ struct App { visible: bool, wayland_cmd_sender: Option>, drag_surface: Option<(SurfaceId, DragSurface, Size)>, + conf: Conf, } impl App { diff --git a/src/view/mod.rs b/src/view/mod.rs index 36635ca..7195a5a 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -6,6 +6,7 @@ use cosmic::{ }, widget, }; +use cosmic_comp_config::workspace::WorkspaceLayout; use crate::{wayland::CaptureImage, App, DragSurface, LayerSurface, Msg, Toplevel, Workspace}; @@ -13,28 +14,36 @@ pub(crate) fn layer_surface<'a>( app: &'a App, surface: &'a LayerSurface, ) -> cosmic::Element<'a, Msg> { - row![ - workspaces_sidebar( - app.workspaces - .iter() - .filter(|i| i.outputs.contains(&surface.output)), - &surface.output - ), - toplevel_previews(app.toplevels.iter().filter(|i| { - if !i.info.output.contains(&surface.output) { - return false; - } + let layout = app.conf.workspace_config.workspace_layout; + let sidebar = workspaces_sidebar( + app.workspaces + .iter() + .filter(|i| i.outputs.contains(&surface.output)), + &surface.output, + layout, + ); + let toplevels = toplevel_previews(app.toplevels.iter().filter(|i| { + if !i.info.output.contains(&surface.output) { + return false; + } - i.info.workspace.iter().any(|workspace| { - app.workspace_for_handle(workspace) - .map_or(false, |x| x.is_active) - }) - })) - ] - .spacing(12) - .height(iced::Length::Fill) - .width(iced::Length::Fill) - .into() + i.info.workspace.iter().any(|workspace| { + app.workspace_for_handle(workspace) + .map_or(false, |x| x.is_active) + }) + })); + match layout { + WorkspaceLayout::Vertical => row![sidebar, toplevels] + .spacing(12) + .height(iced::Length::Fill) + .width(iced::Length::Fill) + .into(), + WorkspaceLayout::Horizontal => column![sidebar, toplevels] + .spacing(12) + .height(iced::Length::Fill) + .width(iced::Length::Fill) + .into(), + } } fn close_button(on_press: Msg) -> cosmic::Element<'static, Msg> { @@ -89,17 +98,21 @@ fn workspace_sidebar_entry<'a>( fn workspaces_sidebar<'a>( workspaces: impl Iterator, output: &'a wl_output::WlOutput, + layout: WorkspaceLayout, ) -> cosmic::Element<'a, Msg> { + let sidebar_entries = workspaces + .map(|w| workspace_sidebar_entry(w, output)) + .collect(); + let sidebar_entries_container: cosmic::Element<'_, _> = match layout { + WorkspaceLayout::Vertical => column(sidebar_entries).into(), + WorkspaceLayout::Horizontal => row(sidebar_entries).into(), + }; widget::container( - iced::widget::dnd_listener(column( - workspaces - .map(|w| workspace_sidebar_entry(w, output)) - .collect(), - )) - .on_enter(Msg::DndWorkspaceEnter) - .on_exit(Msg::DndWorkspaceLeave) - .on_drop(Msg::DndWorkspaceDrop) - .on_data(Msg::DndWorkspaceData), + iced::widget::dnd_listener(sidebar_entries_container) + .on_enter(Msg::DndWorkspaceEnter) + .on_exit(Msg::DndWorkspaceLeave) + .on_drop(Msg::DndWorkspaceDrop) + .on_data(Msg::DndWorkspaceData), ) .width(iced::Length::Fill) .height(iced::Length::Fill)