From 15091632304c35cbf32f9d62a3515e9db85bc69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= Date: Fri, 4 Apr 2025 15:43:32 +0200 Subject: [PATCH] fix(app): match padding to designs Also makes the maximize button change to restore when the window is maximized. --- iced | 2 +- res/icons/window-restore-symbolic.svg | 4 ++ src/app/mod.rs | 57 ++++++++++++++++++--------- src/widget/header_bar.rs | 44 +++++++++++++++------ src/widget/scrollable.rs | 3 ++ 5 files changed, 80 insertions(+), 30 deletions(-) create mode 100644 res/icons/window-restore-symbolic.svg diff --git a/iced b/iced index 0053fd17..696aa926 160000 --- a/iced +++ b/iced @@ -1 +1 @@ -Subproject commit 0053fd177af075a986aff948386f1169050045b8 +Subproject commit 696aa92626e22f09268d4254a8be5e60a46fcea0 diff --git a/res/icons/window-restore-symbolic.svg b/res/icons/window-restore-symbolic.svg new file mode 100644 index 00000000..bcb506f5 --- /dev/null +++ b/res/icons/window-restore-symbolic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/app/mod.rs b/src/app/mod.rs index 2f4192b6..d73d024c 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -541,23 +541,30 @@ impl ApplicationExt for App { fn view_main(&self) -> Element> { let core = self.core(); let is_condensed = core.is_condensed(); - // TODO: More granularity might be needed for different resize border - // and window border handling of maximized and tiled windows + // TODO: More granularity might be needed for different window border + // handling of maximized and tiled windows let sharp_corners = core.window.sharp_corners; let content_container = core.window.content_container; + let show_context = core.window.show_context; + let context_is_overlay = core.window.context_is_overlay; let nav_bar_active = core.nav_bar_active(); let focused = core .focused_window() .is_some_and(|i| Some(i) == self.core().main_window_id()); - let main_content_padding = if content_container { - if nav_bar_active { - [0, 8, 8, 0] - } else { - [0, 8, 8, 8] - } - } else { + let border_padding = if sharp_corners { 8 } else { 7 }; + + let main_content_padding = if !content_container { [0, 0, 0, 0] + } else { + let right_padding = if show_context && !context_is_overlay { + 0 + } else { + border_padding + }; + let left_padding = if nav_bar_active { 0 } else { border_padding }; + + [0, right_padding, 0, left_padding] }; let content_row = crate::widget::row::with_children({ @@ -568,7 +575,16 @@ impl ApplicationExt for App { .nav_bar() .map(|nav| id_container(nav, iced_core::id::Id::new("COSMIC_nav_bar"))) { - widgets.push(container(nav).padding([0, 8, 8, 8]).into()); + widgets.push( + container(nav) + .padding([ + 0, + if is_condensed { border_padding } else { 8 }, + border_padding, + border_padding, + ]) + .into(), + ); true } else { false @@ -579,7 +595,7 @@ impl ApplicationExt for App { //TODO: reduce duplication let context_width = core.context_width(has_nav); - if core.window.context_is_overlay && core.window.show_context { + if context_is_overlay && show_context { if let Some(context) = self.context_drawer() { widgets.push( crate::widget::context_drawer( @@ -600,7 +616,7 @@ impl ApplicationExt for App { }) .apply(container) .padding(if content_container { - [0, 8, 8, 0] + [0, border_padding, border_padding, border_padding] } else { [0, 0, 0, 0] }) @@ -648,7 +664,7 @@ impl ApplicationExt for App { }) .apply(container) .padding(if content_container { - [0, 8, 8, 0] + [0, border_padding, border_padding, border_padding] } else { [0, 0, 0, 0] }) @@ -665,11 +681,15 @@ impl ApplicationExt for App { }); let content_col = crate::widget::column::with_capacity(2) .push(content_row) - .push_maybe( - self.footer() - .map(|footer| container(footer.map(crate::Action::App)).padding([0, 8, 8, 8])), - ); - let content: Element<_> = if core.window.content_container { + .push_maybe(self.footer().map(|footer| { + container(footer.map(crate::Action::App)).padding([ + 0, + border_padding, + border_padding, + border_padding, + ]) + })); + let content: Element<_> = if content_container { content_col .apply(container) .width(iced::Length::Fill) @@ -692,6 +712,7 @@ impl ApplicationExt for App { Some({ let mut header = crate::widget::header_bar() .focused(focused) + .maximized(sharp_corners) .title(&core.window.header_title) .on_drag(crate::Action::Cosmic(Action::Drag)) .on_right_click(crate::Action::Cosmic(Action::ShowWindowMenu)) diff --git a/src/widget/header_bar.rs b/src/widget/header_bar.rs index 80a2cbd8..dcd8aa0f 100644 --- a/src/widget/header_bar.rs +++ b/src/widget/header_bar.rs @@ -23,6 +23,7 @@ pub fn header_bar<'a, Message>() -> HeaderBar<'a, Message> { end: Vec::new(), density: None, focused: false, + maximized: false, on_double_click: None, } } @@ -76,6 +77,9 @@ pub struct HeaderBar<'a, Message> { /// Focused state of the window focused: bool, + + /// Maximized state of the window + maximized: bool, } impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { @@ -302,10 +306,22 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { // Also packs the window controls at the very end. end.push(self.window_controls()); - let height = match self.density.unwrap_or_else(crate::config::header_size) { - Density::Compact => 40.0, - Density::Spacious => 48.0, - Density::Standard => 48.0, + // Center content depending on window border + let padding = match self.density.unwrap_or_else(crate::config::header_size) { + Density::Compact => { + if self.maximized { + [4, 8, 4, 8] + } else { + [3, 7, 4, 7] + } + } + _ => { + if self.maximized { + [8, 8, 8, 8] + } else { + [7, 7, 8, 7] + } + } }; let portion = ((start.len().max(end.len()) as f32 / center.len().max(1) as f32).round() as u16) @@ -349,8 +365,8 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { }), ) .align_y(iced::Alignment::Center) - .height(Length::Fixed(height)) - .padding([0, 8]) + .height(Length::Fixed(32.0 + padding[0] as f32 + padding[2] as f32)) + .padding(padding) .spacing(8) .apply(widget::container) .class(crate::theme::Container::HeaderBar { @@ -424,11 +440,17 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> { .take() .map(|m: Message| icon!("window-minimize-symbolic", 16, m)), ) - .push_maybe( - self.on_maximize - .take() - .map(|m| icon!("window-maximize-symbolic", 16, m)), - ) + .push_maybe(self.on_maximize.take().map(|m| { + icon!( + if self.maximized { + "window-restore-symbolic" + } else { + "window-maximize-symbolic" + }, + 16, + m + ) + })) .push_maybe( self.on_close .take() diff --git a/src/widget/scrollable.rs b/src/widget/scrollable.rs index 71f63aad..81ed3533 100644 --- a/src/widget/scrollable.rs +++ b/src/widget/scrollable.rs @@ -8,4 +8,7 @@ pub fn scrollable<'a, Message>( element: impl Into>, ) -> widget::Scrollable<'a, Message, crate::Theme, Renderer> { widget::scrollable(element) + .scroller_width(8.0) + .scrollbar_width(8.0) + .scrollbar_padding(8.0) }