Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package foot for openSUSE:Factory checked in at 2023-07-24 18:25:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/foot (Old) and /work/SRC/openSUSE:Factory/.foot.new.1467 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "foot" Mon Jul 24 18:25:49 2023 rev:24 rq:1099851 version:1.15.1 Changes: -------- --- /work/SRC/openSUSE:Factory/foot/foot.changes 2023-07-17 19:23:26.769792950 +0200 +++ /work/SRC/openSUSE:Factory/.foot.new.1467/foot.changes 2023-07-24 18:26:05.482194155 +0200 @@ -1,0 +2,13 @@ +Fri Jul 21 07:11:08 UTC 2023 - Arnav Singh <opens...@arnavion.dev> + +- Update to v1.15.1: + * Background transparency (alpha) is now disabled in fullscreened windows. + * systemd service and socket units of foot-server are no longer instanced + on the WAYLAND_DISPLAY env var. They are now singletons and part of + the standard graphical-session.target. This also means the socket path + does not incorporate the WAYLAND_DISPLAY value. The list of socket paths + that footclient tries to connect to has been updated accordingly. + * Fixed various bugs related to fractional scaling, font sizes, and more. + * See https://codeberg.org/dnkl/foot/releases/tag/1.15.1 for more details. + +------------------------------------------------------------------- Old: ---- foot-1.15.0.tar.gz New: ---- foot-1.15.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ foot.spec ++++++ --- /var/tmp/diff_new_pack.HJGrvs/_old 2023-07-24 18:26:06.146198056 +0200 +++ /var/tmp/diff_new_pack.HJGrvs/_new 2023-07-24 18:26:06.154198102 +0200 @@ -17,7 +17,7 @@ Name: foot -Version: 1.15.0 +Version: 1.15.1 Release: 0 Summary: A Wayland terminal emulator License: MIT @@ -108,8 +108,8 @@ %{_mandir}/man1/footclient.1.gz %{_mandir}/man5/foot.ini.5.gz %{_mandir}/man7/foot-ctlseqs.7.gz -%{_userunitdir}/foot-server@.service -%{_userunitdir}/foot-server@.socket +%{_userunitdir}/foot-server.service +%{_userunitdir}/foot-server.socket %files extra-terminfo %{_datadir}/terminfo/f/foot-extra ++++++ foot-1.15.0.tar.gz -> foot-1.15.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/CHANGELOG.md new/foot/CHANGELOG.md --- old/foot/CHANGELOG.md 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/CHANGELOG.md 2023-07-21 08:57:03.000000000 +0200 @@ -1,5 +1,6 @@ # Changelog +* [1.15.1](#1-15-1) * [1.15.0](#1-15-0) * [1.14.0](#1-14-0) * [1.13.1](#1-13-1) @@ -42,6 +43,61 @@ * [1.2.0](#1-2-0) +## 1.15.1 + +### Changed + +* When window is mapped, use metadata (DPI, scaling factor, subpixel + configuration) from the monitor we were most recently mapped on, + instead of the one least recently. +* Starlight theme (the default theme) updated to [V4][starlight-v4] +* Background transparency (alpha) is now disabled in fullscreened + windows ([#1416][1416]). +* Foot server systemd units now use the standard + graphical-session.target ([#1281][1281]). +* If `$XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock` does not exist, + `footclient` now tries `$XDG_RUNTIME_DIR/foot.sock`, then + `/tmp/foot.sock`, even if `$WAYLAND_DISPLAY` and/or + `$XDG_RUNTIME_DIR` are defined ([#1281][1281]). +* Font baseline calculation: try to center the text within the line, + instead of anchoring it at the top ([#1302][1302]). + +[starlight-v4]: https://github.com/CosmicToast/starlight/blob/v4/CHANGELOG.md#v4 +[1416]: https://codeberg.org/dnkl/foot/issues/1416 +[1281]: https://codeberg.org/dnkl/foot/pulls/1281 +[1302]: https://codeberg.org/dnkl/foot/issues/1302 + + +### Fixed + +* Use appropriate rounding when applying fractional scales. +* Xcursor not being scaled correctly on `fractional-scale-v1` capable + compositors. +* `dpi-aware=yes` being broken on `fractional-scale-v1` capable + compositors (and when a fractional scaling factor is being used) + ([#1404][1404]). +* Initial font size being wrong on `fractional-scale-v1` capable + compositors, with multiple monitors with different scaling factors + connected ([#1404][1404]). +* Crash when _pointer capability_ is removed from a seat, on + compositors without `cursor-shape-v1 support` ([#1411][1411]). +* Crash on exit, if the mouse is hovering over the foot window (does + not happen on all compositors) +* Visual glitches when CSD titlebar is transparent. + +[1404]: https://codeberg.org/dnkl/foot/issues/1404 +[1411]: https://codeberg.org/dnkl/foot/pulls/1411 + + +### Contributors + +* Ayush Agarwal +* CismonX +* Max Gautier +* Ronan Pigott +* xdavidwu + + ## 1.15.0 ### Added diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/client.c new/foot/client.c --- old/foot/client.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/client.c 2023-07-21 08:57:03.000000000 +0200 @@ -374,16 +374,19 @@ const char *xdg_runtime = getenv("XDG_RUNTIME_DIR"); if (xdg_runtime != NULL) { const char *wayland_display = getenv("WAYLAND_DISPLAY"); - if (wayland_display != NULL) + if (wayland_display != NULL) { snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/foot-%s.sock", xdg_runtime, wayland_display); - else + connected = (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) == 0); + } + if (!connected) { + LOG_WARN("%s: failed to connect, will now try %s/foot.sock", + addr.sun_path, xdg_runtime); snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/foot.sock", xdg_runtime); - - if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) == 0) - connected = true; - else + connected = (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) == 0); + } + if (!connected) LOG_WARN("%s: failed to connect, will now try /tmp/foot.sock", addr.sun_path); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/config.c new/foot/config.c --- old/foot/config.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/config.c 2023-07-21 08:57:03.000000000 +0200 @@ -49,22 +49,22 @@ static const uint32_t default_color_table[256] = { // Regular 0x242424, - 0xcf1745, - 0x3ecf5b, - 0xcfcf17, - 0x0ba6da, - 0xd926ac, - 0x17cfa1, + 0xf62b5a, + 0x47b413, + 0xe3c401, + 0x24acd4, + 0xf2affd, + 0x13c299, 0xe6e6e6, // Bright 0x616161, - 0xff1a53, - 0x17e640, - 0xecff1a, - 0x1ac6ff, - 0xf53dc7, - 0x1affc6, + 0xff4d51, + 0x35d450, + 0xe9e836, + 0x5dc5f8, + 0xfeabf2, + 0x24dfc4, 0xffffff, // 6x6x6 RGB cube diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/doc/foot.1.scd new/foot/doc/foot.1.scd --- old/foot/doc/foot.1.scd 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/doc/foot.1.scd 2023-07-21 08:57:03.000000000 +0200 @@ -121,14 +121,14 @@ of a socket provided by a supervision daemon (such as systemd or s6), and use that socket as it's own. - Two systemd units (foot-server@.{service,socket}) are provided to use that - feature with systemd. They need to be instantiated with the value of - $WAYLAND_DISPLAY (multiples instances can co-exists). + Two systemd units (foot-server.{service,socket}) are provided to use that + feature with systemd. To use socket activation, only enable the + socket unit. Note that starting *foot --server* as a systemd service will use - the environment of the systemd user instance; thus, if you need specific - environment variables, you'll need to import them using *systemctl --user - import-environment* or use a drop-in for the foot-server service. + the environment of the systemd user instance; thus, you'll need + to import *$WAYLAND_DISPLAY* in it using *systemctl --user + import-environment WAYLAND_DISPLAY*. *-H*,*--hold* Remain open after child process exits. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/doc/foot.ini.5.scd new/foot/doc/foot.ini.5.scd --- old/foot/doc/foot.ini.5.scd 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/doc/foot.ini.5.scd 2023-07-21 08:57:03.000000000 +0200 @@ -563,15 +563,15 @@ *regular0*, *regular1* *..* *regular7* The eight basic ANSI colors (Black, Red, Green, Yellow, Blue, - Magenta, Cyan, White). Default: _242424_, _cf1745_, _3ecf5b_, - _cfcf17_, _0ba6da_, _d926ac_, _17cfa1_, _e6e6e6_ (starlight - theme). + Magenta, Cyan, White). Default: _242424_, _f62b5a_, _47b413_, + _e3c401_, _24acd4_, _f2affd_, _13c299_, _e6e6e6_ (starlight + theme, V4). *bright0*, *bright1* *..* *bright7* The eight bright ANSI colors (Black, Red, Green, Yellow, Blue, - Magenta, Cyan, White). Default: _616161_, _ff1a53_, _17e640_, - _ecff1a_, _1ac6ff_, _f53dc7_, _1affc6_, _ffffff_ (starlight - theme). + Magenta, Cyan, White). Default: _616161_, _ff4d51_, _35d450_, + _e9e836_, _5dc5f8_, _feabf2_, _24dfc4_, _ffffff_ (starlight + theme, V4). *dim0*, *dim1* *..* *dim7* Custom colors to use with dimmed colors. Dimmed colors do not have diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/doc/footclient.1.scd new/foot/doc/footclient.1.scd --- old/foot/doc/footclient.1.scd 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/doc/footclient.1.scd 2023-07-21 08:57:03.000000000 +0200 @@ -146,6 +146,11 @@ Used to construct the default _PATH_ for the *--server-socket* option, when no explicit argument is given (see above). +If the socket at default _PATH_ does not exist, *footclient* will +fallback to the less specific path, with the following priority: +*$XDG\_RUNTIME\_DIR/foot-$WAYLAND\_DISPLAY.sock*, +*$XDG\_RUNTIME\_DIR/foot.sock*, */tmp/foot.sock*. + ## Variables set in the child process *TERM* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/foot-server.service.in new/foot/foot-server.service.in --- old/foot/foot-server.service.in 1970-01-01 01:00:00.000000000 +0100 +++ new/foot/foot-server.service.in 2023-07-21 08:57:03.000000000 +0200 @@ -0,0 +1,13 @@ +[Service] +ExecStart=@bindir@/foot --server=3 +UnsetEnvironment=LISTEN_PID LISTEN_FDS LISTEN_FDNAMES +NonBlocking=true + +[Unit] +Requires=%N.socket +Description=Foot terminal server mode +Documentation=man:foot(1) +PartOf=graphical-session.target + +[Install] +WantedBy=graphical-session.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/foot-server.socket new/foot/foot-server.socket --- old/foot/foot-server.socket 1970-01-01 01:00:00.000000000 +0100 +++ new/foot/foot-server.socket 2023-07-21 08:57:03.000000000 +0200 @@ -0,0 +1,9 @@ +[Socket] +ListenStream=%t/foot.sock + +[Unit] +PartOf=graphical-session.target +ConditionEnvironment=WAYLAND_DISPLAY + +[Install] +WantedBy=graphical-session.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/foot-ser...@.service.in new/foot/foot-ser...@.service.in --- old/foot/foot-ser...@.service.in 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/foot-ser...@.service.in 1970-01-01 01:00:00.000000000 +0100 @@ -1,13 +0,0 @@ -[Service] -ExecStart=@bindir@/foot --server=3 -Environment=WAYLAND_DISPLAY=%i -UnsetEnvironment=LISTEN_PID LISTEN_FDS LISTEN_FDNAMES -NonBlocking=true - -[Unit] -Requires=%N.socket -Description=Foot terminal server mode for WAYLAND_DISPLAY=%i -Documentation=man:foot(1) - -[Install] -WantedBy=wayland-instance@.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/foot-server@.socket new/foot/foot-server@.socket --- old/foot/foot-server@.socket 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/foot-server@.socket 1970-01-01 01:00:00.000000000 +0100 @@ -1,5 +0,0 @@ -[Socket] -ListenStream=%t/foot-%i.sock - -[Install] -WantedBy=wayland-instance@.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/foot.ini new/foot/foot.ini --- old/foot/foot.ini 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/foot.ini 2023-07-21 08:57:03.000000000 +0200 @@ -75,27 +75,27 @@ [colors] # alpha=1.0 -# background=002b36 -# foreground=839496 +# background=242424 +# foreground=ffffff ## Normal/regular colors (color palette 0-7) -# regular0=073642 # black -# regular1=dc322f # red -# regular2=859900 # green -# regular3=b58900 # yellow -# regular4=268bd2 # blue -# regular5=d33682 # magenta -# regular6=2aa198 # cyan -# regular7=eee8d5 # white +# regular0=242424 # black +# regular1=f62b5a # red +# regular2=47b413 # green +# regular3=e3c401 # yellow +# regular4=24acd4 # blue +# regular5=f2affd # magenta +# regular6=13c299 # cyan +# regular7=e6e6e6 # white ## Bright colors (color palette 8-15) -# bright0=08404f # bright black -# bright1=e35f5c # bright red -# bright2=9fb700 # bright green -# bright3=d9a400 # bright yellow -# bright4=4ba1de # bright blue -# bright5=dc619d # bright magenta -# bright6=32c1b6 # bright cyan +# bright0=616161 # bright black +# bright1=ff4d51 # bright red +# bright2=35d450 # bright green +# bright3=e9e836 # bright yellow +# bright4=5dc5f8 # bright blue +# bright5=feabf2 # bright magenta +# bright6=24dfc4 # bright cyan # bright7=ffffff # bright white ## dimmed colors (see foot.ini(5) man page) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/input.c new/foot/input.c --- old/foot/input.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/input.c 2023-07-21 08:57:03.000000000 +0200 @@ -2739,8 +2739,6 @@ struct terminal *term = win->term; term->active_surface = term_surface_kind(term, surface); - if (term->active_surface != TERM_SURF_GRID) - return; LOG_DBG("touch_down: touch=%p, x=%d, y=%d", (void *)wl_touch, wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); @@ -2785,6 +2783,7 @@ WL_POINTER_BUTTON_STATE_RELEASED); /* fallthrough */ case TOUCH_STATE_SCROLLING: + term->active_surface = TERM_SURF_NONE; seat->touch.state = TOUCH_STATE_IDLE; break; @@ -2815,7 +2814,7 @@ switch (seat->touch.state) { case TOUCH_STATE_HELD: - if (time <= seat->touch.time) { + if (time <= seat->touch.time && term->active_surface == TERM_SURF_GRID) { if (touch_to_scroll(seat, term, surface_x, surface_y)) seat->touch.state = TOUCH_STATE_SCROLLING; break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/meson.build new/foot/meson.build --- old/foot/meson.build 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/meson.build 2023-07-21 08:57:03.000000000 +0200 @@ -1,5 +1,5 @@ project('foot', 'c', - version: '1.15.0', + version: '1.15.1', license: 'MIT', meson_version: '>=0.59.0', default_options: [ @@ -329,13 +329,13 @@ configure_file( configuration: configuration, - input: 'foot-ser...@.service.in', + input: 'foot-server.service.in', output: '@BASENAME@', install_dir: systemd_units_dir ) install_data( - 'foot-server@.socket', + 'foot-server.socket', install_dir: systemd_units_dir) endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/pgo/pgo.c new/foot/pgo/pgo.c --- old/foot/pgo/pgo.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/pgo/pgo.c 2023-07-21 08:57:03.000000000 +0200 @@ -96,6 +96,7 @@ void wayl_win_destroy(struct wl_window *win) {} void wayl_win_alpha_changed(struct wl_window *win) {} bool wayl_win_set_urgent(struct wl_window *win) { return true; } +bool wayl_fractional_scaling(const struct wayland *wayl) { return true; } bool spawn(struct reaper *reaper, const char *cwd, char *const argv[], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/render.c new/foot/render.c --- old/foot/render.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/render.c 2023-07-21 08:57:03.000000000 +0200 @@ -305,7 +305,12 @@ static inline int font_baseline(const struct terminal *term) { - return term->font_y_ofs + term->fonts[0]->ascent; + const struct fcft_font *font = term->fonts[0]; + const int line_height = term->cell_height; + const int font_height = font->ascent + font->descent; + const int glyph_top_y = round((line_height - font_height) / 2.); + + return term->font_y_ofs + glyph_top_y + font->ascent; } static void @@ -526,8 +531,35 @@ uint32_t swap = _fg; _fg = _bg; _bg = swap; - } else if (cell->attrs.bg_src == COLOR_DEFAULT) - alpha = term->colors.alpha; + } + + else if (cell->attrs.bg_src == COLOR_DEFAULT) { + if (term->window->is_fullscreen) { + /* + * Note: disable transparency when fullscreened. + * + * This is because the wayland protocol recommends + * (mandates even?) the compositor render a black + * background behind fullscreened transparent windows. + * + * In other words, transparency does not work when + * fullscreened, in the sense that you don't see + * what's behind the window. + * + * And if we keep our alpha channel, the background + * color will just look weird. For example, if the + * background color is white, and alpha is 0.5, then + * the window will be drawn in a shade of gray while + * fullscreened. + * + * By disabling the alpha channel, the window will at + * least be rendered in the intended background color. + */ + xassert(alpha == 0xffff); + } else { + alpha = term->colors.alpha; + } + } } if (unlikely(is_selected && _fg == _bg)) { @@ -1926,12 +1958,15 @@ wl_surface_attach(sub_surf->surface.surf, buf->wl_buf, 0, 0); wl_surface_damage_buffer(sub_surf->surface.surf, 0, 0, buf->width, buf->height); - struct wl_region *region = wl_compositor_create_region(term->wl->compositor); - if (region != NULL) { - wl_region_add(region, 0, 0, buf->width, buf->height); - wl_surface_set_opaque_region(sub_surf->surface.surf, region); - wl_region_destroy(region); - } + if (alpha == 0xffff) { + struct wl_region *region = wl_compositor_create_region(term->wl->compositor); + if (region != NULL) { + wl_region_add(region, 0, 0, buf->width, buf->height); + wl_surface_set_opaque_region(sub_surf->surface.surf, region); + wl_region_destroy(region); + } + } else + wl_surface_set_opaque_region(sub_surf->surface.surf, NULL); wl_surface_commit(sub_surf->surface.surf); quirk_weston_subsurface_desync_off(sub_surf->sub); @@ -3841,23 +3876,9 @@ if (term->cell_width == 0 && term->cell_height == 0) return false; - float scale = -1; - if (wayl_fractional_scaling(term->wl)) { - scale = term->window->scale; - } else { - tll_foreach(term->window->on_outputs, it) { - if (it->item->scale > scale) - scale = it->item->scale; - } - } - - if (scale < 0.) { - /* Haven't 'entered' an output yet? */ - scale = term->scale; - } - - width *= scale; - height *= scale; + const float scale = term->scale; + width = round(width * scale); + height = round(height * scale); if (width == 0 && height == 0) { /* @@ -3942,9 +3963,9 @@ /* Drop out of URL mode */ urls_reset(term); + LOG_DBG("resized: size=%dx%d (scale=%.2f)", width, height, term->scale); term->width = width; term->height = height; - term->scale = scale; const uint32_t scrollback_lines = term->render.scrollback_lines; @@ -4148,12 +4169,11 @@ sixel_reflow(term); -#if defined(_DEBUG) && LOG_ENABLE_DBG - LOG_DBG("resize: %dx%d, grid: cols=%d, rows=%d " + LOG_DBG("resized: grid: cols=%d, rows=%d " "(left-margin=%d, right-margin=%d, top-margin=%d, bottom-margin=%d)", - term->width, term->height, term->cols, term->rows, - term->margins.left, term->margins.right, term->margins.top, term->margins.bottom); -#endif + term->cols, term->rows, + term->margins.left, term->margins.right, + term->margins.top, term->margins.bottom); if (term->scroll_region.start >= term->rows) term->scroll_region.start = 0; @@ -4295,13 +4315,17 @@ #endif LOG_DBG("setting %scursor shape using a client-side cursor surface", - shape == CURSOR_SHAPE_CUSTOM ? "custom " : ""); + seat->pointer.shape == CURSOR_SHAPE_CUSTOM ? "custom " : ""); - const int scale = seat->pointer.scale; + const float scale = seat->pointer.scale; struct wl_cursor_image *image = seat->pointer.cursor->images[0]; + struct wl_buffer *buf = wl_cursor_image_get_buffer(image); + + wayl_surface_scale_explicit_width_height( + seat->mouse_focus->window, + &seat->pointer.surface, image->width, image->height, scale); - wl_surface_attach( - seat->pointer.surface.surf, wl_cursor_image_get_buffer(image), 0, 0); + wl_surface_attach(seat->pointer.surface.surf, buf, 0, 0); wl_pointer_set_cursor( seat->wl_pointer, seat->pointer.serial, @@ -4311,8 +4335,6 @@ wl_surface_damage_buffer( seat->pointer.surface.surf, 0, 0, INT32_MAX, INT32_MAX); - wl_surface_set_buffer_scale(seat->pointer.surface.surf, scale); - xassert(seat->pointer.xcursor_callback == NULL); seat->pointer.xcursor_callback = wl_surface_frame(seat->pointer.surface.surf); wl_callback_add_listener(seat->pointer.xcursor_callback, &xcursor_listener, seat); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/terminal.c new/foot/terminal.c --- old/foot/terminal.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/terminal.c 2023-07-21 08:57:03.000000000 +0200 @@ -733,7 +733,8 @@ } static bool -term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4]) +term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4], + bool resize_grid) { for (size_t i = 0; i < 4; i++) { xassert(fonts[i] != NULL); @@ -777,8 +778,15 @@ sixel_cell_size_changed(term); - /* Use force, since cell-width/height may have changed */ - render_resize_force(term, term->width / term->scale, term->height / term->scale); + /* Optimization - some code paths (are forced to) call + * render_resize() after this function */ + if (resize_grid) { + /* Use force, since cell-width/height may have changed */ + render_resize_force( + term, + round(term->width / term->scale), + round(term->height / term->scale)); + } return true; } @@ -793,41 +801,34 @@ * Conceptually, we use the physical monitor specs to calculate * the DPI, and we ignore the output's scaling factor. * - * However, to deal with fractional scaling, where we're told to - * render at e.g. 2x, but are then downscaled by the compositor to - * e.g. 1.25, we use the scaled DPI value multiplied by the scale - * factor instead. + * However, to deal with legacy fractional scaling, where we're + * told to render at e.g. 2x, but are then downscaled by the + * compositor to e.g. 1.25, we use the scaled DPI value multiplied + * by the scale factor instead. * * For integral scaling factors the resulting DPI is the same as * if we had used the physical DPI. * - * For fractional scaling factors we'll get a DPI *larger* than - * the physical DPI, that ends up being right when later + * For legacy fractional scaling factors we'll get a DPI *larger* + * than the physical DPI, that ends up being right when later * downscaled by the compositor. + * + * With the newer fractional-scale-v1 protocol, we use the + * monitorâs real DPI, since we scale everything to the correct + * scaling factor (no downscaling done by the compositor). */ - /* Use highest DPI from outputs we're mapped on */ - double dpi = 0.0; - xassert(term->window != NULL); - tll_foreach(term->window->on_outputs, it) { - if (it->item->dpi > dpi) - dpi = it->item->dpi; - } - - /* If we're not mapped, use DPI from first monitor. Hopefully this is where we'll get mapped later... */ - if (dpi == 0.) { - tll_foreach(term->wl->monitors, it) { - dpi = it->item.dpi; - break; - } - } + xassert(tll_length(term->wl->monitors) > 0); - if (dpi == 0) { - /* No monitors? */ - dpi = 96.; - } + const struct wl_window *win = term->window; + const struct monitor *mon = tll_length(win->on_outputs) > 0 + ? tll_back(win->on_outputs) + : &tll_front(term->wl->monitors); - return dpi; + if (wayl_fractional_scaling(term->wl)) + return mon->dpi.physical; + else + return mon->dpi.scaled; } static enum fcft_subpixel @@ -846,7 +847,8 @@ * output or not. * * Thus, when determining which subpixel mode to use, we can't do - * much but select *an* output. So, we pick the first one. + * much but select *an* output. So, we pick the one we were most + * recently mapped on. * * If we're not mapped at all, we pick the first available * monitor, and hope that's where we'll eventually get mapped. @@ -856,7 +858,7 @@ */ if (tll_length(term->window->on_outputs) > 0) - wl_subpixel = tll_front(term->window->on_outputs)->subpixel; + wl_subpixel = tll_back(term->window->on_outputs)->subpixel; else if (tll_length(term->wl->monitors) > 0) wl_subpixel = tll_front(term->wl->monitors).subpixel; else @@ -903,7 +905,7 @@ } static bool -reload_fonts(struct terminal *term) +reload_fonts(struct terminal *term, bool resize_grid) { const struct config *conf = term->conf; @@ -1030,7 +1032,7 @@ } } - return success ? term_set_fonts(term, fonts) : success; + return success ? term_set_fonts(term, fonts, resize_grid) : success; } static bool @@ -1048,7 +1050,7 @@ } } - return reload_fonts(term); + return reload_fonts(term, true); } static void fdm_client_terminated( @@ -1282,11 +1284,9 @@ reaper_add(term->reaper, term->slave, &fdm_client_terminated, term); /* Guess scale; we're not mapped yet, so we don't know on which - * output we'll be. Pick highest scale we find for now */ - tll_foreach(term->wl->monitors, it) { - if (it->item.scale > term->scale) - term->scale = it->item.scale; - } + * output we'll be. Use scaling factor from first monitor */ + xassert(tll_length(term->wl->monitors) > 0); + term->scale = tll_front(term->wl->monitors).scale; memcpy(term->colors.table, term->conf->colors.table, sizeof(term->colors.table)); @@ -1295,7 +1295,7 @@ goto err; /* Load fonts */ - if (!term_font_dpi_changed(term, 0)) + if (!term_font_dpi_changed(term, 0.)) goto err; term->font_subpixel = get_font_subpixel(term); @@ -1607,8 +1607,6 @@ if (term == NULL) return 0; - key_binding_unref(term->wl->key_binding_manager, term->conf); - tll_foreach(term->wl->terms, it) { if (it->item == term) { tll_remove(term->wl->terms, it); @@ -1654,6 +1652,8 @@ } mtx_unlock(&term->render.workers.lock); + key_binding_unref(term->wl->key_binding_manager, term->conf); + urls_reset(term); free(term->vt.osc.data); @@ -1993,7 +1993,7 @@ } } - return reload_fonts(term); + return reload_fonts(term, true); } static bool @@ -2016,7 +2016,7 @@ } } - return reload_fonts(term); + return reload_fonts(term, true); } static bool @@ -2040,7 +2040,7 @@ } } - return reload_fonts(term); + return reload_fonts(term, true); } bool @@ -2078,10 +2078,40 @@ } bool -term_font_dpi_changed(struct terminal *term, int old_scale) +term_update_scale(struct terminal *term) +{ + const struct wl_window *win = term->window; + + /* + * We have a number of âsourcesâ we can use as scale. We choose + * the scale in the following order: + * + * - âpreferredâ scale, from the fractional-scale-v1 protocol + * - scaling factor of output we most recently were mapped on + * - if weâre not mapped, use the scaling factor from the first + * available output. + * - if there arenât any outputs available, use 1.0 + */ + const float new_scale = + (wayl_fractional_scaling(term->wl) && win->scale > 0. + ? win->scale + : (tll_length(win->on_outputs) > 0 + ? tll_back(win->on_outputs)->scale + : 1.)); + + if (new_scale == term->scale) + return false; + + LOG_DBG("scaling factor changed: %.2f -> %.2f", term->scale, new_scale); + term->scale = new_scale; + return true; +} + +bool +term_font_dpi_changed(struct terminal *term, float old_scale) { float dpi = get_font_dpi(term); - xassert(term->scale > 0); + xassert(term->scale > 0.); bool was_scaled_using_dpi = term->font_is_sized_by_dpi; bool will_scale_using_dpi = term->conf->dpi_aware; @@ -2093,11 +2123,10 @@ : old_scale != term->scale); if (need_font_reload) { - LOG_DBG("DPI/scale change: DPI-awareness=%s, " - "DPI: %.2f -> %.2f, scale: %d -> %d, " + LOG_DBG("DPI/scale change: DPI-aware=%s, " + "DPI: %.2f -> %.2f, scale: %.2f -> %.2f, " "sizing font based on monitor's %s", - term->conf->dpi_aware == DPI_AWARE_AUTO ? "auto" : - term->conf->dpi_aware == DPI_AWARE_YES ? "yes" : "no", + term->conf->dpi_aware ? "yes" : "no", term->font_dpi, dpi, old_scale, term->scale, will_scale_using_dpi ? "DPI" : "scaling factor"); } @@ -2106,9 +2135,9 @@ term->font_is_sized_by_dpi = will_scale_using_dpi; if (!need_font_reload) - return true; + return false; - return reload_fonts(term); + return reload_fonts(term, false); } void @@ -3507,7 +3536,7 @@ #if defined(_DEBUG) && LOG_ENABLE_DBG if (term->ascii_printer != new_printer) { - LOG_DBG("§switching ASCII printer %s -> %s", + LOG_DBG("switching ASCII printer %s -> %s", term->ascii_printer == &ascii_printer_fast ? "fast" : "generic", new_printer == &ascii_printer_fast ? "fast" : "generic"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/terminal.h new/foot/terminal.h --- old/foot/terminal.h 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/terminal.h 2023-07-21 08:57:03.000000000 +0200 @@ -736,10 +736,11 @@ bool term_paste_data_to_slave( struct terminal *term, const void *data, size_t len); +bool term_update_scale(struct terminal *term); bool term_font_size_increase(struct terminal *term); bool term_font_size_decrease(struct terminal *term); bool term_font_size_reset(struct terminal *term); -bool term_font_dpi_changed(struct terminal *term, int old_scale); +bool term_font_dpi_changed(struct terminal *term, float old_scale); void term_font_subpixel_changed(struct terminal *term); int term_pt_or_px_as_pixels( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/themes/chiba-dark new/foot/themes/chiba-dark --- old/foot/themes/chiba-dark 1970-01-01 01:00:00.000000000 +0100 +++ new/foot/themes/chiba-dark 2023-07-21 08:57:03.000000000 +0200 @@ -0,0 +1,27 @@ +# -*- conf -*- +# theme: Chiba Dark +# author: ayushnix (https://sr.ht/~ayushnix) +# description: A dark theme with bright cyberpunk colors (WCAG AAA compliant) + +[cursor] +color = 181818 cdcdcd + +[colors] +foreground = cdcdcd +background = 181818 +regular0 = 181818 +regular1 = ff8599 +regular2 = 00c545 +regular3 = de9d00 +regular4 = 00b4ff +regular5 = fd71f8 +regular6 = 00bfae +regular7 = cdcdcd +bright0 = 262626 +bright1 = ff9eb2 +bright2 = 19de5e +bright3 = f7b619 +bright4 = 19cdff +bright5 = ff8aff +bright6 = 19d8c7 +bright7 = dadada diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/themes/starlight new/foot/themes/starlight --- old/foot/themes/starlight 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/themes/starlight 2023-07-21 08:57:03.000000000 +0200 @@ -1,24 +1,24 @@ # -*- conf -*- -# Theme: starlight (https://github.com/CosmicToast/starlight) +# Theme: starlight V4 (https://github.com/CosmicToast/starlight) [colors] foreground = FFFFFF background = 242424 regular0 = 242424 -regular1 = CF1745 -regular2 = 3ECF5B -regular3 = CFCF17 -regular4 = 0BA6DA -regular5 = D926AC -regular6 = 17CFA1 -regular7 = E6E6E6 +regular1 = f62b5a +regular2 = 47b413 +regular3 = e3c401 +regular4 = 24acd4 +regular5 = f2affd +regular6 = 13c299 +regular7 = e6e6e6 bright0 = 616161 -bright1 = FF1A53 -bright2 = 17E640 -bright3 = ECFF1A -bright4 = 1AC6FF -bright5 = F53DC7 -bright6 = 1AFFC6 -bright7 = FFFFFF +bright1 = ff4d51 +bright2 = 35d450 +bright3 = e9e836 +bright4 = 5dc5f8 +bright5 = feabf2 +bright6 = 24dfc4 +bright7 = ffffff diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/vt.c new/foot/vt.c --- old/foot/vt.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/vt.c 2023-07-21 08:57:03.000000000 +0200 @@ -437,6 +437,27 @@ } static void +tab_set(struct terminal *term) +{ + int col = term->grid->cursor.point.col; + + if (tll_length(term->tab_stops) == 0 || tll_back(term->tab_stops) < col) { + tll_push_back(term->tab_stops, col); + return; + } + + tll_foreach(term->tab_stops, it) { + if (it->item < col) { + continue; + } + if (it->item > col) { + tll_insert_before(term->tab_stops, it, col); + } + break; + } +} + +static void action_esc_dispatch(struct terminal *term, uint8_t final) { LOG_DBG("ESC: %s", esc_as_string(term, final)); @@ -478,14 +499,7 @@ break; case 'H': - tll_foreach(term->tab_stops, it) { - if (it->item >= term->grid->cursor.point.col) { - tll_insert_before(term->tab_stops, it, term->grid->cursor.point.col); - break; - } - } - - tll_push_back(term->tab_stops, term->grid->cursor.point.col); + tab_set(term); break; case 'M': diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/wayland.c new/foot/wayland.c --- old/foot/wayland.c 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/wayland.c 2023-07-21 08:57:03.000000000 +0200 @@ -341,8 +341,10 @@ } else { if (seat->wl_pointer != NULL) { #if defined(HAVE_CURSOR_SHAPE) - wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device); - seat->pointer.shape_device = NULL; + if (seat->pointer.shape_device != NULL) { + wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device); + seat->pointer.shape_device = NULL; + } #endif wl_pointer_release(seat->wl_pointer); @@ -396,15 +398,35 @@ static void update_term_for_output_change(struct terminal *term) { - if (tll_length(term->window->on_outputs) == 0) - return; - - float old_scale = term->scale; - - render_resize(term, term->width / term->scale, term->height / term->scale); - term_font_dpi_changed(term, old_scale); + const float old_scale = term->scale; + const float logical_width = term->width / term->scale; + const float logical_height = term->height / term->scale; + + /* Note: order matters! term_update_scale() must come first */ + bool scale_updated = term_update_scale(term); + bool fonts_updated = term_font_dpi_changed(term, old_scale); term_font_subpixel_changed(term); + csd_reload_font(term->window, old_scale); + + if (fonts_updated) { + /* + * If the fonts have been updated, the cell dimensions have + * changed. This requires a âforcedâ resize, since the surface + * buffer dimensions may not have been updated (in which case + * render_size() normally shortcuts and returns early). + */ + render_resize_force(term, round(logical_width), round(logical_height)); + } + + else if (scale_updated) { + /* + * A scale update means the surface buffer dimensions have + * been updated, even though the window logical dimensions + * havenât changed. + */ + render_resize(term, round(logical_width), round(logical_height)); + } } static void @@ -433,6 +455,9 @@ double x_inches = mon->dim.mm.width * 0.03937008; double y_inches = mon->dim.mm.height * 0.03937008; + const int width = mon->dim.px_real.width; + const int height = mon->dim.px_real.height; + mon->ppi.real.x = mon->dim.px_real.width / x_inches; mon->ppi.real.y = mon->dim.px_real.height / y_inches; @@ -455,27 +480,36 @@ break; } - int scaled_width = mon->dim.px_scaled.width; - int scaled_height = mon->dim.px_scaled.height; - - if (scaled_width == 0 && scaled_height == 0 && mon->scale > 0) { - /* Estimate scaled width/height if none has been provided */ - scaled_width = mon->dim.px_real.width / mon->scale; - scaled_height = mon->dim.px_real.height / mon->scale; - } + const int scaled_width = mon->dim.px_scaled.width; + const int scaled_height = mon->dim.px_scaled.height; mon->ppi.scaled.x = scaled_width / x_inches; mon->ppi.scaled.y = scaled_height / y_inches; - double px_diag = sqrt(pow(scaled_width, 2) + pow(scaled_height, 2)); - mon->dpi = px_diag / mon->inch * mon->scale; + const double px_diag_physical = sqrt(pow(width, 2) + pow(height, 2)); + mon->dpi.physical = width == 0 && height == 0 + ? 96. + : px_diag_physical / mon->inch; + + const double px_diag_scaled = sqrt(pow(scaled_width, 2) + pow(scaled_height, 2)); + mon->dpi.scaled = scaled_width == 0 && scaled_height == 0 + ? 96. + : px_diag_scaled / mon->inch * mon->scale; - if (mon->dpi > 1000) { + if (mon->dpi.physical > 1000) { if (mon->name != NULL) { - LOG_WARN("%s: DPI=%f is unreasonable, using 96 instead", - mon->name, mon->dpi); + LOG_WARN("%s: DPI=%f (physical) is unreasonable, using 96 instead", + mon->name, mon->dpi.physical); } - mon->dpi = 96; + mon->dpi.physical = 96; + } + + if (mon->dpi.scaled > 1000) { + if (mon->name != NULL) { + LOG_WARN("%s: DPI=%f (logical) is unreasonable, using 96 instead", + mon->name, mon->dpi.scaled); + } + mon->dpi.scaled = 96; } } @@ -1433,6 +1467,11 @@ LOG_ERR("no seats available (wl_seat interface too old?)"); goto out; } + if (tll_length(wayl->monitors) == 0) { + LOG_ERR("no monitors available"); + goto out; + } + if (wayl->primary_selection_device_manager == NULL) LOG_WARN("no primary selection available"); @@ -1485,14 +1524,12 @@ tll_foreach(wayl->monitors, it) { LOG_INFO( - "%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d PPI=%dx%d (physical) PPI=%dx%d (logical), DPI=%.2f", + "%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d, DPI=%.2f/%.2f (physical/scaled)", it->item.name, it->item.dim.px_real.width, it->item.dim.px_real.height, it->item.x, it->item.y, (int)round(it->item.refresh), it->item.model != NULL ? it->item.model : it->item.description, it->item.inch, it->item.scale, - it->item.ppi.real.x, it->item.ppi.real.y, - it->item.ppi.scaled.x, it->item.ppi.scaled.y, - it->item.dpi); + it->item.dpi.physical, it->item.dpi.scaled); } wayl->fd = wl_display_get_fd(wayl->display); @@ -1601,10 +1638,15 @@ uint32_t scale) { struct wl_window *win = data; - win->scale = (float)scale / 120.; - win->have_preferred_scale = true; - LOG_DBG("fractional scale: %.3f", win->scale); + const float new_scale = (float)scale / 120.; + + if (win->scale == new_scale) + return; + + LOG_DBG("fractional scale: %.2f -> %.2f", win->scale, new_scale); + + win->scale = new_scale; update_term_for_output_change(win->term); } @@ -1969,7 +2011,7 @@ int width, int height, float scale) { - if (wayl_fractional_scaling(win->term->wl) && win->have_preferred_scale) { + if (wayl_fractional_scaling(win->term->wl) && win->scale > 0.) { #if defined(HAVE_FRACTIONAL_SCALE) LOG_DBG("scaling by a factor of %.2f using fractional scaling " "(width=%d, height=%d) ", scale, width, height); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/foot/wayland.h new/foot/wayland.h --- old/foot/wayland.h 2023-07-14 12:26:03.000000000 +0200 +++ new/foot/wayland.h 2023-07-21 08:57:03.000000000 +0200 @@ -315,7 +315,10 @@ } scaled; } ppi; - float dpi; + struct { + float scaled; + float physical; + } dpi; int scale; float refresh; @@ -374,7 +377,6 @@ bool unmapped; float scale; - bool have_preferred_scale; struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration;