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.