# Hyprland Fullscreen Mode Configuration: A Complete Guide to Controllers, Handlers, and Layout Rules

> Master Hyprland fullscreen mode configuration. Explore controllers, handlers, and layout rules to optimize your window management. Get the complete guide now.

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

---

**Hyprland fullscreen mode configuration is governed by the `CFullscreenController` singleton, protocol handlers, and per-window layout rules defined in `src/managers/fullscreen/`.**

Configuring fullscreen behavior in the hyprwm/Hyprland compositor requires understanding how the `CFullscreenController` class tracks both internal enforcement and client-requested states. Hyprland fullscreen mode configuration is exposed through the Lua-based config system and implemented in the dedicated fullscreen subsystem under `src/managers/fullscreen/`, allowing granular control over window rules, workspace rules, and scrolling layouts.

## Fullscreen States and Modes

The `CFullscreenController` singleton, accessed via `Fullscreen::controller()`, maintains fullscreen state for every window, workspace, and monitor. It distinguishes between an **internal** mode—what Hyprland enforces—and a **client** mode representing what the application requested.

### The Three Fullscreen Modes

In [`src/managers/fullscreen/FullscreenController.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/fullscreen/FullscreenController.hpp), the enum `eFullscreenMode` defines three possible states:

- `FSMODE_NONE` — The window is not fullscreen.
- `FSMODE_MAXIMIZED` — The window covers the work area but remains a maximized state rather than true fullscreen.
- `FSMODE_FULLSCREEN` — True fullscreen where the window occupies the entire output.

The controller exposes query helpers such as `isFullscreen(window)`, `getFullscreenModes(window)`, and `hasFullscreen(workspace)` to inspect these states.

## Fullscreen Handlers and Layout Integration

Handler selection is delegated through the `IFullscreenHandler` interface. The controller resolves the correct implementation via `getFsHandler(window)` and forwards queries such as `isFullscreen` and `getFullscreenModes` to it.

### Handler Types

[`src/managers/fullscreen/FullscreenController.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/fullscreen/FullscreenController.hpp) defines three handler categories:

- **FULLSCREEN_HANDLER_DEFAULT** — The generic handler used for most standard windows.
- **FULLSCREEN_HANDLER_LAYOUT** — Layout-aware handlers that may treat fullscreen windows specially, such as in scrolling layouts.
- **FULLSCREEN_HANDLER_SCROLLING** — A compound flag (`1 << 2 | FULLSCREEN_HANDLER_LAYOUT`) specifically for the scrolling layout in [`src/managers/fullscreen/handler/FullscreenHandler.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/fullscreen/handler/FullscreenHandler.hpp).

Each handler synchronizes its internal target list through `syncFullscreenTargets` whenever the controller updates a mode.

## Protocol Support for XDG and XWayland

Client fullscreen requests enter the controller through two protocol paths before reaching `CFullscreenController::setFullscreenMode`.

### XDG-Shell Handling

In [`src/protocols/XDGShell.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/protocols/XDGShell.cpp), `CXDGToplevelResource::setFullscreen(bool)` forwards the request to the window’s `setFullscreen` flag. This eventually routes to the controller’s mode setter and notifies the IPC system.

### XWayland Handling

In [`src/managers/XWaylandManager.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/XWaylandManager.cpp), `CHyprXWaylandManager::setWindowFullscreen` updates both the XWayland surface and the XDG surface via `XSurface::setFullscreen`. Both paths converge on the controller to update the internal mode.

## Key Configuration Options

Several configuration knobs in the Lua-based config control fullscreen behavior globally, per-layout, or per-window.

### Allow Pinned Windows to Go Fullscreen

The `binds:allow_pin_fullscreen` option controls whether pinned windows can be forced into fullscreen. The controller checks this bind at [`src/managers/fullscreen/FullscreenController.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/managers/fullscreen/FullscreenController.cpp) line 389 when handling pinned window state transitions.

### Scrolling Layout Single-Column Fullscreen

For scrolling layouts, `scrolling.fullscreen_on_one_column` restricts a fullscreen window to a single column while keeping the rest of the layout visible. This is demonstrated in the example configuration at [`example/hyprland.lua`](https://github.com/hyprwm/Hyprland/blob/main/example/hyprland.lua) lines 96–99.

### Window and Workspace Rules

Per-window rules can force or prevent fullscreen on startup. The example config at [`example/hyprland.lua`](https://github.com/hyprwm/Hyprland/blob/main/example/hyprland.lua) lines 32–36 uses `fullscreen = false` as an XWayland workaround. Workspace rules can also preset a workspace to launch with a fullscreen window.

```lua
-- Enable scrolling-layout fullscreen on a single column
hl.config({
    scrolling = {
        fullscreen_on_one_column = true,
    },
})

-- Global bind to allow pinned windows to go fullscreen
hl.bind("SUPER + F", hl.dsp.toggle_fullscreen({ allow_pin = true }))

-- Per-window rule: start a specific app not in fullscreen
hl.window_rule({
    name  = "myapp-no-fs",
    match = { class = "MyApp" },
    fullscreen = false,
})

-- Toggle fullscreen for the focused window (default bind)
hl.bind("SUPER + SHIFT + F", hl.dsp.window.fullscreen())

```

## Internal Fullscreen Lifecycle

The fullscreen pipeline follows a strict sequence from client request to screen render:

1. **Request** — A client invokes `setFullscreen` through XDG or XWayland protocols.
2. **Controller update** — `CFullscreenController::setFullscreenMode` sets the window’s internal mode to `FSMODE_FULLSCREEN` and optionally updates the client mode.
3. **Handler synchronization** — The handler returned by `getFsHandler(window)` calls `syncFullscreenTargets` to align its internal state.
4. **Rendering** — In [`src/render/Renderer.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/render/Renderer.cpp) line 267, the renderer checks `Fullscreen::controller()->isFullscreen(pWindow)` and skips drawing non-covering windows on the same monitor.
5. **IPC event** — The controller posts a `fullscreen` event so external scripts and `hyprctl` can react in real time.

## Edge Cases and Safeguards

The controller includes several defensive mechanisms to prevent inconsistent states.

### Error-Correction Loops

Many methods in [`FullscreenController.cpp`](https://github.com/hyprwm/Hyprland/blob/main/FullscreenController.cpp) contain error-correction lambdas. If `isFullscreen` or `getFullscreenModes` detects an inconsistency between the window and handler targets, the controller automatically re-invokes `syncFullscreenTargets`.

### Covering Flag

Controller queries accept an optional **covering** argument to differentiate between any fullscreen window and the topmost covering one, preventing incorrect occlusion calculations.

### Pinned Window Restrictions

Pinned windows receive special treatment in the controller logic. Unless `binds:allow_pin_fullscreen` is enabled, the controller blocks pinned windows from entering fullscreen to preserve their always-on-top semantics.

## Summary

- Hyprland fullscreen mode configuration centers on the `CFullscreenController` singleton in `src/managers/fullscreen/`, which tracks internal and client fullscreen states.
- Three modes exist—`FSMODE_NONE`, `FSMODE_MAXIMIZED`, and `FSMODE_FULLSCREEN`—queried through helpers like `isFullscreen(window)`.
- Layout-specific handlers (`IFullscreenHandler`) delegate behavior for default, layout-aware, and scrolling contexts.
- XDG and XWayland protocol requests both converge on `CFullscreenController::setFullscreenMode`.
- User-facing options include `binds:allow_pin_fullscreen`, `scrolling.fullscreen_on_one_column`, and per-window or workspace rules in the Lua config.
- The rendering path in [`src/render/Renderer.cpp`](https://github.com/hyprwm/Hyprland/blob/main/src/render/Renderer.cpp) line 267 skips non-covering windows when `isFullscreen(pWindow)` is true.

## Frequently Asked Questions

### How do I prevent a specific window from starting in fullscreen?

Use a per-window rule in your Hyprland configuration. According to the example config in [`example/hyprland.lua`](https://github.com/hyprwm/Hyprland/blob/main/example/hyprland.lua) lines 32–36, set `fullscreen = false` inside a `window_rule` block matched to the window’s class or title. This forces the controller to initialize the window with `FSMODE_NONE` regardless of client requests.

### What is the difference between maximized and fullscreen in Hyprland?

The `eFullscreenMode` enum in [`FullscreenController.hpp`](https://github.com/hyprwm/Hyprland/blob/main/FullscreenController.hpp) defines `FSMODE_MAXIMIZED` as covering the work area without taking over the full output, while `FSMODE_FULLSCREEN` makes the window occupy the entire monitor surface. The controller handles these as distinct internal states and reports them separately via `getFullscreenModes(window)`.

### Why does my scrolling layout still show other columns when a window is fullscreen?

The `scrolling.fullscreen_on_one_column` option controls this behavior. When set to `true` in [`example/hyprland.lua`](https://github.com/hyprwm/Hyprland/blob/main/example/hyprland.lua) lines 96–99, the scrolling handler confines the fullscreen window to a single column rather than treating it as a true covering fullscreen across the entire output.

### How does Hyprland handle pinned windows entering fullscreen?

The controller at [`FullscreenController.cpp`](https://github.com/hyprwm/Hyprland/blob/main/FullscreenController.cpp) line 389 checks the `binds:allow_pin_fullscreen` bind before permitting a pinned window to enter fullscreen. If the bind is disabled, pinned windows are blocked from fullscreen transitions to maintain their fixed-on-top status above normal windows.