From 226bf7f49dc3b0b32cf7cf8cb9ead20c4268814d Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 3 Jan 2024 17:11:50 +0000 Subject: [PATCH] workspace: Add tiling_state --- src/input/mod.rs | 5 +- src/shell/mod.rs | 41 +++++++----- src/shell/workspace.rs | 11 +++- src/wayland/protocols/workspace.rs | 101 ++++++++++++++++++++++++++++- 4 files changed, 133 insertions(+), 25 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 2ba9d180..077d38f2 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2049,8 +2049,9 @@ impl State { } Action::ToggleTiling => { let output = seat.active_output(); - let workspace = self.common.shell.active_space_mut(&output); - workspace.toggle_tiling(seat); + let workspace = self.common.shell.workspaces.active_mut(&output); + let mut guard = self.common.shell.workspace_state.update(); + workspace.toggle_tiling(seat, &mut guard); } Action::ToggleWindowFloating => { let output = seat.active_output(); diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 2cc44baf..64b1072d 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -8,7 +8,9 @@ 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 cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::{ + State as WState, TilingState, +}; use keyframe::{ease, functions::EaseInOutCubic}; use smithay::{ desktop::{ @@ -238,7 +240,16 @@ fn create_workspace( tiling: bool, theme: cosmic::Theme, ) -> Workspace { - let workspace_handle = state.create_workspace(&group_handle).unwrap(); + let workspace_handle = state + .create_workspace( + &group_handle, + if tiling { + TilingState::TilingEnabled + } else { + TilingState::FloatingOnly + }, + ) + .unwrap(); if active { state.add_workspace_state(&workspace_handle, WState::Active); } @@ -256,7 +267,16 @@ fn move_workspace_to_group( toplevel_info_state: &mut ToplevelInfoState, ) { let old_workspace_handle = workspace.handle; - workspace.handle = workspace_state.create_workspace(group).unwrap(); + workspace.handle = workspace_state + .create_workspace( + group, + if workspace.tiling_enabled { + TilingState::TilingEnabled + } else { + TilingState::FloatingOnly + }, + ) + .unwrap(); workspace_state.set_workspace_capabilities( &workspace.handle, [WorkspaceCapabilities::Activate].into_iter(), @@ -515,15 +535,6 @@ impl WorkspaceSet { workspace_set_idx(state, i as u8 + 1, idx, &workspace.handle); } } - - fn update_tiling_status(&mut self, seat: &Seat, tiling_enabled: bool) { - self.tiling_enabled = tiling_enabled; - for workspace in &mut self.workspaces { - if workspace.tiling_enabled != tiling_enabled { - workspace.toggle_tiling(seat); - } - } - } } #[derive(Debug)] @@ -1001,12 +1012,6 @@ impl Workspaces { ) } - pub fn update_tiling_status(&mut self, seat: &Seat, tiling: bool) { - for set in self.sets.values_mut() { - set.update_tiling_status(seat, tiling) - } - } - pub fn set_theme(&mut self, theme: cosmic::Theme, xdg_activation_state: &XdgActivationState) { for (_, s) in &mut self.sets { s.theme = theme.clone(); diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index a9b8e090..fc80a382 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -14,12 +14,13 @@ use crate::{ protocols::{ screencopy::{BufferParams, Session as ScreencopySession}, toplevel_info::ToplevelInfoState, - workspace::WorkspaceHandle, + workspace::{WorkspaceHandle, WorkspaceUpdateGuard}, }, }, }; use cosmic::theme::CosmicTheme; +use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::TilingState; use id_tree::Tree; use indexmap::IndexSet; use keyframe::{ease, functions::EaseInOutCubic}; @@ -612,7 +613,11 @@ impl Workspace { } } - pub fn toggle_tiling(&mut self, seat: &Seat) { + pub fn toggle_tiling( + &mut self, + seat: &Seat, + workspace_state: &mut WorkspaceUpdateGuard<'_, State>, + ) { if self.tiling_enabled { for window in self .tiling_layer @@ -624,6 +629,7 @@ impl Workspace { self.tiling_layer.unmap(&window); self.floating_layer.map(window, None); } + workspace_state.set_workspace_tiling_state(&self.handle, TilingState::FloatingOnly); self.tiling_enabled = false; } else { let focus_stack = self.focus_stack.get(seat); @@ -638,6 +644,7 @@ impl Workspace { self.tiling_layer .map(window, Some(focus_stack.iter()), None) } + workspace_state.set_workspace_tiling_state(&self.handle, TilingState::TilingEnabled); self.tiling_enabled = true; } } diff --git a/src/wayland/protocols/workspace.rs b/src/wayland/protocols/workspace.rs index 8e38aaa8..a5ae52d5 100644 --- a/src/wayland/protocols/workspace.rs +++ b/src/wayland/protocols/workspace.rs @@ -9,6 +9,7 @@ use smithay::{ Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, }, }; +use wayland_backend::protocol::WEnum; use cosmic_protocols::workspace::v1::server::{ zcosmic_workspace_group_handle_v1::{self, ZcosmicWorkspaceGroupHandleV1}, @@ -74,7 +75,7 @@ pub struct WorkspaceGroupDataInner { } pub type WorkspaceGroupData = Mutex; -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Workspace { id: usize, instances: Vec, @@ -83,6 +84,7 @@ pub struct Workspace { capabilities: Vec, coordinates: Vec, states: HashSet, + tiling: zcosmic_workspace_handle_v1::TilingState, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -96,6 +98,7 @@ pub struct WorkspaceDataInner { capabilities: Vec, coordinates: Vec, states: HashSet, + tiling: Option, } pub type WorkspaceData = Mutex; @@ -124,6 +127,14 @@ pub enum Request { Activate(WorkspaceHandle), Deactivate(WorkspaceHandle), Remove(WorkspaceHandle), + Rename { + workspace: WorkspaceHandle, + name: String, + }, + SetTilingState { + workspace: WorkspaceHandle, + state: WEnum, + }, Create { in_group: WorkspaceGroupHandle, name: String, @@ -339,6 +350,36 @@ where state.requests.push(Request::Remove(workspace_handle)); } } + zcosmic_workspace_handle_v1::Request::Rename { name } => { + if let Some(workspace_handle) = state.workspace_state().get_workspace_handle(obj) { + let mut state = client + .get_data::<::Client>() + .unwrap() + .workspace_state() + .lock() + .unwrap(); + state.requests.push(Request::Rename { + workspace: workspace_handle, + name, + }); + } + } + zcosmic_workspace_handle_v1::Request::SetTilingState { + state: tiling_state, + } => { + if let Some(workspace_handle) = state.workspace_state().get_workspace_handle(obj) { + let mut state = client + .get_data::<::Client>() + .unwrap() + .workspace_state() + .lock() + .unwrap(); + state.requests.push(Request::SetTilingState { + workspace: workspace_handle, + state: tiling_state, + }); + } + } zcosmic_workspace_handle_v1::Request::Destroy => { for group in &mut state.workspace_state_mut().groups { for workspace in &mut group.workspaces { @@ -468,6 +509,18 @@ where }) } + pub fn workspace_tiling_state( + &self, + workspace: &WorkspaceHandle, + ) -> Option { + self.groups.iter().find_map(|g| { + g.workspaces + .iter() + .find(|w| w.id == workspace.id) + .map(|w| w.tiling) + }) + } + pub fn group_handle( &self, group: &ZcosmicWorkspaceGroupHandleV1, @@ -569,12 +622,21 @@ where WorkspaceGroupHandle { id } } - pub fn create_workspace(&mut self, group: &WorkspaceGroupHandle) -> Option { + pub fn create_workspace( + &mut self, + group: &WorkspaceGroupHandle, + tiling: zcosmic_workspace_handle_v1::TilingState, + ) -> Option { if let Some(group) = self.0.groups.iter_mut().find(|g| g.id == group.id) { let id = next_workspace_id(); let workspace = Workspace { id, - ..Default::default() + tiling, + instances: Default::default(), + name: Default::default(), + capabilities: Default::default(), + coordinates: Default::default(), + states: Default::default(), }; group.workspaces.push(workspace); Some(WorkspaceHandle { id }) @@ -758,6 +820,28 @@ where workspace.states.remove(&state); } } + + pub fn workspace_tiling_state( + &self, + workspace: &WorkspaceHandle, + ) -> Option { + self.0.workspace_tiling_state(workspace) + } + + pub fn set_workspace_tiling_state( + &mut self, + workspace: &WorkspaceHandle, + state: zcosmic_workspace_handle_v1::TilingState, + ) { + if let Some(workspace) = self + .0 + .groups + .iter_mut() + .find_map(|g| g.workspaces.iter_mut().find(|w| w.id == workspace.id)) + { + workspace.tiling = state; + } + } } impl<'a, D> Drop for WorkspaceUpdateGuard<'a, D> @@ -963,6 +1047,17 @@ where handle_state.states = workspace.states.clone(); changed = true; } + if instance.version() >= zcosmic_workspace_handle_v1::EVT_TILING_STATE_SINCE { + if handle_state + .tiling + .map(|state| state != workspace.tiling) + .unwrap_or(true) + { + instance.tiling_state(workspace.tiling); + handle_state.tiling = Some(workspace.tiling); + changed = true; + } + } changed }