diff options
| author | user <user@clank> | 2026-08-14 20:52:17 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-14 20:52:17 +0200 |
| commit | a8cd32986134c2ba516a11c64dc474dd79855b0d (patch) | |
| tree | 246817144348f42badcec4158592dac65b12396b /src | |
| parent | sl0ppty: hold the boundaries, not a seat number (diff) | |
| download | slosh-a8cd32986134c2ba516a11c64dc474dd79855b0d.tar.gz slosh-a8cd32986134c2ba516a11c64dc474dd79855b0d.tar.xz slosh-a8cd32986134c2ba516a11c64dc474dd79855b0d.zip | |
sl0ppty: every place the boundaries meet is a crossing
Resizing one row of a two-by-two puts its column boundary out of line with the
one below, which should leave two crossings on the row boundary, one for each.
Only one was found.
find_corners took the first column boundary it saw and then accepted others
only if they occupied exactly the same columns, which is the aligned case and
nothing else: anything out of line was discarded rather than becoming a
crossing of its own. It groups by the columns a boundary occupies now, so
aligned pairs are one crossing that moves both — still the case worth having,
since moving one of a matched pair would put a step in what reads as one line —
and everything else is its own crossing moving its own boundary.
The test starts aligned, moves one row's boundary, and checks the second
crossing appears and that dragging it leaves the other row alone.
Diffstat (limited to 'src')
| -rw-r--r-- | src/app.c | 43 |
1 files changed, 30 insertions, 13 deletions
@@ -2510,14 +2510,16 @@ static void find_corners(app_t *a) { struct gapinfo g[64]; size_t n = collect_gaps(cur(a)->root, g, 64, 0); - for (size_t i = 0; i < n && a->ncorners < 16; i++) { + /* Every place a column boundary runs into a row boundary is its own + * crossing. Two of them that happen to line up are one crossing with two + * boundaries to move; two that do not are two crossings, each moving its + * own. Grouping by the columns they occupy gets both, where taking the first + * and discarding anything unlike it only ever found the aligned case. */ + for (size_t i = 0; i < n; i++) { if (g[i].sp->dir != SPLIT_ROWS) continue; rect_t h = g[i].r; - corner_t c = {0}; - c.h_id = g[i].sp->id; - c.h_edge = g[i].i; - for (size_t j = 0; j < n && c.nv < 2; j++) { + for (size_t j = 0; j < n; j++) { if (g[j].sp->dir != SPLIT_COLS) continue; rect_t v = g[j].r; if ((uint16_t)(v.y + v.h) != h.y && (uint16_t)(h.y + h.h) != v.y) continue; @@ -2526,16 +2528,31 @@ static void find_corners(app_t *a) { ? (uint16_t)(v.x + v.w) : (uint16_t)(h.x + h.w); if (xe <= x0) continue; - if (!c.nv) { - c.r = (rect_t){x0, h.y, (uint16_t)(xe - x0), h.h}; - } else if (c.r.x != x0 || c.r.w != (uint16_t)(xe - x0)) { - continue; /* out of line with the first: not one corner */ + uint16_t w = (uint16_t)(xe - x0); + + corner_t *c = NULL; + for (size_t k = 0; k < a->ncorners; k++) { + corner_t *e = &a->corners[k]; + if (e->h_id == g[i].sp->id && e->h_edge == g[i].i && e->r.x == x0 && + e->r.w == w) { + c = e; + break; + } + } + if (!c) { + if (a->ncorners >= 16) break; + c = &a->corners[a->ncorners++]; + *c = (corner_t){0}; + c->r = (rect_t){x0, h.y, w, h.h}; + c->h_id = g[i].sp->id; + c->h_edge = g[i].i; + } + if (c->nv < 2) { + c->v_id[c->nv] = g[j].sp->id; + c->v_edge[c->nv] = g[j].i; + c->nv++; } - c.v_id[c.nv] = g[j].sp->id; - c.v_edge[c.nv] = g[j].i; - c.nv++; } - if (c.nv) a->corners[a->ncorners++] = c; } } |
