Skip to main content
Version: 2.0

Compositor Setup

Dux Shell

Compositor Setup

Dux Shell works with any Wayland compositor, but we provide optimized configurations for niri, Hyprland, Sway, MangoWC, labwc, and Miracle WM. These configs include DMS-specific keybindings, proper layer shell rules, and recommended settings.

niri Configuration​

niri uses the KDL configuration format. Dux Shell integrates seamlessly with niri's scrollable tiling layout.

Key Configuration Sections​

DMS will automatically apply key binds, gaps, window radius, and colors if you include the following files in your niri config. You can customize gaps, border radius, and window radius in Settings → Compositor.

// Add to the end of ~/.config/niri/config.kdl
include "dms/colors.kdl"
include "dms/layout.kdl"
include "dms/alttab.kdl"
include "dms/binds.kdl"
tip

Be sure that all files exist before including them in the niri configuration.

mkdir -p ~/.config/niri/dms
touch ~/.config/niri/dms/{colors,layout,alttab,binds}.kdl

For manual configuration recommendations, continue below.

Layout​

The niri layout should have a transparent background, in order to integrate wallpapers onto the overview.

layout {
// You can tailor the gaps to fit dms spacing.
gaps 5
background-color "transparent"
}

Layer Rules​

Tell niri to place the wallpaper on the overview.

layer-rule {
match namespace="^quickshell$"
place-within-backdrop true
}

If "Blur Layer" is enabled, you can place the blurred wallpaper on the overview.

layer-rule {
match namespace="dms:blurwallpaper"
place-within-backdrop true
}

For more about layer rules see layer rules.

Startup​

For systemd autostart setup, see the Installation guide. If you prefer not to use systemd, add DMS directly to your niri config:

spawn-at-startup "dms" "run"

// Optional: Clipboard history
spawn-at-startup "bash" "-c" "wl-paste --watch cliphist store &"

Environment Variables​

environment {
XDG_CURRENT_DESKTOP "niri"
QT_QPA_PLATFORM "wayland"
ELECTRON_OZONE_PLATFORM_HINT "auto"
QT_QPA_PLATFORMTHEME "gtk3"
QT_QPA_PLATFORMTHEME_QT6 "gtk3"
}

DMS Keybindings​

For the full list of available IPC commands see IPC

binds {
// Application Launchers
Mod+Space hotkey-overlay-title="Application Launcher" {
spawn "dms" "ipc" "call" "spotlight" "toggle";
}
Mod+V hotkey-overlay-title="Clipboard Manager" {
spawn "dms" "ipc" "call" "clipboard" "toggle";
}
Mod+M hotkey-overlay-title="Task Manager" {
spawn "dms" "ipc" "call" "processlist" "focusOrToggle";
}
Mod+Comma hotkey-overlay-title="Settings" {
spawn "dms" "ipc" "call" "settings" "focusOrToggle";
}
Mod+N hotkey-overlay-title="Notification Center" {
spawn "dms" "ipc" "call" "notifications" "toggle";
}
Mod+Y hotkey-overlay-title="Browse Wallpapers" {
spawn "dms" "ipc" "call" "dankdash" "wallpaper";
}

// Security
Mod+Alt+L hotkey-overlay-title="Lock Screen" {
spawn "dms" "ipc" "call" "lock" "lock";
}

// Audio Controls
XF86AudioRaiseVolume allow-when-locked=true {
spawn "dms" "ipc" "call" "audio" "increment" "3";
}
XF86AudioLowerVolume allow-when-locked=true {
spawn "dms" "ipc" "call" "audio" "decrement" "3";
}
XF86AudioMute allow-when-locked=true {
spawn "dms" "ipc" "call" "audio" "mute";
}

// Brightness Controls
XF86MonBrightnessUp allow-when-locked=true {
spawn "dms" "ipc" "call" "brightness" "increment" "5" "";
}
XF86MonBrightnessDown allow-when-locked=true {
spawn "dms" "ipc" "call" "brightness" "decrement" "5" "";
}

// Touchpad toggle key (OSD needs niri with TouchpadToggled events)
XF86TouchpadToggle allow-when-locked=true repeat=false {
spawn "niri" "msg" "action" "toggle-touchpad";
}
// Hardware On/Off notifications (OSD only)
XF86TouchpadOn allow-when-locked=true repeat=false {
spawn "dms" "ipc" "call" "niri" "showTouchpadOsd" "true";
}
XF86TouchpadOff allow-when-locked=true repeat=false {
spawn "dms" "ipc" "call" "niri" "showTouchpadOsd" "false";
}
}

Window Rules​

Recommended window rules, tailor to your preferences:

window-rule {
match app-id=r#"^org\.gnome\."#
draw-border-with-background false
geometry-corner-radius 12
clip-to-geometry true
}

window-rule {
match app-id=r#"^org\.wezfurlong\.wezterm$"#
match app-id="Alacritty"
match app-id="zen"
match app-id="com.mitchellh.ghostty"
match app-id="kitty"
draw-border-with-background false
}

window-rule {
match is-active=false
opacity 0.9
}

window-rule {
geometry-corner-radius 12
clip-to-geometry true
}

// Open DMS windows as floating by default (optional - DMS can manage this for you, see tip below)
window-rule {
match app-id=r#"^com\.danklinux\.dms$"#
open-floating true
}
DMS-managed floating rule

DMS can manage this rule itself via Settings → Theme & Colors → Floating Windows → Open Windows Floating (on by default). The rule lives in a managed fragment at ~/.config/niri/dms/windowrules.kdl; if that fragment isn't included in your config yet, a First Time Setup banner on the same page creates it and adds the include when you click Setup. DMS floating windows use app ID com.danklinux.dms — remove any hand-written rules targeting the old org.quickshell ID.

Hyprland Configuration​

Hyprland uses a Lua config at ~/.config/hypr/hyprland.lua. DMS needs Hyprland 0.55 or newer, the first release that loads it; dms setup refuses to write the Lua config on older versions.

On 0.55 and 0.56 an install that still runs hyprland.conf keeps working read-only: DMS shows your keybinds, window rules and displays, but won't edit them until you run dms setup to migrate, and dms doctor warns about it. Hyprland 0.57 drops .conf support entirely.

Config layout​

Hyprland must be started with the Lua config for any of this to apply:

Hyprland -c ~/.config/hypr/hyprland.lua

If Hyprland warns that it is using an autogenerated config, or the warning names hyprland.conf, the session is not on the Lua config yet.

dms setup writes the main config plus fragments under ~/.config/hypr/dms/:

FragmentPurposeSettings page
colors.luaTheme colorsWallpaper & colors
layout.luaLayout, gaps, borders, blur, effects, xray layer rulesSystem & integrations → Hyprland, Interface style (Blur strength)
outputs.luaMonitors and display settingsDisplays
cursor.luaCursor settingsWallpaper & colors
input.luaMouse, touchpad and keyboard settingsInput → Mouse & touchpad, Keyboard
binds.luaDMS-managed default shortcuts-
binds-user.luaYour shortcut overridesInput → Keyboard shortcuts
windowrules.luaWindow rulesApplications → Window rules

binds.lua is refreshed by dms setup, so put custom shortcuts in binds-user.lua or use the Keyboard Shortcuts page. Deleting a DMS default there saves an hl.unbind("KEY") line into binds-user.lua so the removal sticks across setup runs; Reset to default drops your override. Binds in your own hyprland.lua are read-only in Settings, DMS does not write files it does not manage.

Stock configs bind a 3-finger horizontal touchpad gesture to workspace switching (hl.gesture in binds.lua). Add your own hl.gesture(...) lines to binds-user.lua to change it, or drop a stock gesture with action = "unset" matching its fingers, direction, and modifiers.

Migrating from hyprland.conf​

dms setup moves legacy hyprland.conf and dms/*.conf into ~/.config/hypr/.dms-backups/<timestamp>/ so Hyprland never sees both formats at once. It also migrates monitor = ... lines into dms/outputs.lua when that file is empty or missing; an existing outputs.lua is left alone.

Hyprland still autogenerates hyprland.conf when launched without -c. DMS sweeps stray copies into the backup folder on the next dms run, so if one keeps reappearing the session is not starting from hyprland.lua.

Check the result with:

dms setup
hyprctl reload
hyprctl configerrors

Key Configuration Sections​

DMS applies colors, displays, layout, cursor, input, keybinds and window rules through the fragments above. dms setup adds these lines for you; if you maintain hyprland.lua by hand, keep them at the end in this order. You can customize gaps, borders, and effects in Settings → System & integrations → Hyprland.

-- Add to the end of ~/.config/hypr/hyprland.lua
require("dms.colors")
require("dms.outputs")
require("dms.layout")
require("dms.cursor")
require("dms.input")
require("dms.binds")
require("dms.binds-user")
require("dms.windowrules")
tip

Be sure that all files exist before including them in the Hyprland configuration.

mkdir -p ~/.config/hypr/dms
touch ~/.config/hypr/dms/{colors,outputs,layout,cursor,input,binds,binds-user,windowrules}.lua

For manual configuration recommendations, continue below.

Startup​

For systemd autostart setup (recommended if you have multiple desktop environments), see the Installation guide. If you prefer not to use systemd, add DMS directly to your Hyprland config:

hl.on("hyprland.start", function()
hl.exec_cmd("dms run")

-- Optional: Clipboard history
hl.exec_cmd("wl-paste --watch cliphist store")
end)

Miscellaneous​

Disables the hyprland backdrop/logo

hl.config({
misc = {
disable_hyprland_logo = true,
disable_splash_rendering = true
}
})

Environment Variables​

hl.env("QT_QPA_PLATFORM", "wayland")
hl.env("QT_QPA_PLATFORMTHEME", "gtk3")
hl.env("QT_QPA_PLATFORMTHEME_QT6", "gtk3")
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "auto")

Layer Rules​

hl.layer_rule({ match = { namespace = "dms" }, no_anim = true })

For more about layer rules see layer rules.

General Layout​

hl.config({
general = {
gaps_in = 5,
gaps_out = 5,
border_size = 0,

col = {
active_border = "rgba(707070ff)",
inactive_border = "rgba(d0d0d0ff)"
},

layout = "dwindle"
}
})

Decoration​

Window opacity on the Compositor page sets active_opacity and inactive_opacity for you. At 100 DMS leaves them to your config.

hl.config({
decoration = {
rounding = 12,

active_opacity = 1.0,
inactive_opacity = 0.9,

shadow = {
enabled = true,
range = 30,
render_power = 4,
offset = "0 5",
color = "rgba(00000070)"
}
}
})

DMS Keybindings​

For the full list of available IPC commands see IPC

local mod = "SUPER"

-- Application Launchers
hl.bind(mod .. " + space", hl.dsp.exec_cmd("dms ipc call spotlight toggle"))
hl.bind(mod .. " + V", hl.dsp.exec_cmd("dms ipc call clipboard toggle"))
hl.bind(mod .. " + M", hl.dsp.exec_cmd("dms ipc call processlist focusOrToggle"))
hl.bind(mod .. " + comma", hl.dsp.exec_cmd("dms ipc call settings focusOrToggle"))
hl.bind(mod .. " + N", hl.dsp.exec_cmd("dms ipc call notifications toggle"))
hl.bind(mod .. " + Y", hl.dsp.exec_cmd("dms ipc call dash toggle wallpaper"))
hl.bind(mod .. " + TAB", hl.dsp.exec_cmd("dms ipc call hypr toggleOverview"))

-- Security
hl.bind(mod .. " + ALT + L", hl.dsp.exec_cmd("dms ipc call lock lock"))

-- Audio Controls
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("dms ipc call audio increment 3"), { locked = true, repeating = true })
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("dms ipc call audio decrement 3"), { locked = true, repeating = true })
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("dms ipc call audio mute"), { locked = true })

-- Brightness Controls
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd([[dms ipc call brightness increment 5 ""]]), { locked = true, repeating = true })
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd([[dms ipc call brightness decrement 5 ""]]), { locked = true, repeating = true })

Window Rules​

-- Opacity for inactive windows
hl.window_rule({ match = { float = false, focus = false }, opacity = "0.9 0.9" })

-- GNOME apps
hl.window_rule({ match = { class = "^(org\\.gnome\\.)" }, border_size = 0, rounding = 12 })

-- Terminal apps - no borders
hl.window_rule({ match = { class = "^(org\\.wezfurlong\\.wezterm)$" }, border_size = 0 })
hl.window_rule({ match = { class = "^(Alacritty)$" }, border_size = 0 })
hl.window_rule({ match = { class = "^(zen)$" }, border_size = 0 })
hl.window_rule({ match = { class = "^(com\\.mitchellh\\.ghostty)$" }, border_size = 0 })
hl.window_rule({ match = { class = "^(kitty)$" }, border_size = 0 })

-- Floating windows
hl.window_rule({ match = { class = "^(gnome-calculator)$" }, float = true })

hl.window_rule({ match = { class = "^(blueman-manager)$" }, float = true })

hl.window_rule({ match = { class = "^(org\\.gnome\\.Nautilus)$" }, float = true })

-- Open DMS windows as floating by default (optional — DMS can manage this for you)
hl.window_rule({ match = { class = "^(com\\.danklinux\\.dms)$" }, float = true })

As on niri, Settings → Interface style → Floating windows → Open floating can manage this rule in ~/.config/hypr/dms/windowrules.lua (click Setup on the banner if the fragment isn't included yet). DMS floating windows use app ID com.danklinux.dms.

Window rule editor​

Settings → Applications → Window rules writes your rules to ~/.config/hypr/dms/windowrules.lua. On Hyprland the editor adds:

  • Match: Group and Modal toggles, plus an Advanced Matching card with Initial class, Initial title, Tag, XDG tag, Workspace, Content (none, photo, video, game), Fullscreen state, and Client fullscreen state. Prefix a tag with negative: to match windows without it.
  • Advanced effects: No initial focus, Stay focused, Focus on activate, Confine pointer, No XDG drags, No glow (0.55+), No wobble (Hyprland main), No auto HDR, Tone mapping, scrolling Column Width, Border color, and Suppress events.

Corner radius is capped at 20 because Hyprland 0.55 and 0.56 reject higher rounding values and drop the rule. Editing a rule keeps any fields the editor doesn't show.

Compositor Settings (Hyprland)​

Settings → System & integrations → Hyprland writes ~/.config/hypr/dms/layout.lua and reloads Hyprland. DMS reads the running Hyprland's options once (hyprctl -j descriptions) and hides or skips anything your version doesn't have.

Tiling layout

LayoutOptions
OffLeaves general:layout to your own config
DwindlePreserve split, Smart split, Force split (Follow mouse, Left, Right)
MasterMaster position, New windows (Stack, Master, Inherit), New windows on top of the stack, Master size
ScrollingDirection, Column Width, Fullscreen single column, Follow focus

Layout overrides

  • Gaps: Auto follows the bar spacing, Custom shows Inner gaps and Outer gaps sliders, Off leaves gaps to your config.
  • Window radius follows Interface style → Corners.
  • Override border size.
  • Resize on border, with a Border grab area slider (general:extend_border_grab_area) for the extra space around borders that still starts a resize.
  • Window opacity for app windows.
  • Xray blur and Bar xray / Frame xray. See Layer Namespaces.

Visual effects

SettingHyprlandNotes
Blur stylemainDefault, Frost, Ripple, Drops, Water, Fluid jar, Prism, Heat shimmer, Acrylic, Aurora, Haze. See Compositor Blur
Glow0.55+Inner glow along window edges in the theme color, with range and Glow falloff sliders
Wobbly windowsmainIntensity and Wobble stiffness sliders
Motion blur0.56+Sample count; more samples look smoother and cost more GPU

Effects apply to every window, including DMS floating windows such as Settings and Notepad, which also wobble. Blur reach is the Blur strength slider under Interface style, not part of this card.

Window groups

Background blur for the group bar, Title padding, Middle click closes, and Hide with one window (Hyprland main). Options your Hyprland doesn't have are not written.

MangoWC Configuration​

MangoWC is a dynamic tiling Wayland compositor based on dwl (wlroots). Configuration lives at ~/.config/mango/config.conf.

Key Configuration Sections​

dms setup writes the main config plus fragments under ~/.config/mango/dms/:

FragmentPurposeSettings page
colors.confTheme colorsWallpaper & colors
layout.confGaps, borders, window radiusSystem & integrations → Compositor
cursor.confCursor theme, size and hide timeoutWallpaper & colors
input.confMouse, touchpad and keyboard settingsInput → Mouse & touchpad, Keyboard
outputs.confMonitors and display settingsDisplays
windowrules.confWindow rulesApplications → Window rules
binds.confKeybindsInput → Keyboard shortcuts

If you maintain config.conf by hand, source every fragment and make sure the files exist. A First Time Setup banner on the matching Settings page adds a missing source line for you.

# Add to the end of ~/.config/mango/config.conf
source=./dms/colors.conf
source=./dms/layout.conf
source=./dms/cursor.conf
source=./dms/input.conf
source=./dms/outputs.conf
source=./dms/windowrules.conf
source=./dms/binds.conf
mkdir -p ~/.config/mango/dms
touch ~/.config/mango/dms/{colors,layout,cursor,input,outputs,windowrules,binds}.conf

Mouse and touchpad rows map onto MangoWC's mouse_* and trackpad_* keys. Keyboard keys (xkb_rules_*, repeat_*, numlock) are written only once you set one of them, so an untouched Keyboard page keeps the keyboard lines in your own config.conf. The Keymap file row is hidden on MangoWC because it has no such option. The numlock key is spelled numlockon or numlock_on to match the installed MangoWC release.

For manual configuration recommendations, continue below.

Startup​

For systemd autostart setup (recommended if you have multiple desktop environments), see the Installation guide. If you prefer not to use systemd, add DMS directly to your MangoWC config:

exec-once=dms run

# Optional: Clipboard history
exec-once=wl-paste --type text --watch cliphist store

Environment Variables​

env=QT_QPA_PLATFORM,wayland
env=ELECTRON_OZONE_PLATFORM_HINT,auto
env=QT_QPA_PLATFORMTHEME,gtk3

Appearance​

Recommended appearance settings for DMS integration:

# Window appearance
border_radius=12
borderpx=0
focused_opacity=1.0
unfocused_opacity=0.9

# Gaps
gappih=5
gappiv=5
gappoh=5
gappov=5

# Shadows (optional)
shadows=1
shadow_only_floating=1
shadows_size=10
shadows_blur=15

Layer Rules​

# Disable animation on DMS layers
layerrule=noanim:1,layer_name:^dms

For more about layer rules see layer rules.

DMS Keybindings​

For the full list of available IPC commands see IPC.

# Application Launchers
bind=SUPER,space,spawn,dms ipc call spotlight toggle
bind=SUPER,v,spawn,dms ipc call clipboard toggle
bind=SUPER,m,spawn,dms ipc call processlist focusOrToggle
bind=SUPER,comma,spawn,dms ipc call settings focusOrToggle
bind=SUPER,n,spawn,dms ipc call notifications toggle
bind=SUPER,y,spawn,dms ipc call dankdash wallpaper

# Security
bind=SUPER+ALT,l,spawn,dms ipc call lock lock

# Audio Controls
bind=NONE,XF86AudioRaiseVolume,spawn,dms ipc call audio increment 3
bind=NONE,XF86AudioLowerVolume,spawn,dms ipc call audio decrement 3
bind=NONE,XF86AudioMute,spawn,dms ipc call audio mute

# Brightness Controls
bind=NONE,XF86MonBrightnessUp,spawn,dms ipc call brightness increment 5
bind=NONE,XF86MonBrightnessDown,spawn,dms ipc call brightness decrement 5

Window Rules​

# GNOME apps
windowrule=isnoborder:1,appid:^org\.gnome\.

# Terminal apps - no borders
windowrule=isnoborder:1,appid:^org\.wezfurlong\.wezterm$
windowrule=isnoborder:1,appid:^Alacritty$
windowrule=isnoborder:1,appid:^com\.mitchellh\.ghostty$
windowrule=isnoborder:1,appid:^kitty$

# Float DMS windows
windowrule=isfloating:1,appid:^org\.quickshell$

Sway Configuration​

Sway is an i3-compatible Wayland compositor. Dux Shell integrates with Sway's tiling layout.

Key Configuration Sections​

Coming Soon

Detailed Sway configuration sections are coming soon. Sway configuration will include:

  • Startup commands
  • Environment variables
  • DMS keybindings
  • Layer rules
  • Window rules

For now, refer to the Example for Sway in the "Other Compositors" section below for basic setup.

Startup​

For systemd autostart setup (recommended if you have multiple desktop environments), see the Installation guide. Otherwise, add DMS directly to your Sway config:

exec dms run

# Optional: Clipboard history
exec wl-paste --watch cliphist store

DMS Keybindings​

For the full list of available IPC commands see IPC. Basic Sway keybinding examples are available in the Example for Sway section below.

labwc Configuration​

labwc is a wlroots-based window-stacking compositor for Wayland, inspired by Openbox.

Key Configuration Sections​

Coming Soon

Detailed labwc configuration sections are coming soon. labwc configuration will include:

  • Startup commands
  • Environment variables
  • DMS keybindings
  • Layer rules
  • Window rules

For now, refer to the labwc documentation for basic setup.

DMS Keybindings​

For the full list of available IPC commands see IPC. labwc keybinding configuration coming soon.

Miracle WM Configuration​

Miracle WM is a tiling Wayland compositor built on Mir.

Key Configuration Sections​

Coming Soon

Detailed Miracle WM configuration sections are coming soon. Miracle WM configuration will include:

  • Startup commands
  • Environment variables
  • DMS keybindings
  • Window rules

Startup​

For systemd autostart setup (recommended if you have multiple desktop environments), see the Installation guide. Otherwise, add DMS directly to your Miracle WM config.

DMS Keybindings​

For the full list of available IPC commands see IPC. Miracle WM keybinding configuration coming soon.

Other Compositors​

Dux Shell works with any Wayland compositor that supports:

  • Layer shell protocol (for panels and overlays)
  • Session lock protocol (for lock screen)
  • ext-workspace-v1 protocol (for workspace management)
  • wlr-output-management-unstable-v1 protocol (for interface scaling + output management)

Note: Some compositor-specific features will be unavailable, such as workspace switching.

Basic Integration​

For other compositors, you need to:

  1. Auto-start DMS:

    dms run
  2. Configure keybindings using the IPC commands from the Keybinds & IPC guide

  3. Set environment variables in ~/.config/environment.d/90-dms.conf (for systemd users) or your compositor config:

    QT_QPA_PLATFORM=wayland

    You can also use systemctl --user edit dms and add Environment=QT_QPA_PLATFORM=wayland under [Service]. This only affects DMS and apps it launches, whereas 90-dms.conf applies to all user sessions.

Example for Sway​

Add to ~/.config/sway/config:

# DMS Keybindings
bindsym $mod+space exec dms ipc call spotlight toggle
bindsym $mod+v exec dms ipc call clipboard toggle
bindsym $mod+m exec dms ipc call processlist focusOrToggle
bindsym $mod+comma exec dms ipc call settings focusOrToggle

# Audio controls
bindsym XF86AudioRaiseVolume exec dms ipc call audio increment 3
bindsym XF86AudioLowerVolume exec dms ipc call audio decrement 3
bindsym XF86AudioMute exec dms ipc call audio mute

# Brightness controls
bindsym XF86MonBrightnessUp exec dms ipc call brightness increment 5
bindsym XF86MonBrightnessDown exec dms ipc call brightness decrement 5

Troubleshooting​

DMS doesn't start automatically​

Check your compositor's logs to ensure the spawn-at-startup or equivalent startup command is running. You can also manually start DMS with dms run to see any error messages.

Keybindings don't work​

Verify that:

  • DMS is running (pgrep -f "dms run")
  • Your keybinding syntax matches your compositor's format

Next Steps​