Skip to content
This repository has been archived by the owner on Sep 29, 2021. It is now read-only.
phillbush edited this page Mar 10, 2021 · 15 revisions

SHOD(1)

NAME

shod - hybrid window manager

SYNOPSIS

shod

DESCRIPTION

shod is an hybrid (tiling and floating) reparenting and themeable multimonitor X11 window manager. shod sets no keybindings; reads no configuration other than X resources; and works only via mouse with a given key modifier (Alt by default) and by responding to client messages with EWMH hints (so you have to use wmctrl(1) to control shod).

shod maintains one monitor for each physical monitor found by Xinerama(1). One of the monitors is the focused one, where new windows go to when they are created. Each monitor contains a set of desktops. One of the desktops of a monitor is the focused desktop for that monitor. shod manages desktop just like how GNOME implements “actions”. If a window is open on the last empty desktop, shod creates a new empty desktop on that monitor. When a desktop has no window, this desktop is deleted.

Each window has one of the following four states:

  • Minimized

    Minimized windows belong to no monitor or desktop. Minimized windows are not shown on the screen. When a minimized window is unminimized, it becomes a normal window on the focused desktop of the focused monitor.

  • Sticky

    Sticky windows belong only to a monitor; but they do not belong to any desktop. Instead, they are "sticked" to the monitor, and they appear on the screen no matter which desktop is focused on that monitor.

  • Tiled

    Tiled windows belong to a desktop and its monitor. The monitor is divided into columns, each window occupies a row in a column. (This tiling style is the same used by the old wmii(1) window manager and the acme(1) editor).

  • Normal

    Normal windows belong to a desktop and its monitor. Normal windows, just like sticky windows, are floating windows. Normal windows appear only when its desktop is the focused one for its monitor.

A non-minimized window can also be made fullscreen. A floating (sticky or normal) window can also be raised above other floating windows or lowered below other floating windows.

When a new window spawns, it is set as Normal, and it is placed in an unoccupied region of the monitor. The first window in a monitor is spawned in the center of the monitor.

The window stacking order is the following (from bottom-to-top):

  • Tiled windows appear below any other windows.
  • Lowered floating windows appear on top of tiled windows.
  • Regular floating windows appear on top of lowered floating windows.
  • Raised floating windows appear on top of regular floating windows.
  • Fullscreen windows appear on top of raised floating windows.

USAGE

shod has several ways of manipulating windows. See the section EXAMPLES for examples on how to use wmctrl(1) for controlling shod.

Manipulating with the mouse

The main method for controlling windows is the mouse.

The config.focusbuttons variable (set at compile time in config.h) specifies which mouse buttons can be used to focus a window when clicking on it. Each bit represents a button. For example, if it is set to 5 (0101 in binary), a window is focused when clicking on it with the first or the third mouse button. If this variable is set to 0, the focus follows the mouse pointer.

The config.raisebuttons variable (set at compile time in config.h) specifies which mouse buttons can be used to raise a window when clicking on it. Each bit represents a button. If this variable is set to 0, all buttons raises a window.

The config.modifier variable (set at compile time in config.h) specifies the modifier key. Pressing the modifier key and dragging a window with the Button 1 (the left mouse button) will move that window. Pressing the modifier key and dragging a corner or side of a window with the Button 3 (the right mouse button) will resize that window in the direction of that corner or side.

Resizing windows can also be performed by dragging a window border with the Button 1, without pressing any modifier. Moving windows can also be performed by dragging a window border with the button 3, without pressing any modifier.

Manipulating via window properties

The wmctrl(1) utility can be used to set window properties, and shod respects and sets those properties in different ways. For example, running the following command toggles the sticky option on the active window.

$ wmctrl -r :ACTIVE: -b toggle,sticky
  • If the sticky property is set on a window, this window becomes sticky (it is displayed on all desktops of the monitor the window is in).
  • If the maximize_vert and maximize_horz properties are set on a window, the window is tiled. For more information on manipulating tiled windows, see the section Manipulating tiled windows below.
  • If the hidden property is set on a window, the window becomes minimized (it won't be displayed on any desktop or on any monitor).
  • If the fullscreen property is set on a window, the window is maximized to fit the entire screen.
  • If the above property is set on a floating window, the window is raised above all other floating windows.
  • If the below property is set on a floating window, the window is lowered below all other floating windows.

All other properties are ignored.

Manipulating via other client messages

shod acts upon other client messages sent to windows and to the root window. Most client messages can be sent via wmctrl(1) with a specific option. The options and the messages they send are specified below.

  • A message sent with the -s NUMBER option of wmctrl(1) makes shod changes the desktop. That is, hide the windows on the current desktop and show the windows on a new desktop. If the desktop is on another monitor, shod instead move the pointer to that monitor and focus a window on it.
  • A message sent with the -k on or -k off options of wmctrl(1) makes shod show or hide the desktop, respectively.
  • A message sent with the -a WINDOW option of wmctrl(1) makes shod change the active window. That is, focus and raise the specified window.
  • A message sent with the -c WINDOW option of wmctrl(1) makes shod close gently the specified window.
  • A message sent with the -e POSITION option of wmctrl(1) makes shod change the position and geometry of the specified window.
  • A message sent with the -s NUMBER option of wmctrl(1) makes shod send a specified window to a specified desktop.
  • A message sent with the -t NUMBER option of wmctrl(1) makes shod move the specified window to the specified desktop.

Manipulating via configure request

shod acts upon configure request events sent to windows via by resizing and moving windows just as if the user have resized or moved them with the mouse.

When a window is moved from one monitor to another, that window moves from the desktop it is in to the focused desktop of the monitor it is moved to.

Manipulating tiled windows

When a window is maximized, it is tiled by shod. A tiled window behaves differently of regular windows. The tiled windows are organized in columns. Each tiled window ocupies a row in a column.

In order to move a tiled window from one column to another just move the window left or right with wmctrl(1) or with the mouse. This will move the window from its current column to the column to its left or right, or it will create a new column, if needed.

In order to move a tiled window up or down a column, just move the window up or down with wmctrl(1) or with the mouse.

Resizing a tiled window with wmctrl(1) or with the mouse will change the size of the window, the size of the column it is in, and the size of the neighboring windows.

ENVIRONMENT

The following environment variables affect the execution of shod

  • DISPLAY

    The display to start shod on.

RESOURCES

shod understands the following X resources.

  • shod.borderWidth

    The size in pixels of the border around windows.

  • shod.cornerWidth

    The size in pixels of the corners of the windows.

  • shod.decoration

    Path to a .xpm file containing the border decorations. If this resource is not present, or if the .xpm file is not in the correct format, shod use solid colors for the borders instead. A sample .xpm file is distributed with shod. The resources shod.borderWidth and shod.cornerWidth should be set accordingly to the size of the decoration on the .xpm file.

  • shod.gapOuter

    The gap in pixels between the sides of the monitor and the windows.

  • shod.gapInner

    The gap in pixels between the tiled windows.

  • shod.ignoreGaps

    If set to “true”, a single tiled window ingores the gaps.

  • shod.ignoreBorders

    If set to “true”, a single tiled window does not have borders.

  • shod.focused

    The color of the focused window.

  • shod.unfocused

    The color of the regular, non-focused windows.

  • shod.urgent

    The color of urgent windows.

EXAMPLES

The following is a sample configuration for X resources. It must be placed in $HOME/.Xresources or $HOME/.Xdefaults or other file called by xrdb(1). This example makes shod draw a 3 pixels wide border around windows, and a 7 pixels wide gap around and between tiled windows. It sets the color of the border of urgent windows to red; the border of the focused window to blue; and the border of regular windows to gray.

shod.borderWidth:   3
shod.gapOuter:      7
shod.gapInner:      7
shod.urgent:        #cc0000
shod.focused:       #3465a4
shod.unfocused:     #555753

The following is a sample configuration for sxhkd(1), a program that binds keypresses (or key releases) to commands. This example uses wmctrl(1) for sending EWMH hints to shod. It uses wmr(1) (a script shown below) for moving and resizing windows, respectively.

# Start terminal (urxvt)
mod1 + Return
	xterm

# Killing windows
mod1 + shift + q
	wmctrl -c :ACTIVE:

# Workspace
mod1 + {1,2,3,4,5,6,7,8,9}
	wmctrl -s {0,1,2,3,4,5,6,7,8,9}
mod1 + shift + {1,2,3,4,5,6,7,8,9}
	wmctrl -r :ACITVE: -t {0,1,2,3,4,5,6,7,8,9}

# Resize/move windows with wmr
mod1 + {c, v, shift + c, shift + v}
	wmr 0 0 {-25 0, 0 -25, +25 0, 0 +25}
mod1 + shift + {h, j, k, l}
	wmr {-10 0, 0 10, 0 -10, 10 0} 0 0

# Change window status to sticky/above/below/minimized/fullscreen/maximized
mod1 + shift + {s, a, b, z, f}
	wmctrl -r :ACTIVE: -b toggle,{sticky,above,below,hidden,fullscreen}
mod1 + shift + t
	wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz

# Call the unminimize.sh script
mod1 + shift + u
	unminimize.sh

The previous example binds the following keys to the following commands:

  • Mod4 + Enter

    Spawns a terminal emulator window.

  • Mod4 + Shift + Q

    Gently closes the active windows.

  • Mod4 + <N>

    Go to the N-th desktop.

  • Mod4 + Shift + <N>

    Send active window to the N-th desktop.

  • Mod4 + C

    Shrink the active window horizontally by 25 pixels.

  • Mod4 + Shift + C

    Expand the active window horizontally by 25 pixels.

  • Mod4 + V

    Shrink the active window vertically by 25 pixels.

  • Mod4 + Shift + V

    Expand the active window vertically by 25 pixels.

  • Mod4 + Shift + H

    Move the active window 10 pixels to the left.

  • Mod4 + Shift + J

    Move the active window 10 pixels down.

  • Mod4 + Shift + K

    Move the active window 10 pixels up.

  • Mod4 + Shift + L

    Move the active window 10 pixels to the right.

  • Mod4 + Shift + S

    Make the active window sticky; or make it normal if it was sticky.

  • Mod4 + Shift + A

    Raise the active window above the others; or move it to its normal place if it was already above others.

  • Mod4 + Shift + B

    Lower the active window below the others; or move it to its normal place if it was already below others.

  • Mod4 + Shift + Z

    Hide the active window.

  • Mod4 + Shift + F

    Make the active window fullscreen; or make it normal if it was already fullscreen.

  • Mod4 + Shift + T

    Tile the active window; or make it floating if it was already tiled.

  • Mod4 + Shift + U

    Call the unminimize.sh script (see below).

The following is a sample script for dmenu(1). This script lists the minimized windows and unminimizes the selected one. This script uses xprop(1) to obtain the X properties set by shod.

#!/bin/sh

lsw() {
	xprop -notype -f "_NET_CLIENT_LIST" 0x \(aq $0+\n\(aq -root "_NET_CLIENT_LIST" |\
	cut -d\(aq \(aq -f2- |\
	sed \(aqs/, */\
/g\(aq
}

ishidden() {
	xprop -notype -f "_NET_WM_STATE" 32a \(aq $0+\n\(aq -id "$1" "_NET_WM_STATE" |\
	cut -d\(aq \(aq -f2- |\
	sed \(aqs/, */\
/g\(aq | grep -q "_NET_WM_STATE_HIDDEN"
}

printname() {
	name="$(xprop -notype -f "_NET_WM_NAME" 8s \(aq $0+\n\(aq -id "$1" "_NET_WM_NAME" 2>/dev/null)"
	[ "$(echo $name)" = "_NET_WM_NAME: not found." ] && \
	name="$(xprop -notype -f "WM_NAME" 8s \(aq $0+\n\(aq -id "$1" "WM_NAME" 2>/dev/null)"

	echo $name |\
	cut -d\(aq \(aq -f2- |\
	sed \(aqs/, */\
/g\(aq
}

for win in $(lsw)
do
	ishidden $win && printf "%s: " $win && printname $win
done |\
dmenu -i -l 8 -p "unminimize window:" |\
cut -d: -f1 |\
xargs wmctrl -b toggle,hidden -ir

The following script moves and resize the active window by a relative amount of pixels.

#!/bin/sh
# wmr: move and resize window relative to its current position and size

set -e

usage() {
	echo "usage: wmr x y w h" >&2
	exit 1
}

[ $# -ne 4 ] && usage
eval $(xdotool getactivewindow getwindowgeometry --shell)
xadd=$1
yadd=$2
wadd=$3
hadd=$4
X=$(( X + xadd ))
Y=$(( Y + yadd ))
WIDTH=$(( WIDTH + wadd ))
HEIGHT=$(( HEIGHT + hadd ))
wmctrl -r :ACTIVE: -e 0,$X,$Y,$WIDTH,$HEIGHT

SEE ALSO

dmenu(1), sxhkd(1), wmctrl(1),

BUGS

Yes.

Clone this wiki locally