# How to Use Hyprland Animation Features: A Complete Guide to Workspace and Window Effects

> Master Hyprland animation features to add workspace transitions and window effects like slide and fade. Customize animations with speeds and bezier curves for a dynamic desktop.

- Repository: [Hypr Development/Hyprland](https://github.com/hyprwm/Hyprland)
- Tags: how-to-guide
- Published: 2026-07-29

---

**Hyprland animation features are controlled through the `animations:` configuration section and rule-based overrides, allowing you to enable workspace transitions, window fades, and layer effects using styles like `slide`, `fade`, and `popin` with customizable speeds and bezier curves.**

Hyprland provides a flexible, data-driven animation system that drives workspace transitions, window fades, and layer-shell effects. Built on Hyprutils' animation utilities and defined in the `hyprwm/Hyprland` repository, these features are fully configurable at runtime without recompiling the compositor. This guide covers the architecture behind Hyprland animation features and provides practical configuration examples for customizing motion throughout your desktop environment.

## Architecture of the Animation System

### The Animation Manager

The core engine lives in **[`src/animation/AnimationManager.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/AnimationManager.cpp)**, which owns a global singleton `CHyprAnimationManager` accessed via `Animation::mgr()`. A high-resolution timer (`m_animationTimer`) ticks roughly every millisecond, invoking `frameTick()` → `tick()` to advance all active animations.

During each tick, the manager iterates over `CAnimatedVariable` instances (representing floats, vectors, or colors) and updates their values according to their configured curves. The implementation batches damage requests to minimize redraws:

```cpp
// From AnimationManager.cpp
CHyprAnimationManager::frameTick() {
    onTicked();                     // reset tick-state
    if (!shouldTickForNext()) return;
    tick();                         // advance animated variables
    Event::bus()->m_events.tick.emit(); // inform other subsystems
}

```

Damage handling occurs through policies like `AVARDAMAGE_*`, where the manager groups owners (windows, workspaces, layers) and issues minimal damage via `damageWindowForPolicies` and `preDamageWorkspace` before and after updates.

### The Configuration Tree

Animation styles and properties are stored in a hierarchical tree managed by `CAnimationTreeController`, defined in **[`src/config/shared/animation/AnimationTree.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/shared/animation/AnimationTree.hpp)**. Each node contains `enabled`, `speed`, `bezier`, and an optional `style` string, populated from your `animations:` section through `Config::animationTree()->setConfigForNode(...)`.

## Configuring Workspace Animations

Workspace transitions are implemented in **[`src/animation/WorkspaceAnimationController.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/WorkspaceAnimationController.cpp)**. When switching workspaces, the compositor calls `Animation::Workspace::startAnimation(PHLWORKSPACE ws, eAnimationType type, bool left, bool instant, std::optional<std::string> style)`, which looks up animation configurations via `Config::animationTree()->getAnimationPropertyConfig(name)`.

### Built-in Animation Styles

The style syntax follows the pattern `<base>[<direction>][<percentage>%]`:

- **slide** – Horizontal movement (left/right)
- **slidevert** – Vertical movement (up/down)
- **fade** – Opacity transition only
- **slidefade** – Simultaneous slide and fade
- **popin** – Scale-based pop-in (commonly used for layers)

Example configurations in `~/.config/hypr/hyprland.conf`:

```ini

# Workspace animation style - slides left covering 75% of monitor width

animations:workspace = slide left 75%

# Special workspace (scratchpad) uses simple fade

animations:specialWorkspace = fade

```

## Global Animation Settings

Master toggles are defined as `CConfigValue`s in **[`src/config/values/ConfigValues.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/values/ConfigValues.cpp)**:

```cpp
MS<Bool>("animations:enabled", "enable animations", true),
MS<Bool>("animations:workspace_wraparound",
         "changes the direction of slide animations between the first and last workspaces", false),

```

To enable the system globally:

```ini
animations:enabled = true
animations:workspace_wraparound = false  # Optional wrap-around behavior

```

## Per-Window and Layer Animation Rules

You can override animations for specific windows or layers using Hyprland's rule system. The parser eventually calls `CAnimatedVariable::setConfig()` with your custom style string.

```ini

# Terminal windows slide in from right, covering 90% of screen

windowrule = animation:slide right 90% , class:^(Alacritty)$

# Notification overlays fade in/out

layerrule = animation:fade , layer:overlay

```

## Customizing Speed and Bezier Curves

Each animation node supports **speed** multipliers and **bezier** curve names stored in `CAnimationPropertyConfig` and applied when `CAnimatedVariable` creates its internal animation object.

Available built-in curves include `linear`, with custom curves defined via the `bezier` config option (initialized in `AnimationManager::CHyprAnimationManager`).

```ini

# Increase workspace animation speed to 1.5x

animations:workspace_speed = 1.5

# Use ease-out curve for smooth deceleration

animations:workspace_bezier = ease-out

```

## Programmatic Animation Control

For developers extending Hyprland, you can trigger workspace switches programmatically:

```cpp
// Trigger animation to workspace ID 2
PHLWORKSPACE target = g_pHyprMonitor->getWorkspaceByID(2);
if (target) {
    // left=false (slide from right), instant=false (animate)
    Animation::Workspace::startAnimation(target, ANIMATION_TYPE_IN, false, false, std::nullopt);
}

```

You can also create custom animation nodes at runtime:

```cpp
// Define custom "myPop" animation
Config::animationTree()->setConfigForNode(
    "myPop",                      // name
    true,                         // enabled
    2.0f,                         // speed multiplier
    "ease-out",                   // bezier curve
    "popin 30%"                   // style string
);

```

Then reference it in rules:

```ini
windowrule = animation:myPop , class:^(Gedit)$

```

To inspect animated variables during debugging:

```cpp
auto* alpha = myWindow->alpha(WINDOW_ALPHA);
if (alpha) {
    std::cout << "Current alpha: " << *alpha << "\n";
    std::cout << "Goal alpha:    " << alpha->goal() << "\n";
}

```

## Summary

- **Enable globally** with `animations:enabled = true` in [`src/config/values/ConfigValues.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/values/ConfigValues.cpp).
- **Choose styles** (`slide`, `slidevert`, `fade`, `slidefade`, `popin`) with optional direction and percentage parameters.
- **Configure workspaces** via `animations:workspace` and `animations:specialWorkspace` using the animation tree in [`src/config/shared/animation/AnimationTree.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/shared/animation/AnimationTree.hpp).
- **Override per-entity** using `windowrule` or `layerrule` directives that inject styles into `CAnimatedVariable` instances.
- **Adjust dynamics** with `animations:workspace_speed` and `animations:workspace_bezier` for fine-tuned motion.
- **Architecture** relies on `CHyprAnimationManager` in [`src/animation/AnimationManager.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/AnimationManager.cpp) for ticking and `WorkspaceAnimationController` for workspace-specific implementation.

## Frequently Asked Questions

### How do I completely disable animations in Hyprland?

Set `animations:enabled = false` in your [`hyprland.conf`](https://github.com/hyprwm/Hyprland/blob/main/hyprland.conf). According to the source in [`src/config/values/ConfigValues.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/values/ConfigValues.cpp), this boolean config value acts as the master switch that prevents the `CHyprAnimationManager` from processing variable updates during its tick cycle, effectively disabling all transitions while maintaining instant state changes.

### What animation styles are available for workspace switching?

Hyprland supports **slide**, **slidevert**, **fade**, **slidefade**, and **popin** as defined in [`src/animation/WorkspaceAnimationController.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/WorkspaceAnimationController.cpp). These can be combined with directional keywords (left, right, top, bottom) and percentage values (e.g., `slide left 80%`) to control the distance traveled during the transition.

### How do I apply different animations to specific applications?

Use the `windowrule` directive with the `animation:` prefix. For example, `windowrule = animation:fade , class:^(Firefox)$` targets Firefox windows specifically. The rule system parses this syntax and calls `CAnimatedVariable::setConfig()` to override the default animation tree configuration for that window's properties.

### Can I customize the speed of workspace transitions independently?

Yes, use `animations:workspace_speed = 1.5` (where 1.0 is default) to adjust timing. This value is retrieved from `CAnimationPropertyConfig` and applied to the internal `Hyprutils::Animation::CAnimation` object. You can also define custom bezier curves with `animations:workspace_bezier` for non-linear acceleration patterns.