Keep blocks still when switching layers

- The main block reserves the width and rows of its biggest layer, so the
  numpad and function row no longer shift between letters and symbols
- Smaller layers stretch into the room: stretch keys widen, rows grow
  taller (rows above the layer, like the function row, keep their height)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 22:35:00 +02:00
co-authored by Claude Opus 5.5
parent 75bbe2e566
commit ac0bfc2741
5 changed files with 66 additions and 14 deletions
+11 -4
View File
@@ -12,16 +12,23 @@ struct KeyboardMetrics {
};
// The keys on screen: blocks of rows, side by side.
// A block can reserve room (minUnits, minRows) so that swapping its rows, e.g.
// switching layers, moves nothing else; its keys stretch into the room.
struct Block {
QList<Row> rows;
bool fillHeight = false; // rows grow to span the full height instead of sharing the row height
bool fillHeight = false; // spans the full height instead of max(rows, minRows) shared rows
qreal minUnits = 0; // reserved width
qsizetype minRows = 0; // reserved height, in shared rows
qsizetype fixedRows = 0; // leading rows that keep the shared height when the block stretches
};
// Lays out blocks to fill `size`. Returns one rect per key, block by block in
// row order (spacers included). One key unit has the same width everywhere;
// rows share one height, set by the tallest block that doesn't fill, and
// shorter blocks sit at the bottom. In each block, stretch keys grow to make
// their row as wide as the widest one, and remaining shorter rows are centered.
// shorter blocks sit at the bottom. A block given more height than its rows
// need (fillHeight, minRows) grows its rows after fixedRows to take it up.
// In each block, stretch keys grow to make their row as wide as the widest
// one (or minUnits), and remaining shorter rows are centered.
QList<QRectF> computeKeyRects(const QList<Block> &blocks, QSizeF size, KeyboardMetrics metrics = {});
inline QList<QRectF> computeKeyRects(const Layer &layer, QSizeF size, KeyboardMetrics metrics = {})
{
@@ -32,5 +39,5 @@ inline QList<QRectF> computeKeyRects(const Layer &layer, QSizeF size, KeyboardMe
qreal rowUnits(const Row &row);
// Width of all blocks in key units, ignoring gaps.
qreal totalUnits(const QList<Block> &blocks);
// Rows of the tallest block that sets the row height (see computeKeyRects).
// Shared rows of the tallest block that sets the row height (see computeKeyRects).
qsizetype totalRows(const QList<Block> &blocks);