Merge branch 'window-size-in-characters' into master

This commit is contained in:
Daniel Eklöf 2020-09-09 19:00:30 +02:00
commit 99023cae99
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
10 changed files with 199 additions and 57 deletions

View file

@ -56,7 +56,14 @@
character width of 1. Must be explicitly enabled with
`tweak.allow-overflowing-double-width-glyphs`
(https://codeberg.org/dnkl/foot/issues/116).
* **initial-window-size-pixels** options to `foot.ini` and
`-w,--window-size-pixels` command line option to `foot`. This option
replaces the now deprecated **geometry** and `-g,--geometry`
options.
* **initial-window-size-chars** option to `foot.ini` and
`-W,--window-size-chars` command line option to `foot`. This option
configures the initial window size in **characters**, and is an
alternative to **initial-window-size-pixels**.
### Removed

View file

@ -11,7 +11,8 @@ _arguments \
'--maximized[start in maximized mode]' \
'--fullscreen[start in fullscreen mode]' \
'--login-shell[start shell as a login shell]' \
'(-g --geometry)'{-g,--geometry}'[window WIDTHxHEIGHT, in pixels (700x500)]:geometry:()' \
'(-w --window-size-pixels)'{-w,--window-size-pixels}'[window WIDTHxHEIGHT, in pixels (700x500)]:size_pixels:()' \
'(-W --window-size-chars)'{-W,--window-size-chars}'[window WIDTHxHEIGHT, in characters (not set)]:size_chars:()' \
'(-s --server)'{-s,--server}'[run as server; open terminals by running footclient]:server:_files' \
'--hold[remain open after child process exits]' \
'(-p --print-pid)'{-p,--print-pid}'[print PID to this file or FD when up and running (server mode only)]:pidfile:_files' \

View file

@ -452,18 +452,49 @@ parse_section_main(const char *key, const char *value, struct config *conf,
conf->app_id = xstrdup(value);
}
else if (strcmp(key, "geometry") == 0) {
else if (strcmp(key, "initial-window-size-pixels") == 0 ||
strcmp(key, "geometry") == 0 /* deprecated */)
{
if (strcmp(key, "geometry") == 0) {
LOG_WARN("deprecated: [default]: geometry: use 'initial-window-size-pixels' instead'");
const char *fmt = "%s:%d: \033[1mgeometry\033[21m, use \033[1minitial-window-size-pixels\033[21m instead";
char *text = xasprintf(fmt, path, lineno);
struct user_notification deprecation = {
.kind = USER_NOTIFICATION_DEPRECATED,
.text = text,
};
tll_push_back(conf->notifications, deprecation);
}
unsigned width, height;
if (sscanf(value, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
LOG_AND_NOTIFY_ERR(
"%s: %d: [default]: geometry: expected WIDTHxHEIGHT, "
"where both are positive integers, got '%s'",
path, lineno, value);
"%s: %d: [default]: initial-window-size-pixels: "
"expected WIDTHxHEIGHT, where both are positive integers, "
"got '%s'", path, lineno, value);
return false;
}
conf->width = width;
conf->height = height;
conf->size.type = CONF_SIZE_PX;
conf->size.px.width = width;
conf->size.px.height = height;
}
else if (strcmp(key, "initial-window-size-chars") == 0) {
unsigned width, height;
if (sscanf(value, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
LOG_AND_NOTIFY_ERR(
"%s: %d: [default]: initial-window-size-chars: "
"expected WIDTHxHEIGHT, where both are positive integers, "
"got '%s'", path, lineno, value);
return false;
}
conf->size.type = CONF_SIZE_CELLS;
conf->size.cells.width = width;
conf->size.cells.height = height;
}
else if (strcmp(key, "pad") == 0) {
@ -1723,7 +1754,8 @@ add_default_mouse_bindings(struct config *conf)
}
bool
config_load(struct config *conf, const char *conf_path, bool errors_are_fatal)
config_load(struct config *conf, const char *conf_path,
user_notifications_t *initial_user_notifications, bool errors_are_fatal)
{
bool ret = false;
@ -1732,8 +1764,13 @@ config_load(struct config *conf, const char *conf_path, bool errors_are_fatal)
.shell = get_shell(),
.title = xstrdup("foot"),
.app_id = xstrdup("foot"),
.width = 700,
.height = 500,
.size = {
.type = CONF_SIZE_PX,
.px = {
.width = 700,
.height = 500,
},
},
.pad_x = 2,
.pad_y = 2,
.startup_mode = STARTUP_WINDOWED,
@ -1812,6 +1849,10 @@ config_load(struct config *conf, const char *conf_path, bool errors_are_fatal)
.notifications = tll_init(),
};
tll_foreach(*initial_user_notifications, it)
tll_push_back(conf->notifications, it->item);
tll_free(*initial_user_notifications);
add_default_key_bindings(conf);
add_default_search_bindings(conf);
add_default_mouse_bindings(conf);
@ -1889,9 +1930,7 @@ config_free(struct config conf)
tll_free(conf.bindings.mouse);
tll_free(conf.bindings.search);
tll_foreach(conf.notifications, it)
free(it->item.text);
tll_free(conf.notifications);
user_notifications_free(&conf.notifications);
}
struct config_font

View file

@ -9,6 +9,8 @@
#include "user-notification.h"
#include "wayland.h"
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
struct config_font {
char *pattern;
double pt_size;
@ -52,10 +54,24 @@ struct config {
char *title;
char *app_id;
bool login_shell;
unsigned width;
unsigned height;
struct {
enum conf_size_type type;
union {
struct {
unsigned width;
unsigned height;
} px;
struct {
unsigned width;
unsigned height;
} cells;
};
} size;
unsigned pad_x;
unsigned pad_y;
enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode;
tll(struct config_font) fonts;
@ -156,7 +172,9 @@ struct config {
user_notifications_t notifications;
};
bool config_load(struct config *conf, const char *path, bool errors_are_fatal);
bool config_load(
struct config *conf, const char *path,
user_notifications_t *initial_user_notifications, bool errors_are_fatal);
void config_free(struct config conf);
struct config_font config_font_parse(const char *pattern);

View file

@ -45,8 +45,14 @@ the foot command line
Default: _monospace_.
*-w*,*--window-size-pixels*=_WIDTHxHEIGHT_
Set initial window width and height, in pixels. Default: _700x500_.
*-W*,*--window-size-chars*=_WIDTHxHEIGHT_
Set initial window width and height, in characters. Default: _not set_.
*-g*,*--geometry*=_WIDTHxHEIGHT_
Set initial window width and height. Default: *700x500*.
Deprecated. Alias for *-w*,*--window-size-pixels*.
*-t*,*--term*=_TERM_
Value to set the environment variable *TERM* to. Default: _foot_.

View file

@ -35,18 +35,28 @@ in this order:
Default: _monospace_.
*geometry*
Initial window width and height in pixels (subject to output
scaling), on the form _WIDTHxHEIGHT_. Default: _700x500_.
*pad*
Padding between border and glyphs, in pixels (subject to output
scaling), on the form _XxY_. Default: _2x2_.
*initial-window-size-pixels*
Initial window width and height in _pixels_ (subject to output
scaling), on the form _WIDTHxHEIGHT_. The height _includes_ the
titlebar when using CSDs. Mutually exclusive to
*initial-window-size-chars*. Default: _700x500_.
*initial-window-size-chars*
Initial window width and height in _characters_, on the form
_WIDTHxHEIGHT_. Mutually exclusive to
*initial-window-size-pixels*. Default: _not set_.
*initial-window-mode*
Initial window mode for each newly spawned window: *windowed*,
*maximized* or *fullscreen*. Default: _windowed_.
*geometry*
Deprecated. Alias for *initial-window-size-pixels*.
*shell*
Executable to launch. Typically a shell. Default: _$SHELL_ if set,
otherwise the user's default shell (as specified in

View file

@ -1,9 +1,10 @@
# -*- conf -*-
# font=monospace
# geometry=700x500
# pad=2x2
# initial-window-size-pixels=700x500 # Or,
# initial-window-size-chars=<COLSxROWS>
# initial-window-mode=windowed
# pad=2x2
# shell=$SHELL (if set, otherwise user's default shell from /etc/passwd)
# term=foot
# login-shell=no

95
main.c
View file

@ -55,7 +55,8 @@ print_usage(const char *prog_name)
" --maximized start in maximized mode\n"
" --fullscreen start in fullscreen mode\n"
" --login-shell start shell as a login shell\n"
" -g,--geometry=WIDTHxHEIGHT set initial width and height\n"
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels (alternative to '--dimensions')\n"
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters (alternative to '--geometry')\n"
" -s,--server[=PATH] run as a server (use 'footclient' to start terminals).\n"
" Without PATH, $XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock will be used.\n"
" --hold remain open after child process exits\n"
@ -143,25 +144,27 @@ main(int argc, char *const *argv)
const char *const prog_name = argv[0];
static const struct option longopts[] = {
{"config", required_argument, NULL, 'c'},
{"check-config", no_argument, NULL, 'C'},
{"term", required_argument, NULL, 't'},
{"title", required_argument, NULL, 'T'},
{"app-id", required_argument, NULL, 'a'},
{"login-shell", no_argument, NULL, 'L'},
{"font", required_argument, NULL, 'f'},
{"geometry", required_argument, NULL, 'g'},
{"server", optional_argument, NULL, 's'},
{"hold", no_argument, NULL, 'H'},
{"maximized", no_argument, NULL, 'm'},
{"fullscreen", no_argument, NULL, 'F'},
{"presentation-timings", no_argument, NULL, 'P'}, /* Undocumented */
{"print-pid", required_argument, NULL, 'p'},
{"log-colorize", optional_argument, NULL, 'l'},
{"log-no-syslog", no_argument, NULL, 'S'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, no_argument, NULL, 0},
{"config", required_argument, NULL, 'c'},
{"check-config", no_argument, NULL, 'C'},
{"term", required_argument, NULL, 't'},
{"title", required_argument, NULL, 'T'},
{"app-id", required_argument, NULL, 'a'},
{"login-shell", no_argument, NULL, 'L'},
{"font", required_argument, NULL, 'f'},
{"geometry", required_argument, NULL, 'g'}, /* Deprecated */
{"window-size-pixels", required_argument, NULL, 'w'},
{"window-size-chars", required_argument, NULL, 'W'},
{"server", optional_argument, NULL, 's'},
{"hold", no_argument, NULL, 'H'},
{"maximized", no_argument, NULL, 'm'},
{"fullscreen", no_argument, NULL, 'F'},
{"presentation-timings", no_argument, NULL, 'P'}, /* Undocumented */
{"print-pid", required_argument, NULL, 'p'},
{"log-colorize", optional_argument, NULL, 'l'},
{"log-no-syslog", no_argument, NULL, 'S'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, no_argument, NULL, 0},
};
bool check_config = false;
@ -171,6 +174,7 @@ main(int argc, char *const *argv)
const char *conf_app_id = NULL;
bool login_shell = false;
tll(char *) conf_fonts = tll_init();
enum conf_size_type conf_size_type = CONF_SIZE_PX;
int conf_width = -1;
int conf_height = -1;
bool as_server = false;
@ -183,9 +187,10 @@ main(int argc, char *const *argv)
const char *pid_file = NULL;
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
bool log_syslog = true;
user_notifications_t user_notifications = tll_init();
while (true) {
int c = getopt_long(argc, argv, "+c:Ct:a:Lf:g:s::Pp:l::Svh", longopts, NULL);
int c = getopt_long(argc, argv, "+c:Ct:a:Lf:g:w:W:s::Pp:l::Svh", longopts, NULL);
if (c == -1)
break;
@ -237,12 +242,37 @@ main(int argc, char *const *argv)
break;
case 'g': {
LOG_WARN("deprecated: -g,--geometry command line option. Use -w,--window-size-pixels instead");
struct user_notification deprecation = {
.kind = USER_NOTIFICATION_DEPRECATED,
.text = xstrdup(
"\033[1m-g,--geometry\033[21m command line option. "
"Use \033[1m-w,--window-size-pixels\033[21m instead"),
};
tll_push_back(user_notifications, deprecation);
/* FALLTHROUGH */
}
case 'w': {
unsigned width, height;
if (sscanf(optarg, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
fprintf(stderr, "error: invalid geometry: %s\n", optarg);
fprintf(stderr, "error: invalid window-size-pixels: %s\n", optarg);
return EXIT_FAILURE;
}
conf_size_type = CONF_SIZE_PX;
conf_width = width;
conf_height = height;
break;
}
case 'W': {
unsigned width, height;
if (sscanf(optarg, "%ux%u", &width, &height) != 2 || width == 0 || height == 0) {
fprintf(stderr, "error: invalid window-size-chars: %s\n", optarg);
return EXIT_FAILURE;
}
conf_size_type = CONF_SIZE_CELLS;
conf_width = width;
conf_height = height;
break;
@ -323,7 +353,7 @@ main(int argc, char *const *argv)
}
struct config conf = {NULL};
if (!config_load(&conf, conf_path, check_config)) {
if (!config_load(&conf, conf_path, &user_notifications, check_config)) {
config_free(conf);
return ret;
}
@ -362,10 +392,21 @@ main(int argc, char *const *argv)
tll_push_back(conf.fonts, config_font_parse(it->item));
tll_free(conf_fonts);
}
if (conf_width > 0)
conf.width = conf_width;
if (conf_height > 0)
conf.height = conf_height;
if (conf_width > 0 && conf_height > 0) {
conf.size.type = conf_size_type;
switch (conf_size_type) {
case CONF_SIZE_PX:
conf.size.px.width = conf_width;
conf.size.px.height = conf_height;
break;
case CONF_SIZE_CELLS:
conf.size.cells.width = conf_width;
conf.size.cells.height = conf_height;
break;
}
}
if (conf_server_socket_path != NULL) {
free(conf.server_socket_path);
conf.server_socket_path = xstrdup(conf_server_socket_path);

View file

@ -2032,13 +2032,24 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
width = term->unmaximized_width;
height = term->unmaximized_height;
} else {
width = term->conf->width;
height = term->conf->height;
switch (term->conf->size.type) {
case CONF_SIZE_PX:
width = term->conf->size.px.width;
height = term->conf->size.px.height;
if (term->window->use_csd == CSD_YES) {
/* Take CSD title bar into account */
assert(!term->window->is_fullscreen);
height -= term->conf->csd.title_height;
if (term->window->use_csd == CSD_YES) {
/* Take CSD title bar into account */
assert(!term->window->is_fullscreen);
height -= term->conf->csd.title_height;
}
break;
case CONF_SIZE_CELLS:
width = 2 * term->conf->pad_x;
height = 2 * term->conf->pad_y;
width += term->conf->size.cells.width * term->cell_width;
height += term->conf->size.cells.height * term->cell_height;
break;
}
width *= scale;

View file

@ -14,3 +14,11 @@ struct user_notification {
};
typedef tll(struct user_notification) user_notifications_t;
static inline void
user_notifications_free(user_notifications_t *notifications)
{
tll_foreach(*notifications, it)
free(it->item.text);
tll_free(*notifications);
}