Skip to content

swallow

bakkeby edited this page Aug 5, 2024 · 4 revisions

This patch adds "window swallowing" to dwm in a similar manner to the Plan 9 window system rio.

Clients marked with isterminal in config.h swallow a window opened by any child process, e.g. running xclock in a terminal. Closing the xclock window restores the terminal window in the current position.

Window swallowing helps users spawning a lot of graphical programs from their command line by avoiding cluttering the screen with many unusable terminals.

This patch is directly based on the swallow patch on the suckless website with some significant differences.

The original patch works by replacing the actual window of the terminal client with that of the swallowed window. When the swallowed window is closed the terminal client is restored with the window it originally had.

This works relatively well, but this solution has complications when it comes to size hints. As an example the swallowed window could set size hints that define the minimum or maximum size of the Client which again would apply to the next swallowed window.

What this patch does differently is that instead of exchanging client windows the clients themselves are swapped in the client list. The benefit of this is that the properties of the terminal client and the properties of the swallowed client are isolated from each other.

One side effect of this is if the terminal client is floating then the size and position of the swallowed client may not be the same because the new window could be sending ConfigureRequest events to specify its desired size and position. Because of this two options ignorecfgreqpos and ignorecfgreqsize has been added. They are flags to specifically indicate that configure requests to change the position and size, respectively, should be ignored for the client. As this is very specific only the former is explicitly used in the swallow function and no additional options have been added to config.h.

This patch also improves on multi-monitor support when it comes to window swallowing.

Configuration

Client rule options:

  • isterminal - only clients marked with isterminal = 1 are allowed to swallow windows
  • noswallow - if set to 1 then the window should never be swallowed by a terminal (e.g. xev)

The swallowfloating option in config.h if set to 1 then floating windows will be swallowed. If set to 0 then floating windows will not be swallowed. Effectively this means that if the option is set to 0 then this overrides the noswallow client rule (like as if this is set to 1 for all floating windows).

By default the terminal window will inherit the fullscreen property of the graphical window when unswallowed. This can be disabled by setting the swterminheritfs option in config.h to 0.

Fullscreen compatibility

In general the window swallowing functionality should be intuitive with the floating, tiled and fullscreen states seamlessly transitioning between clients on swallow and unswallow giving the illusion that it is the same window.

As such there is no need to pay attention to the below, but if there should be any doubt about what the expected behaviour is in certain scenarios then the below tables should cover it.

Expected behaviour with config swterminheritfs = 1 (default).

Terminal before Swallowing window >> State at unswallow Terminal after
Tiled Tiled >> Tiled Tiled
Tiled Tiled >> Floating (x y w h) Floating (x y w h)
Tiled Tiled >> Fullscreen (tiled) Fullscreen (tiled)
Tiled Tiled >> Fullscreen (floating) Fullscreen (floating)
Floating (x y w h) Floating (x y w h) >> Tiled Tiled
Floating (x y w h) Floating (x y w h) >> Floating (a b c d) Floating (a b c d)
Floating (x y w h) Floating (x y w h) >> Fullscreen (tiled) Fullscreen (tiled)
Floating (x y w h) Floating (x y w h) >> Fullscreen (floating) Fullscreen (floating)
Fullscreen (tiled) Fullscreen (tiled) >> Tiled Tiled
Fullscreen (tiled) Fullscreen (tiled) >> Floating (x y w h) Floating (x y w h)
Fullscreen (tiled) Fullscreen (tiled) >> Fullscreen (tiled) Fullscreen (tiled)
Fullscreen (tiled) Fullscreen (tiled) >> Fullscreen (floating) Fullscreen (floating)
Fullscreen (floating) Fullscreen (floating) >> Tiled Tiled
Fullscreen (floating) Fullscreen (floating) >> Floating (x y w h) Floating (x y w h)
Fullscreen (floating) Fullscreen (floating) >> Fullscreen (tiled) Fullscreen (tiled)
Fullscreen (floating) Fullscreen (floating) >> Fullscreen (floating) Fullscreen (floating)

Expected behaviour with config swterminheritfs = 0.

Terminal before Swallowing window >> State at unswallow Terminal after
Tiled Tiled >> Tiled Tiled
Tiled Tiled >> Floating (x y w h) Floating (x y w h)
Tiled Tiled >> Fullscreen (tiled) Tiled
Tiled Tiled >> Fullscreen (floating) Floating (x y w h)
Floating (x y w h) Floating (x y w h) >> Tiled Tiled
Floating (x y w h) Floating (x y w h) >> Floating (a b c d) Floating (a b c d)
Floating (x y w h) Floating (x y w h) >> Fullscreen (tiled) Tiled
Floating (x y w h) Floating (x y w h) >> Fullscreen (floating) Floating (x y w h)
Fullscreen (tiled) Fullscreen (tiled) >> Tiled Tiled
Fullscreen (tiled) Fullscreen (tiled) >> Floating (x y w h) Floating (x y w h)
Fullscreen (tiled) Fullscreen (tiled) >> Fullscreen (tiled) Fullscreen (tiled)
Fullscreen (tiled) Fullscreen (tiled) >> Fullscreen (floating) Fullscreen (floating)
Fullscreen (floating) Fullscreen (floating) >> Tiled Tiled
Fullscreen (floating) Fullscreen (floating) >> Floating (x y w h) Floating (x y w h)
Fullscreen (floating) Fullscreen (floating) >> Fullscreen (tiled) Fullscreen (tiled)
Fullscreen (floating) Fullscreen (floating) >> Fullscreen (floating) Fullscreen (floating)

Dependencies

  • libxcb
  • Xlib-libxcb
  • xcb-res

These dependencies are needed due to the X Resource Extension which is unsupported in vanilla Xlib.

Notes

The window swallowing functionality requires dwm to walk the process tree, which is an inherently OS-specific task.

Only terminals created by local processes can swallow windows, and only windows created by local processes can be swallowed.

swallow.gif

Download

Clone this wiki locally