diff --git a/CHANGELOG.md b/CHANGELOG.md index cee4ddef..3e4c2a6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,8 @@ * `[colors-light]` section to `foot.ini`. Replaces `[colors2]`. * `XTGETTCAP`: added `query-os-name`, returning the OS foot is compiled for (e.g. _'Linux'_) ([#2209][2209]). +* `pad` option now supports 4-directional padding format: + `LEFTxTOPxRIGHTxBOTTOM` (e.g., `20x10x20x10`). [2212]: https://codeberg.org/dnkl/foot/issues/2212 [2209]: https://codeberg.org/dnkl/foot/issues/2209 diff --git a/config.c b/config.c index 14e836c1..b1ff329c 100644 --- a/config.c +++ b/config.c @@ -945,13 +945,12 @@ parse_section_main(struct context *ctx) } else if (streq(key, "pad")) { - unsigned x, y; + unsigned x, y, left, top, right, bottom; char mode[64] = {0}; - int ret = sscanf(value, "%ux%u %63s", &x, &y, mode); - + int ret = sscanf(value, "%ux%ux%ux%u %63s", &left, &top, &right, &bottom, mode); enum center_when center = CENTER_NEVER; - if (ret == 3) { + if (ret == 5) { if (strcasecmp(mode, "center") == 0) center = CENTER_ALWAYS; else if (strcasecmp(mode, "center-when-fullscreen") == 0) @@ -960,20 +959,38 @@ parse_section_main(struct context *ctx) center = CENTER_MAXIMIZED_AND_FULLSCREEN; else center = CENTER_INVALID; + } else if (ret < 4) { + ret = sscanf(value, "%ux%u %63s", &x, &y, mode); + if (ret >= 2) { + left = right = x; + top = bottom = y; + if (ret == 3) { + if (strcasecmp(mode, "center") == 0) + center = CENTER_ALWAYS; + else if (strcasecmp(mode, "center-when-fullscreen") == 0) + center = CENTER_FULLSCREEN; + else if (strcasecmp(mode, "center-when-maximized-and-fullscreen") == 0) + center = CENTER_MAXIMIZED_AND_FULLSCREEN; + else + center = CENTER_INVALID; + } + } } - if ((ret != 2 && ret != 3) || center == CENTER_INVALID) { + if ((ret < 2 || ret > 5) || center == CENTER_INVALID) { LOG_CONTEXTUAL_ERR( - "invalid padding (must be in the form PAD_XxPAD_Y " + "invalid padding (must be in the form RIGHTxTOPxLEFTxBOTTOM or XxY " "[center|" "center-when-fullscreen|" "center-when-maximized-and-fullscreen])"); return false; } - conf->pad_x = x; - conf->pad_y = y; - conf->center_when = ret == 2 ? CENTER_NEVER : center; + conf->pad_left = left; + conf->pad_top = top; + conf->pad_right = right; + conf->pad_bottom = bottom; + conf->center_when = (ret == 4 || ret == 2) ? CENTER_NEVER : center; return true; } @@ -3453,8 +3470,10 @@ config_load(struct config *conf, const char *conf_path, .width = 700, .height = 500, }, - .pad_x = 0, - .pad_y = 0, + .pad_left = 0, + .pad_top = 0, + .pad_right = 0, + .pad_bottom = 0, .center_when = CENTER_MAXIMIZED_AND_FULLSCREEN, .resize_by_cells = true, .resize_keep_grid = true, diff --git a/config.h b/config.h index 9ca47753..d7db5ecc 100644 --- a/config.h +++ b/config.h @@ -232,8 +232,10 @@ struct config { uint32_t height; } size; - unsigned pad_x; - unsigned pad_y; + unsigned pad_left; + unsigned pad_top; + unsigned pad_right; + unsigned pad_bottom; enum center_when center_when; bool resize_by_cells; diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index a9e4f045..be8c131e 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -301,9 +301,20 @@ empty string to be set, but it must be quoted: *KEY=""* ``` _XxY_ [center | center-when-fullscreen | center-when-maximized-and-fullscreen] ``` + or + ``` + RIGHTxTOPxLEFTxBOTTOM [center | center-when-fullscreen | center-when-maximized-and-fullscreen] + ``` - This will add _at least_ X pixels on both the left and right - sides, and Y pixels on the top and bottom sides. + - `_XxY_` adds _at least_: + - X pixels on the left and right sides. + - Y pixels on the top and bottom sides. + + - `LEFTxTOPxRIGHTxBOTTOM` adds **at least**: + - LEFT pixels to the left + - TOP pixels to the top + - RIGHT pixels to the right + - BOTTOM pixels to the bottom When no centering is specified, the grid content is anchored to the top left corner. I.e. if the window manager forces an odd diff --git a/render.c b/render.c index 3aa7d543..627da5d6 100644 --- a/render.c +++ b/render.c @@ -4504,8 +4504,8 @@ set_size_from_grid(struct terminal *term, int *width, int *height, int cols, int new_height = rows * term->cell_height; /* Include any configured padding */ - new_width += 2 * term->conf->pad_x * term->scale; - new_height += 2 * term->conf->pad_y * term->scale; + new_width += (term->conf->pad_left + term->conf->pad_right) * term->scale; + new_height += (term->conf->pad_top + term->conf->pad_bottom) * term->scale; /* Round to multiples of scale */ new_width = round(term->scale * round(new_width / term->scale)); @@ -4613,18 +4613,22 @@ render_resize(struct terminal *term, int width, int height, uint8_t opts) /* Padding */ const int max_pad_x = (width - min_width) / 2; const int max_pad_y = (height - min_height) / 2; - const int pad_x = min(max_pad_x, scale * term->conf->pad_x); - const int pad_y = min(max_pad_y, scale * term->conf->pad_y); + const int pad_left = min(max_pad_x, scale * term->conf->pad_left); + const int pad_right = min(max_pad_x, scale * term->conf->pad_right); + const int pad_top = min(max_pad_y, scale * term->conf->pad_top); + const int pad_bottom= min(max_pad_y, scale * term->conf->pad_bottom); if (is_floating && (opts & RESIZE_BY_CELLS) && term->conf->resize_by_cells) { /* If resizing in cell increments, restrict the width and height */ - width = ((width - 2 * pad_x) / term->cell_width) * term->cell_width + 2 * pad_x; + width = ((width - (pad_left + pad_right)) / term->cell_width) + * term->cell_width + (pad_left + pad_right); width = max(min_width, roundf(scale * roundf(width / scale))); - height = ((height - 2 * pad_y) / term->cell_height) * term->cell_height + 2 * pad_y; + height = ((height - (pad_top + pad_bottom)) / term->cell_height) + * term->cell_height + (pad_top + pad_bottom); height = max(min_height, roundf(scale * roundf(height / scale))); } @@ -4651,8 +4655,10 @@ render_resize(struct terminal *term, int width, int height, uint8_t opts) int old_rows = term->rows; /* Screen rows/cols after resize */ - const int new_cols = (term->width - 2 * pad_x) / term->cell_width; - const int new_rows = (term->height - 2 * pad_y) / term->cell_height; + const int new_cols = + (term->width - (pad_left + pad_right)) / term->cell_width; + const int new_rows = + (term->height - (pad_top + pad_bottom)) / term->cell_height; /* * Requirements for scrollback: @@ -4705,16 +4711,16 @@ render_resize(struct terminal *term, int width, int height, uint8_t opts) 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.left = pad_left; + term->margins.top = pad_top; } term->margins.right = total_x_pad - term->margins.left; term->margins.bottom = total_y_pad - term->margins.top; - xassert(term->margins.left >= pad_x); - xassert(term->margins.right >= pad_x); - xassert(term->margins.top >= pad_y); - xassert(term->margins.bottom >= pad_y); + xassert(term->margins.left >= pad_left); + xassert(term->margins.right >= pad_right); + xassert(term->margins.top >= pad_top); + xassert(term->margins.bottom >= pad_bottom); if (new_cols == old_cols && new_rows == old_rows) { LOG_DBG("grid layout unaffected; skipping reflow");