Commit Graph
5 Commits
Author SHA1 Message Date
LGUG2Z f5933d1ff8 feat(wm): drag to swap
A window the user drags with the pointer onto the tile of another window swaps
places with it, and a window let go where there is no tile goes back to its own.
It is the first thing komorebi does about what the user does with the pointer.

KWin reports the start and the end of a drag on the window
(interactiveMoveResizeStarted and Finished). The bridge sends both with the
window's frame, and the end with the position of the pointer: the window manager
asks where the pointer is right after a drag, and when the bridge does not
answer that in time, the table's last position is the one the drag ended at. The
table turns a move into MoveStart and MoveEnd; a resize raises nothing yet. The
bridge also stops asking KWin again for the position komorebi gave the window,
which is the user's now.

Where the window is let go decides the rest. On another monitor it goes there,
with its stack, in the place of the container under the pointer. With the window
container behavior Append it joins the container under the pointer instead of
swapping with it, and with the float override on it floats where it was let go.
A terminal that keeps its frame a few pixels short of its tile is not taken for
a move on its own monitor, as in the spike; the usage page says so.
2026-10-28 07:20:49 -07:00
LGUG2Z 189aeb1005 feat(wm): more than one monitor
Every monitor has workspaces of its own, which KWin's per-output desktops show
independently, so a second monitor is mostly the window manager's business:
which monitor has the focus, and how a window gets from one to the other.

At the edge of a monitor, focus and move now cross to the monitor on that side,
where they used to fail with "there is no container in this direction": the
focus lands on the container nearest the monitor it came from, and a move swaps
with the container at that edge (cross-monitor-move-behaviour insert puts it in
among the containers there, no-op keeps it). A window that opens or gets the
focus on a monitor that is not the focused one focuses that monitor, which also
makes the scrolling test of a strip next to another monitor guard real code.

The monitor commands come with it: focusing a monitor by index, in order or
under the pointer, a workspace of another monitor, moving and sending the
focused window to another monitor, to a workspace of it or to a named workspace
(in the window manager these are moves between monitors, so they were left out
of the workspace commands), moving and swapping workspaces between monitors, and
a display index preference that keeps a monitor at the index the user gives it.
eager-focus focuses the first window of an executable on any workspace of any
monitor; its window is found in a container or among the floating windows, the
two places a window can be until stacks, monocle and maximize exist.
2026-10-28 07:20:37 -07:00
LGUG2Z 3cc5dceb7d feat(wm): lock
Containers can be locked since the model came in, and a locked container keeps
its index while others are inserted, removed or swapped around it; nothing could
lock one. `komorebic toggle-lock` locks the focused container, or unlocks it,
and the `LockMonitorWorkspaceContainer` and `UnlockMonitorWorkspaceContainer`
messages lock and unlock a container by the index of its monitor, its workspace
and itself, for a program such as a status bar.

The vm-commands sweep locks and unlocks a container.
2026-10-28 07:20:37 -07:00
LGUG2Z 554d77aed9 feat(wm): promote
The first tile of a layout is its largest, and the place for the window being
worked on. `komorebic promote` moves the focused window there, with the windows
that were before it each moving one tile on; `promote-swap` swaps it with the
window that has the first tile, and from the first tile swaps it back with the
window it was last swapped with; `promote-window left|right|up|down` promotes
the window on that side of the focused one; and `promote-focus` gives the focus
to the first tile and moves nothing.

The grid layout has no largest tile, so the four do nothing there.

The vm-commands sweep gains the four.
2026-10-28 07:20:37 -07:00
LGUG2Z 1bbb534844 feat(wm): move and cycle containers
With the focus moving, the next thing a key has to do is move the focused
window. `komorebic move left|right|up|down` swaps the focused container with the
one whose tile is on that side, as the layout sees it, and `komorebic cycle-move
next|previous` with the next or the previous one in the workspace's order. The
workspace is tiled again, the window that moved keeps the focus, and the pointer
follows it.

The swap goes through the lockable sequence, so a lock stays with its index: the
container moved onto a locked index is locked in its place.

Moving towards a side with no window fails and moves nothing. Moving into the
next monitor comes with more than one monitor, and the floating layer's own move
with the floating layer.

The VM test moves a window in a real KWin and back, and checks that KWin has
every window where komorebi asked.
2026-10-28 07:20:37 -07:00