# How to Create Custom Hyprland Rules for Specific Applications

> Learn to create custom Hyprland rules for specific applications. Automate floating states, opacity, monitor placement & more using windowrule syntax for a personalized workflow.

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

---

**Hyprland’s window-rule subsystem lets you automatically apply floating states, opacity, monitor placement, and decoration settings to windows matching specific class or title selectors using `windowrule` (static) and `windowrulev2` (dynamic) syntax in your configuration file.**

Creating custom Hyprland rules for specific applications allows you to enforce window behavior, visual effects, and workspace placement without manual intervention. In the `hyprwm/Hyprland` source code, this functionality is implemented through the `CWindowRule` and `CWindowRuleApplicator` classes located in the desktop rule subsystem. This guide explains the configuration syntax and internal implementation details you need to automate your window management.

## Understanding the Hyprland Rule Engine Architecture

The rule engine is split between static and dynamic evaluation pipelines to optimize performance. According to the source code in [`src/desktop/rule/windowRule/WindowRule.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/rule/windowRule/WindowRule.hpp), a **`CWindowRule`** object (often paired with **`CRuleWithEffects`**) defines the selector criteria and the effects to apply, such as opacity, size, or border styles. 

When Hyprland parses your configuration, each `windowrule` or `windowrulev2` line instantiates a `CWindowRule` that is stored in the global rule manager. The **`CWindowRuleApplicator`** (defined in [`src/desktop/rule/windowRule/WindowRuleApplicator.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/rule/windowRule/WindowRuleApplicator.hpp)) attaches to each **`CWindow`** instance via the `m_ruleApplicator` pointer found in [`src/desktop/view/Window.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.hpp).

The applicator evaluates rules in two modes:

- **Static selectors** – Checked once at window creation via `matchesStaticSelector`. These handle properties like class name or window title.
- **Dynamic selectors** – Re-evaluated whenever window properties change (e.g., workspace switches). These use the `windowrulev2` prefix and trigger `applyDynamicRule`.

All rendering decisions—such as `decorate()`, `renderUnfocused()`, and `opaque()`—query the applicator to determine final window state, ensuring rule changes apply instantly without restarting Hyprland.

## Configuration Syntax: Static vs. Dynamic Rules

Hyprland distinguishes between one-time application rules and persistent conditional rules through different configuration keywords.

### Static Rules with windowrule

Static rules evaluate when a window is first mapped. Use these for permanent attributes like initial floating state or monitor assignment.

```ini

# Syntax: windowrule = <effect>, <selector>

windowrule = floating, class:^Discord$
windowrule = monitor DP-1, class:^Discord$

```

*Implementation:* When the window is created, `CWindowRuleApplicator::applyStaticRule` is invoked. The `floating` effect calls `CWindowRuleEffectContainer::setProperty(WINDOW_RULE_EFFECT_FLOATING, true)`, while `monitor DP-1` triggers the workspace placement controller to move the window before it appears on screen.

### Dynamic Rules with windowrulev2

Dynamic rules re-evaluate when window properties change. Use these for conditional behaviors based on workspace or focus state.

```ini
windowrulev2 = opacity 0.85, workspace:2 && class:^Alacritty$

```

*Implementation:* The `workspace:2` selector creates a dynamic condition. `CWindowRuleApplicator::applyDynamicRule` runs whenever the window moves to a different workspace, updating opacity via `CWindowRuleEffectContainer::setProperty(WINDOW_RULE_EFFECT_OPACITY, 0.85)`.

## Practical Implementation Examples

These concrete examples demonstrate how to interact with the rule engine defined in [`src/desktop/view/Window.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.cpp) and related files.

### Force Floating Windows and Monitor Assignment

To force Discord to open floating and display on a specific monitor:

```ini
windowrule = floating, class:^Discord$
windowrule = monitor DP-1, class:^Discord$

```

*Source reference:* The monitor string is resolved by `CWorkspacePlacementController::ensurePersistentWorkspacesPresent` during rule application.

### Workspace-Based Opacity Control

Reduce opacity for terminals on specific workspaces:

```ini
windowrulev2 = opacity 0.85, workspace:2 && class:^Alacritty$

```

*Effect:* The opacity is dynamically adjusted via the `CWindowRuleEffectContainer` whenever the window enters or leaves workspace 2.

### Size Constraints and Performance Tuning

Set explicit dimensions or disable animations for games:

```ini

# Set initial size to 1024x768 pixels

windowrule = size 1024 768, class:^Alacritty$

# Disable animations and background dimming for games

windowrule = noanim, class:^SuperTuxKart$
windowrule = nodimaround, class:^SuperTuxKart$

```

*Implementation:* The `size` rule invokes `CWindowRuleEffectContainer::setSize`, which calls `CWindow::resize` during the mapping phase. The `noanim` and `nodimaround` effects set boolean flags checked by the renderer in [`src/render/Renderer.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/render/Renderer.cpp) before drawing frames.

### Launch-Time Rules with exec-once

Apply rules to applications launched via `exec-once` using the embedded rule syntax parsed by [`src/config/supplementary/executor/Executor.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/supplementary/executor/Executor.hpp):

```ini
exec-once = alacritty, class:^Alacritty$, monitor:DP-1, floating

```

*Implementation:* The executor parses parameters after the command using `buildFromExecString` to create a temporary `CWindowRule` attached to the new PID, ensuring the rule applies before the window surfaces.

## Core Source Files for Rule Customization

| File Path | Role in Rule System |
|-----------|---------------------|
| [`src/desktop/rule/windowRule/WindowRule.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/rule/windowRule/WindowRule.hpp) | Defines `CWindowRule`, `CRuleWithEffects`, and parsing helpers including `buildFromExecString`. |
| [`src/desktop/rule/windowRule/WindowRuleApplicator.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/rule/windowRule/WindowRuleApplicator.hpp) | Implements `CWindowRuleApplicator` which evaluates static and dynamic rules per-window. |
| [`src/desktop/view/Window.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.hpp) | Declares `CWindow` with the `m_ruleApplicator` member for querying rule effects. |
| [`src/desktop/view/Window.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.cpp) | Contains rule evaluation logic triggered on window map and property changes. |
| [`src/config/supplementary/executor/Executor.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/supplementary/executor/Executor.hpp) | Handles `exec-once` commands that embed temporary window rules. |
| [`example/hyprland.lua`](https://github.com/hyprwm/Hyprland/blob/main/example/hyprland.lua) | Reference configuration demonstrating `windowrule` syntax placement. |

## Summary

- **Hyprland rules** automate window behavior through the `CWindowRule` and `CWindowRuleApplicator` classes in the desktop rule subsystem.
- Use **`windowrule`** for static, one-time application at window creation (class, title matching).
- Use **`windowrulev2`** for dynamic re-evaluation when properties like workspace or floating state change.
- Rule effects modify rendering decisions via `CWindowRuleEffectContainer` properties checked by `CWindow` methods like `decorate()` and `opaque()`.
- Changes to rules take effect immediately without restarting the compositor.
- The `exec-once` command supports inline rule application parsed by the executor in [`src/config/supplementary/executor/Executor.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/config/supplementary/executor/Executor.hpp).

## Frequently Asked Questions

### What is the difference between windowrule and windowrulev2?

**`windowrule`** applies effects once when a window is created and matches against static properties like class or title. **`windowrulev2`** creates dynamic rules that re-evaluate when window properties change, such as when moving between workspaces or toggling floating state. According to the source in [`src/desktop/rule/windowRule/WindowRuleApplicator.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/rule/windowRule/WindowRuleApplicator.hpp), static rules use `applyStaticRule` while dynamic rules rely on `applyDynamicRule`.

### How do I match applications by class name in Hyprland?

Use the `class:` selector with a regular expression pattern. For example, `class:^Discord$` matches windows where the WM_CLASS property exactly equals "Discord". The matching logic resides in `matchesStaticSelector` within the rule applicator implementation.

### Can I apply rules to already running windows?

Rules defined in your configuration apply to new windows automatically. For existing windows, you must reload the configuration (which updates the rule manager) or use dynamic `windowrulev2` rules that re-evaluate on property changes. The rule engine in [`src/desktop/view/Window.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.cpp) queries the applicator on every relevant property update, ensuring dynamic conditions are checked continuously.

### Where are window rules evaluated in the Hyprland source code?

Rule evaluation occurs in [`src/desktop/view/Window.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.cpp) when windows are mapped, and in `CWindowRuleApplicator` methods for static and dynamic checking. Rendering decisions in [`src/render/Renderer.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/render/Renderer.cpp) and input handling in [`src/managers/input/InputManager.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/input/InputManager.cpp) query the `m_ruleApplicator` pointer attached to each `CWindow` to determine final behavior.