Let the two bottom-pinned screens have the window
The chats list and the conversation each pin something to the bottom — the tab bar, the compose bar — and each marks the band above it :fill-height so the scroll in it takes the rest. Neither said anything about its own root, which under jvui is as tall as what is in it: the band asks for the rest of the screen, is told the rest is what the backlog already occupies, and the whole screen paints into a strip along the top with the window empty below it. The split view already said :fill-height, one wrapper further out, which is why only the narrow layouts showed this. :reserve moves onto the :scroll from the column around it. It only ever meant "leave this much of the height behind", and the viewport is what has to be told: a column does not read it, so the scroll took everything down to the bottom edge and the strip below went off the window until the layout settled. The numbers are unchanged — below-list and below-messages count what follows, and what follows the column is what follows the scroll in it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7f86322 parent: 468684e modified
src/frq/app.clj +16 -5 | @@ -297,7 +297,14 @@ | ||
| 297 | 297 | ;; What goes with the page is its centring at 620, on a window between that |
| 298 | 298 | ;; and the split view's 900: the list is full-bleed there now, which is |
| 299 | 299 | ;; what the conversation beside it has always been. |
| 300 | - [:vbox {:spacing 8 :margin 12} | |
| 300 | + ;; `:fill-height` on the outermost box, not only on the band inside it. | |
| 301 | + ;; A backend that gives a column the height of what is in it hands the | |
| 302 | + ;; band below a window's worth of nothing to divide: the list asks for | |
| 303 | + ;; the rest of the screen, is told the rest is forty points, and the | |
| 304 | + ;; whole screen paints into a strip along the top with the window empty | |
| 305 | + ;; under it. Every screen that pins something to the bottom says this on | |
| 306 | + ;; its own root — the split view already said it, one wrapper further out. | |
| 307 | + [:vbox {:spacing 8 :margin 12 :fill-height true} | |
| 301 | 308 | [:vbox {:key :head :spacing 8} |
| 302 | 309 | ;; Your nick in the title, where "Chats" alone said nothing you did not |
| 303 | 310 | ;; already know. It is what every channel calls you and what your own |
| @@ -345,8 +352,9 @@ | ||
| 345 | 352 | ;; the tabs' strip out of what it may take. |
| 346 | 353 | ;; Named, so it is the same list — and the same scroll position — when the |
| 347 | 354 | ;; reader comes back from a conversation. |
| 348 | - [:vbox {:key :list :fill-height true :reserve (below-list)} | |
| 349 | - [:scroll {:scroll-key "chats-list" :orientation :vertical} | |
| 355 | + [:vbox {:key :list :fill-height true} | |
| 356 | + [:scroll {:scroll-key "chats-list" :orientation :vertical | |
| 357 | + :reserve (below-list)} | |
| 350 | 358 | (if (seq buffers) |
| 351 | 359 | ;; Keyed on the name, because this list reorders: opening a |
| 352 | 360 | ;; conversation bumps it to the top, and unkeyed children reconcile by |
| @@ -1309,7 +1317,10 @@ | ||
| 1309 | 1317 | ;; plain End for its own caret and leaves this one alone — so it arrives |
| 1310 | 1318 | ;; here by bubbling up from whatever had the focus. The window backend |
| 1311 | 1319 | ;; registers the handler and never calls it: keys there belong to egui. |
| 1312 | - [:vbox {:spacing 8 :margin 12 | |
| 1320 | + ;; `:fill-height` for the reason the chats screen gives on its own root: | |
| 1321 | + ;; without it this column is as tall as what is in it, and the compose bar | |
| 1322 | + ;; sits wherever the backlog happens to end rather than at the bottom. | |
| 1323 | + [:vbox {:spacing 8 :margin 12 :fill-height true | |
| 1313 | 1324 | :on-key (fn [k] |
| 1314 | 1325 | (when (= k "ctrl+end") (s/jump-to-present!)))} |
| 1315 | 1326 | [:hbox {:spacing 8} |
| @@ -1361,10 +1372,10 @@ | ||
| 1361 | 1372 | ;; it every time the panel was toggled. |
| 1362 | 1373 | [:hbox {:spacing 8 :wrap false} |
| 1363 | 1374 | [:vbox {:key :messages :fill-height true |
| 1364 | - :reserve (below-messages) | |
| 1365 | 1375 | :width-request (if show-users? (messages-width) 0)} |
| 1366 | 1376 | [:scroll {:scroll-key (messages-scroll-key) |
| 1367 | 1377 | :orientation :vertical |
| 1378 | + :reserve (below-messages) | |
| 1368 | 1379 | :stick-to-bottom true |
| 1369 | 1380 | :scroll-to-bottom @s/jump-tick |
| 1370 | 1381 | :on-change #(reset! s/at-present? (= "end" %)) |
| @@ -297,7 +297,14 @@ | |||
| 297 | ;; What goes with the page is its centring at 620, on a window between that | 297 | ;; What goes with the page is its centring at 620, on a window between that |
| 298 | ;; and the split view's 900: the list is full-bleed there now, which is | 298 | ;; and the split view's 900: the list is full-bleed there now, which is |
| 299 | ;; what the conversation beside it has always been. | 299 | ;; what the conversation beside it has always been. |
| 300 | - [:vbox {:spacing 8 :margin 12} | 300 | + ;; `:fill-height` on the outermost box, not only on the band inside it. |
| 301 | + ;; A backend that gives a column the height of what is in it hands the | ||
| 302 | + ;; band below a window's worth of nothing to divide: the list asks for | ||
| 303 | + ;; the rest of the screen, is told the rest is forty points, and the | ||
| 304 | + ;; whole screen paints into a strip along the top with the window empty | ||
| 305 | + ;; under it. Every screen that pins something to the bottom says this on | ||
| 306 | + ;; its own root — the split view already said it, one wrapper further out. | ||
| 307 | + [:vbox {:spacing 8 :margin 12 :fill-height true} | ||
| 301 | [:vbox {:key :head :spacing 8} | 308 | [:vbox {:key :head :spacing 8} |
| 302 | ;; Your nick in the title, where "Chats" alone said nothing you did not | 309 | ;; Your nick in the title, where "Chats" alone said nothing you did not |
| 303 | ;; already know. It is what every channel calls you and what your own | 310 | ;; already know. It is what every channel calls you and what your own |
| @@ -345,8 +352,9 @@ | |||
| 345 | ;; the tabs' strip out of what it may take. | 352 | ;; the tabs' strip out of what it may take. |
| 346 | ;; Named, so it is the same list — and the same scroll position — when the | 353 | ;; Named, so it is the same list — and the same scroll position — when the |
| 347 | ;; reader comes back from a conversation. | 354 | ;; reader comes back from a conversation. |
| 348 | - [:vbox {:key :list :fill-height true :reserve (below-list)} | 355 | + [:vbox {:key :list :fill-height true} |
| 349 | - [:scroll {:scroll-key "chats-list" :orientation :vertical} | 356 | + [:scroll {:scroll-key "chats-list" :orientation :vertical |
| 357 | + :reserve (below-list)} | ||
| 350 | (if (seq buffers) | 358 | (if (seq buffers) |
| 351 | ;; Keyed on the name, because this list reorders: opening a | 359 | ;; Keyed on the name, because this list reorders: opening a |
| 352 | ;; conversation bumps it to the top, and unkeyed children reconcile by | 360 | ;; conversation bumps it to the top, and unkeyed children reconcile by |
| @@ -1309,7 +1317,10 @@ | |||
| 1309 | ;; plain End for its own caret and leaves this one alone — so it arrives | 1317 | ;; plain End for its own caret and leaves this one alone — so it arrives |
| 1310 | ;; here by bubbling up from whatever had the focus. The window backend | 1318 | ;; here by bubbling up from whatever had the focus. The window backend |
| 1311 | ;; registers the handler and never calls it: keys there belong to egui. | 1319 | ;; registers the handler and never calls it: keys there belong to egui. |
| 1312 | - [:vbox {:spacing 8 :margin 12 | 1320 | + ;; `:fill-height` for the reason the chats screen gives on its own root: |
| 1321 | + ;; without it this column is as tall as what is in it, and the compose bar | ||
| 1322 | + ;; sits wherever the backlog happens to end rather than at the bottom. | ||
| 1323 | + [:vbox {:spacing 8 :margin 12 :fill-height true | ||
| 1313 | :on-key (fn [k] | 1324 | :on-key (fn [k] |
| 1314 | (when (= k "ctrl+end") (s/jump-to-present!)))} | 1325 | (when (= k "ctrl+end") (s/jump-to-present!)))} |
| 1315 | [:hbox {:spacing 8} | 1326 | [:hbox {:spacing 8} |
| @@ -1361,10 +1372,10 @@ | |||
| 1361 | ;; it every time the panel was toggled. | 1372 | ;; it every time the panel was toggled. |
| 1362 | [:hbox {:spacing 8 :wrap false} | 1373 | [:hbox {:spacing 8 :wrap false} |
| 1363 | [:vbox {:key :messages :fill-height true | 1374 | [:vbox {:key :messages :fill-height true |
| 1364 | - :reserve (below-messages) | ||
| 1365 | :width-request (if show-users? (messages-width) 0)} | 1375 | :width-request (if show-users? (messages-width) 0)} |
| 1366 | [:scroll {:scroll-key (messages-scroll-key) | 1376 | [:scroll {:scroll-key (messages-scroll-key) |
| 1367 | :orientation :vertical | 1377 | :orientation :vertical |
| 1378 | + :reserve (below-messages) | ||
| 1368 | :stick-to-bottom true | 1379 | :stick-to-bottom true |
| 1369 | :scroll-to-bottom @s/jump-tick | 1380 | :scroll-to-bottom @s/jump-tick |
| 1370 | :on-change #(reset! s/at-present? (= "end" %)) | 1381 | :on-change #(reset! s/at-present? (= "end" %)) |