Commit Graph
3 Commits
Author SHA1 Message Date
LGUG2Z c03e5d2970 feat(wm): the neighbours follow the drag
While the user drags an edge of a tiled window, the tiles next to it follow, and
not only once it is let go.

KWin reports every step of a resize with the frame the pointer asks for. The
bridge passes one on every 16 ms at most, the newest, with a single-shot timer
for the last one of a burst, and the window manager keeps at most one step
waiting, since each says where the edge is now. ResizeStart keeps the layout as
it is when the user takes hold (LiveResize), and every step and the end are
worked out from it: a drag ends the same with its steps as without them, and one
that is taken back puts the neighbors back. The dragged window is the user's
until they let go, so Window::set_position leaves the windows being resized
alone, whatever tiles the workspace.

vm-live-resize holds the edge part way and all the way and reads the neighbors
while the button is down. With the neighbors following, KWin's window snapping
pulled a dragged edge 9 pixels past the pointer in vm-drag-resize, since the gap
between two tiles is inside its default zone, so both drag suites turn snapping
off; PLATFORM.md and drag-resize.md say so. Like vm-drag-resize, it drags
against the daemon the module starts with the session, and reads the drags that
daemon has handled from the unit's journal.

vm-live-resize waits for the panel's room (Kde.wait_for_panel_room) before it
opens the windows. The daemon learned of the room while the pointer was down in
a first case that had begun without it, and the retile that came with it moved
the neighbor, not the pointer.
2026-10-28 07:20:57 -07:00
LGUG2Z af560f47d7 feat(wm): resize by dragging an edge
Dragging an edge or a corner of a tiled window resizes its tile when the user
lets go: each edge of the tile moves by what the pointer moved it, the neighbors
give up or take the room, and the window is put on its tile.

A drag is measured from the frame the window had when the user took hold of it,
edge by edge, and resizes the container of the window that was dragged, through
resize_window and so within its bound (no tile below a tenth of the work area).
KWin reports the window's frame all through a drag, so the table keeps the frame
of the start for the window manager (Backend::drag_origin). At the end the frame
can still be short of the pointer, because KWin changes it once the client has
drawn at the new size; the bridge keeps the frame the last step of the drag
asked for and sends it as `requested`, and the end of a resize is that frame.
The window of a stack has the tile of the stack; a floating window and the
window of a monocle have none, and are left as the user made them.

The end of a resize is read apart from the window's frame, and that deviates
from the spike. The spike stores the frame the last step asked for as the
window's own frame, where the next frame event replaces it. KWin sends one a
millisecond after the end, with what the client has drawn so far (660 pixels of
the 672 asked for), and a window manager that is busy with an earlier event
reads that frame when it handles the end: a tile moved by 60 pixels for a drag
of 72. Here the table keeps the end apart (Table::drag_end, and
Backend::drag_end for the window manager, None by default), ResizeEnd reads it
as ResizeStart reads drag_origin, and the window's frame stays the one KWin
reports. A resize that sent no step ends at the frame. The order that failed is
a test of the KWin backend with the real table and window manager, in which the
tile took 140 of the 200 pixels without this.

komorebi-layouts at the pinned revision has the fix of LGUG2Z/komorebi#1765, so
nothing is vendored, and docs/drag-resize.md says what a drag does and why each
rule is there. vm-drag-resize drags edges and corners of three tiles with the
pointer that the session node has (komorebi_vm.Pointer), whose moves are batched
in the guest. The suite drags against the daemon the module starts with the
session, and reads the drags that daemon has handled from the unit's journal.

vm-drag-resize waits, for 30 seconds at most, for the daemon to have the room
KWin takes for the panel before it opens the windows (Kde.wait_for_panel_room).
The panel moved every tile in the middle of a case that began before the daemon
learned of it, which showed as an edge that was not dragged. It is a wait and
not a check, since a session that is too slow may never take the room.
2026-10-28 07:20:57 -07:00
LGUG2Z 95eb4d5039 feat(wm): resize from the CLI
`komorebic resize-edge left|right|up|down increase|decrease` moves one edge of
the focused tile, and `resize-axis` both edges along an axis, by the delta that
`resize-delta` sets (50 pixels to start with; komorebi-layouts moves an edge by
half of it). The neighbors give up the room.

A resize is an adjustment of the container's tile that the workspace keeps, one
per container, and that the layout applies whenever it tiles. Before each
tiling, the workspace clears the parts its layout cannot apply, such as the
height of a column. No tile may end up narrower or shorter than a tenth of the
work area, or than it already is: a resize that would make one so is granted as
far as it can go, not dropped.

`retile` drops the adjustments, and the `RetileWithResizeDimensions` message
tiles with them. `save-resize` and `load-resize` write them to a file and read
them back, and `quick-save-resize` and `quick-load-resize` do the same with one
file in the daemon's temporary directory.

The vm-commands sweep gains every resize command, and the saving and loading.
2026-10-28 07:20:37 -07:00