Let the compose box take the lines a message needs
The field was one line and slid a long message sideways through it. It takes up to five now and wraps into them, which is the shape the box has in every other client and the one anybody writing a paragraph expects. The reserve below the message list has to hear about it. That strip is counted in points here — the list is given a height rather than finding one — so a compose bar that got taller without saying so grows down over the bottom edge of the window instead of shortening the backlog above it. `:on-rows` is the field saying so, and twenty points a line is a 16-point face's line box rounded up: the reserve has to be at least what the field took. Nothing changes in a terminal, where the field is the fixed block of three rows it already was and nothing fires `:on-rows`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
d27ef4e parent: ffa0ccb modified
src/frq/app.clj +24 -1 | @@ -1204,6 +1204,13 @@ | ||
| 1204 | 1204 | ;; width that stops short of it. |
| 1205 | 1205 | (def ^:private users-width 180) |
| 1206 | 1206 | |
| 1207 | +;; How many lines the compose field is currently drawn as. The window backend | |
| 1208 | +;; says so when it changes — a field with room to grow wraps a long message | |
| 1209 | +;; onto a second and third line instead of sliding it sideways — and the | |
| 1210 | +;; reserve below has to hear about it, since nothing in this tree is laid out | |
| 1211 | +;; by anything but these counts. | |
| 1212 | +(defonce ^:private draft-rows (atom 1)) | |
| 1213 | + | |
| 1207 | 1214 | ;; What the rows under the conversation need left to them: the jump button's |
| 1208 | 1215 | ;; row, the separator, the compose bar and the air around it. The columns of |
| 1209 | 1216 | ;; the row reserve it, and so nothing inside them has to — a `:scroll` that |
| @@ -1227,7 +1234,16 @@ | ||
| 1227 | 1234 | (if @s/attachment 76 0))) |
| 1228 | 1235 | ;; The two extra rows the terminal's compose field wraps into, in points: |
| 1229 | 1236 | ;; a row down the page is two cells' worth of the scale. |
| 1230 | - (if @terminal? (* 4 (chrome-scale)) 0))) | |
| 1237 | + (if @terminal? (* 4 (chrome-scale)) 0) | |
| 1238 | + ;; And the lines a window's compose field has GROWN by. Unscaled and | |
| 1239 | + ;; outside the terminal's arm on purpose: the field only reports its | |
| 1240 | + ;; height where it can change — the terminal's is the fixed block of | |
| 1241 | + ;; three rows reserved just above — so `draft-rows` is one there and | |
| 1242 | + ;; this term is zero. Twenty points a line is a 16-point face's line | |
| 1243 | + ;; box rounded up: the reserve has to be at least what the field took, | |
| 1244 | + ;; because a point too few does not crop the list, it slides the | |
| 1245 | + ;; compose bar off the bottom of the window. | |
| 1246 | + (* 20 (dec @draft-rows)))) | |
| 1231 | 1247 | |
| 1232 | 1248 | (defn- messages-width |
| 1233 | 1249 | "How wide the message list may be with the people panel beside it. |
| @@ -1476,6 +1492,13 @@ | ||
| 1476 | 1492 | ;; the minimum it always was. |
| 1477 | 1493 | :hexpand true |
| 1478 | 1494 | :rows (if @terminal? 3 1) |
| 1495 | + ;; In a window the field starts as one line and takes another | |
| 1496 | + ;; every time the message stops fitting, up to five — past | |
| 1497 | + ;; which it scrolls, keeping the caret in view. A paragraph | |
| 1498 | + ;; typed into a one-line box was readable a dozen characters | |
| 1499 | + ;; at a time, which is not how anybody writes one. | |
| 1500 | + :max-rows 5 | |
| 1501 | + :on-rows #(reset! draft-rows %) | |
| 1479 | 1502 | ;; The break is worth saying out loud where it is new: Enter |
| 1480 | 1503 | ;; sends, as it always has, and the box under it takes a |
| 1481 | 1504 | ;; paragraph now — which nobody would think to try unasked. |
| @@ -1204,6 +1204,13 @@ | |||
| 1204 | ;; width that stops short of it. | 1204 | ;; width that stops short of it. |
| 1205 | (def ^:private users-width 180) | 1205 | (def ^:private users-width 180) |
| 1206 | 1206 | ||
| 1207 | +;; How many lines the compose field is currently drawn as. The window backend | ||
| 1208 | +;; says so when it changes — a field with room to grow wraps a long message | ||
| 1209 | +;; onto a second and third line instead of sliding it sideways — and the | ||
| 1210 | +;; reserve below has to hear about it, since nothing in this tree is laid out | ||
| 1211 | +;; by anything but these counts. | ||
| 1212 | +(defonce ^:private draft-rows (atom 1)) | ||
| 1213 | + | ||
| 1207 | ;; What the rows under the conversation need left to them: the jump button's | 1214 | ;; What the rows under the conversation need left to them: the jump button's |
| 1208 | ;; row, the separator, the compose bar and the air around it. The columns of | 1215 | ;; row, the separator, the compose bar and the air around it. The columns of |
| 1209 | ;; the row reserve it, and so nothing inside them has to — a `:scroll` that | 1216 | ;; the row reserve it, and so nothing inside them has to — a `:scroll` that |
| @@ -1227,7 +1234,16 @@ | |||
| 1227 | (if @s/attachment 76 0))) | 1234 | (if @s/attachment 76 0))) |
| 1228 | ;; The two extra rows the terminal's compose field wraps into, in points: | 1235 | ;; The two extra rows the terminal's compose field wraps into, in points: |
| 1229 | ;; a row down the page is two cells' worth of the scale. | 1236 | ;; a row down the page is two cells' worth of the scale. |
| 1230 | - (if @terminal? (* 4 (chrome-scale)) 0))) | 1237 | + (if @terminal? (* 4 (chrome-scale)) 0) |
| 1238 | + ;; And the lines a window's compose field has GROWN by. Unscaled and | ||
| 1239 | + ;; outside the terminal's arm on purpose: the field only reports its | ||
| 1240 | + ;; height where it can change — the terminal's is the fixed block of | ||
| 1241 | + ;; three rows reserved just above — so `draft-rows` is one there and | ||
| 1242 | + ;; this term is zero. Twenty points a line is a 16-point face's line | ||
| 1243 | + ;; box rounded up: the reserve has to be at least what the field took, | ||
| 1244 | + ;; because a point too few does not crop the list, it slides the | ||
| 1245 | + ;; compose bar off the bottom of the window. | ||
| 1246 | + (* 20 (dec @draft-rows)))) | ||
| 1231 | 1247 | ||
| 1232 | (defn- messages-width | 1248 | (defn- messages-width |
| 1233 | "How wide the message list may be with the people panel beside it. | 1249 | "How wide the message list may be with the people panel beside it. |
| @@ -1476,6 +1492,13 @@ | |||
| 1476 | ;; the minimum it always was. | 1492 | ;; the minimum it always was. |
| 1477 | :hexpand true | 1493 | :hexpand true |
| 1478 | :rows (if @terminal? 3 1) | 1494 | :rows (if @terminal? 3 1) |
| 1495 | + ;; In a window the field starts as one line and takes another | ||
| 1496 | + ;; every time the message stops fitting, up to five — past | ||
| 1497 | + ;; which it scrolls, keeping the caret in view. A paragraph | ||
| 1498 | + ;; typed into a one-line box was readable a dozen characters | ||
| 1499 | + ;; at a time, which is not how anybody writes one. | ||
| 1500 | + :max-rows 5 | ||
| 1501 | + :on-rows #(reset! draft-rows %) | ||
| 1479 | ;; The break is worth saying out loud where it is new: Enter | 1502 | ;; The break is worth saying out loud where it is new: Enter |
| 1480 | ;; sends, as it always has, and the box under it takes a | 1503 | ;; sends, as it always has, and the box under it takes a |
| 1481 | ;; paragraph now — which nobody would think to try unasked. | 1504 | ;; paragraph now — which nobody would think to try unasked. |