fix: Use globals instead of thread-locals
Better support for multi-threaded applications, especially cosmic-comp rendering in parallel on multiple threads, each potentially accessing global configurations such as the active theme, icon_theme and more...
This commit is contained in:
parent
f655710d55
commit
b40839638a
16 changed files with 183 additions and 216 deletions
|
|
@ -31,95 +31,85 @@ pub fn icon<'a, Message>(handle: impl Into<Handle>) -> Button<'a, Message> {
|
|||
|
||||
impl<'a, Message> Button<'a, Message> {
|
||||
pub fn new(icon: Icon) -> Self {
|
||||
crate::theme::THEME.with(|theme_cell| {
|
||||
let theme = theme_cell.borrow();
|
||||
let theme = theme.cosmic();
|
||||
let padding = theme.space_xxs();
|
||||
let guard = crate::theme::THEME.lock().unwrap();
|
||||
let theme = guard.cosmic();
|
||||
let padding = theme.space_xxs();
|
||||
|
||||
Self {
|
||||
id: Id::unique(),
|
||||
label: Cow::Borrowed(""),
|
||||
tooltip: Cow::Borrowed(""),
|
||||
on_press: None,
|
||||
width: Length::Shrink,
|
||||
height: Length::Shrink,
|
||||
padding: Padding::from(padding),
|
||||
spacing: theme.space_xxxs(),
|
||||
icon_size: if icon.handle.symbolic { 16 } else { 24 },
|
||||
line_height: 20,
|
||||
font_size: 14,
|
||||
font_weight: Weight::Normal,
|
||||
style: Style::Icon,
|
||||
variant: icon,
|
||||
}
|
||||
})
|
||||
Self {
|
||||
id: Id::unique(),
|
||||
label: Cow::Borrowed(""),
|
||||
tooltip: Cow::Borrowed(""),
|
||||
on_press: None,
|
||||
width: Length::Shrink,
|
||||
height: Length::Shrink,
|
||||
padding: Padding::from(padding),
|
||||
spacing: theme.space_xxxs(),
|
||||
icon_size: if icon.handle.symbolic { 16 } else { 24 },
|
||||
line_height: 20,
|
||||
font_size: 14,
|
||||
font_weight: Weight::Normal,
|
||||
style: Style::Icon,
|
||||
variant: icon,
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies the **Extra Small** button size preset.
|
||||
pub fn extra_small(mut self) -> Self {
|
||||
crate::theme::THEME.with(|theme_cell| {
|
||||
let theme = theme_cell.borrow();
|
||||
let theme = theme.cosmic();
|
||||
let guard = crate::theme::THEME.lock().unwrap();
|
||||
let theme = guard.cosmic();
|
||||
|
||||
self.font_size = 14;
|
||||
self.font_weight = Weight::Normal;
|
||||
self.icon_size = 16;
|
||||
self.line_height = 20;
|
||||
self.padding = Padding::from(theme.space_xxs());
|
||||
self.spacing = theme.space_xxxs();
|
||||
});
|
||||
self.font_size = 14;
|
||||
self.font_weight = Weight::Normal;
|
||||
self.icon_size = 16;
|
||||
self.line_height = 20;
|
||||
self.padding = Padding::from(theme.space_xxs());
|
||||
self.spacing = theme.space_xxxs();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Applies the **Medium** button size preset.
|
||||
pub fn medium(mut self) -> Self {
|
||||
crate::theme::THEME.with(|theme_cell| {
|
||||
let theme = theme_cell.borrow();
|
||||
let theme = theme.cosmic();
|
||||
let guard = crate::theme::THEME.lock().unwrap();
|
||||
let theme = guard.cosmic();
|
||||
|
||||
self.font_size = 24;
|
||||
self.font_weight = Weight::Normal;
|
||||
self.icon_size = 32;
|
||||
self.line_height = 32;
|
||||
self.padding = Padding::from(theme.space_xs());
|
||||
self.spacing = theme.space_xxs();
|
||||
});
|
||||
self.font_size = 24;
|
||||
self.font_weight = Weight::Normal;
|
||||
self.icon_size = 32;
|
||||
self.line_height = 32;
|
||||
self.padding = Padding::from(theme.space_xs());
|
||||
self.spacing = theme.space_xxs();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Applies the **Large** button size preset.
|
||||
pub fn large(mut self) -> Self {
|
||||
crate::theme::THEME.with(|theme_cell| {
|
||||
let theme = theme_cell.borrow();
|
||||
let theme = theme.cosmic();
|
||||
let guard = crate::theme::THEME.lock().unwrap();
|
||||
let theme = guard.cosmic();
|
||||
|
||||
self.font_size = 28;
|
||||
self.font_weight = Weight::Normal;
|
||||
self.icon_size = 40;
|
||||
self.line_height = 36;
|
||||
self.padding = Padding::from(theme.space_xs());
|
||||
self.spacing = theme.space_xxs();
|
||||
});
|
||||
self.font_size = 28;
|
||||
self.font_weight = Weight::Normal;
|
||||
self.icon_size = 40;
|
||||
self.line_height = 36;
|
||||
self.padding = Padding::from(theme.space_xs());
|
||||
self.spacing = theme.space_xxs();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Applies the **Extra Large** button size preset.
|
||||
pub fn extra_large(mut self) -> Self {
|
||||
crate::theme::THEME.with(|theme_cell| {
|
||||
let theme = theme_cell.borrow();
|
||||
let theme = theme.cosmic();
|
||||
let padding = theme.space_xs();
|
||||
let guard = crate::theme::THEME.lock().unwrap();
|
||||
let theme = guard.cosmic();
|
||||
let padding = theme.space_xs();
|
||||
|
||||
self.font_size = 32;
|
||||
self.font_weight = Weight::Light;
|
||||
self.icon_size = 56;
|
||||
self.line_height = 44;
|
||||
self.padding = Padding::from(padding);
|
||||
self.spacing = theme.space_xxs();
|
||||
});
|
||||
self.font_size = 32;
|
||||
self.font_weight = Weight::Light;
|
||||
self.icon_size = 56;
|
||||
self.line_height = 44;
|
||||
self.padding = Padding::from(padding);
|
||||
self.spacing = theme.space_xxs();
|
||||
|
||||
self
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ pub struct Appearance {
|
|||
impl Appearance {
|
||||
// TODO: `Radius` is not `const fn` compatible.
|
||||
pub fn new() -> Self {
|
||||
let rad_0 = THEME.with(|t| t.borrow().cosmic().corner_radii.radius_0);
|
||||
let rad_0 = THEME.lock().unwrap().cosmic().corner_radii.radius_0;
|
||||
Self {
|
||||
shadow_offset: Vector::new(0.0, 0.0),
|
||||
background: None,
|
||||
|
|
|
|||
|
|
@ -51,26 +51,24 @@ impl Text {
|
|||
|
||||
impl<'a, Message> Button<'a, Message> {
|
||||
pub fn new(text: Text) -> Self {
|
||||
crate::theme::THEME.with(|theme_cell| {
|
||||
let theme = theme_cell.borrow();
|
||||
let theme = theme.cosmic();
|
||||
Self {
|
||||
id: Id::unique(),
|
||||
label: Cow::Borrowed(""),
|
||||
tooltip: Cow::Borrowed(""),
|
||||
on_press: None,
|
||||
width: Length::Shrink,
|
||||
height: Length::Fixed(theme.space_l().into()),
|
||||
padding: Padding::from([0, theme.space_s()]),
|
||||
spacing: theme.space_xxxs(),
|
||||
icon_size: 16,
|
||||
line_height: 20,
|
||||
font_size: 14,
|
||||
font_weight: Weight::Normal,
|
||||
style: Style::Standard,
|
||||
variant: text,
|
||||
}
|
||||
})
|
||||
let guard = crate::theme::THEME.lock().unwrap();
|
||||
let theme = guard.cosmic();
|
||||
Self {
|
||||
id: Id::unique(),
|
||||
label: Cow::Borrowed(""),
|
||||
tooltip: Cow::Borrowed(""),
|
||||
on_press: None,
|
||||
width: Length::Shrink,
|
||||
height: Length::Fixed(theme.space_l().into()),
|
||||
padding: Padding::from([0, theme.space_s()]),
|
||||
spacing: theme.space_xxxs(),
|
||||
icon_size: 16,
|
||||
line_height: 20,
|
||||
font_size: 14,
|
||||
font_weight: Weight::Normal,
|
||||
style: Style::Standard,
|
||||
variant: text,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn leading_icon(mut self, icon: impl Into<icon::Handle>) -> Self {
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ impl<'a, Message: 'a + Clone> Widget<Message, crate::Theme, crate::Renderer>
|
|||
renderer.with_layer(parent_bounds, |renderer| {
|
||||
let selection_background = theme.selection_background();
|
||||
|
||||
let c_rad = THEME.with(|t| t.borrow().cosmic().corner_radii);
|
||||
let c_rad = THEME.lock().unwrap().cosmic().corner_radii;
|
||||
|
||||
// NOTE: Workaround to round the border of the unselected, unhovered image.
|
||||
if !self.selected && !is_mouse_over {
|
||||
|
|
|
|||
|
|
@ -177,11 +177,7 @@ fn padded_control<'a, Message>(
|
|||
}
|
||||
|
||||
fn menu_control_padding() -> Padding {
|
||||
crate::theme::THEME
|
||||
.with(|t| {
|
||||
let t = t.borrow();
|
||||
let cosmic = t.cosmic();
|
||||
[cosmic.space_xxs(), cosmic.space_m()]
|
||||
})
|
||||
.into()
|
||||
let guard = crate::theme::THEME.lock().unwrap();
|
||||
let cosmic = guard.cosmic();
|
||||
[cosmic.space_xxs(), cosmic.space_m()].into()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ where
|
|||
copied_to_clipboard_label: T,
|
||||
) -> ColorPicker<'a, Message> {
|
||||
let on_update = self.on_update;
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().spacing);
|
||||
let spacing = THEME.lock().unwrap().cosmic().spacing;
|
||||
let mut inner = column![
|
||||
// segmented buttons
|
||||
segmented_control::horizontal(self.model)
|
||||
|
|
@ -595,7 +595,7 @@ where
|
|||
let bounds = canvas_layout.bounds();
|
||||
// Draw the handle on the saturation value canvas
|
||||
|
||||
let t = THEME.with(|t| t.borrow().clone());
|
||||
let t = THEME.lock().unwrap().clone();
|
||||
let t = t.cosmic();
|
||||
let handle_radius = f32::from(t.space_xs()) / 2.0;
|
||||
let (x, y) = (
|
||||
|
|
@ -779,7 +779,7 @@ pub fn color_button<'a, Message: 'static>(
|
|||
color: Option<Color>,
|
||||
icon_portion: Length,
|
||||
) -> crate::widget::Button<'a, Message> {
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().spacing);
|
||||
let spacing = THEME.lock().unwrap().cosmic().spacing;
|
||||
|
||||
button(if color.is_some() {
|
||||
Element::from(vertical_space(Length::Fixed(f32::from(spacing.space_s))))
|
||||
|
|
|
|||
|
|
@ -67,11 +67,7 @@ impl<'a, Message: Clone + 'static> From<Dialog<'a, Message>> for Element<'a, Mes
|
|||
space_s,
|
||||
space_xxs,
|
||||
..
|
||||
} = theme::THEME.with(|theme_cell| {
|
||||
let theme = theme_cell.borrow();
|
||||
let theme = theme.cosmic();
|
||||
theme.spacing
|
||||
});
|
||||
} = theme::THEME.lock().unwrap().cosmic().spacing;
|
||||
|
||||
let mut content_col = widget::column::with_capacity(3 + dialog.controls.len() * 2);
|
||||
content_col = content_col.push(widget::text::title3(dialog.title));
|
||||
|
|
|
|||
|
|
@ -75,38 +75,35 @@ impl Named {
|
|||
lookup.find()
|
||||
};
|
||||
|
||||
crate::icon_theme::DEFAULT.with(|theme| {
|
||||
let theme = theme.borrow();
|
||||
let theme = crate::icon_theme::DEFAULT.lock().unwrap();
|
||||
let themes = if theme.as_ref() == crate::icon_theme::COSMIC {
|
||||
vec![theme.as_ref()]
|
||||
} else {
|
||||
vec![theme.as_ref(), crate::icon_theme::COSMIC]
|
||||
};
|
||||
|
||||
let themes = if theme.as_ref() == crate::icon_theme::COSMIC {
|
||||
vec![theme.as_ref()]
|
||||
} else {
|
||||
vec![theme.as_ref(), crate::icon_theme::COSMIC]
|
||||
};
|
||||
let mut result = themes.iter().find_map(|t| locate(t, name));
|
||||
|
||||
let mut result = themes.iter().find_map(|t| locate(t, name));
|
||||
|
||||
// On failure, attempt to locate fallback icon.
|
||||
if result.is_none() {
|
||||
if matches!(fallback, Some(IconFallback::Default)) {
|
||||
for new_name in name.rmatch_indices('-').map(|(pos, _)| &name[..pos]) {
|
||||
result = themes.iter().find_map(|t| locate(t, new_name));
|
||||
if result.is_some() {
|
||||
break;
|
||||
}
|
||||
// On failure, attempt to locate fallback icon.
|
||||
if result.is_none() {
|
||||
if matches!(fallback, Some(IconFallback::Default)) {
|
||||
for new_name in name.rmatch_indices('-').map(|(pos, _)| &name[..pos]) {
|
||||
result = themes.iter().find_map(|t| locate(t, new_name));
|
||||
if result.is_some() {
|
||||
break;
|
||||
}
|
||||
} else if let Some(IconFallback::Names(fallbacks)) = fallback {
|
||||
for fallback in fallbacks {
|
||||
result = themes.iter().find_map(|t| locate(t, fallback));
|
||||
if result.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if let Some(IconFallback::Names(fallbacks)) = fallback {
|
||||
for fallback in fallbacks {
|
||||
result = themes.iter().find_map(|t| locate(t, fallback));
|
||||
if result.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
})
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
|
|
|||
|
|
@ -1361,7 +1361,7 @@ where
|
|||
bounds.y = bounds.y + bounds.height - width;
|
||||
bounds.height = width;
|
||||
|
||||
let rad_0 = THEME.with(|t| t.borrow().cosmic().corner_radii.radius_0);
|
||||
let rad_0 = THEME.lock().unwrap().cosmic().corner_radii.radius_0;
|
||||
renderer.fill_quad(
|
||||
renderer::Quad {
|
||||
bounds,
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ pub fn search_input<'a, Message>(
|
|||
where
|
||||
Message: Clone + 'static,
|
||||
{
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs());
|
||||
let spacing = THEME.lock().unwrap().cosmic().space_xxs();
|
||||
|
||||
TextInput::new(placeholder, value)
|
||||
.padding([0, spacing, 0, spacing])
|
||||
|
|
@ -117,7 +117,7 @@ pub fn secure_input<'a, Message>(
|
|||
where
|
||||
Message: Clone + 'static,
|
||||
{
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs());
|
||||
let spacing = THEME.lock().unwrap().cosmic().space_xxs();
|
||||
let mut input = TextInput::new(placeholder, value)
|
||||
.padding([0, spacing, 0, spacing])
|
||||
.style(crate::theme::TextInput::Default)
|
||||
|
|
@ -156,7 +156,7 @@ pub fn inline_input<'a, Message>(
|
|||
where
|
||||
Message: Clone + 'static,
|
||||
{
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs());
|
||||
let spacing = THEME.lock().unwrap().cosmic().space_xxs();
|
||||
|
||||
TextInput::new(placeholder, value)
|
||||
.style(crate::theme::TextInput::Inline)
|
||||
|
|
@ -223,7 +223,7 @@ where
|
|||
/// - a placeholder,
|
||||
/// - the current value
|
||||
pub fn new(placeholder: impl Into<Cow<'a, str>>, value: impl Into<Cow<'a, str>>) -> Self {
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs());
|
||||
let spacing = THEME.lock().unwrap().cosmic().space_xxs();
|
||||
|
||||
let v: Cow<'a, str> = value.into();
|
||||
TextInput {
|
||||
|
|
@ -486,7 +486,7 @@ where
|
|||
}
|
||||
|
||||
pub fn on_clear(self, on_clear: Message) -> Self {
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs());
|
||||
let spacing = THEME.lock().unwrap().cosmic().space_xxs();
|
||||
|
||||
self.trailing_icon(
|
||||
crate::widget::icon::from_name("edit-clear-symbolic")
|
||||
|
|
@ -992,7 +992,7 @@ pub fn layout<Message>(
|
|||
tree: &mut Tree,
|
||||
) -> layout::Node {
|
||||
let limits = limits.width(width);
|
||||
let spacing = THEME.with(|t| t.borrow().cosmic().space_xxs());
|
||||
let spacing = THEME.lock().unwrap().cosmic().space_xxs();
|
||||
let mut nodes = Vec::with_capacity(3);
|
||||
|
||||
let text_pos = if let Some(label) = label {
|
||||
|
|
@ -2186,9 +2186,7 @@ pub fn draw<'a, Message>(
|
|||
let font = font.unwrap_or_else(|| renderer.default_font());
|
||||
let size = size.unwrap_or_else(|| renderer.default_size().0);
|
||||
|
||||
let radius_0 = THEME
|
||||
.with(|t| t.borrow().cosmic().corner_radii.radius_0)
|
||||
.into();
|
||||
let radius_0 = THEME.lock().unwrap().cosmic().corner_radii.radius_0.into();
|
||||
let (cursor, offset) = if let Some(focus) = &state.is_focused {
|
||||
match state.cursor.state(value) {
|
||||
cursor::State::Index(position) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue