natemaia / dk

X11 window manager
MIT License
20 stars 0 forks source link

A list based tiling window manager in the vein of dwm, bspwm, and xmonad.

Some basics:

Installation

You need the xcb headers

Arch

xcb-proto xcb-util xcb-util-wm xcb-util-cursor xcb-util-keysyms

Void

libxcb-devel xcb-proto xcb-util-devel xcb-util-wm-devel xcb-util-cursor-devel xcb-util-keysyms-devel

Debian/Ubuntu

libxcb-randr0-dev libxcb-util-dev libxcb-icccm4-dev libxcb-cursor-dev libxcb-keysyms1-dev libxcb-res0-dev

Other systems should have packages with similar names.

To compile run

make

Edit config.h if needed, then run (as root if needed)

make install

If at any time you want to uninstall, run

make uninstall

Updating

In order to update dk when built from source you can run

cd dk
git fetch
git reset --hard HEAD
git merge '@{u}'
make
sudo make install

Keybinds

As mentioned above dk has no keybind support so you'll need a program like
sxhkd, xbindkeys, etc. to launch programs and control the window manager.
We'll install sxhkd because the example config uses it.

Arch/Debian/Ubuntu/Void/etc.

sxhkd

Usage

To start dk you can add the following to your ~/.xinitrc

exec dk

Optionally copy the example dkrc and/or sxhkdrc to ~/.config/dk/

mkdir -p ~/.config/dk
cp /usr/local/share/doc/dk/dkrc ~/.config/dk/
cp /usr/local/share/doc/dk/sxhkdrc ~/.config/dk/

Configuration

There are example dkrc and sxhkdrc files in doc/ or
/usr/local/share/doc/dk after installation.

dk looks for an rc file in the following order

$DKRC                     # user specified location
$HOME/.config/dk/dkrc     # default location

and tries to run it, it must be executable in order for this to happen.

Advanced changes and configuration like new layouts, callbacks, or commands
can be done by copying the default config header config.def.h to config.h,
editing it and recompiling. This file isn't tracked by git so you can keep your
configuration and avoid conflicts when pulling new updates.

dkcmd

Most of your interaction with the window manager will be using dkcmd
which writes one or more commands into the socket where it is then read
and parsed by the window manager (see Commands section below).

dkcmd accepts one flag with an optional file argument

dkcmd status type=bar num=1 | dkcmd -p

# or
dkcmd -p output.json

Syntax Outline

The commands have a very basic syntax and parsing, the input is broken
down into smaller pieces (tokens) which are then passed to the matching
keyword function, otherwise an error is returned.

Tokens are delimited by one or more:

This means the following inputs are all equivalent.

setting=value
setting value
setting="value"
setting = 'value'
setting "value"
setting     "value"

and result in two tokens: setting and value


Quotation exists as a way to preserve whitespace and avoid interpretation by the shell,
otherwise we have no way of determining whether an argument is a continuation of the
previous or the beginning of the next. Consider the following

title="^open files$"

If the value being matched has quotes in it, they can be escaped or strong quoted

title="^\"preserved quotes\"$"
title='^"preserved quotes"$'

For various commands dk will expect a certain data type or format to be given.


Commands

dkcmd COMMAND

WM

Ws and Mon

mon and ws operate on monitors and workspaces respectively.

ws  [SUBCOMMAND] [CLIENT] TARGET
mon [SUBCOMMAND] [CLIENT] TARGET
Subcommands

view View the TARGET, default if no subcommand is given.

ws view TARGET
ws TARGET

send Send CLIENT to the TARGET.

mon send [CLIENT] TARGET

follow Follow CLIENT to the TARGET.

ws follow [CLIENT] TARGET

Rule

rule operates on window rules.

rule [SUBCOMMAND] MATCH SETTING
Subcommands

apply applies RULE to all matching windows, if RULE is * apply all rules and MATCH is ignored.

rule apply RULE [MATCH]

remove removes RULE, if RULE is * remove all rules and MATCH is ignored.

rule remove RULE [MATCH]
Settings

class instance title type (string) regex to match the window class, instance, title, and
type respectively (may be prefixed with match_ for clarity). Regex matching is always done case insensitive
with extended regex mode enabled.

rule [SUBCOMMAND] class="^firefox$" instance="^navigator$" title="^mozilla firefox$" type=dialog [SETTING]

type currently only supports dialog and splash windows, all others are treated as normal windows.


ws (integer/string) determine what workspace the window should be on.

rule MATCH ws=1      # using index
rule MATCH ws=term   # using name

mon (integer/string) determine what monitor the window should be on.

rule MATCH mon=1          # using index
rule MATCH mon=HDMI-A-0   # using name

x y w width h height bw border_width (integer/string) determine the window location and size.

rule MATCH x=20 y=100 w=1280 h=720 bw=0         # using absolute values
rule MATCH x=center y=center w=1280 h=720 bw=0  # using gravities

callback (string) determine a callback function to be invoked on window open and close. These are defined in the config header and compiled into the source, one example is provided.

rule MATCH callback=albumart

float stick (boolean) determine if the window should be floating or stick respectively.

rule MATCH float=true stick=true

ignore_cfg (boolean) determine if the window should ignore configure request
events (size or location changes).

rule MATCH ignore_cfg=true

ignore_msg (boolean) determine if the window should ignore client message
window activation events (grabbing focus).

rule MATCH ignore_msg=true

focus (boolean) determine if the window should be focused and view it's workspace.
If mon is also set it will be activated first before viewing the workspace.

rule MATCH focus=true

terminal (boolean) determine if the window should be considered a terminal for
absorbing other windows and not being absorbed itself.

rule MATCH terminal=true

no_absorb (boolean) determine if the window should never absorb other windows.

rule MATCH no_absorb=true

scratch (boolean) determine if the window should be in the scratchpad.

rule MATCH scratch=true

Set

set operates on workspace or global configuration settings.

set [WS] SETTING
set ws=_ [apply] SETTING
Settings

numws (integer) change the number of workspaces to allocate.

set numws=10

name (string) change the WS name.

set ws=1 name="term"

static_ws (boolean) disable dynamic workspaces for multi-head systems.

set static_ws=false

mon (integer/string) change which monitor WS should be on (requires static_ws=true).

set ws=1 mon=HDMI-A-0
set ws=1 mon=1

master stack (integer) change the number of windows to occupy the master area (tile layout).

set [WS] stack  3            # absolute values have no signs
set [WS] master +1 stack -1  # relative change with signed integers (+/-)

msplit ssplit (float) change the workspace master or stack split ratios respectively.

set [WS] msplit +0.1
set [WS] ssplit 0.55

gap (integer) change the workspace gap width.

set [WS] gap 10

tile_hints (boolean) obey size hints in tiled layouts.

set tile_hints=true

tile_tohead (boolean) place new windows at the head of the list in tiled layouts.

set tile_tohead=true

smart_gap (boolean) whether gaps are disabled on workspaces with only one tiled window.

set smart_gap=true

smart_border (boolean) whether borders are disabled on workspaces with only one tiled window.

set smart_border=true

focus_urgent (boolean) focus windows that request it.

set focus_urgent=true

focus_open (boolean) whether windows are focused when opened.

set focus_open=false

focus_mouse (boolean) whether window focus follows the mouse.

set focus_mouse=false

obey_motif (boolean) whether to obey motif hints for borders.

set obey_motif=false

win_minxy (integer) amount of window (in pixels) to be kept on the screen when moving.

set win_minxy=20

win_minwh (integer) minimum window size.

set win_minwh=50

apply when changing the default _ workspace apply settings to existing real workspaces.

set ws=_ apply SETTING

layout (string) change the workspace window layout.

set [WS] layout mono

border change the window border sizes and colours.

set border w=5 ow=3 colour f='#6699cc' u='#444444' r='#ee5555' of='#222222' ou='#222222' or='#222222'

pad change the workspace padding.

set [WS] pad l=50 r=50 t=50 b=50

mouse change the mouse binds for move and resize (global, does not take a workspace).

set mouse move=button1 resize=button2 mod=mod1

Win

win operates on windows.

win [CLIENT] ACTION
Settings

cycle cycle windows in place.

win cycle

float change the window floating state.

win [CLIENT] float
win [CLIENT] float=false

full change the window fullscreen state.

win [CLIENT] full

fakefull change the window fake fullscreen state (allow moving, resizing, and tiling when fullscreen).

win [CLIENT] fakefull

stick change the window sticky state.

win [CLIENT] stick

swap change the window between it's current location and master.

win [CLIENT] swap

kill close the window.

win [CLIENT] kill

focus (integer/string) change the focused window.

win CLIENT focus  # focus window by id
win focus next    # focus the next window
win focus +2      # focus two windows ahead

scratch view or hide a scratchpad window.

With no other arguments

win scratch
win [CLIENT] scratch # same toggle behaviour but on the passed window
win [CLIENT] scratch push # push the given window or the active window.

mvstack (integer/string) move a tiled window around the stack.

win [CLIENT] mvstack up

resize change the window size, location, and border width.

win [CLIENT] resize x=100 y=100 w=1280 h=720 bw=1
win [CLIENT] resize x=center y=center w=1280 h=720 bw=1

Status

status print status information as JSON to a file or stdout.

status [TYPE] [FILE] [NUM]
Subcommands

type (string) the type of status info to output and when to trigger.

status type=ws [FILE] [NUM]

file (string) the location of the status file.

status file=/tmp/dk.status [TYPE] [NUM]

num (integer) the number of times to output, -1 is infinite and default if not specified.

status [TYPE] [FILE]        # output forever
status num=1 [TYPE] [FILE]  # output once

Todo

Contributing

I'm very open to contributions or ideas, please feel free to email me or open an issue/PR. For myself I have various builds that can help finding issues or provide some insight. These include:

stderr debug output

make debug

debug output and function calls

make fdebug

don't strip debug symbols (for gdb, valgrind, etc.).

make nostrip

Credits

See the LICENSE file for a list of authors/contributors.

Huge thanks to Kjetil Molteberg (@badkarma) for the logo.

Non contributors that I owe a huge thanks to: