Jump to content

# dwl

From ArchWiki

Related articles

- Window manager
- Wayland
- mangowc

dwl is a wlroots-based Wayland compositor, similar in spirit to dwm. It is minimal, fast, and extensible through community-made patches. By default, it comes with very little functionality, it is usable in its base state, but more QOL features can be applied if desired.

Note dwl is currently unmaintained as the maintainer seems to not have the time or capacity to keep up with upstream changes.

## Installation

dwl can be installed with the dwlAUR or dwl-gitAUR packages. Make any required configuration changes before building and installing, see makepkg.

Tip Upstream instructions can also be followed, but will install files without having pacman keeping track of them.

## Configuration

dwl is configured at compile-time by editing some of its source files, specifically `config.h`. For detailed information on these settings, see the included, well-commented `config.def.h`.

The official website has a number of patches that can add extra functionality to dwl. These patches primarily make changes to the `dwl.c` file but also make changes to the `config.h` file where appropriate. For information on applying patches, see the Patching packages article.

### Enable XWayland

To build dwl with Xwayland enabled, install xorg-xwayland and uncomment the following lines in the build file like so:

    /path/to/config.mk

    # Uncomment to build XWayland support
    XWAYLAND = -DXWAYLAND
    XLIBS = xcb xcb-icccm

## Usage

dwl can be started from a display manager of choice, by selecting the desktop entry in the menu that it provides.

For starting dwl from a getty, execute the command as follows:

    $ dwl

You can also autostart a command using the `-s` flag. This command will have information about selected layouts, current window title, app-id, and tags written to it's stdin by dwl. You can use this to populate your status bar. If your command does not consume the data sent by dwl, append `<&-` to it like this:

    dwl -s 'sh /path/to/autostart.sh <&-'

If using a display manager, this can be appended to the `Exec` line in the desktop entry.

Note See the upstream guide for more detailed information on dwl usage.

## Tips and tricks

### Floating layout for some windows

For some windows, such as preferences dialogs, it does not make sense for these windows to be tiled - they should be free-floating instead. For example, to make Firefox's preferences dialog float, add the following to your rules array:

    /path/to/config.def.h

    static const Rule rules[] = {
    ...
    { NULL, "Firefox Preferences", 1 << 8, 1, -1 },
    ...
    };

### Taking screenshots

The script below will first create a directory `/path/to/pics`, then if that succeeds it will take a screenshot and save it to a file with the current date and extension `.png` in that newly made directory:

    /path/to/scripts/screenshot.sh

    #!/bin/sh
    mkdir -p /path/to/pics && grim "/path/to/pics/$(date +'%m-%d-%Y-%H%M%S').png"

Additionally, if you also want to take screenshots with a selection box instead of taking a screenshot of all monitors, create the following:

    /path/to/scripts/screenshotsel.sh

    #!/bin/sh
    mkdir -p /path/to/pics && grim -g "$(slurp)" "/path/to/pics/$(date +'%m-%d-%Y-%H%M%S').png"

For taking a screenshot and saving it to the clipboard instead of it being saved to a place on the filesystem create the script below:

    /path/to/scripts/screenshotselcopy.sh

    #!/bin/sh
    grim -g "$(slurp)" - | wl-copy

Finally add the following:

    /path/to/config.def.h

    static const Key keys[] = {
    ...
    { 0, XKB_KEY_Print, spawn, SHCMD("path/to/scripts/screenshot.sh") },
    { WLR_MODIFIER_SHIFT, XKB_KEY_Print, spawn, SHCMD("path/to/scripts/screenshotsel.sh") },
    { WLR_MODIFIER_CTRL, XKB_KEY_Print, spawn, SHCMD("path/to/scripts/screenshotselcopy.sh") },
    ...
    };

This maps taking screenshots to the `Print` key, taking screenshots with a selection box to the `Shift+Print` keys, and finally taking screenshots then copying it to the clipboard with `Ctrl+Print` keys.

Note

- If layer animations are patched onto a build of dwl, it may be required to disable those specifically for slurp as grim will end up capturing the selector borders as well.
- All scripts above will need executable permissions, make sure to apply that to them. Additionally, there are a few prerequisites, install grim, slurp, and wl-clipboard for them to function properly.

### Adjusting volume

install pipewire-pulse, or pulseaudio, then add these options for volume management:

    /path/to/config.def.h

    static const char *up_vol[]   = { "pactl", "set-sink-volume", "@DEFAULT_SINK@", "+10%",   NULL };
    static const char *down_vol[] = { "pactl", "set-sink-volume", "@DEFAULT_SINK@", "-10%",   NULL };
    static const char *mute_vol[] = { "pactl", "set-sink-mute",   "@DEFAULT_SINK@", "toggle", NULL };

    static const Key keys[] = {
    ...
    { 0, XKB_KEY_XF86AudioRaiseVolume, spawn, {.v = up_vol } },
    { 0, XKB_KEY_XF86AudioLowerVolume, spawn, {.v = down_vol } },
    { 0, XKB_KEY_XF86AudioMute, spawn, {.v = mute_vol } },
    ...
    };

### Autostart

A patch is available, that allows you to autostart specified applications. One such example can be seen below:

    /path/to/config.def.h

    /* Autostart */
    static const char *const autostart[] = {
        "wbg", "/path/to/your/image", NULL,
        NULL /* terminate */
    };

You can specify more applications by adding them to the list, each entry comma-separated and followed by `NULL`. For example, you could start a bar, a notification daemon, or any background service you need. Just make sure each command and its arguments are properly quoted.

### Better mouse resizing

By default when resizing dwl will warp the cursor to the bottom right corner, with a patch this behavior can be changed.

That patch allows you to configure window resizing to be more flexible, instead of warping to the bottom right corner it comes with multiple modes:

- Warping the cursor to a selected corner.
- Locking the cursor in place while resizing.
- Disabling cursor warping altogether.
- Relative corner resizing, with this whichever corner the cursor is closest to is the one that will be resized.

A working configuration example of this patch can be found below:

    path/to/config.def.h

    /* resize_corner:
     * 0: top-left
     * 1: top-right
     * 2: bottom-left
     * 3: bottom-right
     * 4: closest to the cursor
     */
    static const int resize_corner = 4;
    static const int warp_cursor = 0;	/* 1: warp to corner, 0: don’t warp */
    static const int lock_cursor = 0;	/* 1: lock cursor, 0: do not lock */

With this, when resizing the corner closest to the cursor will be selected, the cursor will not warp, and finally the cursor will not lock itself in place.

## Troubleshooting

### Fixing misbehaving Java applications

See Java#Gray window, applications not resizing with WM, menus immediately closing.

### Fixing gaps around terminal windows

If there are empty gaps of desktop space outside terminal windows, it is likely due to the terminal's font size. Either adjust the size until finding the ideal scale that closes the gap, or toggle `resizehints` to 0 in `config.h`.

This will cause dwl to ignore resize requests from all client windows, not just terminals. The downside to this workaround is that some terminals may suffer redraw anomalies, such as ghost lines and premature line wraps, among others.

Alternatively, if you use the st terminal emulator, you can apply the anysize patch and recompile st.

## See also

- bemenu - A wayland native alternative to dmenu.
- An introduction to dwl.
- dwls git repository.

Category:

- Wayland compositors

dwl
Add topic