mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-02 07:15:31 -04:00
Merge branch 'master' into releases/1.15
This commit is contained in:
commit
62c6c9a78a
21 changed files with 410 additions and 208 deletions
53
CHANGELOG.md
53
CHANGELOG.md
|
|
@ -1,5 +1,6 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
* [Unreleased](#unreleased)
|
||||||
* [1.15.0](#1-15-0)
|
* [1.15.0](#1-15-0)
|
||||||
* [1.14.0](#1-14-0)
|
* [1.14.0](#1-14-0)
|
||||||
* [1.13.1](#1-13-1)
|
* [1.13.1](#1-13-1)
|
||||||
|
|
@ -42,6 +43,58 @@
|
||||||
* [1.2.0](#1-2-0)
|
* [1.2.0](#1-2-0)
|
||||||
|
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
### Added
|
||||||
|
### 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
|
||||||
|
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
### Removed
|
||||||
|
### 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
|
||||||
|
|
||||||
|
|
||||||
|
### Security
|
||||||
|
### Contributors
|
||||||
|
|
||||||
|
|
||||||
## 1.15.0
|
## 1.15.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
15
client.c
15
client.c
|
|
@ -374,16 +374,19 @@ main(int argc, char *const *argv)
|
||||||
const char *xdg_runtime = getenv("XDG_RUNTIME_DIR");
|
const char *xdg_runtime = getenv("XDG_RUNTIME_DIR");
|
||||||
if (xdg_runtime != NULL) {
|
if (xdg_runtime != NULL) {
|
||||||
const char *wayland_display = getenv("WAYLAND_DISPLAY");
|
const char *wayland_display = getenv("WAYLAND_DISPLAY");
|
||||||
if (wayland_display != NULL)
|
if (wayland_display != NULL) {
|
||||||
snprintf(addr.sun_path, sizeof(addr.sun_path),
|
snprintf(addr.sun_path, sizeof(addr.sun_path),
|
||||||
"%s/foot-%s.sock", xdg_runtime, wayland_display);
|
"%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),
|
snprintf(addr.sun_path, sizeof(addr.sun_path),
|
||||||
"%s/foot.sock", xdg_runtime);
|
"%s/foot.sock", xdg_runtime);
|
||||||
|
connected = (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) == 0);
|
||||||
if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) == 0)
|
}
|
||||||
connected = true;
|
if (!connected)
|
||||||
else
|
|
||||||
LOG_WARN("%s: failed to connect, will now try /tmp/foot.sock", addr.sun_path);
|
LOG_WARN("%s: failed to connect, will now try /tmp/foot.sock", addr.sun_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
24
config.c
24
config.c
|
|
@ -49,22 +49,22 @@ static const size_t min_csd_border_width = 5;
|
||||||
static const uint32_t default_color_table[256] = {
|
static const uint32_t default_color_table[256] = {
|
||||||
// Regular
|
// Regular
|
||||||
0x242424,
|
0x242424,
|
||||||
0xcf1745,
|
0xf62b5a,
|
||||||
0x3ecf5b,
|
0x47b413,
|
||||||
0xcfcf17,
|
0xe3c401,
|
||||||
0x0ba6da,
|
0x24acd4,
|
||||||
0xd926ac,
|
0xf2affd,
|
||||||
0x17cfa1,
|
0x13c299,
|
||||||
0xe6e6e6,
|
0xe6e6e6,
|
||||||
|
|
||||||
// Bright
|
// Bright
|
||||||
0x616161,
|
0x616161,
|
||||||
0xff1a53,
|
0xff4d51,
|
||||||
0x17e640,
|
0x35d450,
|
||||||
0xecff1a,
|
0xe9e836,
|
||||||
0x1ac6ff,
|
0x5dc5f8,
|
||||||
0xf53dc7,
|
0xfeabf2,
|
||||||
0x1affc6,
|
0x24dfc4,
|
||||||
0xffffff,
|
0xffffff,
|
||||||
|
|
||||||
// 6x6x6 RGB cube
|
// 6x6x6 RGB cube
|
||||||
|
|
|
||||||
|
|
@ -121,14 +121,14 @@ the foot command line
|
||||||
of a socket provided by a supervision daemon (such as systemd or s6), and
|
of a socket provided by a supervision daemon (such as systemd or s6), and
|
||||||
use that socket as it's own.
|
use that socket as it's own.
|
||||||
|
|
||||||
Two systemd units (foot-server@.{service,socket}) are provided to use that
|
Two systemd units (foot-server.{service,socket}) are provided to use that
|
||||||
feature with systemd. They need to be instantiated with the value of
|
feature with systemd. To use socket activation, only enable the
|
||||||
$WAYLAND_DISPLAY (multiples instances can co-exists).
|
socket unit.
|
||||||
|
|
||||||
Note that starting *foot --server* as a systemd service will use
|
Note that starting *foot --server* as a systemd service will use
|
||||||
the environment of the systemd user instance; thus, if you need specific
|
the environment of the systemd user instance; thus, you'll need
|
||||||
environment variables, you'll need to import them using *systemctl --user
|
to import *$WAYLAND_DISPLAY* in it using *systemctl --user
|
||||||
import-environment* or use a drop-in for the foot-server service.
|
import-environment WAYLAND_DISPLAY*.
|
||||||
|
|
||||||
*-H*,*--hold*
|
*-H*,*--hold*
|
||||||
Remain open after child process exits.
|
Remain open after child process exits.
|
||||||
|
|
|
||||||
|
|
@ -563,15 +563,15 @@ can configure the background transparency with the _alpha_ option.
|
||||||
|
|
||||||
*regular0*, *regular1* *..* *regular7*
|
*regular0*, *regular1* *..* *regular7*
|
||||||
The eight basic ANSI colors (Black, Red, Green, Yellow, Blue,
|
The eight basic ANSI colors (Black, Red, Green, Yellow, Blue,
|
||||||
Magenta, Cyan, White). Default: _242424_, _cf1745_, _3ecf5b_,
|
Magenta, Cyan, White). Default: _242424_, _f62b5a_, _47b413_,
|
||||||
_cfcf17_, _0ba6da_, _d926ac_, _17cfa1_, _e6e6e6_ (starlight
|
_e3c401_, _24acd4_, _f2affd_, _13c299_, _e6e6e6_ (starlight
|
||||||
theme).
|
theme, V4).
|
||||||
|
|
||||||
*bright0*, *bright1* *..* *bright7*
|
*bright0*, *bright1* *..* *bright7*
|
||||||
The eight bright ANSI colors (Black, Red, Green, Yellow, Blue,
|
The eight bright ANSI colors (Black, Red, Green, Yellow, Blue,
|
||||||
Magenta, Cyan, White). Default: _616161_, _ff1a53_, _17e640_,
|
Magenta, Cyan, White). Default: _616161_, _ff4d51_, _35d450_,
|
||||||
_ecff1a_, _1ac6ff_, _f53dc7_, _1affc6_, _ffffff_ (starlight
|
_e9e836_, _5dc5f8_, _feabf2_, _24dfc4_, _ffffff_ (starlight
|
||||||
theme).
|
theme, V4).
|
||||||
|
|
||||||
*dim0*, *dim1* *..* *dim7*
|
*dim0*, *dim1* *..* *dim7*
|
||||||
Custom colors to use with dimmed colors. Dimmed colors do not have
|
Custom colors to use with dimmed colors. Dimmed colors do not have
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,11 @@ terminfo entries manually, by copying *foot* and *foot-direct* to
|
||||||
Used to construct the default _PATH_ for the *--server-socket*
|
Used to construct the default _PATH_ for the *--server-socket*
|
||||||
option, when no explicit argument is given (see above).
|
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
|
## Variables set in the child process
|
||||||
|
|
||||||
*TERM*
|
*TERM*
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=@bindir@/foot --server=3
|
ExecStart=@bindir@/foot --server=3
|
||||||
Environment=WAYLAND_DISPLAY=%i
|
|
||||||
UnsetEnvironment=LISTEN_PID LISTEN_FDS LISTEN_FDNAMES
|
UnsetEnvironment=LISTEN_PID LISTEN_FDS LISTEN_FDNAMES
|
||||||
NonBlocking=true
|
NonBlocking=true
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Requires=%N.socket
|
Requires=%N.socket
|
||||||
Description=Foot terminal server mode for WAYLAND_DISPLAY=%i
|
Description=Foot terminal server mode
|
||||||
Documentation=man:foot(1)
|
Documentation=man:foot(1)
|
||||||
|
PartOf=graphical-session.target
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=wayland-instance@.target
|
WantedBy=graphical-session.target
|
||||||
9
foot-server.socket
Normal file
9
foot-server.socket
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Socket]
|
||||||
|
ListenStream=%t/foot.sock
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
PartOf=graphical-session.target
|
||||||
|
ConditionEnvironment=WAYLAND_DISPLAY
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=graphical-session.target
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
[Socket]
|
|
||||||
ListenStream=%t/foot-%i.sock
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=wayland-instance@.target
|
|
||||||
34
foot.ini
34
foot.ini
|
|
@ -75,27 +75,27 @@
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
# alpha=1.0
|
# alpha=1.0
|
||||||
# background=002b36
|
# background=242424
|
||||||
# foreground=839496
|
# foreground=ffffff
|
||||||
|
|
||||||
## Normal/regular colors (color palette 0-7)
|
## Normal/regular colors (color palette 0-7)
|
||||||
# regular0=073642 # black
|
# regular0=242424 # black
|
||||||
# regular1=dc322f # red
|
# regular1=f62b5a # red
|
||||||
# regular2=859900 # green
|
# regular2=47b413 # green
|
||||||
# regular3=b58900 # yellow
|
# regular3=e3c401 # yellow
|
||||||
# regular4=268bd2 # blue
|
# regular4=24acd4 # blue
|
||||||
# regular5=d33682 # magenta
|
# regular5=f2affd # magenta
|
||||||
# regular6=2aa198 # cyan
|
# regular6=13c299 # cyan
|
||||||
# regular7=eee8d5 # white
|
# regular7=e6e6e6 # white
|
||||||
|
|
||||||
## Bright colors (color palette 8-15)
|
## Bright colors (color palette 8-15)
|
||||||
# bright0=08404f # bright black
|
# bright0=616161 # bright black
|
||||||
# bright1=e35f5c # bright red
|
# bright1=ff4d51 # bright red
|
||||||
# bright2=9fb700 # bright green
|
# bright2=35d450 # bright green
|
||||||
# bright3=d9a400 # bright yellow
|
# bright3=e9e836 # bright yellow
|
||||||
# bright4=4ba1de # bright blue
|
# bright4=5dc5f8 # bright blue
|
||||||
# bright5=dc619d # bright magenta
|
# bright5=feabf2 # bright magenta
|
||||||
# bright6=32c1b6 # bright cyan
|
# bright6=24dfc4 # bright cyan
|
||||||
# bright7=ffffff # bright white
|
# bright7=ffffff # bright white
|
||||||
|
|
||||||
## dimmed colors (see foot.ini(5) man page)
|
## dimmed colors (see foot.ini(5) man page)
|
||||||
|
|
|
||||||
5
input.c
5
input.c
|
|
@ -2739,8 +2739,6 @@ wl_touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
||||||
struct terminal *term = win->term;
|
struct terminal *term = win->term;
|
||||||
|
|
||||||
term->active_surface = term_surface_kind(term, surface);
|
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,
|
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));
|
wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y));
|
||||||
|
|
@ -2785,6 +2783,7 @@ wl_touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
||||||
WL_POINTER_BUTTON_STATE_RELEASED);
|
WL_POINTER_BUTTON_STATE_RELEASED);
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case TOUCH_STATE_SCROLLING:
|
case TOUCH_STATE_SCROLLING:
|
||||||
|
term->active_surface = TERM_SURF_NONE;
|
||||||
seat->touch.state = TOUCH_STATE_IDLE;
|
seat->touch.state = TOUCH_STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2815,7 +2814,7 @@ wl_touch_motion(void *data, struct wl_touch *wl_touch, uint32_t time,
|
||||||
|
|
||||||
switch (seat->touch.state) {
|
switch (seat->touch.state) {
|
||||||
case TOUCH_STATE_HELD:
|
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))
|
if (touch_to_scroll(seat, term, surface_x, surface_y))
|
||||||
seat->touch.state = TOUCH_STATE_SCROLLING;
|
seat->touch.state = TOUCH_STATE_SCROLLING;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -329,13 +329,13 @@ if systemd.found() or custom_systemd_units_dir != ''
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
input: 'foot-server@.service.in',
|
input: 'foot-server.service.in',
|
||||||
output: '@BASENAME@',
|
output: '@BASENAME@',
|
||||||
install_dir: systemd_units_dir
|
install_dir: systemd_units_dir
|
||||||
)
|
)
|
||||||
|
|
||||||
install_data(
|
install_data(
|
||||||
'foot-server@.socket',
|
'foot-server.socket',
|
||||||
install_dir: systemd_units_dir)
|
install_dir: systemd_units_dir)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ wayl_win_init(struct terminal *term, const char *token)
|
||||||
void wayl_win_destroy(struct wl_window *win) {}
|
void wayl_win_destroy(struct wl_window *win) {}
|
||||||
void wayl_win_alpha_changed(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_win_set_urgent(struct wl_window *win) { return true; }
|
||||||
|
bool wayl_fractional_scaling(const struct wayland *wayl) { return true; }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
spawn(struct reaper *reaper, const char *cwd, char *const argv[],
|
spawn(struct reaper *reaper, const char *cwd, char *const argv[],
|
||||||
|
|
|
||||||
98
render.c
98
render.c
|
|
@ -305,7 +305,12 @@ color_brighten(const struct terminal *term, uint32_t color)
|
||||||
static inline int
|
static inline int
|
||||||
font_baseline(const struct terminal *term)
|
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
|
static void
|
||||||
|
|
@ -526,8 +531,35 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
||||||
uint32_t swap = _fg;
|
uint32_t swap = _fg;
|
||||||
_fg = _bg;
|
_fg = _bg;
|
||||||
_bg = swap;
|
_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)) {
|
if (unlikely(is_selected && _fg == _bg)) {
|
||||||
|
|
@ -1926,12 +1958,15 @@ render_osd(struct terminal *term, const struct wayl_sub_surface *sub_surf,
|
||||||
wl_surface_attach(sub_surf->surface.surf, buf->wl_buf, 0, 0);
|
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);
|
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 (alpha == 0xffff) {
|
||||||
if (region != NULL) {
|
struct wl_region *region = wl_compositor_create_region(term->wl->compositor);
|
||||||
wl_region_add(region, 0, 0, buf->width, buf->height);
|
if (region != NULL) {
|
||||||
wl_surface_set_opaque_region(sub_surf->surface.surf, region);
|
wl_region_add(region, 0, 0, buf->width, buf->height);
|
||||||
wl_region_destroy(region);
|
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);
|
wl_surface_commit(sub_surf->surface.surf);
|
||||||
quirk_weston_subsurface_desync_off(sub_surf->sub);
|
quirk_weston_subsurface_desync_off(sub_surf->sub);
|
||||||
|
|
@ -3841,23 +3876,9 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
if (term->cell_width == 0 && term->cell_height == 0)
|
if (term->cell_width == 0 && term->cell_height == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float scale = -1;
|
const float scale = term->scale;
|
||||||
if (wayl_fractional_scaling(term->wl)) {
|
width = round(width * scale);
|
||||||
scale = term->window->scale;
|
height = round(height * 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;
|
|
||||||
|
|
||||||
if (width == 0 && height == 0) {
|
if (width == 0 && height == 0) {
|
||||||
/*
|
/*
|
||||||
|
|
@ -3942,9 +3963,9 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
/* Drop out of URL mode */
|
/* Drop out of URL mode */
|
||||||
urls_reset(term);
|
urls_reset(term);
|
||||||
|
|
||||||
|
LOG_DBG("resized: size=%dx%d (scale=%.2f)", width, height, term->scale);
|
||||||
term->width = width;
|
term->width = width;
|
||||||
term->height = height;
|
term->height = height;
|
||||||
term->scale = scale;
|
|
||||||
|
|
||||||
const uint32_t scrollback_lines = term->render.scrollback_lines;
|
const uint32_t scrollback_lines = term->render.scrollback_lines;
|
||||||
|
|
||||||
|
|
@ -4148,12 +4169,11 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
|
|
||||||
sixel_reflow(term);
|
sixel_reflow(term);
|
||||||
|
|
||||||
#if defined(_DEBUG) && LOG_ENABLE_DBG
|
LOG_DBG("resized: grid: cols=%d, rows=%d "
|
||||||
LOG_DBG("resize: %dx%d, grid: cols=%d, rows=%d "
|
|
||||||
"(left-margin=%d, right-margin=%d, top-margin=%d, bottom-margin=%d)",
|
"(left-margin=%d, right-margin=%d, top-margin=%d, bottom-margin=%d)",
|
||||||
term->width, term->height, term->cols, term->rows,
|
term->cols, term->rows,
|
||||||
term->margins.left, term->margins.right, term->margins.top, term->margins.bottom);
|
term->margins.left, term->margins.right,
|
||||||
#endif
|
term->margins.top, term->margins.bottom);
|
||||||
|
|
||||||
if (term->scroll_region.start >= term->rows)
|
if (term->scroll_region.start >= term->rows)
|
||||||
term->scroll_region.start = 0;
|
term->scroll_region.start = 0;
|
||||||
|
|
@ -4295,13 +4315,17 @@ render_xcursor_update(struct seat *seat)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOG_DBG("setting %scursor shape using a client-side cursor surface",
|
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_cursor_image *image = seat->pointer.cursor->images[0];
|
||||||
|
struct wl_buffer *buf = wl_cursor_image_get_buffer(image);
|
||||||
|
|
||||||
wl_surface_attach(
|
wayl_surface_scale_explicit_width_height(
|
||||||
seat->pointer.surface.surf, wl_cursor_image_get_buffer(image), 0, 0);
|
seat->mouse_focus->window,
|
||||||
|
&seat->pointer.surface, image->width, image->height, scale);
|
||||||
|
|
||||||
|
wl_surface_attach(seat->pointer.surface.surf, buf, 0, 0);
|
||||||
|
|
||||||
wl_pointer_set_cursor(
|
wl_pointer_set_cursor(
|
||||||
seat->wl_pointer, seat->pointer.serial,
|
seat->wl_pointer, seat->pointer.serial,
|
||||||
|
|
@ -4311,8 +4335,6 @@ render_xcursor_update(struct seat *seat)
|
||||||
wl_surface_damage_buffer(
|
wl_surface_damage_buffer(
|
||||||
seat->pointer.surface.surf, 0, 0, INT32_MAX, INT32_MAX);
|
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);
|
xassert(seat->pointer.xcursor_callback == NULL);
|
||||||
seat->pointer.xcursor_callback = wl_surface_frame(seat->pointer.surface.surf);
|
seat->pointer.xcursor_callback = wl_surface_frame(seat->pointer.surface.surf);
|
||||||
wl_callback_add_listener(seat->pointer.xcursor_callback, &xcursor_listener, seat);
|
wl_callback_add_listener(seat->pointer.xcursor_callback, &xcursor_listener, seat);
|
||||||
|
|
|
||||||
137
terminal.c
137
terminal.c
|
|
@ -733,7 +733,8 @@ term_line_height_update(struct terminal *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
xassert(fonts[i] != NULL);
|
xassert(fonts[i] != NULL);
|
||||||
|
|
@ -777,8 +778,15 @@ term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4])
|
||||||
|
|
||||||
sixel_cell_size_changed(term);
|
sixel_cell_size_changed(term);
|
||||||
|
|
||||||
/* Use force, since cell-width/height may have changed */
|
/* Optimization - some code paths (are forced to) call
|
||||||
render_resize_force(term, term->width / term->scale, term->height / term->scale);
|
* 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -793,41 +801,34 @@ get_font_dpi(const struct terminal *term)
|
||||||
* Conceptually, we use the physical monitor specs to calculate
|
* Conceptually, we use the physical monitor specs to calculate
|
||||||
* the DPI, and we ignore the output's scaling factor.
|
* the DPI, and we ignore the output's scaling factor.
|
||||||
*
|
*
|
||||||
* However, to deal with fractional scaling, where we're told to
|
* However, to deal with legacy fractional scaling, where we're
|
||||||
* render at e.g. 2x, but are then downscaled by the compositor to
|
* told to render at e.g. 2x, but are then downscaled by the
|
||||||
* e.g. 1.25, we use the scaled DPI value multiplied by the scale
|
* compositor to e.g. 1.25, we use the scaled DPI value multiplied
|
||||||
* factor instead.
|
* by the scale factor instead.
|
||||||
*
|
*
|
||||||
* For integral scaling factors the resulting DPI is the same as
|
* For integral scaling factors the resulting DPI is the same as
|
||||||
* if we had used the physical DPI.
|
* if we had used the physical DPI.
|
||||||
*
|
*
|
||||||
* For fractional scaling factors we'll get a DPI *larger* than
|
* For legacy fractional scaling factors we'll get a DPI *larger*
|
||||||
* the physical DPI, that ends up being right when later
|
* than the physical DPI, that ends up being right when later
|
||||||
* downscaled by the compositor.
|
* 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 */
|
xassert(tll_length(term->wl->monitors) > 0);
|
||||||
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... */
|
const struct wl_window *win = term->window;
|
||||||
if (dpi == 0.) {
|
const struct monitor *mon = tll_length(win->on_outputs) > 0
|
||||||
tll_foreach(term->wl->monitors, it) {
|
? tll_back(win->on_outputs)
|
||||||
dpi = it->item.dpi;
|
: &tll_front(term->wl->monitors);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dpi == 0) {
|
if (wayl_fractional_scaling(term->wl))
|
||||||
/* No monitors? */
|
return mon->dpi.physical;
|
||||||
dpi = 96.;
|
else
|
||||||
}
|
return mon->dpi.scaled;
|
||||||
|
|
||||||
return dpi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum fcft_subpixel
|
static enum fcft_subpixel
|
||||||
|
|
@ -846,7 +847,8 @@ get_font_subpixel(const struct terminal *term)
|
||||||
* output or not.
|
* output or not.
|
||||||
*
|
*
|
||||||
* Thus, when determining which subpixel mode to use, we can't do
|
* 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
|
* If we're not mapped at all, we pick the first available
|
||||||
* monitor, and hope that's where we'll eventually get mapped.
|
* monitor, and hope that's where we'll eventually get mapped.
|
||||||
|
|
@ -856,7 +858,7 @@ get_font_subpixel(const struct terminal *term)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (tll_length(term->window->on_outputs) > 0)
|
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)
|
else if (tll_length(term->wl->monitors) > 0)
|
||||||
wl_subpixel = tll_front(term->wl->monitors).subpixel;
|
wl_subpixel = tll_front(term->wl->monitors).subpixel;
|
||||||
else
|
else
|
||||||
|
|
@ -903,7 +905,7 @@ font_loader_thread(void *_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
reload_fonts(struct terminal *term)
|
reload_fonts(struct terminal *term, bool resize_grid)
|
||||||
{
|
{
|
||||||
const struct config *conf = term->conf;
|
const struct config *conf = term->conf;
|
||||||
|
|
||||||
|
|
@ -1030,7 +1032,7 @@ reload_fonts(struct terminal *term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success ? term_set_fonts(term, fonts) : success;
|
return success ? term_set_fonts(term, fonts, resize_grid) : success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -1048,7 +1050,7 @@ load_fonts_from_conf(struct terminal *term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reload_fonts(term);
|
return reload_fonts(term, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fdm_client_terminated(
|
static void fdm_client_terminated(
|
||||||
|
|
@ -1282,11 +1284,9 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
||||||
reaper_add(term->reaper, term->slave, &fdm_client_terminated, term);
|
reaper_add(term->reaper, term->slave, &fdm_client_terminated, term);
|
||||||
|
|
||||||
/* Guess scale; we're not mapped yet, so we don't know on which
|
/* 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 */
|
* output we'll be. Use scaling factor from first monitor */
|
||||||
tll_foreach(term->wl->monitors, it) {
|
xassert(tll_length(term->wl->monitors) > 0);
|
||||||
if (it->item.scale > term->scale)
|
term->scale = tll_front(term->wl->monitors).scale;
|
||||||
term->scale = it->item.scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(term->colors.table, term->conf->colors.table, sizeof(term->colors.table));
|
memcpy(term->colors.table, term->conf->colors.table, sizeof(term->colors.table));
|
||||||
|
|
||||||
|
|
@ -1295,7 +1295,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Load fonts */
|
/* Load fonts */
|
||||||
if (!term_font_dpi_changed(term, 0))
|
if (!term_font_dpi_changed(term, 0.))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
term->font_subpixel = get_font_subpixel(term);
|
term->font_subpixel = get_font_subpixel(term);
|
||||||
|
|
@ -1607,8 +1607,6 @@ term_destroy(struct terminal *term)
|
||||||
if (term == NULL)
|
if (term == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
key_binding_unref(term->wl->key_binding_manager, term->conf);
|
|
||||||
|
|
||||||
tll_foreach(term->wl->terms, it) {
|
tll_foreach(term->wl->terms, it) {
|
||||||
if (it->item == term) {
|
if (it->item == term) {
|
||||||
tll_remove(term->wl->terms, it);
|
tll_remove(term->wl->terms, it);
|
||||||
|
|
@ -1654,6 +1652,8 @@ term_destroy(struct terminal *term)
|
||||||
}
|
}
|
||||||
mtx_unlock(&term->render.workers.lock);
|
mtx_unlock(&term->render.workers.lock);
|
||||||
|
|
||||||
|
key_binding_unref(term->wl->key_binding_manager, term->conf);
|
||||||
|
|
||||||
urls_reset(term);
|
urls_reset(term);
|
||||||
|
|
||||||
free(term->vt.osc.data);
|
free(term->vt.osc.data);
|
||||||
|
|
@ -1993,7 +1993,7 @@ term_font_size_adjust_by_points(struct terminal *term, float amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reload_fonts(term);
|
return reload_fonts(term, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -2016,7 +2016,7 @@ term_font_size_adjust_by_pixels(struct terminal *term, int amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reload_fonts(term);
|
return reload_fonts(term, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -2040,7 +2040,7 @@ term_font_size_adjust_by_percent(struct terminal *term, bool increment, float pe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reload_fonts(term);
|
return reload_fonts(term, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -2078,10 +2078,40 @@ term_font_size_reset(struct terminal *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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);
|
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 was_scaled_using_dpi = term->font_is_sized_by_dpi;
|
||||||
bool will_scale_using_dpi = term->conf->dpi_aware;
|
bool will_scale_using_dpi = term->conf->dpi_aware;
|
||||||
|
|
@ -2093,11 +2123,10 @@ term_font_dpi_changed(struct terminal *term, int old_scale)
|
||||||
: old_scale != term->scale);
|
: old_scale != term->scale);
|
||||||
|
|
||||||
if (need_font_reload) {
|
if (need_font_reload) {
|
||||||
LOG_DBG("DPI/scale change: DPI-awareness=%s, "
|
LOG_DBG("DPI/scale change: DPI-aware=%s, "
|
||||||
"DPI: %.2f -> %.2f, scale: %d -> %d, "
|
"DPI: %.2f -> %.2f, scale: %.2f -> %.2f, "
|
||||||
"sizing font based on monitor's %s",
|
"sizing font based on monitor's %s",
|
||||||
term->conf->dpi_aware == DPI_AWARE_AUTO ? "auto" :
|
term->conf->dpi_aware ? "yes" : "no",
|
||||||
term->conf->dpi_aware == DPI_AWARE_YES ? "yes" : "no",
|
|
||||||
term->font_dpi, dpi, old_scale, term->scale,
|
term->font_dpi, dpi, old_scale, term->scale,
|
||||||
will_scale_using_dpi ? "DPI" : "scaling factor");
|
will_scale_using_dpi ? "DPI" : "scaling factor");
|
||||||
}
|
}
|
||||||
|
|
@ -2106,9 +2135,9 @@ term_font_dpi_changed(struct terminal *term, int old_scale)
|
||||||
term->font_is_sized_by_dpi = will_scale_using_dpi;
|
term->font_is_sized_by_dpi = will_scale_using_dpi;
|
||||||
|
|
||||||
if (!need_font_reload)
|
if (!need_font_reload)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
return reload_fonts(term);
|
return reload_fonts(term, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -3507,7 +3536,7 @@ term_update_ascii_printer(struct terminal *term)
|
||||||
|
|
||||||
#if defined(_DEBUG) && LOG_ENABLE_DBG
|
#if defined(_DEBUG) && LOG_ENABLE_DBG
|
||||||
if (term->ascii_printer != new_printer) {
|
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",
|
term->ascii_printer == &ascii_printer_fast ? "fast" : "generic",
|
||||||
new_printer == &ascii_printer_fast ? "fast" : "generic");
|
new_printer == &ascii_printer_fast ? "fast" : "generic");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -736,10 +736,11 @@ bool term_to_slave(struct terminal *term, const void *data, size_t len);
|
||||||
bool term_paste_data_to_slave(
|
bool term_paste_data_to_slave(
|
||||||
struct terminal *term, const void *data, size_t len);
|
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_increase(struct terminal *term);
|
||||||
bool term_font_size_decrease(struct terminal *term);
|
bool term_font_size_decrease(struct terminal *term);
|
||||||
bool term_font_size_reset(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);
|
void term_font_subpixel_changed(struct terminal *term);
|
||||||
|
|
||||||
int term_pt_or_px_as_pixels(
|
int term_pt_or_px_as_pixels(
|
||||||
|
|
|
||||||
27
themes/chiba-dark
Normal file
27
themes/chiba-dark
Normal file
|
|
@ -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
|
||||||
|
|
@ -1,24 +1,24 @@
|
||||||
# -*- conf -*-
|
# -*- conf -*-
|
||||||
# Theme: starlight (https://github.com/CosmicToast/starlight)
|
# Theme: starlight V4 (https://github.com/CosmicToast/starlight)
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
foreground = FFFFFF
|
foreground = FFFFFF
|
||||||
background = 242424
|
background = 242424
|
||||||
|
|
||||||
regular0 = 242424
|
regular0 = 242424
|
||||||
regular1 = CF1745
|
regular1 = f62b5a
|
||||||
regular2 = 3ECF5B
|
regular2 = 47b413
|
||||||
regular3 = CFCF17
|
regular3 = e3c401
|
||||||
regular4 = 0BA6DA
|
regular4 = 24acd4
|
||||||
regular5 = D926AC
|
regular5 = f2affd
|
||||||
regular6 = 17CFA1
|
regular6 = 13c299
|
||||||
regular7 = E6E6E6
|
regular7 = e6e6e6
|
||||||
|
|
||||||
bright0 = 616161
|
bright0 = 616161
|
||||||
bright1 = FF1A53
|
bright1 = ff4d51
|
||||||
bright2 = 17E640
|
bright2 = 35d450
|
||||||
bright3 = ECFF1A
|
bright3 = e9e836
|
||||||
bright4 = 1AC6FF
|
bright4 = 5dc5f8
|
||||||
bright5 = F53DC7
|
bright5 = feabf2
|
||||||
bright6 = 1AFFC6
|
bright6 = 24dfc4
|
||||||
bright7 = FFFFFF
|
bright7 = ffffff
|
||||||
|
|
|
||||||
30
vt.c
30
vt.c
|
|
@ -436,6 +436,27 @@ UNITTEST
|
||||||
xassert(term.vt.private == expected);
|
xassert(term.vt.private == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
action_esc_dispatch(struct terminal *term, uint8_t final)
|
action_esc_dispatch(struct terminal *term, uint8_t final)
|
||||||
{
|
{
|
||||||
|
|
@ -478,14 +499,7 @@ action_esc_dispatch(struct terminal *term, uint8_t final)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'H':
|
case 'H':
|
||||||
tll_foreach(term->tab_stops, it) {
|
tab_set(term);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
|
|
|
||||||
102
wayland.c
102
wayland.c
|
|
@ -341,8 +341,10 @@ seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||||
} else {
|
} else {
|
||||||
if (seat->wl_pointer != NULL) {
|
if (seat->wl_pointer != NULL) {
|
||||||
#if defined(HAVE_CURSOR_SHAPE)
|
#if defined(HAVE_CURSOR_SHAPE)
|
||||||
wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device);
|
if (seat->pointer.shape_device != NULL) {
|
||||||
seat->pointer.shape_device = NULL;
|
wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device);
|
||||||
|
seat->pointer.shape_device = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wl_pointer_release(seat->wl_pointer);
|
wl_pointer_release(seat->wl_pointer);
|
||||||
|
|
@ -396,15 +398,35 @@ static const struct wl_seat_listener seat_listener = {
|
||||||
static void
|
static void
|
||||||
update_term_for_output_change(struct terminal *term)
|
update_term_for_output_change(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (tll_length(term->window->on_outputs) == 0)
|
const float old_scale = term->scale;
|
||||||
return;
|
const float logical_width = term->width / term->scale;
|
||||||
|
const float logical_height = term->height / term->scale;
|
||||||
|
|
||||||
float old_scale = term->scale;
|
/* Note: order matters! term_update_scale() must come first */
|
||||||
|
bool scale_updated = term_update_scale(term);
|
||||||
render_resize(term, term->width / term->scale, term->height / term->scale);
|
bool fonts_updated = term_font_dpi_changed(term, old_scale);
|
||||||
term_font_dpi_changed(term, old_scale);
|
|
||||||
term_font_subpixel_changed(term);
|
term_font_subpixel_changed(term);
|
||||||
|
|
||||||
csd_reload_font(term->window, old_scale);
|
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
|
static void
|
||||||
|
|
@ -433,6 +455,9 @@ output_update_ppi(struct monitor *mon)
|
||||||
double x_inches = mon->dim.mm.width * 0.03937008;
|
double x_inches = mon->dim.mm.width * 0.03937008;
|
||||||
double y_inches = mon->dim.mm.height * 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.x = mon->dim.px_real.width / x_inches;
|
||||||
mon->ppi.real.y = mon->dim.px_real.height / y_inches;
|
mon->ppi.real.y = mon->dim.px_real.height / y_inches;
|
||||||
|
|
||||||
|
|
@ -455,27 +480,36 @@ output_update_ppi(struct monitor *mon)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scaled_width = mon->dim.px_scaled.width;
|
const int scaled_width = mon->dim.px_scaled.width;
|
||||||
int scaled_height = mon->dim.px_scaled.height;
|
const 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
mon->ppi.scaled.x = scaled_width / x_inches;
|
mon->ppi.scaled.x = scaled_width / x_inches;
|
||||||
mon->ppi.scaled.y = scaled_height / y_inches;
|
mon->ppi.scaled.y = scaled_height / y_inches;
|
||||||
|
|
||||||
double px_diag = sqrt(pow(scaled_width, 2) + pow(scaled_height, 2));
|
const double px_diag_physical = sqrt(pow(width, 2) + pow(height, 2));
|
||||||
mon->dpi = px_diag / mon->inch * mon->scale;
|
mon->dpi.physical = width == 0 && height == 0
|
||||||
|
? 96.
|
||||||
|
: px_diag_physical / mon->inch;
|
||||||
|
|
||||||
if (mon->dpi > 1000) {
|
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.physical > 1000) {
|
||||||
if (mon->name != NULL) {
|
if (mon->name != NULL) {
|
||||||
LOG_WARN("%s: DPI=%f is unreasonable, using 96 instead",
|
LOG_WARN("%s: DPI=%f (physical) is unreasonable, using 96 instead",
|
||||||
mon->name, mon->dpi);
|
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 @@ wayl_init(struct fdm *fdm, struct key_binding_manager *key_binding_manager,
|
||||||
LOG_ERR("no seats available (wl_seat interface too old?)");
|
LOG_ERR("no seats available (wl_seat interface too old?)");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (tll_length(wayl->monitors) == 0) {
|
||||||
|
LOG_ERR("no monitors available");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (wayl->primary_selection_device_manager == NULL)
|
if (wayl->primary_selection_device_manager == NULL)
|
||||||
LOG_WARN("no primary selection available");
|
LOG_WARN("no primary selection available");
|
||||||
|
|
||||||
|
|
@ -1485,14 +1524,12 @@ wayl_init(struct fdm *fdm, struct key_binding_manager *key_binding_manager,
|
||||||
|
|
||||||
tll_foreach(wayl->monitors, it) {
|
tll_foreach(wayl->monitors, it) {
|
||||||
LOG_INFO(
|
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.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.x, it->item.y, (int)round(it->item.refresh),
|
||||||
it->item.model != NULL ? it->item.model : it->item.description,
|
it->item.model != NULL ? it->item.model : it->item.description,
|
||||||
it->item.inch, it->item.scale,
|
it->item.inch, it->item.scale,
|
||||||
it->item.ppi.real.x, it->item.ppi.real.y,
|
it->item.dpi.physical, it->item.dpi.scaled);
|
||||||
it->item.ppi.scaled.x, it->item.ppi.scaled.y,
|
|
||||||
it->item.dpi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wayl->fd = wl_display_get_fd(wayl->display);
|
wayl->fd = wl_display_get_fd(wayl->display);
|
||||||
|
|
@ -1601,10 +1638,15 @@ static void fractional_scale_preferred_scale(
|
||||||
uint32_t scale)
|
uint32_t scale)
|
||||||
{
|
{
|
||||||
struct wl_window *win = data;
|
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);
|
update_term_for_output_change(win->term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1969,7 +2011,7 @@ wayl_surface_scale_explicit_width_height(
|
||||||
int width, int height, float scale)
|
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)
|
#if defined(HAVE_FRACTIONAL_SCALE)
|
||||||
LOG_DBG("scaling by a factor of %.2f using fractional scaling "
|
LOG_DBG("scaling by a factor of %.2f using fractional scaling "
|
||||||
"(width=%d, height=%d) ", scale, width, height);
|
"(width=%d, height=%d) ", scale, width, height);
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,10 @@ struct monitor {
|
||||||
} scaled;
|
} scaled;
|
||||||
} ppi;
|
} ppi;
|
||||||
|
|
||||||
float dpi;
|
struct {
|
||||||
|
float scaled;
|
||||||
|
float physical;
|
||||||
|
} dpi;
|
||||||
|
|
||||||
int scale;
|
int scale;
|
||||||
float refresh;
|
float refresh;
|
||||||
|
|
@ -374,7 +377,6 @@ struct wl_window {
|
||||||
bool unmapped;
|
bool unmapped;
|
||||||
|
|
||||||
float scale;
|
float scale;
|
||||||
bool have_preferred_scale;
|
|
||||||
|
|
||||||
struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration;
|
struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue