config: dpi-aware: remove ‘auto’ value, and default to ‘no’

We now default to scaling fonts using the scaling factor, not monitor
DPI.

The ‘auto’ value for dpi-aware has been removed.

Documentation (man pages and README) have been updated to reflect the
new default.
This commit is contained in:
Daniel Eklöf 2023-06-26 17:55:04 +02:00
parent 32b8c5c9b6
commit 64b6b5d2a7
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 48 additions and 88 deletions

View file

@ -411,27 +411,53 @@ This is not how it is meant to be. Fonts are measured in _point sizes_
**for a reason**; a given point size should have the same height on
all mediums, be it printers or monitors, regardless of their DPI.
Foots default behavior is to use the monitors DPI to size fonts when
output scaling has been disabled on **all** monitors. If at least one
monitor has output scaling enabled, fonts will instead by sized using
the scaling factor.
That said, on Wayland, Hi-DPI monitors are typically handled by
configuring a _"scaling factor"_ in the compositor. This is usually
expressed as either a rational value (e.g. _1.5_), or as a percentage
(e.g. _150%_), by which all fonts and window sizes are supposed to be
multiplied.
This can be changed to either **always** use the monitors DPI
(regardless of scaling factor), or to **never** use it, with the
`dpi-aware` option in `foot.ini`. See the man page, **foot.ini**(5)
for more information.
For this reason, and because of the new _fractional scaling_ protocol
(see below for details), and because this is how Wayland applications
are expected to behave, foot >= 1.15 will default to scaling fonts
using the compositors scaling factor, and **not** the monitor
DPI.
When fonts are sized using the monitors DPI, glyphs should always
have the same physical height, regardless of monitor.
This means the (assuming the monitors are at the same viewing
distance) the font size will appear to change when you move the foot
window across different monitors, **unless** you have configured the
monitors scaling factors correctly in the compositor.
Furthermore, foot will re-size the fonts on-the-fly when the window is
moved between screens with different DPIs values. If the window covers
multiple screens, with different DPIs, the highest DPI will be used.
This can be changed by setting the `dpi-aware` option to `yes` in
`foot.ini`. When enabled, fonts will **not** be sized using the
scaling factor, but will instead be sized using the monitors
DPI. When the foot window is moved across monitors, the font size is
updated for the current monitors DPI.
This means that, assuming the monitors are **at the same viewing
distance**, the font size will appear to be the same, at all times.
_Note_: if you configure **pixelsize**, rather than **size**, then DPI
changes will **not** change the font size. Pixels are always pixels.
### Fractional scaling on Wayland
For a long time, there was no **true** support for _fractional
scaling_. That is, values like 1.5 (150%), 1.8 (180%) etc, only
integer values, like 2 (200%).
Compositors that _did_ support fractional scaling did so using a hack;
all applications were told to scale to 200%, and then the compositor
would down-scale the rendered image to e.g. 150%. This works OK for
everything **except fonts**, which ended up blurry.
With _wayland-protocols 1.32_, a new protocol was introduced, that
allows compositors to tell applications the _actual_ scaling
factor. Applications can then scale the image using a _viewport_
object, instead of setting a scale factor on the raw pixel buffer.
## Supported OSCs
OSC, _Operating System Command_, are escape sequences that interacts

View file

@ -972,17 +972,8 @@ parse_section_main(struct context *ctx)
else if (strcmp(key, "underline-thickness") == 0)
return value_to_pt_or_px(ctx, &conf->underline_thickness);
else if (strcmp(key, "dpi-aware") == 0) {
if (strcmp(value, "auto") == 0)
conf->dpi_aware = DPI_AWARE_AUTO;
else {
bool value;
if (!value_to_bool(ctx, &value))
return false;
conf->dpi_aware = value ? DPI_AWARE_YES : DPI_AWARE_NO;
}
return true;
}
else if (strcmp(key, "dpi-aware") == 0)
return value_to_bool(ctx, &conf->dpi_aware);
else if (strcmp(key, "workers") == 0)
return value_to_uint16(ctx, 10, &conf->render_worker_count);
@ -2939,7 +2930,7 @@ config_load(struct config *conf, const char *conf_path,
.use_custom_underline_offset = false,
.box_drawings_uses_font_glyphs = false,
.underline_thickness = {.pt = 0., .px = -1},
.dpi_aware = DPI_AWARE_AUTO, /* DPI-aware when scaling-factor == 1 */
.dpi_aware = false,
.bell = {
.urgent = false,
.notify = false,

View file

@ -137,7 +137,7 @@ struct config {
enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode;
enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware;
bool dpi_aware;
struct config_font_list fonts[4];
struct font_size_adjustment font_size_adjustment;

View file

@ -185,7 +185,7 @@ empty string to be set, but it must be quoted: *KEY=""*)
Default: _no_.
*dpi-aware*
*auto*, *yes*, or *no*.
Boolean.
When set to *yes*, fonts are sized using the monitor's DPI, making
a font of a given size have the same physical size, regardless of
@ -199,12 +199,6 @@ empty string to be set, but it must be quoted: *KEY=""*)
instead sized using the monitor's scaling factor; doubling the
scaling factor *does* double the font size.
Finally, if set to *auto*, fonts will be sized using the monitor's
DPI if _all_ monitors have a scaling factor of 1. If at least one
monitor as a scaling factor larger than 1 (regardless of whether
the foot window is mapped on that monitor or not), fonts will be
scaled using the scaling factor.
Note that this option typically does not work with bitmap fonts,
which only contains a pre-defined set of sizes, and cannot be
dynamically scaled. Whichever size (of the available ones) that
@ -217,7 +211,7 @@ empty string to be set, but it must be quoted: *KEY=""*)
to size the font (*dpi-aware=no*), the font's pixel size will be
multiplied with the scaling factor.
Default: _auto_
Default: _no_
*pad*
Padding between border and glyphs, in pixels (subject to output

View file

@ -20,7 +20,7 @@
# underline-offset=<font metrics>
# underline-thickness=<font underline thickness>
# box-drawings-uses-font-glyphs=no
# dpi-aware=auto
# dpi-aware=no
# initial-window-size-pixels=700x500 # Or,
# initial-window-size-chars=<COLSxROWS>

View file

@ -912,42 +912,6 @@ get_font_subpixel(const struct terminal *term)
return FCFT_SUBPIXEL_DEFAULT;
}
static bool
term_font_size_by_dpi(const struct terminal *term)
{
switch (term->conf->dpi_aware) {
case DPI_AWARE_YES: return true;
case DPI_AWARE_NO: return false;
case DPI_AWARE_AUTO:
/*
* Scale using DPI if all monitors have a scaling factor or 1.
*
* The idea is this: if a user, with multiple monitors, have
* enabled scaling on at least one monitor, then he/she has
* most likely done so to match the size of his/hers other
* monitors.
*
* I.e. if the user has one monitor with a scaling factor of
* one, and another with a scaling factor of two, he/she
* expects things to be twice as large on the second
* monitor.
*
* If we (foot) scale using DPI on the first monitor, and
* using the scaling factor on the second monitor, foot will
* *not* look twice as big on the second monitor.
*/
tll_foreach(term->wl->monitors, it) {
const struct monitor *mon = &it->item;
if (mon->scale > 1)
return false;
}
return true;
}
BUG("unhandled DPI awareness value");
}
int
term_pt_or_px_as_pixels(const struct terminal *term,
const struct pt_or_px *pt_or_px)
@ -2158,7 +2122,7 @@ term_font_dpi_changed(struct terminal *term, int old_scale)
xassert(term->scale > 0);
bool was_scaled_using_dpi = term->font_is_sized_by_dpi;
bool will_scale_using_dpi = term_font_size_by_dpi(term);
bool will_scale_using_dpi = term->conf->dpi_aware;
bool need_font_reload =
was_scaled_using_dpi != will_scale_using_dpi ||

View file

@ -511,6 +511,7 @@ test_section_main(void)
test_boolean(&ctx, &parse_section_main, "box-drawings-uses-font-glyphs", &conf.box_drawings_uses_font_glyphs);
test_boolean(&ctx, &parse_section_main, "locked-title", &conf.locked_title);
test_boolean(&ctx, &parse_section_main, "notify-focus-inhibit", &conf.notify_focus_inhibit);
test_boolean(&ctx, &parse_section_main, "dpi-aware", &conf.dpi_aware);
test_pt_or_px(&ctx, &parse_section_main, "font-size-adjustment", &conf.font_size_adjustment.pt_or_px); /* TODO: test N% values too */
test_pt_or_px(&ctx, &parse_section_main, "line-height", &conf.line_height);
@ -524,17 +525,6 @@ test_section_main(void)
test_spawn_template(&ctx, &parse_section_main, "notify", &conf.notify);
test_enum(
&ctx, &parse_section_main, "dpi-aware",
9,
(const char *[]){"on", "true", "yes", "1",
"off", "false", "no", "0",
"auto"},
(int []){DPI_AWARE_YES, DPI_AWARE_YES, DPI_AWARE_YES, DPI_AWARE_YES,
DPI_AWARE_NO, DPI_AWARE_NO, DPI_AWARE_NO, DPI_AWARE_NO,
DPI_AWARE_AUTO},
(int *)&conf.dpi_aware);
test_enum(&ctx, &parse_section_main, "selection-target",
4,
(const char *[]){"none", "primary", "clipboard", "both"},

View file

@ -373,11 +373,6 @@ update_terms_on_monitor(struct monitor *mon)
tll_foreach(wayl->terms, it) {
struct terminal *term = it->item;
if (term->conf->dpi_aware == DPI_AWARE_AUTO) {
update_term_for_output_change(term);
continue;
}
tll_foreach(term->window->on_outputs, it2) {
if (it2->item == mon) {
update_term_for_output_change(term);