Skip to main content

Module tree

Module tree 

Source
Expand description

Dwindle, as Hyprland actually does it: a tree, not a formula.

The arrangement people mean by “Hyprland tiling” cannot be written as a function of how many windows there are. Read addTarget in Hyprland’s DwindleAlgorithm.cpp and the reason is immediate: a new window splits a specific existing window — the one under the mouse, or the focused one — and the split runs across whichever axis that window’s own box is longer on. Two windows opened in a different order, or with the cursor somewhere else, give different layouts. There is no count to compute from.

So this is a binary tree. Leaves are windows; every branch remembers which way it was cut and where. Inserting replaces a leaf with a branch holding the old window and the new one. Removing replaces a branch with whichever child is left, which is what makes closing a window hand its space back to its neighbour rather than reshuffling the screen.

Per-branch ratios are the other half of it: resizing a window moves one seam, and everything on the far side of the tree stays exactly where it is.

Tiling::insert splits the tile it is pointed at however small that tile already is, so tiles go on halving for as long as windows keep opening. Settings::minimum is the floor (#134). insert still ignores it, because it is what a layout falls back to when nothing else will do; the two insert_* methods beside it refuse a split that would go under it, so a layout can try them first, and the seam movers will not move a seam to take a tile under it either.

A window’s own floor is the other bound (#115): what its application says it cannot go under, frame included, handed in with Tiling::set_floors. It is the one thing that moves a seam nobody dragged. Tiling::layout lays a split out at its own ratio, then moves it just far enough for a side under a window’s floor to reach it, taking the room from the other side down to its floors and Settings::minimum, and no further. The ratio the branch holds is left as it was, so a window whose floor goes away hands the room back and the arrangement is the one the user made. Where the room is not there, the window is laid out short and Tiling::cramped says so. The splits and the seams are held to the same floors: insert_fitting and insert_largest refuse a split that would put a window under its own, and a seam stops at the floors on either side of it. Each of those sentences is a test in floor_tests.

Structs§

Need 🔒
What a subtree asks of the room along one axis: the least it must have for every window in it that has a floor of its own to be at that floor, and the least it will give up.
Tiling
A dwindle tree.

Enums§

Axis
Which way a branch was cut.
Edge
Which side of a window was grabbed.
Node 🔒

Constants§

SLACK 🔒
How far under the minimum a tile may come out and still count as at it.

Functions§

cut 🔒
goes_second 🔒
Whether a window added to rect across axis takes the second child: the half the pointer is in, and the far side by default.
holds 🔒
Whether half is at least a window’s floor and the minimum, both ways.
length 🔒
A size read from a caller as a size: a finite length of more than nothing, and anything else as no size at all.
need_of 🔒
What a window with floor asks of the room along axis: its own floor to pull towards, and the larger of that and the minimum to give down to.
shared 🔒
The ratio a split of rect across axis is drawn at, when it holds ratio and its two children ask first and second of the room (#115).
within 🔒
value held to low..=high, or otherwise when that range is empty.