diff --git a/cosmic-comp-config/src/lib.rs b/cosmic-comp-config/src/lib.rs index b65c114b..92e1c545 100644 --- a/cosmic-comp-config/src/lib.rs +++ b/cosmic-comp-config/src/lib.rs @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize}; pub mod input; +pub mod workspace; #[derive(Debug, Clone, Deserialize, Serialize)] pub struct XkbConfig { diff --git a/cosmic-comp-config/src/workspace.rs b/cosmic-comp-config/src/workspace.rs new file mode 100644 index 00000000..c27c7ee7 --- /dev/null +++ b/cosmic-comp-config/src/workspace.rs @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-3.0-only + +use serde::{Deserialize, Serialize}; + +fn default_workspace_layout() -> WorkspaceLayout { + WorkspaceLayout::Vertical +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WorkspaceConfig { + pub workspace_mode: WorkspaceMode, + pub workspace_amount: WorkspaceAmount, + #[serde(default = "default_workspace_layout")] + pub workspace_layout: WorkspaceLayout, +} + +impl Default for WorkspaceConfig { + fn default() -> Self { + Self { + workspace_mode: WorkspaceMode::OutputBound, + workspace_amount: WorkspaceAmount::Dynamic, + workspace_layout: WorkspaceLayout::Vertical, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum WorkspaceAmount { + Dynamic, + Static(u8), +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum WorkspaceMode { + OutputBound, + Global, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum WorkspaceLayout { + Vertical, + Horizontal, +} diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 993426b5..569d1f9e 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -11,7 +11,6 @@ use std::{ #[cfg(feature = "debug")] use crate::debug::{fps_ui, profiler_ui}; use crate::{ - config::WorkspaceLayout, shell::{ focus::target::WindowGroup, grabs::SeatMoveGrabState, layout::tiling::ANIMATION_DURATION, CosmicMapped, CosmicMappedRenderElement, OverviewMode, Trigger, WorkspaceRenderElement, @@ -32,6 +31,7 @@ use crate::{ }, }; +use cosmic_comp_config::workspace::WorkspaceLayout; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::FailureReason; use keyframe::{ease, functions::EaseInOutCubic}; use smithay::{ @@ -557,7 +557,7 @@ where let offset = match previous.as_ref() { Some((previous, previous_idx, start)) => { - let layout = state.config.static_conf.workspace_layout; + let layout = state.config.workspace.workspace_layout; let workspace = state .shell diff --git a/src/config/key_bindings.rs b/src/config/key_bindings.rs index e77b5f12..227bbef8 100644 --- a/src/config/key_bindings.rs +++ b/src/config/key_bindings.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::shell::{focus::FocusDirection, grabs::ResizeEdge, Direction, ResizeDirection}; +use cosmic_comp_config::workspace::WorkspaceLayout; use serde::Deserialize; use smithay::{ backend::input::KeyState, @@ -8,7 +9,7 @@ use smithay::{ }; use std::collections::HashMap; -use super::{types::*, WorkspaceLayout}; +use super::types::*; #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] pub enum KeyModifier { diff --git a/src/config/mod.rs b/src/config/mod.rs index 8640b6a8..89c46c21 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - shell::{Shell, WorkspaceAmount}, + shell::Shell, state::{BackendData, State}, wayland::protocols::output_configuration::OutputConfigurationState, }; @@ -29,7 +29,11 @@ mod key_bindings; pub use key_bindings::{Action, KeyModifier, KeyModifiers, KeyPattern}; mod types; pub use self::types::*; -use cosmic_comp_config::{input::InputConfig, XkbConfig}; +use cosmic_comp_config::{ + input::InputConfig, + workspace::{WorkspaceConfig, WorkspaceLayout}, + XkbConfig, +}; #[derive(Debug)] pub struct Config { @@ -40,30 +44,15 @@ pub struct Config { pub input_default: InputConfig, pub input_touchpad: InputConfig, pub input_devices: HashMap, + pub workspace: WorkspaceConfig, } #[derive(Debug, Deserialize)] pub struct StaticConfig { pub key_bindings: HashMap, - pub workspace_mode: WorkspaceMode, - pub workspace_amount: WorkspaceAmount, - #[serde(default = "default_workspace_layout")] - pub workspace_layout: WorkspaceLayout, pub tiling_enabled: bool, } -#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)] -pub enum WorkspaceMode { - OutputBound, - Global, -} - -#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)] -pub enum WorkspaceLayout { - Vertical, - Horizontal, -} - #[derive(Debug)] pub struct DynamicConfig { outputs: (Option, OutputsConfig), @@ -96,10 +85,6 @@ fn default_enabled() -> bool { true } -fn default_workspace_layout() -> WorkspaceLayout { - WorkspaceLayout::Vertical -} - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct OutputConfig { pub mode: ((i32, i32), Option), @@ -155,18 +140,23 @@ impl Config { }) .expect("Failed to add cosmic-config to the event loop"); let xdg = xdg::BaseDirectories::new().ok(); + let workspace = get_config::(&config, "workspaces"); Config { - static_conf: Self::load_static(xdg.as_ref()), + static_conf: Self::load_static(xdg.as_ref(), workspace.workspace_layout), dynamic_conf: Self::load_dynamic(xdg.as_ref()), xkb: get_config(&config, "xkb-config"), input_default: get_config(&config, "input-default"), input_touchpad: get_config(&config, "input-touchpad"), input_devices: get_config(&config, "input-devices"), + workspace, config, } } - fn load_static(xdg: Option<&xdg::BaseDirectories>) -> StaticConfig { + fn load_static( + xdg: Option<&xdg::BaseDirectories>, + workspace_layout: WorkspaceLayout, + ) -> StaticConfig { let mut locations = if let Some(base) = xdg { vec![ base.get_config_file("cosmic-comp.ron"), @@ -192,10 +182,7 @@ impl Config { ron::de::from_reader(OpenOptions::new().read(true).open(path).unwrap()) .expect("Malformed config file"); - key_bindings::add_default_bindings( - &mut config.key_bindings, - config.workspace_layout, - ); + key_bindings::add_default_bindings(&mut config.key_bindings, workspace_layout); return config; } @@ -203,9 +190,6 @@ impl Config { StaticConfig { key_bindings: HashMap::new(), - workspace_mode: WorkspaceMode::Global, - workspace_amount: WorkspaceAmount::Dynamic, - workspace_layout: WorkspaceLayout::Vertical, tiling_enabled: false, } } @@ -516,6 +500,11 @@ fn config_changed(config: cosmic_config::Config, keys: Vec, state: &mut state.common.config.input_devices = value; update_input(state); } + "workspaces" => { + state.common.config.workspace = + get_config::(&config, "workspaces"); + state.common.shell.update_config(&state.common.config); + } _ => {} } } diff --git a/src/input/mod.rs b/src/input/mod.rs index 7db3ff0f..15ea9edb 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2,7 +2,7 @@ use crate::{ backend::render::cursor::CursorState, - config::{xkb_config_to_wl, Action, Config, KeyPattern, WorkspaceLayout}, + config::{xkb_config_to_wl, Action, Config, KeyPattern}, shell::{ focus::{target::PointerFocusTarget, FocusDirection}, grabs::{ResizeEdge, SeatMoveGrabState}, @@ -18,6 +18,7 @@ use crate::{ wayland::{handlers::screencopy::ScreencopySessions, protocols::screencopy::Session}, }; use calloop::{timer::Timer, RegistrationToken}; +use cosmic_comp_config::workspace::WorkspaceLayout; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; #[allow(deprecated)] use smithay::{ @@ -1518,7 +1519,7 @@ impl State { match result { FocusResult::None => { - match (focus, self.common.config.static_conf.workspace_layout) { + match (focus, self.common.config.workspace.workspace_layout) { (FocusDirection::Left, WorkspaceLayout::Horizontal) | (FocusDirection::Up, WorkspaceLayout::Vertical) => self .handle_action( @@ -1574,7 +1575,7 @@ impl State { match workspace.move_current_element(direction, seat) { MoveResult::MoveFurther(_move_further) => { - match (direction, self.common.config.static_conf.workspace_layout) { + match (direction, self.common.config.workspace.workspace_layout) { (Direction::Left, WorkspaceLayout::Horizontal) | (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action( Action::MoveToPreviousWorkspace, diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 4bda1f7a..87b0f287 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1,6 +1,5 @@ use calloop::LoopHandle; use indexmap::IndexMap; -use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, sync::atomic::{AtomicBool, Ordering}, @@ -8,6 +7,7 @@ use std::{ }; use wayland_backend::server::ClientId; +use cosmic_comp_config::workspace::{WorkspaceAmount, WorkspaceMode}; use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState; use keyframe::{ease, functions::EaseInOutCubic}; use smithay::{ @@ -35,7 +35,7 @@ use smithay::{ }; use crate::{ - config::{Config, KeyModifiers, KeyPattern, WorkspaceMode}, + config::{Config, KeyModifiers, KeyPattern}, state::client_has_security_context, utils::prelude::*, wayland::protocols::{ @@ -189,12 +189,6 @@ pub struct WorkspaceSet { pub(crate) workspaces: Vec, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub enum WorkspaceAmount { - Dynamic, - Static(u8), -} - fn create_workspace( state: &mut WorkspaceUpdateGuard<'_, State>, output: &Output, @@ -466,8 +460,8 @@ impl Workspaces { Workspaces { sets: IndexMap::new(), backup_set: None, - amount: config.static_conf.workspace_amount, - mode: config.static_conf.workspace_mode, + amount: config.workspace.workspace_amount, + mode: config.workspace.workspace_mode, tiling_enabled: config.static_conf.tiling_enabled, theme, } @@ -592,11 +586,16 @@ impl Workspaces { workspace_state: &mut WorkspaceUpdateGuard<'_, State>, toplevel_info_state: &mut ToplevelInfoState, ) { + let old_mode = self.mode; + + self.mode = config.workspace.workspace_mode; + self.amount = config.workspace.workspace_amount; + if self.sets.len() <= 1 { return; } - match (self.mode, config.static_conf.workspace_mode) { + match (old_mode, self.mode) { (WorkspaceMode::Global, WorkspaceMode::OutputBound) => { // We basically just unlink the existing spaces, so nothing needs to be updated } diff --git a/src/wayland/protocols/workspace.rs b/src/wayland/protocols/workspace.rs index fe5f638a..91186ca5 100644 --- a/src/wayland/protocols/workspace.rs +++ b/src/wayland/protocols/workspace.rs @@ -70,6 +70,7 @@ pub struct WorkspaceGroupHandle { pub struct WorkspaceGroupDataInner { outputs: Vec, capabilities: Vec, + workspace_count: usize, } pub type WorkspaceGroupData = Mutex; @@ -870,6 +871,11 @@ where changed = true; } + if handle_state.workspace_count != group.workspaces.len() { + changed = true; + } + handle_state.workspace_count = group.workspaces.len(); + for workspace in &mut group.workspaces { if send_workspace_to_client::(dh, instance, workspace) { changed = true;