aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_hints.py
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-18 15:24:25 +0200
committeruser <user@clank>2026-08-18 15:24:25 +0200
commit8231838e92e5a31e85f53f8efa1b2a1e407e7cd1 (patch)
treee81381faaa6505e09c75824c04ea749512dd04c2 /tests/test_hints.py
parentsl0ppty: the make tools the last commit described (diff)
downloadslosh-8231838e92e5a31e85f53f8efa1b2a1e407e7cd1.tar.gz
slosh-8231838e92e5a31e85f53f8efa1b2a1e407e7cd1.tar.xz
slosh-8231838e92e5a31e85f53f8efa1b2a1e407e7cd1.zip
sl0ppty: the middle of a border is the button, not all of it
Clicking a pane's border to split toward it is the right gesture and was the wrong target. A border is the longest thing on the screen and it sits between two things you did mean to click -- a title, a gap, the pane beyond it -- so reaching a cell too far changed the layout, and the top row was worse than the sides: clicking a pane's header to focus it split it upward. So the target shrank. Each side carries a *handle* of three to seven cells in the middle, and only the handle splits; the rest of the edge is the *rim*, which arms the guide and does nothing when pressed. Three is the floor the pane buttons already settled on for the reason written there -- a one-cell target is a thing you miss with a mouse -- and seven is the ceiling, because a third of a tall pane's border is most of that border again and brings the accidents back with it. Hover now answers two questions in two stages, because they are two questions. Anywhere on an edge, the edge goes heavy and the handle thickens by a cell into the pane: that says where the button is, which is the thing you can no longer infer. On the handle, the dashed boundary and the arrow as well: that says what the click will do. The hint follows the same split, so sweeping an edge neither draws a boundary nor offers a split you cannot get from where the pointer is. Three things this had to get right. **The thickened handle is registered, not just painted.** The guide adds the hit for the inner strip in the frame that draws it, and reads the outer rect back from the hit list rather than recomputing it, so there is one opinion about where the handle is (D6). A handle you can see and cannot click would be worse than either mistake alone. **The top row cannot put its handle in the middle.** The buttons own its right and a centred title -- the default -- owns exactly the middle. The title winning is the existing rule, and it is what keeps a double-click rename from splitting twice on its way, so the handle is placed last, in the widest run of cells the row has left and nearest the middle among equals. A row with nothing left offers no upward split; its other three edges are unaffected. Each handle cell is then painted only if the hit list still agrees it belongs to the handle, so a block never lands on a pane's name. **The row keeps the drag and loses the split.** `title:<id>` takes no side now and `title:<id>:t` -- the handle -- carries one, which is why the press path reads the side out of the action instead of assuming it. Press-and-hold skips the dwell on a handle, where a press means something, rather than anywhere on an edge. Verified: `make retest`, 1801 checks, all green. Nine of them are new or rewritten: the two-stage guide, the caption belonging to the handle, the rim splitting nothing on any of the four sides, the top row's handle still splitting upward on a titled pane, and the rim of the top row not. Tests read the handle's cell out of the hit list (`Snapshot.handle`/`.rim`) rather than deriving the geometry, so a test cannot agree with a broken formula. Also checked by hand on a live session, which is where the placement rule earned itself: hovering the rim draws the heavy edge and the block and no dashed line, hovering the handle adds the line and the arrow, three clicks on pane headers split nothing, and on a pane titled `sl0ppty` the top handle lands to the right of the title and left of the buttons -- `drag to move ยท click to split up` at x=42, `drag to move` either side of it.
Diffstat (limited to 'tests/test_hints.py')
-rw-r--r--tests/test_hints.py22
1 files changed, 17 insertions, 5 deletions
diff --git a/tests/test_hints.py b/tests/test_hints.py
index fd85711..61349a7 100644
--- a/tests/test_hints.py
+++ b/tests/test_hints.py
@@ -77,16 +77,28 @@ def test_the_zoom_hint_says_which_way_it_goes():
def test_a_border_names_the_direction_it_would_split():
+ """The caption belongs to the handle, not the whole edge: the rest of an
+ edge does nothing, and telling you it splits would be a lie about it."""
with Session(SH, cols=96, rows=22) as s:
s.settle(20)
p = s.pane()
- for x, y, word in (
- (p["x"], p["y"] + 2, "split left"),
- (p["x"] + p["w"] - 1, p["y"] + 2, "split right"),
- (p["x"] + 6, p["y"] + p["h"] - 1, "split down"),
+ for side, word in (
+ ("l", "split left"),
+ ("r", "split right"),
+ ("b", "split down"),
+ ("t", "split up"),
):
+ x, y = s.snapshot().handle(p["id"], side)
hover(s, x, y)
- check(f"the border says {word}", word in bar(s), repr(bar(s)))
+ check(f"the {side} handle says {word}", word in bar(s), repr(bar(s)))
+
+ rx, ry = s.snapshot().rim(p["id"], "l")
+ hover(s, rx, ry)
+ check(
+ "and the rest of the edge says nothing about splitting",
+ "split" not in bar(s),
+ repr(bar(s)),
+ )
def test_the_gap_and_the_strip_and_the_bar():