aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-09-20 12:57:41 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-10-02 09:33:08 +0300
commit1fa9dd32ed028c88248644a13421c098fef72894 (patch)
treee6ea60b5b0b7ebc390ecc623b091bbe3dc40fdf0
parent2781d3a74338806f631acda99e9f702b1b59a3e6 (diff)
downloadniri-1fa9dd32ed028c88248644a13421c098fef72894.tar.gz
niri-1fa9dd32ed028c88248644a13421c098fef72894.tar.bz2
niri-1fa9dd32ed028c88248644a13421c098fef72894.zip
config: Split Layout from LayoutPart
-rw-r--r--niri-config/src/appearance.rs214
-rw-r--r--niri-config/src/layout.rs127
-rw-r--r--niri-config/src/lib.rs480
-rw-r--r--niri-config/src/macros.rs10
-rw-r--r--niri-config/src/utils.rs15
-rw-r--r--niri-visual-tests/src/cases/gradient_area.rs4
-rw-r--r--niri-visual-tests/src/cases/layout.rs4
-rw-r--r--niri-visual-tests/src/cases/tile.rs4
-rw-r--r--src/layer/mapped.rs4
-rw-r--r--src/layout/floating.rs4
-rw-r--r--src/layout/focus_ring.rs4
-rw-r--r--src/layout/insert_hint_element.rs6
-rw-r--r--src/layout/mod.rs24
-rw-r--r--src/layout/scrolling.rs8
-rw-r--r--src/layout/shadow.rs4
-rw-r--r--src/layout/tab_indicator.rs16
-rw-r--r--src/layout/tests.rs33
-rw-r--r--src/layout/tests/fullscreen.rs2
-rw-r--r--src/layout/workspace.rs4
-rw-r--r--src/niri.rs4
-rw-r--r--src/tests/animations.rs2
21 files changed, 559 insertions, 414 deletions
diff --git a/niri-config/src/appearance.rs b/niri-config/src/appearance.rs
index dfe4ebbb..bdcbb318 100644
--- a/niri-config/src/appearance.rs
+++ b/niri-config/src/appearance.rs
@@ -5,7 +5,7 @@ use knuffel::errors::DecodeError;
use miette::{miette, IntoDiagnostic as _};
use smithay::backend::renderer::Color32F;
-use crate::utils::MergeWith;
+use crate::utils::{Flag, MergeWith};
use crate::FloatOrInt;
pub const DEFAULT_BACKGROUND_COLOR: Color = Color::from_array_unpremul([0.25, 0.25, 0.25, 1.]);
@@ -222,23 +222,15 @@ impl CornerRadius {
}
}
-#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FocusRing {
- #[knuffel(child)]
pub off: bool,
- #[knuffel(child, unwrap(argument), default = Self::default().width)]
- pub width: FloatOrInt<0, 65535>,
- #[knuffel(child, default = Self::default().active_color)]
+ pub width: f64,
pub active_color: Color,
- #[knuffel(child, default = Self::default().inactive_color)]
pub inactive_color: Color,
- #[knuffel(child, default = Self::default().urgent_color)]
pub urgent_color: Color,
- #[knuffel(child)]
pub active_gradient: Option<Gradient>,
- #[knuffel(child)]
pub inactive_gradient: Option<Gradient>,
- #[knuffel(child)]
pub urgent_gradient: Option<Gradient>,
}
@@ -246,7 +238,7 @@ impl Default for FocusRing {
fn default() -> Self {
Self {
off: false,
- width: FloatOrInt(4.),
+ width: 4.,
active_color: Color::from_rgba8_unpremul(127, 200, 255, 255),
inactive_color: Color::from_rgba8_unpremul(80, 80, 80, 255),
urgent_color: Color::from_rgba8_unpremul(155, 0, 0, 255),
@@ -257,23 +249,15 @@ impl Default for FocusRing {
}
}
-#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Border {
- #[knuffel(child)]
pub off: bool,
- #[knuffel(child, unwrap(argument), default = Self::default().width)]
- pub width: FloatOrInt<0, 65535>,
- #[knuffel(child, default = Self::default().active_color)]
+ pub width: f64,
pub active_color: Color,
- #[knuffel(child, default = Self::default().inactive_color)]
pub inactive_color: Color,
- #[knuffel(child, default = Self::default().urgent_color)]
pub urgent_color: Color,
- #[knuffel(child)]
pub active_gradient: Option<Gradient>,
- #[knuffel(child)]
pub inactive_gradient: Option<Gradient>,
- #[knuffel(child)]
pub urgent_gradient: Option<Gradient>,
}
@@ -281,7 +265,7 @@ impl Default for Border {
fn default() -> Self {
Self {
off: true,
- width: FloatOrInt(4.),
+ width: 4.,
active_color: Color::from_rgba8_unpremul(255, 200, 127, 255),
inactive_color: Color::from_rgba8_unpremul(80, 80, 80, 255),
urgent_color: Color::from_rgba8_unpremul(155, 0, 0, 255),
@@ -329,7 +313,7 @@ impl MergeWith<BorderRule> for Border {
self.off = false;
}
- merge_clone!((self, part), width);
+ merge!((self, part), width);
merge_color_gradient!(
(self, part),
@@ -348,21 +332,14 @@ impl MergeWith<BorderRule> for FocusRing {
}
}
-#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Shadow {
- #[knuffel(child)]
pub on: bool,
- #[knuffel(child, default = Self::default().offset)]
pub offset: ShadowOffset,
- #[knuffel(child, unwrap(argument), default = Self::default().softness)]
- pub softness: FloatOrInt<0, 1024>,
- #[knuffel(child, unwrap(argument), default = Self::default().spread)]
- pub spread: FloatOrInt<-1024, 1024>,
- #[knuffel(child, unwrap(argument), default = Self::default().draw_behind_window)]
+ pub softness: f64,
+ pub spread: f64,
pub draw_behind_window: bool,
- #[knuffel(child, default = Self::default().color)]
pub color: Color,
- #[knuffel(child)]
pub inactive_color: Option<Color>,
}
@@ -374,8 +351,8 @@ impl Default for Shadow {
x: FloatOrInt(0.),
y: FloatOrInt(5.),
},
- softness: FloatOrInt(30.),
- spread: FloatOrInt(5.),
+ softness: 30.,
+ spread: 5.,
draw_behind_window: false,
color: Color::from_rgba8_unpremul(0, 0, 0, 0x77),
inactive_color: None,
@@ -390,7 +367,7 @@ impl MergeWith<ShadowRule> for Shadow {
self.on = false;
}
- merge_clone!((self, part), softness, spread);
+ merge!((self, part), softness, spread);
merge_clone!((self, part), offset, draw_behind_window, color);
@@ -440,8 +417,8 @@ impl From<WorkspaceShadow> for Shadow {
Self {
on: !value.off,
offset: value.offset,
- softness: value.softness,
- spread: value.spread,
+ softness: value.softness.0,
+ spread: value.spread.0,
draw_behind_window: false,
color: value.color,
inactive_color: None,
@@ -449,37 +426,22 @@ impl From<WorkspaceShadow> for Shadow {
}
}
-#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq)]
pub struct TabIndicator {
- #[knuffel(child)]
pub off: bool,
- #[knuffel(child)]
pub hide_when_single_tab: bool,
- #[knuffel(child)]
pub place_within_column: bool,
- #[knuffel(child, unwrap(argument), default = Self::default().gap)]
- pub gap: FloatOrInt<-65535, 65535>,
- #[knuffel(child, unwrap(argument), default = Self::default().width)]
- pub width: FloatOrInt<0, 65535>,
- #[knuffel(child, default = Self::default().length)]
+ pub gap: f64,
+ pub width: f64,
pub length: TabIndicatorLength,
- #[knuffel(child, unwrap(argument), default = Self::default().position)]
pub position: TabIndicatorPosition,
- #[knuffel(child, unwrap(argument), default = Self::default().gaps_between_tabs)]
- pub gaps_between_tabs: FloatOrInt<0, 65535>,
- #[knuffel(child, unwrap(argument), default = Self::default().corner_radius)]
- pub corner_radius: FloatOrInt<0, 65535>,
- #[knuffel(child)]
+ pub gaps_between_tabs: f64,
+ pub corner_radius: f64,
pub active_color: Option<Color>,
- #[knuffel(child)]
pub inactive_color: Option<Color>,
- #[knuffel(child)]
pub urgent_color: Option<Color>,
- #[knuffel(child)]
pub active_gradient: Option<Gradient>,
- #[knuffel(child)]
pub inactive_gradient: Option<Gradient>,
- #[knuffel(child)]
pub urgent_gradient: Option<Gradient>,
}
@@ -489,14 +451,14 @@ impl Default for TabIndicator {
off: false,
hide_when_single_tab: false,
place_within_column: false,
- gap: FloatOrInt(5.),
- width: FloatOrInt(4.),
+ gap: 5.,
+ width: 4.,
length: TabIndicatorLength {
total_proportion: Some(0.5),
},
position: TabIndicatorPosition::Left,
- gaps_between_tabs: FloatOrInt(0.),
- corner_radius: FloatOrInt(0.),
+ gaps_between_tabs: 0.,
+ corner_radius: 0.,
active_color: None,
inactive_color: None,
urgent_color: None,
@@ -507,6 +469,70 @@ impl Default for TabIndicator {
}
}
+impl MergeWith<TabIndicatorPart> for TabIndicator {
+ fn merge_with(&mut self, part: &TabIndicatorPart) {
+ self.off |= part.off;
+ if part.on {
+ self.off = false;
+ }
+
+ merge!(
+ (self, part),
+ hide_when_single_tab,
+ place_within_column,
+ gap,
+ width,
+ gaps_between_tabs,
+ corner_radius,
+ );
+
+ merge_clone!((self, part), length, position);
+
+ merge_color_gradient_opt!(
+ (self, part),
+ (active_color, active_gradient),
+ (inactive_color, inactive_gradient),
+ (urgent_color, urgent_gradient),
+ );
+ }
+}
+
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
+pub struct TabIndicatorPart {
+ #[knuffel(child)]
+ pub off: bool,
+ #[knuffel(child)]
+ pub on: bool,
+ #[knuffel(child)]
+ pub hide_when_single_tab: Option<Flag>,
+ #[knuffel(child)]
+ pub place_within_column: Option<Flag>,
+ #[knuffel(child, unwrap(argument))]
+ pub gap: Option<FloatOrInt<-65535, 65535>>,
+ #[knuffel(child, unwrap(argument))]
+ pub width: Option<FloatOrInt<0, 65535>>,
+ #[knuffel(child)]
+ pub length: Option<TabIndicatorLength>,
+ #[knuffel(child, unwrap(argument))]
+ pub position: Option<TabIndicatorPosition>,
+ #[knuffel(child, unwrap(argument))]
+ pub gaps_between_tabs: Option<FloatOrInt<0, 65535>>,
+ #[knuffel(child, unwrap(argument))]
+ pub corner_radius: Option<FloatOrInt<0, 65535>>,
+ #[knuffel(child)]
+ pub active_color: Option<Color>,
+ #[knuffel(child)]
+ pub inactive_color: Option<Color>,
+ #[knuffel(child)]
+ pub urgent_color: Option<Color>,
+ #[knuffel(child)]
+ pub active_gradient: Option<Gradient>,
+ #[knuffel(child)]
+ pub inactive_gradient: Option<Gradient>,
+ #[knuffel(child)]
+ pub urgent_gradient: Option<Gradient>,
+}
+
#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
pub struct TabIndicatorLength {
#[knuffel(property)]
@@ -521,13 +547,10 @@ pub enum TabIndicatorPosition {
Bottom,
}
-#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq)]
pub struct InsertHint {
- #[knuffel(child)]
pub off: bool,
- #[knuffel(child, default = Self::default().color)]
pub color: Color,
- #[knuffel(child)]
pub gradient: Option<Gradient>,
}
@@ -541,6 +564,29 @@ impl Default for InsertHint {
}
}
+impl MergeWith<InsertHintPart> for InsertHint {
+ fn merge_with(&mut self, part: &InsertHintPart) {
+ self.off |= part.off;
+ if part.on {
+ self.off = false;
+ }
+
+ merge_color_gradient!((self, part), (color, gradient));
+ }
+}
+
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
+pub struct InsertHintPart {
+ #[knuffel(child)]
+ pub off: bool,
+ #[knuffel(child)]
+ pub on: bool,
+ #[knuffel(child)]
+ pub color: Option<Color>,
+ #[knuffel(child)]
+ pub gradient: Option<Gradient>,
+}
+
#[derive(knuffel::DecodeScalar, Debug, Clone, Copy, PartialEq, Eq)]
pub enum BlockOutFrom {
Screencast,
@@ -1016,16 +1062,9 @@ mod tests {
#[test]
fn test_border_rule_on_off_merging() {
fn is_on(config: &str, rules: &[&str]) -> String {
- let mut resolved = BorderRule {
- off: false,
- on: false,
- width: None,
- active_color: None,
- inactive_color: None,
- urgent_color: None,
- active_gradient: None,
- inactive_gradient: None,
- urgent_gradient: None,
+ let mut resolved = Border {
+ off: config == "off",
+ ..Default::default()
};
for rule in rules.iter().copied() {
@@ -1038,14 +1077,7 @@ mod tests {
resolved.merge_with(&rule);
}
- let mut border = Border {
- off: config == "off",
- ..Default::default()
- };
-
- border.merge_with(&resolved);
-
- if border.off { "off" } else { "on" }.to_owned()
+ if resolved.off { "off" } else { "on" }.to_owned()
}
assert_snapshot!(is_on("off", &[]), @"off");
@@ -1095,13 +1127,11 @@ mod tests {
)
.unwrap();
- let mut border_rule = BorderRule::default();
+ let mut border = config.resolve_layout().border;
for rule in &config.window_rules {
- border_rule.merge_with(&rule.border);
+ border.merge_with(&rule.border);
}
- let border = config.layout.border.merged_with(&border_rule);
-
// Gradient should be None because it's overwritten.
assert_debug_snapshot!(
(
@@ -1166,15 +1196,13 @@ mod tests {
)
.unwrap();
- let mut border_rule = BorderRule::default();
+ let mut border = config.resolve_layout().border;
let mut tab_indicator_rule = TabIndicatorRule::default();
for rule in &config.window_rules {
- border_rule.merge_with(&rule.border);
+ border.merge_with(&rule.border);
tab_indicator_rule.merge_with(&rule.tab_indicator);
}
- let border = config.layout.border.merged_with(&border_rule);
-
// Gradient should be None because it's overwritten.
assert_debug_snapshot!(
(
diff --git a/niri-config/src/layout.rs b/niri-config/src/layout.rs
index 768199d5..f84528bd 100644
--- a/niri-config/src/layout.rs
+++ b/niri-config/src/layout.rs
@@ -4,65 +4,130 @@ use niri_ipc::{ColumnDisplay, SizeChange};
use crate::appearance::{
Border, FocusRing, InsertHint, Shadow, TabIndicator, DEFAULT_BACKGROUND_COLOR,
};
-use crate::utils::expect_only_children;
-use crate::{Color, FloatOrInt};
+use crate::utils::{expect_only_children, Flag, MergeWith};
+use crate::{BorderRule, Color, FloatOrInt, InsertHintPart, ShadowRule, TabIndicatorPart};
-#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq)]
pub struct Layout {
- #[knuffel(child, default)]
pub focus_ring: FocusRing,
- #[knuffel(child, default)]
pub border: Border,
- #[knuffel(child, default)]
pub shadow: Shadow,
- #[knuffel(child, default)]
pub tab_indicator: TabIndicator,
- #[knuffel(child, default)]
pub insert_hint: InsertHint,
- #[knuffel(child, unwrap(children), default)]
pub preset_column_widths: Vec<PresetSize>,
- #[knuffel(child)]
- pub default_column_width: Option<DefaultPresetSize>,
- #[knuffel(child, unwrap(children), default)]
+ pub default_column_width: Option<PresetSize>,
pub preset_window_heights: Vec<PresetSize>,
- #[knuffel(child, unwrap(argument), default)]
pub center_focused_column: CenterFocusedColumn,
- #[knuffel(child)]
pub always_center_single_column: bool,
- #[knuffel(child)]
pub empty_workspace_above_first: bool,
- #[knuffel(child, unwrap(argument, str), default = Self::default().default_column_display)]
pub default_column_display: ColumnDisplay,
- #[knuffel(child, unwrap(argument), default = Self::default().gaps)]
- pub gaps: FloatOrInt<0, 65535>,
- #[knuffel(child, default)]
+ pub gaps: f64,
pub struts: Struts,
- #[knuffel(child, default = DEFAULT_BACKGROUND_COLOR)]
pub background_color: Color,
}
impl Default for Layout {
fn default() -> Self {
Self {
- focus_ring: Default::default(),
- border: Default::default(),
- shadow: Default::default(),
- tab_indicator: Default::default(),
- insert_hint: Default::default(),
- preset_column_widths: Default::default(),
- default_column_width: Default::default(),
- center_focused_column: Default::default(),
+ focus_ring: FocusRing::default(),
+ border: Border::default(),
+ shadow: Shadow::default(),
+ tab_indicator: TabIndicator::default(),
+ insert_hint: InsertHint::default(),
+ preset_column_widths: vec![
+ PresetSize::Proportion(1. / 3.),
+ PresetSize::Proportion(0.5),
+ PresetSize::Proportion(2. / 3.),
+ ],
+ default_column_width: Some(PresetSize::Proportion(0.5)),
+ center_focused_column: CenterFocusedColumn::Never,
always_center_single_column: false,
empty_workspace_above_first: false,
default_column_display: ColumnDisplay::Normal,
- gaps: FloatOrInt(16.),
- struts: Default::default(),
- preset_window_heights: Default::default(),
+ gaps: 16.,
+ struts: Struts::default(),
+ preset_window_heights: vec![
+ PresetSize::Proportion(1. / 3.),
+ PresetSize::Proportion(0.5),
+ PresetSize::Proportion(2. / 3.),
+ ],
background_color: DEFAULT_BACKGROUND_COLOR,
}
}
}
+impl MergeWith<LayoutPart> for Layout {
+ fn merge_with(&mut self, part: &LayoutPart) {
+ merge!(
+ (self, part),
+ focus_ring,
+ border,
+ shadow,
+ tab_indicator,
+ insert_hint,
+ always_center_single_column,
+ empty_workspace_above_first,
+ gaps,
+ );
+
+ merge_clone!(
+ (self, part),
+ preset_column_widths,
+ preset_window_heights,
+ center_focused_column,
+ default_column_display,
+ struts,
+ background_color,
+ );
+
+ if let Some(x) = part.default_column_width {
+ self.default_column_width = x.0;
+ }
+
+ if self.preset_column_widths.is_empty() {
+ self.preset_column_widths = Layout::default().preset_column_widths;
+ }
+
+ if self.preset_window_heights.is_empty() {
+ self.preset_window_heights = Layout::default().preset_window_heights;
+ }
+ }
+}
+
+#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq)]
+pub struct LayoutPart {
+ #[knuffel(child)]
+ pub focus_ring: Option<BorderRule>,
+ #[knuffel(child)]
+ pub border: Option<BorderRule>,
+ #[knuffel(child)]
+ pub shadow: Option<ShadowRule>,
+ #[knuffel(child)]
+ pub tab_indicator: Option<TabIndicatorPart>,
+ #[knuffel(child)]
+ pub insert_hint: Option<InsertHintPart>,
+ #[knuffel(child, unwrap(children))]
+ pub preset_column_widths: Option<Vec<PresetSize>>,
+ #[knuffel(child)]
+ pub default_column_width: Option<DefaultPresetSize>,
+ #[knuffel(child, unwrap(children))]
+ pub preset_window_heights: Option<Vec<PresetSize>>,
+ #[knuffel(child, unwrap(argument))]
+ pub center_focused_column: Option<CenterFocusedColumn>,
+ #[knuffel(child)]
+ pub always_center_single_column: Option<Flag>,
+ #[knuffel(child)]
+ pub empty_workspace_above_first: Option<Flag>,
+ #[knuffel(child, unwrap(argument, str))]
+ pub default_column_display: Option<ColumnDisplay>,
+ #[knuffel(child, unwrap(argument))]
+ pub gaps: Option<FloatOrInt<0, 65535>>,
+ #[knuffel(child)]
+ pub struts: Option<Struts>,
+ #[knuffel(child)]
+ pub background_color: Option<Color>,
+}
+
#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)]
pub enum PresetSize {
Proportion(#[knuffel(argument)] f64),
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index 575be90b..6dd32620 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -36,6 +36,7 @@ pub use crate::layout::*;
pub use crate::misc::*;
pub use crate::output::{Output, OutputName, Outputs, Position, Vrr};
pub use crate::utils::FloatOrInt;
+use crate::utils::MergeWith as _;
pub use crate::window_rule::{FloatingPosition, RelativeTo, WindowRule};
pub use crate::workspace::Workspace;
@@ -50,7 +51,7 @@ pub struct Config {
#[knuffel(children(name = "spawn-sh-at-startup"))]
pub spawn_sh_at_startup: Vec<SpawnShAtStartup>,
#[knuffel(child, default)]
- pub layout: Layout,
+ pub layout: LayoutPart,
#[knuffel(child, default)]
pub prefer_no_csd: bool,
#[knuffel(child, default)]
@@ -133,6 +134,35 @@ impl Config {
let _span = tracy_client::span!("Config::parse");
knuffel::parse(filename, text)
}
+
+ pub fn resolve_layout(&self) -> Layout {
+ let mut rv = Layout::from_part(&self.layout);
+
+ // Preserve the behavior we'd always had for the border section:
+ // - `layout {}` gives border = off
+ // - `layout { border {} }` gives border = on
+ // - `layout { border { off } }` gives border = off
+ //
+ // This behavior is inconsistent with the rest of the config where adding an empty section
+ // generally doesn't change the outcome. Particularly, shadows are also disabled by default
+ // (like borders), and they always had an `on` instead of an `off` for this reason, so that
+ // writing `layout { shadow {} }` still results in shadow = off, as it should.
+ //
+ // Unfortunately, the default config has always had wording that heavily implies that
+ // `layout { border {} }` enables the borders. This wording is sure to be present in a lot
+ // of users' configs by now, which we can't change.
+ //
+ // Another way to make things consistent would be to default borders to on. However, that
+ // is annoying because it would mean changing many tests that rely on borders being off by
+ // default. This would also contradict the intended default borders value (off).
+ //
+ // So, let's just work around the problem here, preserving the original behavior.
+ if self.layout.border.is_some_and(|x| !x.on && !x.off) {
+ rv.border.off = false;
+ }
+
+ rv
+ }
}
impl Default for Config {
@@ -778,181 +808,182 @@ mod tests {
command: "qs -c ~/source/qs/MyAwesomeShell",
},
],
- layout: Layout {
- focus_ring: FocusRing {
- off: false,
- width: FloatOrInt(
- 5.0,
- ),
- active_color: Color {
- r: 0.0,
- g: 0.39215687,
- b: 0.78431374,
- a: 1.0,
- },
- inactive_color: Color {
- r: 1.0,
- g: 0.78431374,
- b: 0.39215687,
- a: 0.0,
- },
- urgent_color: Color {
- r: 0.60784316,
- g: 0.0,
- b: 0.0,
- a: 1.0,
- },
- active_gradient: Some(
- Gradient {
- from: Color {
- r: 0.039215688,
- g: 0.078431375,
- b: 0.11764706,
- a: 1.0,
- },
- to: Color {
+ layout: LayoutPart {
+ focus_ring: Some(
+ BorderRule {
+ off: false,
+ on: false,
+ width: Some(
+ FloatOrInt(
+ 5.0,
+ ),
+ ),
+ active_color: Some(
+ Color {
r: 0.0,
- g: 0.5019608,
- b: 1.0,
+ g: 0.39215687,
+ b: 0.78431374,
a: 1.0,
},
- angle: 180,
- relative_to: WorkspaceView,
- in_: GradientInterpolation {
- color_space: Srgb,
- hue_interpolation: Shorter,
+ ),
+ inactive_color: Some(
+ Color {
+ r: 1.0,
+ g: 0.78431374,
+ b: 0.39215687,
+ a: 0.0,
},
- },
- ),
- inactive_gradient: None,
- urgent_gradient: None,
- },
- border: Border {
- off: false,
- width: FloatOrInt(
- 3.0,
- ),
- active_color: Color {
- r: 1.0,
- g: 0.78431374,
- b: 0.49803922,
- a: 1.0,
- },
- inactive_color: Color {
- r: 1.0,
- g: 0.78431374,
- b: 0.39215687,
- a: 0.0,
- },
- urgent_color: Color {
- r: 0.60784316,
- g: 0.0,
- b: 0.0,
- a: 1.0,
- },
- active_gradient: None,
- inactive_gradient: None,
- urgent_gradient: None,
- },
- shadow: Shadow {
- on: false,
- offset: ShadowOffset {
- x: FloatOrInt(
- 10.0,
),
- y: FloatOrInt(
- -20.0,
+ urgent_color: None,
+ active_gradient: Some(
+ Gradient {
+ from: Color {
+ r: 0.039215688,
+ g: 0.078431375,
+ b: 0.11764706,
+ a: 1.0,
+ },
+ to: Color {
+ r: 0.0,
+ g: 0.5019608,
+ b: 1.0,
+ a: 1.0,
+ },
+ angle: 180,
+ relative_to: WorkspaceView,
+ in_: GradientInterpolation {
+ color_space: Srgb,
+ hue_interpolation: Shorter,
+ },
+ },
),
+ inactive_gradient: None,
+ urgent_gradient: None,
},
- softness: FloatOrInt(
- 30.0,
- ),
- spread: FloatOrInt(
- 5.0,
- ),
- draw_behind_window: false,
- color: Color {
- r: 0.0,
- g: 0.0,
- b: 0.0,
- a: 0.46666667,
+ ),
+ border: Some(
+ BorderRule {
+ off: false,
+ on: false,
+ width: Some(
+ FloatOrInt(
+ 3.0,
+ ),
+ ),
+ active_color: None,
+ inactive_color: Some(
+ Color {
+ r: 1.0,
+ g: 0.78431374,
+ b: 0.39215687,
+ a: 0.0,
+ },
+ ),
+ urgent_color: None,
+ active_gradient: None,
+ inactive_gradient: None,
+ urgent_gradient: None,
},
- inactive_color: None,
- },
- tab_indicator: TabIndicator {
- off: false,
- hide_when_single_tab: false,
- place_within_column: false,
- gap: FloatOrInt(
- 5.0,
- ),
- width: FloatOrInt(
- 10.0,
- ),
- length: TabIndicatorLength {
- total_proportion: Some(
- 0.5,
+ ),
+ shadow: Some(
+ ShadowRule {
+ off: false,
+ on: false,
+ offset: Some(
+ ShadowOffset {
+ x: FloatOrInt(
+ 10.0,
+ ),
+ y: FloatOrInt(
+ -20.0,
+ ),
+ },
),
+ softness: None,
+ spread: None,
+ draw_behind_window: None,
+ color: None,
+ inactive_color: None,
},
- position: Top,
- gaps_between_tabs: FloatOrInt(
- 0.0,
- ),
- corner_radius: FloatOrInt(
- 0.0,
- ),
- active_color: None,
- inactive_color: None,
- urgent_color: None,
- active_gradient: None,
- inactive_gradient: None,
- urgent_gradient: None,
- },
- insert_hint: InsertHint {
- off: false,
- color: Color {
- r: 1.0,
- g: 0.78431374,
- b: 0.49803922,
- a: 1.0,
+ ),
+ tab_indicator: Some(
+ TabIndicatorPart {
+ off: false,
+ on: false,
+ hide_when_single_tab: None,
+ place_within_column: None,
+ gap: None,
+ width: Some(
+ FloatOrInt(
+ 10.0,
+ ),
+ ),
+ l