From e9111394c79c958d703bf795209bb1f127602637 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 7 Sep 2023 13:28:08 -0700 Subject: [PATCH] WIP Use cosmic-config for workspace settings `WorkspaceAmount` now can be changed dynamically, which seems to basically work. We'll see how that works with `WorkspaceMode` and `WorkspaceLayout`. If `WorkspaceLayout` can be changed at runtime, we'll have to update default keybindings in some way. --- cosmic-comp-config/src/lib.rs | 1 + cosmic-comp-config/src/workspace.rs | 43 ++++++++++++++++++++++ src/backend/render/mod.rs | 4 +-- src/config/key_bindings.rs | 3 +- src/config/mod.rs | 56 +++++++++++++---------------- src/input/mod.rs | 7 ++-- src/shell/mod.rs | 39 +++++++++++++------- 7 files changed, 103 insertions(+), 50 deletions(-) create mode 100644 cosmic-comp-config/src/workspace.rs 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..89000b8c --- /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::Global, + 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 d5dafe0f..d5c1933a 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, 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::{ @@ -518,7 +518,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 d8b8bd06..83dad6b2 100644 --- a/src/config/key_bindings.rs +++ b/src/config/key_bindings.rs @@ -3,6 +3,7 @@ use crate::shell::{ focus::FocusDirection, grabs::ResizeEdge, layout::tiling::Direction, ResizeDirection, }; +use cosmic_comp_config::workspace::WorkspaceLayout; use serde::Deserialize; use smithay::{ backend::input::KeyState, @@ -10,7 +11,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 98b56c9d..4b3f03ed 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, Data, 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,15 +44,12 @@ 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, #[serde(default = "default_active_hint")] pub active_hint: u8, @@ -56,18 +57,6 @@ pub struct StaticConfig { pub gaps: (u8, u8), } -#[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), @@ -108,10 +97,6 @@ fn default_gaps() -> (u8, u8) { (0, 4) } -fn default_workspace_layout() -> WorkspaceLayout { - WorkspaceLayout::Vertical -} - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct OutputConfig { pub mode: ((i32, i32), Option), @@ -167,18 +152,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"), @@ -204,10 +194,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; } @@ -215,9 +202,6 @@ impl Config { StaticConfig { key_bindings: HashMap::new(), - workspace_mode: WorkspaceMode::Global, - workspace_amount: WorkspaceAmount::Dynamic, - workspace_layout: WorkspaceLayout::Vertical, tiling_enabled: false, active_hint: default_active_hint(), gaps: default_gaps(), @@ -530,6 +514,16 @@ fn config_changed(config: cosmic_config::Config, keys: Vec, state: &mut state.common.config.input_devices = value; update_input(state); } + "workspaces" => { + let value = get_config::(&config, "workspaces"); + state + .common + .shell + .workspaces + .update_amount(value.workspace_amount); + // TODO workspace mode + // TODO workspace count + } _ => {} } } diff --git a/src/input/mod.rs b/src/input/mod.rs index c4fa79cc..46bb1c5c 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}, @@ -14,6 +14,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::{ @@ -1241,7 +1242,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( @@ -1301,7 +1302,7 @@ impl State { match workspace.tiling_layer.move_current_node(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 d07046c1..e0185b13 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1,5 +1,4 @@ use calloop::LoopHandle; -use serde::{Deserialize, Serialize}; use std::{ cell::RefCell, collections::HashMap, @@ -9,6 +8,7 @@ use std::{ use tracing::warn; use wayland_backend::server::ClientId; +use cosmic_comp_config::workspace::{WorkspaceAmount, WorkspaceMode as ConfigMode}; use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState; use keyframe::{ease, functions::EaseInOutCubic}; use smithay::{ @@ -36,7 +36,7 @@ use smithay::{ }; use crate::{ - config::{Config, KeyModifiers, KeyPattern, OutputConfig, WorkspaceMode as ConfigMode}, + config::{Config, KeyModifiers, KeyPattern, OutputConfig}, state::client_has_security_context, utils::prelude::*, wayland::protocols::{ @@ -184,12 +184,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>, group_handle: &WorkspaceGroupHandle, @@ -435,6 +429,12 @@ impl WorkspaceSet { } } } + + pub fn update_amount(&mut self, amount: WorkspaceAmount) { + self.amount = amount; + // TODO + // - what if there are more workspace than amount? + } } #[derive(Debug)] @@ -443,19 +443,20 @@ pub enum WorkspaceMode { Global(WorkspaceSet), } +// TODO way to change mode, amount? impl WorkspaceMode { pub fn new( - config: crate::config::WorkspaceMode, + config: cosmic_comp_config::workspace::WorkspaceMode, amount: WorkspaceAmount, state: &mut WorkspaceUpdateGuard<'_, State>, tiling_enabled: bool, gaps: (u8, u8), ) -> WorkspaceMode { match config { - crate::config::WorkspaceMode::Global => { + cosmic_comp_config::workspace::WorkspaceMode::Global => { WorkspaceMode::Global(WorkspaceSet::new(state, amount, 0, tiling_enabled, gaps)) } - crate::config::WorkspaceMode::OutputBound => { + cosmic_comp_config::workspace::WorkspaceMode::OutputBound => { WorkspaceMode::OutputBound(HashMap::new(), amount) } } @@ -572,6 +573,18 @@ impl WorkspaceMode { } } } + + pub fn update_amount(&mut self, amount: WorkspaceAmount) { + match self { + WorkspaceMode::Global(set) => set.update_amount(amount), + WorkspaceMode::OutputBound(sets, ammount_ref) => { + *ammount_ref = amount; + for set in sets.values_mut() { + set.update_amount(amount) + } + } + } + } } pub struct InvalidWorkspaceIndex; @@ -603,8 +616,8 @@ impl Shell { let tiling_enabled = config.static_conf.tiling_enabled; let mode = WorkspaceMode::new( - config.static_conf.workspace_mode, - config.static_conf.workspace_amount, + config.workspace.workspace_mode, + config.workspace.workspace_amount, &mut workspace_state.update(), tiling_enabled, config.static_conf.gaps,