From 04edd3b9090cd0971f6b4f97fa34400bce7720e1 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 10 Nov 2025 14:45:18 -0800 Subject: [PATCH] Add margins for auto-hide panels without exclusive zones Works alongside panel changes in https://github.com/pop-os/cosmic-panel/pull/485. We can't set an exclusive zone in the panel, since that would cause all the workspaces to re-layout to make space for it, and also impact workspace capture. Instead, cosmic-workspaces reads the config and adds appropriate margins. --- src/main.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++- src/view/mod.rs | 4 ++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 629d6af..bbdd06b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ use cosmic::{ }; use cosmic_comp_config::CosmicCompConfig; use cosmic_config::{CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry}; -use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfigEntry}; +use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfigEntry, PanelAnchor}; use i18n_embed::DesktopLanguageRequester; use std::{ collections::{HashMap, HashSet}, @@ -352,6 +352,54 @@ impl App { self.capture_filter = capture_filter.clone(); self.send_wayland_cmd(backend::Cmd::CaptureFilter(capture_filter)); } + + fn panel_regions(&self, output_handle: &wl_output::WlOutput) -> iced::Padding { + let Some(output) = self.outputs.iter().find(|o| o.handle == *output_handle) else { + return iced::Padding::ZERO; + }; + + let mut regions = iced::Padding::ZERO; + // TODO: If compositor supports overlap notify, also use that? + // Or otherwise verify the panel is actually running. + for config in self.panel_configs.values().flatten() { + if config.autohide.is_some() && !config.exclusive_zone { + let dimention_constraints = config.get_dimensions( + Some((output.width as u32, output.height as u32)), + None, + Some(config.get_effective_anchor_gap()), + ); + let size = + config.size.get_applet_icon_size_with_padding(true) + u32::from(config.margin); + match config.anchor { + PanelAnchor::Left => { + let size = dimention_constraints.0.map_or(size, |constraints| { + size.clamp(constraints.start, constraints.end) + }); + regions.left += size as f32; + } + PanelAnchor::Right => { + let size = dimention_constraints.0.map_or(size, |constraints| { + size.clamp(constraints.start, constraints.end) + }); + regions.right += size as f32; + } + PanelAnchor::Top => { + let size = dimention_constraints.1.map_or(size, |constraints| { + size.clamp(constraints.start, constraints.end) + }); + regions.top += size as f32; + } + PanelAnchor::Bottom => { + let size = dimention_constraints.1.map_or(size, |constraints| { + size.clamp(constraints.start, constraints.end) + }); + regions.bottom += size as f32; + } + } + } + } + regions + } } impl Application for App { diff --git a/src/view/mod.rs b/src/view/mod.rs index af280d9..9d1363f 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -150,6 +150,10 @@ pub(crate) fn layer_surface<'a>( .width(Length::Fill), ), }; + + let panel_regions = app.panel_regions(&surface.output); + let container = widget::container(container).padding(panel_regions); + let output = surface.output.clone(); widget::mouse_area(container) .on_scroll(move |delta| Msg::OnScroll(output.clone(), delta))