aboutsummaryrefslogtreecommitdiff
path: root/niri-config/src
diff options
context:
space:
mode:
authorHoru <73709188+HigherOrderLogic@users.noreply.github.com>2025-08-29 15:31:50 +1000
committerGitHub <noreply@github.com>2025-08-29 05:31:50 +0000
commit1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f (patch)
tree60aa82866d4f3fa0105447419d154c69fba521f1 /niri-config/src
parentd9833fc1c3de306f500662471ae001094813dbd5 (diff)
downloadniri-1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f.tar.gz
niri-1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f.tar.bz2
niri-1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f.zip
feat: cubic-bezier curve for animation (#2059)
* feat: bezier curve for animation * fixes --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
Diffstat (limited to 'niri-config/src')
-rw-r--r--niri-config/src/animations.rs92
-rw-r--r--niri-config/src/lib.rs11
2 files changed, 100 insertions, 3 deletions
diff --git a/niri-config/src/animations.rs b/niri-config/src/animations.rs
index 90ff0bf2..d265026e 100644
--- a/niri-config/src/animations.rs
+++ b/niri-config/src/animations.rs
@@ -69,12 +69,13 @@ pub struct EasingParams {
pub curve: Curve,
}
-#[derive(knuffel::DecodeScalar, Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Curve {
Linear,
EaseOutQuad,
EaseOutCubic,
EaseOutExpo,
+ CubicBezier(f64, f64, f64, f64),
}
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -540,7 +541,94 @@ impl Animation {
));
}
- easing_params.curve = Some(parse_arg_node("curve", child, ctx)?);
+ let mut iter_args = child.arguments.iter();
+ let val = iter_args.next().ok_or_else(|| {
+ DecodeError::missing(child, "additional argument `curve` is required")
+ })?;
+ let animation_curve_string: String =
+ knuffel::traits::DecodeScalar::decode(val, ctx)?;
+
+ let animation_curve = match animation_curve_string.as_str() {
+ "linear" => Some(Curve::Linear),
+ "ease-out-quad" => Some(Curve::EaseOutQuad),
+ "ease-out-cubic" => Some(Curve::EaseOutCubic),
+ "ease-out-expo" => Some(Curve::EaseOutExpo),
+ "cubic-bezier" => {
+ let val = iter_args.next().ok_or_else(|| {
+ DecodeError::missing(
+ child,
+ "missing x1 coordinate for cubic Bézier curve control point",
+ )
+ })?;
+ // the X axis represents time frame so it cannot be negative
+ // or larger than 1
+ let x1: FloatOrInt<0, 1> =
+ knuffel::traits::DecodeScalar::decode(val, ctx)?;
+ let val = iter_args.next().ok_or_else(|| {
+ DecodeError::missing(
+ child,
+ "missing y1 coordinate for cubic Bézier curve control point",
+ )
+ })?;
+ let y1: FloatOrInt<{ i32::MIN }, { i32::MAX }> =
+ knuffel::traits::DecodeScalar::decode(val, ctx)?;
+ let val = iter_args.next().ok_or_else(|| {
+ DecodeError::missing(
+ child,
+ "missing x2 coordinate for cubic Bézier curve control point",
+ )
+ })?;
+ let x2: FloatOrInt<0, 1> =
+ knuffel::traits::DecodeScalar::decode(val, ctx)?;
+ let val = iter_args.next().ok_or_else(|| {
+ DecodeError::missing(
+ child,
+ "missing y2 coordinate for cubic Bézier curve control point",
+ )
+ })?;
+ let y2: FloatOrInt<{ i32::MIN }, { i32::MAX }> =
+ knuffel::traits::DecodeScalar::decode(val, ctx)?;
+
+ Some(Curve::CubicBezier(x1.0, y1.0, x2.0, y2.0))
+ }
+ unexpected_curve => {
+ ctx.emit_error(DecodeError::unexpected(
+ &val.literal,
+ "argument",
+ format!(
+ "unexpected animation curve `{unexpected_curve}`. \
+ Niri only supports five animation curves: \
+ `ease-out-quad`, `ease-out-cubic`, `ease-out-expo`, `linear` and `cubic-bezier`."
+ ),
+ ));
+
+ None
+ }
+ };
+
+ if let Some(val) = iter_args.next() {
+ ctx.emit_error(DecodeError::unexpected(
+ &val.literal,
+ "argument",
+ "unexpected argument",
+ ));
+ }
+ for name in child.properties.keys() {
+ ctx.emit_error(DecodeError::unexpected(
+ name,
+ "property",
+ format!("unexpected property `{}`", name.escape_default()),
+ ));
+ }
+ for child in child.children() {
+ ctx.emit_error(DecodeError::unexpected(
+ child,
+ "node",
+ format!("unexpected node `{}`", child.node_name.escape_default()),
+ ));
+ }
+
+ easing_params.curve = animation_curve;
}
name_str => {
if !process_children(child, ctx)? {
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index ce821c5e..8e07839e 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -441,6 +441,10 @@ mod tests {
}
window-open { off; }
+
+ window-close {
+ curve "cubic-bezier" 0.05 0.7 0.1 1
+ }
}
gestures {
@@ -1038,7 +1042,12 @@ mod tests {
kind: Easing(
EasingParams {
duration_ms: 150,
- curve: EaseOutQuad,
+ curve: CubicBezier(
+ 0.05,
+ 0.7,
+ 0.1,
+ 1.0,
+ ),
},
),
},