Scroll when there are more tiles than fit
Shrinking the grid to fit meant a configured tile-width was quietly ignored the moment enough windows were open — a setting that silently does not apply is a bug, not a policy. Tiles are now the size the config asks for and the extra rows scroll. The layout became a viewport: it reports how many rows fit, elem/tile/ label take a scroll offset and return nothing for tiles above or below the fold, and hit-testing follows the offset so a click lands on what is under the cursor rather than what used to be there. Any keyboard move goes through select(), which scrolls the least that keeps the selection visible; PgUp/PgDn jump a screen. A scrollbar appears in the right margin only when there is something to scroll, so it reads as a hint rather than furniture. Tiles scrolled out of sight get a null buffer, which unmaps their subsurface, and the live clock skips them — a long list no longer spends readback bandwidth on pixels nobody can see. Re-placing the subsurfaces happens once per dispatch in the event loop rather than inside the key handler, so holding an arrow key coalesces. Shrinking survives for one case only: a tile too large for even a single row or column, where otherwise nothing could be drawn. The old shrink-to-fit test was rewritten around that, since its premise (twenty tiles at full size cannot fit) is now answered by scrolling instead. Verified against the session: 16 tiles at tile-width = 40ppt gives a 2x8 grid with 2 rows visible; three Downs scroll to row 2 and Enter returns index 6, matching its own list; 82% of the viewport changes across the scroll; and the scrollbar thumb measures 634px tall at y=24 unscrolled and y=658 at scroll 2, both what the geometry predicts.
This commit is contained in:
+11
-3
@@ -101,7 +101,7 @@ fn run() -> Result<ExitCode, Box<dyn Error>> {
|
||||
theme.font.clone(),
|
||||
theme.font_px * scale as f32,
|
||||
(theme.line_h * scale) as f32,
|
||||
(layout.label(0).map(|r| r.w).unwrap_or(theme.tile_w) * scale) as f32,
|
||||
(layout.label(0, 0).map(|r| r.w).unwrap_or(theme.tile_w) * scale) as f32,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -134,12 +134,20 @@ fn run() -> Result<ExitCode, Box<dyn Error>> {
|
||||
app.show(&qh)?;
|
||||
pump(&mut queue, &mut app, |a| a.configured)?;
|
||||
app.paint();
|
||||
app.place_tiles(&qh);
|
||||
app.sync_tiles(&qh);
|
||||
app.arm_frame_callback(&qh);
|
||||
conn.flush()?;
|
||||
phases.mark("mapped");
|
||||
|
||||
pump(&mut queue, &mut app, |a| a.finished())?;
|
||||
// Scrolling re-places the subsurfaces; doing it here rather than inside the
|
||||
// key handler coalesces a held-down arrow into one update per dispatch.
|
||||
while !app.finished() {
|
||||
queue.blocking_dispatch(&mut app)?;
|
||||
if std::mem::take(&mut app.needs_tiles) {
|
||||
app.sync_tiles(&qh);
|
||||
conn.flush()?;
|
||||
}
|
||||
}
|
||||
if opts.verbose {
|
||||
app.report(start.elapsed());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user