Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 47 additions & 45 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
HEIGHT,
components::{Centerbox, menu::MenuType},
config::{self, BarSurface, Config, ModuleName, Modules, WorkspaceIndicatorFormat},
config::{self, Config, ModuleName, Modules, WorkspaceIndicatorFormat},
get_log_spec,
i18n::{Localizer, init_localizer},
ipc::IpcCommand,
Expand All @@ -24,7 +24,7 @@ use crate::{
osd::{self, Osd},
outputs::{HasOutput, Outputs},
services::{ReadOnlyService, xdg_icons},
theme::{AshellTheme, BarLayout, backdrop_color, darken_color, init_theme, use_theme},
theme::{AshellTheme, BarLayout, darken_color, init_theme, use_theme},
};
use flexi_logger::LoggerHandle;
use iced::futures::StreamExt;
Expand Down Expand Up @@ -84,7 +84,7 @@ impl App {
) -> impl FnOnce() -> (Self, Task<Message>) {
move || {
let mut outputs = Outputs::new(
BarLayout::from_appearance(&config.appearance.bar),
BarLayout::new(config.appearance.bar),
config.position,
config.layer,
config.appearance.scale_factor,
Expand Down Expand Up @@ -238,7 +238,7 @@ impl App {
);
let (bar_position, bar_layout, scale_factor) =
use_theme(|t| (t.bar_position, t.bar_layout(), t.scale_factor));
let new_layout = BarLayout::from_appearance(&config.appearance.bar);
let new_layout = BarLayout::new(config.appearance.bar);
if self.general_config.outputs != config.outputs
|| bar_position != config.position
|| bar_layout != new_layout
Expand Down Expand Up @@ -588,61 +588,63 @@ impl App {

let [left, center, right] = self.modules_section(id);

let (space, bar_surface, menu, animations_enabled, bar_radius, blur) =
use_theme(|t| {
(
t.space,
t.bar_surface,
t.menu,
t.animations_enabled,
t.bar_border_radius(),
t.blur,
)
});
let (space, bar, menu, animations_enabled, theme_radius, blur) = use_theme(|t| {
(
t.space,
t.bar,
t.menu,
t.animations_enabled,
t.radius,
t.blur,
)
});
let (bar_bg_opacity, bar_border, bar_inset) =
(bar.opacity.background, bar.border, bar.inset);
let radius = bar_border.radius.resolve(theme_radius);

let has_inset = bar_inset > 0.;

let centerbox = Centerbox::new([left, center, right])
.animated(animations_enabled)
.spacing(space.xxs)
.width(Length::Fill)
.align_items(Alignment::Center)
.height(if bar_surface == BarSurface::Transparent {
HEIGHT
} else {
.height(if has_inset {
HEIGHT - space.xs as f64
} as f32)
.padding(if bar_surface == BarSurface::Transparent {
[space.xxs, space.xxs]
} else {
HEIGHT
} as f32)
.padding(if has_inset {
[0.0, 0.0]
} else {
[space.xxs, space.xxs]
});

let menu_is_open = self.outputs.menu_is_open();
let bar_style = move |t: &Theme| container::Style {
background: match bar_surface {
BarSurface::Solid => Some({
let bg = t.palette().background;
if menu_is_open {
darken_color(bg, menu.backdrop)
} else {
bg
}
.into()
}),
BarSurface::Transparent => {
if menu_is_open {
Some(backdrop_color(menu.backdrop).into())
} else {
None
}
}
},
border: iced::Border {
radius: bar_radius,
let bar_style = move |t: &Theme| {
let bg = t.palette().background.scale_alpha(bar_bg_opacity);

container::Style {
background: {
Some(
if menu_is_open {
darken_color(bg, menu.backdrop)
} else {
bg
}
.into(),
)
},
border: iced::Border {
radius,
color: bar_border.color.get_base(),
width: bar_border.width,
},
..Default::default()
},
..Default::default()
}
};
// In Transparent the individual module groups carry the blur.
let status_bar: Element<'_, Message> = if blur && bar_surface == BarSurface::Solid {
let status_bar: Element<'_, Message> = if blur && bar_bg_opacity > 0. {
blur_container(centerbox).style(bar_style).into()
} else {
container(centerbox).style(bar_style).into()
Expand Down
32 changes: 15 additions & 17 deletions src/components/menu.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::app::{self, App};
use crate::components::{self, ButtonUIRef};
use crate::config::{BarSurface, Position};
use crate::config::Position;
use crate::theme::{backdrop_color, use_theme};
use iced::alignment::Vertical;
use iced::widget::container::Style;
Expand Down Expand Up @@ -301,19 +301,21 @@ impl App {
content: Element<'a, app::Message>,
button_ui_ref: ButtonUIRef,
) -> Element<'a, app::Message> {
let (space, radius, bar_surface, bar_position, menu_backdrop, blur) = use_theme(|t| {
(
t.space,
t.radius,
t.bar_surface,
t.bar_position,
t.menu.backdrop,
t.blur,
)
});
let (space, radius, bar_inset, bar_position, menu_backdrop, menu_opacity, blur) =
use_theme(|t| {
(
t.space,
t.radius,
t.bar.inset,
t.bar_position,
t.menu.backdrop,
t.menu.opacity,
t.blur,
)
});

let menu_style = move |theme: &Theme| Style {
background: Some(theme.palette().background.into()),
background: Some(theme.palette().background.scale_alpha(menu_opacity).into()),
border: Border {
color: theme.extended_palette().background.weakest.color,
width: 1.,
Expand All @@ -337,11 +339,7 @@ impl App {

components::MenuWrapper::new(button_ui_ref.position.x, menu_body)
.padding({
let v_padding = match bar_surface {
BarSurface::Solid => 2,
BarSurface::Transparent => 0,
};

let v_padding = if bar_inset > 0. { 2 } else { 0 };
Padding::new(0.)
.top(if bar_position == Position::Top {
v_padding
Expand Down
2 changes: 2 additions & 0 deletions src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod menu;
mod menu_wrapper;
mod module_group;
mod module_item;
mod module_view;
pub mod password_dialog;
mod position_button;
mod quick_setting_button;
Expand All @@ -25,6 +26,7 @@ pub use menu::MenuSize;
pub use menu_wrapper::*;
pub use module_group::*;
pub use module_item::*;
pub use module_view::*;
pub use position_button::*;
pub use quick_setting_button::*;
pub use slider_control::*;
Expand Down
81 changes: 55 additions & 26 deletions src/components/module_group.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,64 @@
use crate::{config::BarSurface, theme::use_theme};
use crate::{
config::{BorderAppearance, ModuleAppearance},
theme::use_theme,
};
use iced::{
Border, Color, Element,
Border, Element,
widget::{blur_container, container},
};

/// Wraps content with the appropriate bar surface container.
///
/// - `Solid` → pass through as-is (the bar itself carries the background)
/// - `Transparent` → wrap in a container with background color + rounded border,
/// using `blur_container` when compositor blur is enabled
pub fn module_group<'a, Msg: 'static>(content: Element<'a, Msg>) -> Element<'a, Msg> {
let (bar_surface, radius, blur) =
use_theme(|theme| (theme.bar_surface, theme.radius, theme.blur));
/// Wraps content in a container styled from theme
pub fn module_group<'a, Msg: 'static>(
content: Element<'a, Msg>,
module_apperance: ModuleAppearance,
) -> Element<'a, Msg> {
let (theme_space, theme_radius, module_opacity, module_border, blur) = use_theme(|theme| {
(
theme.space,
theme.radius,
theme.bar.opacity.module,
theme.bar.module_border,
theme.blur,
)
});

match bar_surface {
BarSurface::Solid => content,
BarSurface::Transparent => {
let style = move |iced_theme: &iced::Theme| container::Style {
background: Some(iced_theme.palette().background.into()),
border: Border {
width: 0.0,
radius: radius.lg.into(),
color: Color::TRANSPARENT,
},
..container::Style::default()
};
if blur {
blur_container(content).style(style).into()
} else {
container(content).style(style).into()
let border = module_apperance.border.map_or_else(
|| Border {
width: module_border.width,
color: module_border.color.get_base(),
radius: module_border.radius.resolve(theme_radius),
},
|BorderAppearance {
width,
radius,
color,
}| {
Border {
width,
radius: radius.resolve(theme_radius),
color: color.get_base(),
}
},
);
let opacity = module_apperance.opacity.unwrap_or(module_opacity);

let padding = theme_space.resolve(module_apperance.padding);
let style = move |iced_theme: &iced::Theme| {
let background = module_apperance.background.map_or_else(
|| iced_theme.palette().background.scale_alpha(opacity),
|b| b.get_base().scale_alpha(opacity),
);

container::Style {
background: Some(background.into()),
border,
..container::Style::default()
}
};

if blur {
blur_container(content).padding(padding).style(style).into()
} else {
container(content).padding(padding).style(style).into()
}
}
11 changes: 8 additions & 3 deletions src/components/module_item.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{components::position_button, theme::use_theme};
use crate::{components::position_button, config::ModuleAppearance, theme::use_theme};
use iced::{Alignment, Element, Length, widget::container};

use super::ButtonUIRef;
Expand All @@ -9,6 +9,7 @@ use super::ButtonUIRef;
/// When no press handler is set, renders as a plain container.
pub struct ModuleItem<'a, Msg> {
content: Element<'a, Msg>,
appearance: Option<ModuleAppearance>,
on_press: Option<Msg>,
on_press_with_position: Option<Box<dyn Fn(ButtonUIRef) -> Msg + 'a>>,
on_right_press: Option<Msg>,
Expand All @@ -17,9 +18,13 @@ pub struct ModuleItem<'a, Msg> {
on_scroll_down: Option<Msg>,
}

pub fn module_item<'a, Msg: 'static + Clone>(content: Element<'a, Msg>) -> ModuleItem<'a, Msg> {
pub fn module_item<'a, Msg: 'static + Clone>(
content: Element<'a, Msg>,
appearance: Option<ModuleAppearance>,
) -> ModuleItem<'a, Msg> {
ModuleItem {
content,
appearance,
on_press: None,
on_press_with_position: None,
on_right_press: None,
Expand Down Expand Up @@ -64,7 +69,7 @@ impl<'a, Msg: 'static + Clone> ModuleItem<'a, Msg> {
impl<'a, Msg: 'static + Clone> From<ModuleItem<'a, Msg>> for Element<'a, Msg> {
fn from(item: ModuleItem<'a, Msg>) -> Self {
let (space, module_button_style) =
use_theme(|theme| (theme.space, theme.module_button_style()));
use_theme(|theme| (theme.space, theme.module_button_style(item.appearance)));

let has_action = item.on_press.is_some() || item.on_press_with_position.is_some();

Expand Down
Loading