Anvil

Anvil is Ironforge's default window manager. It is a deliberately small Wayland compositor with four desktops, four layouts, an integrated status bar, and built-in notifications. It enables one output and runs Wayland-native applications.

Layouts and windows

Layout Shortcut Window arrangement
Fullscreen Super+F One stacked window fills the output; the bar is hidden.
Max Super+M One stacked window fills the area below the bar.
2-Split Super+S The top window from each of two side stacks is visible.
Sidecar Super+C One main window on the left, with up to three scaled windows on the right.

Sidecar gives every window frame the same logical dimensions, then displays right-side windows at one-third width and height. Swapping a small window with main does not resize either application. Ordinary clicks focus a small window in place; Super+left-click swaps it into main and focuses it. The right stack can contain more than three windows: cycling reveals hidden ones. With the hardware GLES2 renderer, cached Lanczos2 filtering keeps the scaled content readable; other renderers use their native filtering.

Application-requested fullscreen, such as a browser's F11 mode, fills the application's assigned tile in Max, Split, and Sidecar. Neighboring windows and the bar stay visible. Use Super+F to fill the entire output instead.

Windows are borderless by default. Super+T toggles an optional title bar with the application title and a close button for the focused window. Its preference survives layout and desktop changes; fullscreen temporarily hides it. Supporting applications are asked to omit their own decorations, but Anvil cannot remove custom application toolbars. A brief focus outline identifies the window receiving keyboard focus.

Monitor power-off, unplug, and VT/session pauses preserve applications, desktops, focus, and the last layout size. Anvil waits for an output to return and resumes rendering there. Explicitly exiting the compositor still disconnects its clients.

Keyboard and mouse controls

Super is usually the Windows or logo key. These are the built-in defaults; custom binds can override most Super shortcuts.

Shortcut Action
Super+1 through Super+4 Switch desktop.
Super+Shift+1 through Super+Shift+4 Move the focused window to a desktop without following it.
Super+J / Super+K Cycle forward / backward through the stack.
Super+Tab / Super+Shift+Tab Cycle forward / backward through the stack.
Super+H / Super+L Focus the left / right side.
Super+Space Swap across sides in Split or Sidecar; focus follows the same window.
Super+Shift+Space Swap across sides and focus the other window, keeping focus on the original side.
Super+O or Super+Shift+H/L Move the focused window between sides; in Sidecar, swap with the other side.
Super+Shift+J/K Reorder the focused stack.
Super+left-click Swap a right-side Sidecar window into main and focus it.
Super+Return Open the configured terminal, default foot.
Super+P or Super+D Open the configured launcher, default fuzzel.
Super+Shift+D Toggle light/dark appearance.
Super+T Toggle the focused window's title bar outside fullscreen.
Super+N Open or close notification history.
Super+Shift+N Toggle notification Do Not Disturb.
Print Select a rectangle and copy it to the clipboard as PNG.
Shift+Print Select a rectangle and save it under ~/Pictures.
Volume and mute keys Adjust the default PipeWire output through wpctl.
Brightness keys Adjust the backlight through brightnessctl.
Super+Q Ask the focused application window to close.
Super+Shift+Q Exit Anvil.

In Sidecar, cycling and reordering operate on the right stack and do nothing while main is focused. Entering Sidecar makes the focused application main. Super+H/L returns to main or the remembered right selection; from main, that remembered selection is also the target for a swap. In Split, swapping requires a window on both sides.

Built-in bar

The bar is part of the compositor, with an embedded font and no separate bar process, CSS, or bar IPC protocol. Its modules can be reordered or omitted through configuration. The default arrangement includes a title, clickable desktops, clock, CPU, memory, Wi-Fi, DHCP/IP status, volume, battery, and tray. Status collection and drawing run on a backend thread so slow queries do not block application frame processing.

Hovering status modules opens detailed tooltips. The clock uses a configurable IANA timezone, defaults to Europe/Stockholm, and shows an ISO week calendar when /usr/bin/cal is available. Battery reporting combines system batteries and provides per-battery details; the module hides when none are present. Volume reports the default PipeWire sink and its mute state.

Wi-Fi reports association and signal strength. The separate DHCP globe reports whether a wired or wireless interface has a usable IP address and default route. It also works with static addresses and IPv6 automatic configuration; it does not test Internet reachability or DNS. Existing custom module lists must include "dhcp" to display it. The waiting-state color is dhcp_pending, replacing the old wifi_no_ip setting.

The StatusNotifierItem tray supports live icons, tooltips, activation, and context menus, including nested menus. Left-click activates an item, middle-click requests its secondary action, and right-click opens its menu. Explicit tray and notification actions can raise a window and switch to its desktop through trusted activation tokens. Merely receiving a notification never steals focus.

Appearance

The tray's sun or crescent icon and Super+Shift+D switch the desktop between light and dark. The change covers the bar, tooltips, calendar, menus, notifications, title bars, desktop background, wallpaper, and focus outline. Anvil publishes the desktop preference for applications that follow it and also follows external changes to org.gnome.desktop.interface color-scheme. Applications retain control of their own appearance.

Set color_scheme to choose the startup theme. Runtime changes do not rewrite the configuration, so restarting restores that choice. Publishing and monitoring appearance requires gsettings and the GNOME desktop interface schema. Portal-aware applications also need an XDG Desktop Portal Settings backend, such as xdg-desktop-portal-gtk, selected in the active portal configuration.

PNG wallpapers are scaled to fill the output and center-cropped. A shared wallpaper can be overridden under [theme.dark] and [theme.light]; an empty path disables that theme's image. Theme tables also accept palette overrides and on_enter arrays of shell commands, run at startup and when entering that theme. Both wallpapers are loaded at startup, so image or configuration changes require a restart.

Notifications

Anvil provides the session's org.freedesktop.Notifications service. Remove swaync or another notification daemon from session startup to use it; Anvil does not take the bus name from an existing owner.

Notifications appear in a translucent ticker across the bottom edge, including in fullscreen, without resizing applications. Hovering pauses scrolling and the timeout. The service supports actions, inline replies, images, progress, basic markup, clickable links, and a Copy action for detected verification codes. With the Pixman software renderer the ticker is static; use scrolling controls to read long messages.

Left-click invokes the default action, or dismisses a message with no default action. Labelled actions invoke their respective commands. Middle/right-click or a horizontal drag dismisses a message. Click the count or press Super+N to open history, grouped by application. Ordinary notifications remain in history after their popup expires; transient messages are removed.

In history, Up/Down or J/K selects a message, Return invokes its default action, 1–9 invokes alternative actions, and Delete/Backspace dismisses it. Shift+C clears history, Shift+D toggles DND, Y copies a detected verification code, and Left/Right scrolls the message. Escape closes history or cancels a reply. When replying, Return sends, Backspace edits, and Ctrl+U clears text.

DND is persisted across restarts; history is held in memory with a configurable limit. Critical notifications bypass DND and named inhibitors. Optional [[notifications.rules]] entries match application, summary, and body with shell globs to silence, ignore, or hide selected actions.

Scripts can control the running notification service through the session bus:

anvil --notifications toggle
anvil --notifications count
anvil --notifications clear
anvil --notifications dnd-on
anvil --notifications dnd-off
anvil --notifications inhibit screen-sharing
anvil --notifications uninhibit screen-sharing

Screenshots

The screenshot shortcuts use a built-in rectangle selector. Drag with the left mouse button and release to capture; Escape or right-click cancels. The selection can include the bar, and the selector overlay is removed before capture. grim creates the PNG, wl-copy delivers clipboard captures, and notify-send reports saved paths. slurp is not required. Capture tools can also use the supported wlr-screencopy-unstable-v1 protocol directly, for example grim screenshot.png to capture the output.

Configuration

Anvil reads ~/.config/anvil/config.toml, or $XDG_CONFIG_HOME/anvil/config.toml when set. --config FILE selects another file, and command-line settings override TOML. Configuration is read once at startup; editing it requires restarting Anvil. This includes output scale, keyboard settings, commands, binds, and bar policy, even though layouts, appearance, title bars, and notification controls can change during a session.

This partial example shows common settings and their defaults; omitted fields keep their defaults. The source tree's examples/config.toml contains the full configuration, including module styles, theme colors, and status intervals.

scale = 2
default_layout = "max" # fullscreen, max, split, or sidecar
color_scheme = "dark"
terminal = "foot"
launcher = "fuzzel"
volume_up = "wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 0.05+"
volume_down = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05-"
volume_mute = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
brightness_up = "brightnessctl --class=backlight set +5%"
brightness_down = "brightnessctl --class=backlight set 5%-"

[sidecar]
click_to_switch = true

[titlebar]
enabled = false

[focus_outline]
duration_ms = 228 # 0 disables the outline
width = 3
opacity = 0.9

[xkb]
layout = "us"
variant = "altgr-intl"
options = "ctrl:nocaps"

[bar]
enabled = true
height = 28
font_size = 16.0
clock_timezone = "Europe/Stockholm"
modules_left = ["title", "workspaces"]
modules_center = ["clock"]
modules_right = ["cpu", "memory", "wifi", "dhcp", "volume", "battery", "tray"]

[notifications]
enabled = true
opacity = 0.88
speed = 100
timeout_ms = 6000
history_limit = 100

Custom shortcuts use [[bind]] entries with an XKB key name and a shell command. For example, append this optional bind:

[[bind]]
key = "super+r"
command = "~/.local/bin/ssh-picker"

A bind must include at least one modifier: super, shift, ctrl/control, or alt/mod1. Names are case-insensitive and modifier combinations must match exactly. Up to 32 binds are accepted; invalid or duplicate entries are logged and skipped. Custom binds precede built-in Super chords, but notification history, screenshot, volume, and brightness keys retain precedence. Commands run through /bin/sh -c.

Scope and limitations

Anvil supports the regular clipboard and application popups. Its launcher layer-shell support is deliberately narrow and allows only one layer surface at a time. There is no Xwayland, general floating-window policy, general-purpose desktop layer support, drag-and-drop policy, runtime output configuration, touch input, or accessibility protocol support. Only the first output is enabled. It is a focused kiosk-style window policy, not a security sandbox.

The compact ChatGPT robot is one floating-window exception, detected from its Wayland application ID, title, and fixed-size constraints. It appears across desktops and in fullscreen. Drag a non-transparent part to reposition it; its position lasts for the compositor session and it cannot be resized. Unrecognized windows use the normal tiled policy.

Name

The standalone compositor and the legacy forge anvil toolchain command are unrelated. The latter remains a subcommand of the Ironforge build tool.