From 4ec9908f28a0346df87e77313cadb6d12f24fe3a Mon Sep 17 00:00:00 2001 From: William Calliari Date: Sun, 6 Oct 2024 11:35:38 +0200 Subject: [PATCH] Propagate live config changes --- cosmic-comp-config/src/lib.rs | 7 +-- src/config/mod.rs | 12 +++-- src/shell/element/mod.rs | 7 +++ src/shell/element/stack.rs | 4 ++ src/shell/element/stack/tab.rs | 3 +- src/shell/layout/floating/mod.rs | 6 ++- src/shell/layout/tiling/mod.rs | 29 ++++++++--- src/shell/mod.rs | 83 ++++++++++++++++++++++++-------- src/utils/iced.rs | 4 ++ 9 files changed, 121 insertions(+), 34 deletions(-) diff --git a/cosmic-comp-config/src/lib.rs b/cosmic-comp-config/src/lib.rs index 870b98b4..204b3890 100644 --- a/cosmic-comp-config/src/lib.rs +++ b/cosmic-comp-config/src/lib.rs @@ -109,7 +109,6 @@ fn default_repeat_delay() -> u32 { 600 } - #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub struct StackBehavior { pub close_tab_on_middle_click: bool, @@ -117,6 +116,8 @@ pub struct StackBehavior { impl Default for StackBehavior { fn default() -> Self { - Self { close_tab_on_middle_click: true } + Self { + close_tab_on_middle_click: true, + } } -} \ No newline at end of file +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 6ae17b0d..c302a676 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -41,7 +41,8 @@ mod types; pub use self::types::*; use cosmic::config::CosmicTk; use cosmic_comp_config::{ - input::InputConfig, workspace::WorkspaceConfig, CosmicCompConfig, StackBehavior, TileBehavior, XkbConfig + input::InputConfig, workspace::WorkspaceConfig, CosmicCompConfig, StackBehavior, TileBehavior, + XkbConfig, }; #[derive(Debug)] @@ -689,8 +690,13 @@ fn config_changed(config: cosmic_config::Config, keys: Vec, state: &mut "stack_behavior" => { let new = get_config::(&config, "stack_behavior"); if new != state.common.config.cosmic_conf.stack_behavior { - state.common.config.cosmic_conf.stack_behavior = new; - state.common.update_config(); + state.common.config.cosmic_conf.stack_behavior = new.clone(); + + let mut shell = state.common.shell.write().unwrap(); + let shell_ref = &mut *shell; + shell_ref + .workspaces + .update_stack_behavior(new, shell_ref.seats.iter()) } } "active_hint" => { diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index c7ab218c..a9955aba 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -895,6 +895,13 @@ impl CosmicMapped { _ => unreachable!(), }) } + + pub fn update_stack_behavior(&mut self, behavior: &StackBehavior) { + if let CosmicMappedInternal::Stack(stack) = &mut self.element { + let mut inner = stack.0 .0.lock().unwrap(); + inner.program_mut().update_behavior(behavior.clone()); + } + } } impl IsAlive for CosmicMapped { diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index ff033c7f..d03ee0e1 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -116,6 +116,10 @@ impl CosmicStackInternal { pub fn current_focus(&self) -> Option { unsafe { Focus::from_u8(self.pointer_entered.load(Ordering::SeqCst)) } } + + pub fn update_behavior(&mut self, behavior: StackBehavior) { + self.behavior = behavior; + } } pub const TAB_HEIGHT: i32 = 24; diff --git a/src/shell/element/stack/tab.rs b/src/shell/element/stack/tab.rs index f37d859c..d2c73cab 100644 --- a/src/shell/element/stack/tab.rs +++ b/src/shell/element/stack/tab.rs @@ -431,13 +431,12 @@ where if matches!( event, event::Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Middle)) - ) { + ) { if let Some(message) = self.middle_click_message.clone() { shell.publish(message); return event::Status::Captured; } } - } status diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index da47ab15..4e0aa208 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -901,7 +901,11 @@ impl FloatingLayout { if mapped.is_window() { // if it is just a window self.space.unmap_elem(&mapped); - mapped.convert_to_stack((&output, mapped.bbox()), self.theme.clone(), stack_behavior.clone()); + mapped.convert_to_stack( + (&output, mapped.bbox()), + self.theme.clone(), + stack_behavior.clone(), + ); self.map_internal( mapped.clone(), Some(location.as_local()), diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 1cdd24ff..d76cd90f 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -136,7 +136,7 @@ pub struct TilingLayout { swapping_stack_surface_id: Id, last_overview_hover: Option<(Option, TargetZone)>, pub theme: cosmic::Theme, - stack_behavior: StackBehavior, + pub stack_behavior: StackBehavior, } #[derive(Debug, Clone, PartialEq)] @@ -344,7 +344,11 @@ pub struct MinimizedTilingState { } impl TilingLayout { - pub fn new(theme: cosmic::Theme, output: &Output, stack_behavior: StackBehavior) -> TilingLayout { + pub fn new( + theme: cosmic::Theme, + output: &Output, + stack_behavior: StackBehavior, + ) -> TilingLayout { TilingLayout { queue: TreeQueue { trees: { @@ -2124,7 +2128,7 @@ impl TilingLayout { &mut self, mapped: &CosmicMapped, mut focus_stack: FocusStackMut, - stack_behavior: &StackBehavior + stack_behavior: &StackBehavior, ) -> Option { let gaps = self.gaps(); @@ -2141,7 +2145,11 @@ impl TilingLayout { // if it is just a window match tree.get_mut(&node_id).unwrap().data_mut() { Data::Mapped { mapped, .. } => { - mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone(), stack_behavior.clone()); + mapped.convert_to_stack( + (&self.output, mapped.bbox()), + self.theme.clone(), + stack_behavior.clone(), + ); focus_stack.append(&mapped); KeyboardFocusTarget::Element(mapped.clone()) } @@ -2279,7 +2287,12 @@ impl TilingLayout { return None; } let handle = handle.unwrap(); - let stack = CosmicStack::new(surfaces.into_iter(), handle, self.theme.clone(), stack_behavior.clone()); + let stack = CosmicStack::new( + surfaces.into_iter(), + handle, + self.theme.clone(), + stack_behavior.clone(), + ); for child in tree .children_ids(&last_active) @@ -2746,7 +2759,11 @@ impl TilingLayout { Some(TargetZone::WindowStack(window_id, _)) if tree.get(&window_id).is_ok() => { match tree.get_mut(window_id).unwrap().data_mut() { Data::Mapped { mapped, .. } => { - mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone(), self.stack_behavior.clone()); + mapped.convert_to_stack( + (&self.output, mapped.bbox()), + self.theme.clone(), + self.stack_behavior.clone(), + ); let Some(stack) = mapped.stack_ref_mut() else { unreachable!() }; diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 4124aa8e..348c8cdd 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -12,7 +12,8 @@ use wayland_backend::server::ClientId; use crate::wayland::{handlers::data_device, protocols::workspace::WorkspaceCapabilities}; use cosmic_comp_config::{ - workspace::{WorkspaceLayout, WorkspaceMode}, StackBehavior, TileBehavior + workspace::{WorkspaceLayout, WorkspaceMode}, + StackBehavior, TileBehavior, }; use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::{ State as WState, TilingState, @@ -45,7 +46,6 @@ use smithay::{ utils::{IsAlive, Logical, Point, Rectangle, Serial, Size}, wayland::{ compositor::{with_states, SurfaceAttributes}, - foreign_toplevel_list::ForeignToplevelListState, seat::WaylandFocus, session_lock::LockSurface, shell::wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState}, @@ -348,7 +348,13 @@ fn create_workspace( &workspace_handle, [WorkspaceCapabilities::Activate].into_iter(), ); - Workspace::new(workspace_handle, output.clone(), tiling, theme.clone(), stack_behavior) + Workspace::new( + workspace_handle, + output.clone(), + tiling, + theme.clone(), + stack_behavior, + ) } fn move_workspace_to_group( @@ -430,7 +436,7 @@ impl WorkspaceSet { true, tiling_enabled, theme.clone(), - stack_behavior.clone() + stack_behavior.clone(), ); workspace_set_idx(state, 1, idx, &workspace.handle); state.set_workspace_capabilities( @@ -859,7 +865,7 @@ impl Workspaces { false, config.cosmic_conf.autotile, self.theme.clone(), - self.stack_behavior.clone() + self.stack_behavior.clone(), ), ); } @@ -1128,6 +1134,34 @@ impl Workspaces { self.autotile = autotile; self.apply_tile_change(guard, seats); } + + pub fn update_stack_behavior<'a>( + &mut self, + behavior: StackBehavior, + seats: impl Iterator>, + ) { + let seats = seats.cloned().collect::>(); + self.stack_behavior = behavior.clone(); + for (_, set) in &mut self.sets { + set.stack_behavior = behavior.clone(); + + for w in &mut set.workspaces { + w.tiling_layer.stack_behavior = behavior.clone(); + for seat in &seats { + let stack = w.focus_stack.get_mut(seat); + *stack.0 = stack + .0 + .clone() + .into_iter() + .map(|mut window| { + window.update_stack_behavior(&behavior); + window + }) + .collect(); + } + } + } + } } #[derive(Debug)] @@ -3581,13 +3615,17 @@ impl Shell { .toggle_stacking(window, workspace.focus_stack.get_mut(seat), &behavior) } else if let Some(workspace) = self.space_for_mut(window) { if workspace.tiling_layer.mapped().any(|(m, _)| m == window) { - workspace - .tiling_layer - .toggle_stacking(window, workspace.focus_stack.get_mut(seat), &behavior) + workspace.tiling_layer.toggle_stacking( + window, + workspace.focus_stack.get_mut(seat), + &behavior, + ) } else if workspace.floating_layer.mapped().any(|w| w == window) { - workspace - .floating_layer - .toggle_stacking(window, workspace.focus_stack.get_mut(seat), &behavior) + workspace.floating_layer.toggle_stacking( + window, + workspace.focus_stack.get_mut(seat), + &behavior, + ) } else { None } @@ -3606,16 +3644,23 @@ impl Shell { let maybe_window = workspace.focus_stack.get(seat).iter().next().cloned(); if let Some(window) = maybe_window { if set.sticky_layer.mapped().any(|m| m == &window) { - set.sticky_layer - .toggle_stacking_focused(seat, workspace.focus_stack.get_mut(seat), &self.workspaces.stack_behavior) + set.sticky_layer.toggle_stacking_focused( + seat, + workspace.focus_stack.get_mut(seat), + &self.workspaces.stack_behavior, + ) } else if workspace.tiling_layer.mapped().any(|(m, _)| m == &window) { - workspace - .tiling_layer - .toggle_stacking_focused(seat, workspace.focus_stack.get_mut(seat), &self.workspaces.stack_behavior) + workspace.tiling_layer.toggle_stacking_focused( + seat, + workspace.focus_stack.get_mut(seat), + &self.workspaces.stack_behavior, + ) } else if workspace.floating_layer.mapped().any(|w| w == &window) { - workspace - .floating_layer - .toggle_stacking_focused(seat, workspace.focus_stack.get_mut(seat), &self.workspaces.stack_behavior) + workspace.floating_layer.toggle_stacking_focused( + seat, + workspace.focus_stack.get_mut(seat), + &self.workspaces.stack_behavior, + ) } else { None } diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 97c41835..e6ab7b28 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -414,6 +414,10 @@ impl IcedElementInternal

{ }) .collect::>() } + + pub fn program_mut(&mut self) -> &mut P { + &mut self.state.program_mut().0 + } } impl PointerTarget for IcedElement

{