Use cosmic-config for dynamic workspace settings
`WorkspaceAmount`, `WorkspaceMode`, and `WorkspaceLayout` can all be changed dynamically now.
This commit is contained in:
parent
25f5edd6cf
commit
81efd42dd5
9 changed files with 88 additions and 51 deletions
|
|
@ -81,8 +81,5 @@
|
||||||
(modifiers: [], key: "XF86MonBrightnessUp"): Spawn("busctl --user call com.system76.CosmicSettingsDaemon /com/system76/CosmicSettingsDaemon com.system76.CosmicSettingsDaemon IncreaseDisplayBrightness"),
|
(modifiers: [], key: "XF86MonBrightnessUp"): Spawn("busctl --user call com.system76.CosmicSettingsDaemon /com/system76/CosmicSettingsDaemon com.system76.CosmicSettingsDaemon IncreaseDisplayBrightness"),
|
||||||
(modifiers: [], key: "XF86MonBrightnessDown"): Spawn("busctl --user call com.system76.CosmicSettingsDaemon /com/system76/CosmicSettingsDaemon com.system76.CosmicSettingsDaemon DecreaseDisplayBrightness"),
|
(modifiers: [], key: "XF86MonBrightnessDown"): Spawn("busctl --user call com.system76.CosmicSettingsDaemon /com/system76/CosmicSettingsDaemon com.system76.CosmicSettingsDaemon DecreaseDisplayBrightness"),
|
||||||
},
|
},
|
||||||
workspace_mode: OutputBound,
|
|
||||||
workspace_amount: Dynamic,
|
|
||||||
workspace_layout: Vertical,
|
|
||||||
tiling_enabled: false,
|
tiling_enabled: false,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub mod input;
|
pub mod input;
|
||||||
|
pub mod workspace;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct XkbConfig {
|
pub struct XkbConfig {
|
||||||
|
|
|
||||||
43
cosmic-comp-config/src/workspace.rs
Normal file
43
cosmic-comp-config/src/workspace.rs
Normal file
|
|
@ -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,
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,6 @@ use std::{
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use crate::debug::{fps_ui, profiler_ui};
|
use crate::debug::{fps_ui, profiler_ui};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::WorkspaceLayout,
|
|
||||||
shell::{
|
shell::{
|
||||||
focus::target::WindowGroup, grabs::SeatMoveGrabState, layout::tiling::ANIMATION_DURATION,
|
focus::target::WindowGroup, grabs::SeatMoveGrabState, layout::tiling::ANIMATION_DURATION,
|
||||||
CosmicMapped, CosmicMappedRenderElement, OverviewMode, Trigger, WorkspaceRenderElement,
|
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 cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::FailureReason;
|
||||||
use keyframe::{ease, functions::EaseInOutCubic};
|
use keyframe::{ease, functions::EaseInOutCubic};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
|
@ -557,7 +557,7 @@ where
|
||||||
|
|
||||||
let offset = match previous.as_ref() {
|
let offset = match previous.as_ref() {
|
||||||
Some((previous, previous_idx, start)) => {
|
Some((previous, previous_idx, start)) => {
|
||||||
let layout = state.config.static_conf.workspace_layout;
|
let layout = state.config.workspace.workspace_layout;
|
||||||
|
|
||||||
let workspace = state
|
let workspace = state
|
||||||
.shell
|
.shell
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::shell::{focus::FocusDirection, grabs::ResizeEdge, Direction, ResizeDirection};
|
use crate::shell::{focus::FocusDirection, grabs::ResizeEdge, Direction, ResizeDirection};
|
||||||
|
use cosmic_comp_config::workspace::WorkspaceLayout;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::input::KeyState,
|
backend::input::KeyState,
|
||||||
|
|
@ -8,7 +9,7 @@ use smithay::{
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::{types::*, WorkspaceLayout};
|
use super::types::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
|
||||||
pub enum KeyModifier {
|
pub enum KeyModifier {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
shell::{Shell, WorkspaceAmount},
|
shell::Shell,
|
||||||
state::{BackendData, State},
|
state::{BackendData, State},
|
||||||
wayland::protocols::output_configuration::OutputConfigurationState,
|
wayland::protocols::output_configuration::OutputConfigurationState,
|
||||||
};
|
};
|
||||||
|
|
@ -29,7 +29,11 @@ mod key_bindings;
|
||||||
pub use key_bindings::{Action, KeyModifier, KeyModifiers, KeyPattern};
|
pub use key_bindings::{Action, KeyModifier, KeyModifiers, KeyPattern};
|
||||||
mod types;
|
mod types;
|
||||||
pub use self::types::*;
|
pub use self::types::*;
|
||||||
use cosmic_comp_config::{input::InputConfig, XkbConfig};
|
use cosmic_comp_config::{
|
||||||
|
input::InputConfig,
|
||||||
|
workspace::{WorkspaceConfig, WorkspaceLayout},
|
||||||
|
XkbConfig,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
|
@ -40,30 +44,15 @@ pub struct Config {
|
||||||
pub input_default: InputConfig,
|
pub input_default: InputConfig,
|
||||||
pub input_touchpad: InputConfig,
|
pub input_touchpad: InputConfig,
|
||||||
pub input_devices: HashMap<String, InputConfig>,
|
pub input_devices: HashMap<String, InputConfig>,
|
||||||
|
pub workspace: WorkspaceConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct StaticConfig {
|
pub struct StaticConfig {
|
||||||
pub key_bindings: HashMap<key_bindings::KeyPattern, key_bindings::Action>,
|
pub key_bindings: HashMap<key_bindings::KeyPattern, key_bindings::Action>,
|
||||||
pub workspace_mode: WorkspaceMode,
|
|
||||||
pub workspace_amount: WorkspaceAmount,
|
|
||||||
#[serde(default = "default_workspace_layout")]
|
|
||||||
pub workspace_layout: WorkspaceLayout,
|
|
||||||
pub tiling_enabled: bool,
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct DynamicConfig {
|
pub struct DynamicConfig {
|
||||||
outputs: (Option<PathBuf>, OutputsConfig),
|
outputs: (Option<PathBuf>, OutputsConfig),
|
||||||
|
|
@ -96,10 +85,6 @@ fn default_enabled() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_workspace_layout() -> WorkspaceLayout {
|
|
||||||
WorkspaceLayout::Vertical
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
||||||
pub struct OutputConfig {
|
pub struct OutputConfig {
|
||||||
pub mode: ((i32, i32), Option<u32>),
|
pub mode: ((i32, i32), Option<u32>),
|
||||||
|
|
@ -155,18 +140,23 @@ impl Config {
|
||||||
})
|
})
|
||||||
.expect("Failed to add cosmic-config to the event loop");
|
.expect("Failed to add cosmic-config to the event loop");
|
||||||
let xdg = xdg::BaseDirectories::new().ok();
|
let xdg = xdg::BaseDirectories::new().ok();
|
||||||
|
let workspace = get_config::<WorkspaceConfig>(&config, "workspaces");
|
||||||
Config {
|
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()),
|
dynamic_conf: Self::load_dynamic(xdg.as_ref()),
|
||||||
xkb: get_config(&config, "xkb-config"),
|
xkb: get_config(&config, "xkb-config"),
|
||||||
input_default: get_config(&config, "input-default"),
|
input_default: get_config(&config, "input-default"),
|
||||||
input_touchpad: get_config(&config, "input-touchpad"),
|
input_touchpad: get_config(&config, "input-touchpad"),
|
||||||
input_devices: get_config(&config, "input-devices"),
|
input_devices: get_config(&config, "input-devices"),
|
||||||
|
workspace,
|
||||||
config,
|
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 {
|
let mut locations = if let Some(base) = xdg {
|
||||||
vec![
|
vec![
|
||||||
base.get_config_file("cosmic-comp.ron"),
|
base.get_config_file("cosmic-comp.ron"),
|
||||||
|
|
@ -192,10 +182,7 @@ impl Config {
|
||||||
ron::de::from_reader(OpenOptions::new().read(true).open(path).unwrap())
|
ron::de::from_reader(OpenOptions::new().read(true).open(path).unwrap())
|
||||||
.expect("Malformed config file");
|
.expect("Malformed config file");
|
||||||
|
|
||||||
key_bindings::add_default_bindings(
|
key_bindings::add_default_bindings(&mut config.key_bindings, workspace_layout);
|
||||||
&mut config.key_bindings,
|
|
||||||
config.workspace_layout,
|
|
||||||
);
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
@ -203,9 +190,6 @@ impl Config {
|
||||||
|
|
||||||
StaticConfig {
|
StaticConfig {
|
||||||
key_bindings: HashMap::new(),
|
key_bindings: HashMap::new(),
|
||||||
workspace_mode: WorkspaceMode::Global,
|
|
||||||
workspace_amount: WorkspaceAmount::Dynamic,
|
|
||||||
workspace_layout: WorkspaceLayout::Vertical,
|
|
||||||
tiling_enabled: false,
|
tiling_enabled: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -516,6 +500,11 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
|
||||||
state.common.config.input_devices = value;
|
state.common.config.input_devices = value;
|
||||||
update_input(state);
|
update_input(state);
|
||||||
}
|
}
|
||||||
|
"workspaces" => {
|
||||||
|
state.common.config.workspace =
|
||||||
|
get_config::<WorkspaceConfig>(&config, "workspaces");
|
||||||
|
state.common.shell.update_config(&state.common.config);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::cursor::CursorState,
|
backend::render::cursor::CursorState,
|
||||||
config::{xkb_config_to_wl, Action, Config, KeyPattern, WorkspaceLayout},
|
config::{xkb_config_to_wl, Action, Config, KeyPattern},
|
||||||
shell::{
|
shell::{
|
||||||
focus::{target::PointerFocusTarget, FocusDirection},
|
focus::{target::PointerFocusTarget, FocusDirection},
|
||||||
grabs::{ResizeEdge, SeatMoveGrabState},
|
grabs::{ResizeEdge, SeatMoveGrabState},
|
||||||
|
|
@ -18,6 +18,7 @@ use crate::{
|
||||||
wayland::{handlers::screencopy::ScreencopySessions, protocols::screencopy::Session},
|
wayland::{handlers::screencopy::ScreencopySessions, protocols::screencopy::Session},
|
||||||
};
|
};
|
||||||
use calloop::{timer::Timer, RegistrationToken};
|
use calloop::{timer::Timer, RegistrationToken};
|
||||||
|
use cosmic_comp_config::workspace::WorkspaceLayout;
|
||||||
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType;
|
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType;
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
|
@ -1518,7 +1519,7 @@ impl State {
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
FocusResult::None => {
|
FocusResult::None => {
|
||||||
match (focus, self.common.config.static_conf.workspace_layout) {
|
match (focus, self.common.config.workspace.workspace_layout) {
|
||||||
(FocusDirection::Left, WorkspaceLayout::Horizontal)
|
(FocusDirection::Left, WorkspaceLayout::Horizontal)
|
||||||
| (FocusDirection::Up, WorkspaceLayout::Vertical) => self
|
| (FocusDirection::Up, WorkspaceLayout::Vertical) => self
|
||||||
.handle_action(
|
.handle_action(
|
||||||
|
|
@ -1574,7 +1575,7 @@ impl State {
|
||||||
|
|
||||||
match workspace.move_current_element(direction, seat) {
|
match workspace.move_current_element(direction, seat) {
|
||||||
MoveResult::MoveFurther(_move_further) => {
|
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::Left, WorkspaceLayout::Horizontal)
|
||||||
| (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action(
|
| (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action(
|
||||||
Action::MoveToPreviousWorkspace,
|
Action::MoveToPreviousWorkspace,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use calloop::LoopHandle;
|
use calloop::LoopHandle;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
|
@ -8,6 +7,7 @@ use std::{
|
||||||
};
|
};
|
||||||
use wayland_backend::server::ClientId;
|
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 cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState;
|
||||||
use keyframe::{ease, functions::EaseInOutCubic};
|
use keyframe::{ease, functions::EaseInOutCubic};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
|
@ -35,7 +35,7 @@ use smithay::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, KeyModifiers, KeyPattern, WorkspaceMode},
|
config::{Config, KeyModifiers, KeyPattern},
|
||||||
state::client_has_security_context,
|
state::client_has_security_context,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::protocols::{
|
wayland::protocols::{
|
||||||
|
|
@ -189,12 +189,6 @@ pub struct WorkspaceSet {
|
||||||
pub(crate) workspaces: Vec<Workspace>,
|
pub(crate) workspaces: Vec<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
|
||||||
pub enum WorkspaceAmount {
|
|
||||||
Dynamic,
|
|
||||||
Static(u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_workspace(
|
fn create_workspace(
|
||||||
state: &mut WorkspaceUpdateGuard<'_, State>,
|
state: &mut WorkspaceUpdateGuard<'_, State>,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
|
|
@ -466,8 +460,8 @@ impl Workspaces {
|
||||||
Workspaces {
|
Workspaces {
|
||||||
sets: IndexMap::new(),
|
sets: IndexMap::new(),
|
||||||
backup_set: None,
|
backup_set: None,
|
||||||
amount: config.static_conf.workspace_amount,
|
amount: config.workspace.workspace_amount,
|
||||||
mode: config.static_conf.workspace_mode,
|
mode: config.workspace.workspace_mode,
|
||||||
tiling_enabled: config.static_conf.tiling_enabled,
|
tiling_enabled: config.static_conf.tiling_enabled,
|
||||||
theme,
|
theme,
|
||||||
}
|
}
|
||||||
|
|
@ -592,11 +586,16 @@ impl Workspaces {
|
||||||
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
|
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
|
||||||
toplevel_info_state: &mut ToplevelInfoState<State, CosmicSurface>,
|
toplevel_info_state: &mut ToplevelInfoState<State, CosmicSurface>,
|
||||||
) {
|
) {
|
||||||
|
let old_mode = self.mode;
|
||||||
|
|
||||||
|
self.mode = config.workspace.workspace_mode;
|
||||||
|
self.amount = config.workspace.workspace_amount;
|
||||||
|
|
||||||
if self.sets.len() <= 1 {
|
if self.sets.len() <= 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match (self.mode, config.static_conf.workspace_mode) {
|
match (old_mode, self.mode) {
|
||||||
(WorkspaceMode::Global, WorkspaceMode::OutputBound) => {
|
(WorkspaceMode::Global, WorkspaceMode::OutputBound) => {
|
||||||
// We basically just unlink the existing spaces, so nothing needs to be updated
|
// We basically just unlink the existing spaces, so nothing needs to be updated
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ pub struct WorkspaceGroupHandle {
|
||||||
pub struct WorkspaceGroupDataInner {
|
pub struct WorkspaceGroupDataInner {
|
||||||
outputs: Vec<Output>,
|
outputs: Vec<Output>,
|
||||||
capabilities: Vec<GroupCapabilities>,
|
capabilities: Vec<GroupCapabilities>,
|
||||||
|
workspace_count: usize,
|
||||||
}
|
}
|
||||||
pub type WorkspaceGroupData = Mutex<WorkspaceGroupDataInner>;
|
pub type WorkspaceGroupData = Mutex<WorkspaceGroupDataInner>;
|
||||||
|
|
||||||
|
|
@ -870,6 +871,11 @@ where
|
||||||
changed = true;
|
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 {
|
for workspace in &mut group.workspaces {
|
||||||
if send_workspace_to_client::<D>(dh, instance, workspace) {
|
if send_workspace_to_client::<D>(dh, instance, workspace) {
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue