diff --git a/CHANGELOG.md b/CHANGELOG.md index dc49a9d4..de632cc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,13 @@ ## Unreleased ### Added + +* The `pad` option now accepts an optional third argument, `center` + (e.g. `pad=5x5 center`), causing the grid to be centered in the + window, with equal amount of padding of the left/right and + top/bottom side (https://codeberg.org/dnkl/foot/issues/273). + + ### Changed * The fcft and tllist library subprojects are now handled via Meson diff --git a/config.c b/config.c index 883cf27c..0e106584 100644 --- a/config.c +++ b/config.c @@ -466,9 +466,15 @@ parse_section_main(const char *key, const char *value, struct config *conf, else if (strcmp(key, "pad") == 0) { unsigned x, y; - if (sscanf(value, "%ux%u", &x, &y) != 2) { + char mode[16] = {0}; + + int ret = sscanf(value, "%ux%u %15s", &x, &y, mode); + bool center = strcasecmp(mode, "center") == 0; + bool invalid_mode = !center && mode[0] != '\0'; + + if ((ret != 2 && ret != 3) || invalid_mode) { LOG_AND_NOTIFY_ERR( - "%s:%d: [default]: pad: expected PAD_XxPAD_Y, " + "%s:%d: [default]: pad: expected PAD_XxPAD_Y [center], " "where both are positive integers, got '%s'", path, lineno, value); return false; @@ -476,6 +482,7 @@ parse_section_main(const char *key, const char *value, struct config *conf, conf->pad_x = x; conf->pad_y = y; + conf->center = center; } else if (strcmp(key, "bold-text-in-bright") == 0) diff --git a/config.h b/config.h index a1b27c04..21b79230 100644 --- a/config.h +++ b/config.h @@ -70,6 +70,7 @@ struct config { unsigned pad_x; unsigned pad_y; + bool center; bool bold_in_bright; enum { diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 9cabc1d2..4bf40af2 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -73,7 +73,18 @@ in this order: *pad* Padding between border and glyphs, in pixels (subject to output - scaling), on the form _XxY_. Default: _2x2_. + scaling), on the form _XxY_. + + This will add _at least_ X pixels on both the left and right + sides, and Y pixels on the top and bottom sides. The grid content + will be anchored in the top left corner. I.e. if the window + manager forces an odd window size on foot, the additional pixels + will be added to the right and bottom sides. + + To instead center the grid content, append *center* (e.g. *pad=5x5 + center*). + + Default: _2x2_. *initial-window-size-pixels* Initial window width and height in _pixels_ (subject to output diff --git a/foot.ini b/foot.ini index adaf6088..76491372 100644 --- a/foot.ini +++ b/foot.ini @@ -8,7 +8,7 @@ # initial-window-size-pixels=700x500 # Or, # initial-window-size-chars= # initial-window-mode=windowed -# pad=2x2 +# pad=2x2 # optionally append 'center' # shell=$SHELL (if set, otherwise user's default shell from /etc/passwd) # term=foot # login-shell=no diff --git a/render.c b/render.c index 6995a51b..354d7b99 100644 --- a/render.c +++ b/render.c @@ -2638,10 +2638,20 @@ maybe_resize(struct terminal *term, int width, int height, bool force) assert(new_rows >= 1); /* Margins */ - term->margins.left = pad_x; - term->margins.top = pad_y; - term->margins.right = term->width - new_cols * term->cell_width - term->margins.left; - term->margins.bottom = term->height - new_rows * term->cell_height - term->margins.top; + const int grid_width = new_cols * term->cell_width; + const int grid_height = new_rows * term->cell_height; + const int total_x_pad = term->width - grid_width; + const int total_y_pad = term->height - grid_height; + + if (term->conf->center) { + term->margins.left = total_x_pad / 2; + term->margins.top = total_y_pad / 2; + } else { + term->margins.left = pad_x; + term->margins.top = pad_y; + } + term->margins.right = total_x_pad - term->margins.left; + term->margins.bottom = total_y_pad - term->margins.top; assert(term->margins.left >= pad_x); assert(term->margins.right >= pad_x);