mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-27 06:46:44 -04:00
Merge branch 'master' of https://codeberg.org/dnkl/foot
This commit is contained in:
commit
8445da4853
103 changed files with 1655 additions and 579 deletions
112
.gitlab-ci.yml
112
.gitlab-ci.yml
|
|
@ -1,112 +0,0 @@
|
||||||
stages:
|
|
||||||
- build
|
|
||||||
|
|
||||||
variables:
|
|
||||||
GIT_SUBMODULE_STRATEGY: normal
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- apk update
|
|
||||||
- apk add musl-dev linux-headers meson ninja gcc scdoc ncurses
|
|
||||||
- apk add libxkbcommon-dev pixman-dev freetype-dev fontconfig-dev harfbuzz-dev utf8proc-dev
|
|
||||||
- apk add wayland-dev wayland-protocols
|
|
||||||
- apk add git
|
|
||||||
- apk add check-dev
|
|
||||||
- apk add ttf-hack font-noto-emoji
|
|
||||||
|
|
||||||
debug-x64:
|
|
||||||
image: alpine:edge
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- cd subprojects
|
|
||||||
- git clone https://codeberg.org/dnkl/fcft.git
|
|
||||||
- cd ..
|
|
||||||
- mkdir -p bld/debug
|
|
||||||
- cd bld/debug
|
|
||||||
- meson --buildtype=debug -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../../
|
|
||||||
- ninja -v -k0
|
|
||||||
- ninja -v test
|
|
||||||
artifacts:
|
|
||||||
reports:
|
|
||||||
junit: bld/debug/meson-logs/testlog.junit.xml
|
|
||||||
|
|
||||||
debug-x64-no-grapheme-clustering:
|
|
||||||
image: alpine:edge
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- apk del harfbuzz harfbuzz-dev utf8proc utf8proc-dev
|
|
||||||
- cd subprojects
|
|
||||||
- git clone https://codeberg.org/dnkl/fcft.git
|
|
||||||
- cd ..
|
|
||||||
- mkdir -p bld/debug
|
|
||||||
- cd bld/debug
|
|
||||||
- meson --buildtype=debug -Dgrapheme-clustering=disabled -Dfcft:grapheme-shaping=disabled -Dfcft:run-shaping=disabled -Dfcft:test-text-shaping=false ../../
|
|
||||||
- ninja -v -k0
|
|
||||||
- ninja -v test
|
|
||||||
- ./foot --version
|
|
||||||
- ./footclient --version
|
|
||||||
artifacts:
|
|
||||||
reports:
|
|
||||||
junit: bld/debug/meson-logs/testlog.junit.xml
|
|
||||||
|
|
||||||
release-x64:
|
|
||||||
image: alpine:edge
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- cd subprojects
|
|
||||||
- git clone https://codeberg.org/dnkl/fcft.git
|
|
||||||
- cd ..
|
|
||||||
- mkdir -p bld/release
|
|
||||||
- cd bld/release
|
|
||||||
- meson --buildtype=release -Db_pgo=generate -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../../
|
|
||||||
- ninja -v -k0
|
|
||||||
- ninja -v test
|
|
||||||
- ./foot --version
|
|
||||||
- ./footclient --version
|
|
||||||
artifacts:
|
|
||||||
reports:
|
|
||||||
junit: bld/release/meson-logs/testlog.junit.xml
|
|
||||||
|
|
||||||
debug-x86:
|
|
||||||
image: i386/alpine:edge
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- cd subprojects
|
|
||||||
- git clone https://codeberg.org/dnkl/fcft.git
|
|
||||||
- cd ..
|
|
||||||
- mkdir -p bld/debug
|
|
||||||
- cd bld/debug
|
|
||||||
- meson --buildtype=debug -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../../
|
|
||||||
- ninja -v -k0
|
|
||||||
- ninja -v test
|
|
||||||
- ./foot --version
|
|
||||||
- ./footclient --version
|
|
||||||
artifacts:
|
|
||||||
reports:
|
|
||||||
junit: bld/debug/meson-logs/testlog.junit.xml
|
|
||||||
|
|
||||||
release-x86:
|
|
||||||
image: i386/alpine:edge
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- cd subprojects
|
|
||||||
- git clone https://codeberg.org/dnkl/fcft.git
|
|
||||||
- cd ..
|
|
||||||
- mkdir -p bld/release
|
|
||||||
- cd bld/release
|
|
||||||
- meson --buildtype=release -Db_pgo=generate -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../../
|
|
||||||
- ninja -v -k0
|
|
||||||
- ninja -v test
|
|
||||||
- ./foot --version
|
|
||||||
- ./footclient --version
|
|
||||||
artifacts:
|
|
||||||
reports:
|
|
||||||
junit: bld/release/meson-logs/testlog.junit.xml
|
|
||||||
|
|
||||||
codespell:
|
|
||||||
image: alpine:edge
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- apk add python3
|
|
||||||
- apk add py3-pip
|
|
||||||
- pip install codespell
|
|
||||||
- codespell -Lser,doas,zar README.md INSTALL.md CHANGELOG.md *.c *.h doc/*.scd
|
|
||||||
|
|
@ -33,7 +33,7 @@ pipeline:
|
||||||
image: alpine:latest
|
image: alpine:latest
|
||||||
commands:
|
commands:
|
||||||
- apk update
|
- apk update
|
||||||
- apk add musl-dev linux-headers meson ninja gcc scdoc ncurses
|
- apk add musl-dev linux-headers meson ninja gcc clang scdoc ncurses
|
||||||
- apk add libxkbcommon-dev pixman-dev freetype-dev fontconfig-dev harfbuzz-dev utf8proc-dev
|
- apk add libxkbcommon-dev pixman-dev freetype-dev fontconfig-dev harfbuzz-dev utf8proc-dev
|
||||||
- apk add wayland-dev wayland-protocols
|
- apk add wayland-dev wayland-protocols
|
||||||
- apk add git
|
- apk add git
|
||||||
|
|
@ -50,7 +50,7 @@ pipeline:
|
||||||
- ./footclient --version
|
- ./footclient --version
|
||||||
- cd ../..
|
- cd ../..
|
||||||
|
|
||||||
# Release
|
# Release (gcc)
|
||||||
- mkdir -p bld/release-x64
|
- mkdir -p bld/release-x64
|
||||||
- cd bld/release-x64
|
- cd bld/release-x64
|
||||||
- meson --buildtype=release -Db_pgo=generate -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../..
|
- meson --buildtype=release -Db_pgo=generate -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../..
|
||||||
|
|
@ -60,6 +60,16 @@ pipeline:
|
||||||
- ./footclient --version
|
- ./footclient --version
|
||||||
- cd ../..
|
- cd ../..
|
||||||
|
|
||||||
|
# Release (clang)
|
||||||
|
- mkdir -p bld/release-x64-clang
|
||||||
|
- cd bld/release-x64-clang
|
||||||
|
- CC=clang meson --buildtype=release -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../..
|
||||||
|
- ninja -v -k0
|
||||||
|
- ninja -v test
|
||||||
|
- ./foot --version
|
||||||
|
- ./footclient --version
|
||||||
|
- cd ../..
|
||||||
|
|
||||||
# no grapheme clustering
|
# no grapheme clustering
|
||||||
- apk del harfbuzz harfbuzz-dev utf8proc utf8proc-dev
|
- apk del harfbuzz harfbuzz-dev utf8proc utf8proc-dev
|
||||||
- mkdir -p bld/debug
|
- mkdir -p bld/debug
|
||||||
|
|
@ -80,7 +90,7 @@ pipeline:
|
||||||
image: i386/alpine:latest
|
image: i386/alpine:latest
|
||||||
commands:
|
commands:
|
||||||
- apk update
|
- apk update
|
||||||
- apk add musl-dev linux-headers meson ninja gcc scdoc ncurses
|
- apk add musl-dev linux-headers meson ninja gcc clang scdoc ncurses
|
||||||
- apk add libxkbcommon-dev pixman-dev freetype-dev fontconfig-dev harfbuzz-dev utf8proc-dev
|
- apk add libxkbcommon-dev pixman-dev freetype-dev fontconfig-dev harfbuzz-dev utf8proc-dev
|
||||||
- apk add wayland-dev wayland-protocols
|
- apk add wayland-dev wayland-protocols
|
||||||
- apk add git
|
- apk add git
|
||||||
|
|
@ -97,7 +107,7 @@ pipeline:
|
||||||
- ./footclient --version
|
- ./footclient --version
|
||||||
- cd ../..
|
- cd ../..
|
||||||
|
|
||||||
# Release
|
# Release (gcc)
|
||||||
- mkdir -p bld/release-x86
|
- mkdir -p bld/release-x86
|
||||||
- cd bld/release-x86
|
- cd bld/release-x86
|
||||||
- meson --buildtype=release -Db_pgo=generate -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../..
|
- meson --buildtype=release -Db_pgo=generate -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../..
|
||||||
|
|
@ -106,3 +116,13 @@ pipeline:
|
||||||
- ./foot --version
|
- ./foot --version
|
||||||
- ./footclient --version
|
- ./footclient --version
|
||||||
- cd ../..
|
- cd ../..
|
||||||
|
|
||||||
|
# Release (clang)
|
||||||
|
- mkdir -p bld/release-x86-clang
|
||||||
|
- cd bld/release-x86-clang
|
||||||
|
- CC=clang meson --buildtype=release -Dgrapheme-clustering=enabled -Dfcft:grapheme-shaping=enabled -Dfcft:run-shaping=enabled -Dfcft:test-text-shaping=true ../..
|
||||||
|
- ninja -v -k0
|
||||||
|
- ninja -v test
|
||||||
|
- ./foot --version
|
||||||
|
- ./footclient --version
|
||||||
|
- cd ../..
|
||||||
|
|
|
||||||
110
CHANGELOG.md
110
CHANGELOG.md
|
|
@ -1,6 +1,7 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
* [Unreleased](#unreleased)
|
* [Unreleased](#unreleased)
|
||||||
|
* [1.14.0](#1-14-0)
|
||||||
* [1.13.1](#1-13-1)
|
* [1.13.1](#1-13-1)
|
||||||
* [1.13.0](#1-13-0)
|
* [1.13.0](#1-13-0)
|
||||||
* [1.12.1](#1-12-1)
|
* [1.12.1](#1-12-1)
|
||||||
|
|
@ -42,6 +43,24 @@
|
||||||
|
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
### Added
|
||||||
|
### Changed
|
||||||
|
### Deprecated
|
||||||
|
### Removed
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* Incorrect icon in dock and window switcher on Gnome ([#1317][1317])
|
||||||
|
* Crash when scrolling after resizing the window with non-zero
|
||||||
|
scrolling regions.
|
||||||
|
|
||||||
|
[1317]: https://codeberg.org/dnkl/foot/issues/1317
|
||||||
|
|
||||||
|
|
||||||
|
### Security
|
||||||
|
### Contributors
|
||||||
|
|
||||||
|
|
||||||
|
## 1.14.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|
@ -49,8 +68,24 @@
|
||||||
* Support (optional) for utmp logging with libutempter.
|
* Support (optional) for utmp logging with libutempter.
|
||||||
* `kxIN` and `kxOUT` (focus in/out events) to terminfo.
|
* `kxIN` and `kxOUT` (focus in/out events) to terminfo.
|
||||||
* `name` capability to `XTGETTCAP`.
|
* `name` capability to `XTGETTCAP`.
|
||||||
|
* String values in `foot.ini` may now be quoted. This can be used to
|
||||||
|
set a value to the empty string, for example.
|
||||||
|
* Environment variables can now be **unset**, by setting
|
||||||
|
`[environment].<variable>=""` (quotes are required) ([#1225][1225]).
|
||||||
|
* `font-size-adjustment=N[px]` option, letting you configure how much
|
||||||
|
to increment/decrement the font size when zooming in or out
|
||||||
|
([#1188][1188]).
|
||||||
|
* Bracketed paste terminfo entries (`BD`, `BE`, `PE` and `PS`, added
|
||||||
|
to ncurses in 2022-12-24). Vim makes use of these.
|
||||||
|
* “Report version” terminfo entries (`XR`/`xr`).
|
||||||
|
* “Report DA2” terminfo entries (`RV`/`rv`).
|
||||||
|
* `XF` terminfo capability (focus in/out events available).
|
||||||
|
* `$TERM_PROGRAM` and `$TERM_PROGRAM_VERSION` environment variables
|
||||||
|
set in the slave process.
|
||||||
|
|
||||||
[1136]: https://codeberg.org/dnkl/foot/issues/1136
|
[1136]: https://codeberg.org/dnkl/foot/issues/1136
|
||||||
|
[1225]: https://codeberg.org/dnkl/foot/issues/1225
|
||||||
|
[1188]: https://codeberg.org/dnkl/foot/issues/1188
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
@ -64,13 +99,20 @@
|
||||||
("permanently reset") instead of `2` ("reset") for DEC private
|
("permanently reset") instead of `2` ("reset") for DEC private
|
||||||
modes that are known but unsupported.
|
modes that are known but unsupported.
|
||||||
* Set `PWD` environment variable in the slave process ([#1179][1179]).
|
* Set `PWD` environment variable in the slave process ([#1179][1179]).
|
||||||
|
* DPI is now forced to 96 when found to be unreasonably high.
|
||||||
|
* Set default log level to warning ([#1215][1215]).
|
||||||
|
* Default `grapheme-width-method` from `wcswidth` to `double-width`.
|
||||||
|
* When determining initial font size, do FontConfig config
|
||||||
|
substitution if the user-provided font pattern has no {pixel}size
|
||||||
|
option ([#1287][1287]).
|
||||||
|
* DECRST of DECCOLM and DECSCLM removed from terminfo.
|
||||||
|
|
||||||
[1166]: https://codeberg.org/dnkl/foot/issues/1166
|
[1166]: https://codeberg.org/dnkl/foot/issues/1166
|
||||||
[1179]: https://codeberg.org/dnkl/foot/issues/1179
|
[1179]: https://codeberg.org/dnkl/foot/issues/1179
|
||||||
|
[1215]: https://codeberg.org/dnkl/foot/pulls/1215
|
||||||
|
[1287]: https://codeberg.org/dnkl/foot/issues/1287
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
|
||||||
### Removed
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
* Crash in `foot --server` on key press, after another `footclient`
|
* Crash in `foot --server` on key press, after another `footclient`
|
||||||
|
|
@ -80,16 +122,76 @@
|
||||||
that does not allow Wayland buffer re-use (e.g. KDE/plasma)
|
that does not allow Wayland buffer re-use (e.g. KDE/plasma)
|
||||||
([#1173][1173])
|
([#1173][1173])
|
||||||
* Scrollback search matches not being highlighted correctly, on
|
* Scrollback search matches not being highlighted correctly, on
|
||||||
compositors that does now allow Wayland buffer re-use
|
compositors that does not allow Wayland buffer re-use
|
||||||
(e.g. KDE/plasma).
|
(e.g. KDE/plasma).
|
||||||
|
* Nanosecs "overflow" when calculating timeout value for
|
||||||
|
`resize-delay-ms` option.
|
||||||
|
* Missing backslash in ST terminator in escape sequences in the
|
||||||
|
built-in terminfo (accessed via XTGETTCAP).
|
||||||
|
* Crash when interactively resizing the window with a very large
|
||||||
|
scrollback.
|
||||||
|
* Crash when a sixel image exceeds the current sixel max height.
|
||||||
|
* Crash after reverse-scrolling (`CSI Ps T`) in the ‘normal’
|
||||||
|
(non-alternate) screen ([#1190][1190]).
|
||||||
|
* Background transparency being applied to the text "behind" the
|
||||||
|
cursor. Only applies to block cursor using inversed fg/bg
|
||||||
|
colors. ([#1205][1205]).
|
||||||
|
* Crash when monitor’s physical size is "too small" ([#1209][1209]).
|
||||||
|
* Line-height adjustment when incrementing/decrementing the font size
|
||||||
|
with a user-set line-height ([#1218][1218]).
|
||||||
|
* Scaling factor not being correctly applied when converting pt-or-px
|
||||||
|
config values (e.g. letter offsets, line height etc).
|
||||||
|
* Selection being stuck visually when `IL` and `DL`.
|
||||||
|
* URL underlines sometimes still being visible after exiting URL mode.
|
||||||
|
* Text-bindings, and pipe-* bindings, with multiple key mappings
|
||||||
|
causing a crash (double-free) on exit ([#1259][1259]).
|
||||||
|
* Double-width glyphs glitching when surrounded by glyphs overflowing
|
||||||
|
into the double-width glyph ([#1256][1256]).
|
||||||
|
* Wayland protocol violation when ack:ing a configure event for an
|
||||||
|
unmapped surface ([#1249][1249]).
|
||||||
|
* `xdg_toplevel::set_min_size()` not being called.
|
||||||
|
* Key bindings with consumed modifiers masking other key bindings
|
||||||
|
([#1280][1280]).
|
||||||
|
* Multi-character compose sequences with the kitty keyboard protocol
|
||||||
|
([#1288][1288]).
|
||||||
|
* Crash when application output scrolls very fast, e.g. `yes`
|
||||||
|
([#1305][1305]).
|
||||||
|
* Crash when application scrolls **many** lines (> ~2³¹).
|
||||||
|
* DECCOLM erasing the screen ([#1265][1265]).
|
||||||
|
|
||||||
[1173]: https://codeberg.org/dnkl/foot/issues/1173
|
[1173]: https://codeberg.org/dnkl/foot/issues/1173
|
||||||
|
[1190]: https://codeberg.org/dnkl/foot/issues/1190
|
||||||
|
[1205]: https://codeberg.org/dnkl/foot/issues/1205
|
||||||
|
[1209]: https://codeberg.org/dnkl/foot/issues/1209
|
||||||
|
[1218]: https://codeberg.org/dnkl/foot/issues/1218
|
||||||
|
[1259]: https://codeberg.org/dnkl/foot/issues/1259
|
||||||
|
[1256]: https://codeberg.org/dnkl/foot/issues/1256
|
||||||
|
[1249]: https://codeberg.org/dnkl/foot/issues/1249
|
||||||
|
[1280]: https://codeberg.org/dnkl/foot/issues/1280
|
||||||
|
[1288]: https://codeberg.org/dnkl/foot/issues/1288
|
||||||
|
[1305]: https://codeberg.org/dnkl/foot/issues/1305
|
||||||
|
[1265]: https://codeberg.org/dnkl/foot/issues/1265
|
||||||
|
|
||||||
|
|
||||||
### Security
|
|
||||||
### Contributors
|
### Contributors
|
||||||
|
|
||||||
|
* Alexey Sakovets
|
||||||
|
* Andrea Pappacoda
|
||||||
|
* Antoine Beaupré
|
||||||
|
* argosatcore
|
||||||
* Craig Barnes
|
* Craig Barnes
|
||||||
|
* EuCaue
|
||||||
|
* Grigory Kirillov
|
||||||
|
* Harri Nieminen
|
||||||
|
* Hugo Osvaldo Barrera
|
||||||
|
* jaroeichler
|
||||||
|
* Joakim Nohlgård
|
||||||
|
* Nick Hastings
|
||||||
|
* Soren A D
|
||||||
|
* Torsten Trautwein
|
||||||
|
* Vladimír Magyar
|
||||||
|
* woojiq
|
||||||
|
* Yorick Peterse
|
||||||
|
|
||||||
|
|
||||||
## 1.13.1
|
## 1.13.1
|
||||||
|
|
|
||||||
18
INSTALL.md
18
INSTALL.md
|
|
@ -327,6 +327,7 @@ We will use the `pgo` binary along with input corpus generated by
|
||||||
`scripts/generate-alt-random-writes.py`:
|
`scripts/generate-alt-random-writes.py`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
./utils/xtgettcap
|
||||||
./footclient --version
|
./footclient --version
|
||||||
./foot --version
|
./foot --version
|
||||||
tmp_file=$(mktemp)
|
tmp_file=$(mktemp)
|
||||||
|
|
@ -349,9 +350,10 @@ rm ${tmp_file}
|
||||||
```
|
```
|
||||||
|
|
||||||
The first step, running `./foot --version` and `./footclient
|
The first step, running `./foot --version` and `./footclient
|
||||||
--version` might seem unnecessary, but is needed to ensure we have
|
--version` etc, might seem unnecessary, but is needed to ensure we
|
||||||
_some_ profiling data for functions not covered by the PGO helper
|
have _some_ profiling data for functions not covered by the PGO helper
|
||||||
binary. Without this, the final link phase will fail.
|
binary, for **all** binaries. Without this, the final link phase will
|
||||||
|
fail.
|
||||||
|
|
||||||
The snippet above then creates an (empty) temporary file. Then, it
|
The snippet above then creates an (empty) temporary file. Then, it
|
||||||
runs a script that generates random escape sequences (if you cat
|
runs a script that generates random escape sequences (if you cat
|
||||||
|
|
@ -371,6 +373,7 @@ This method requires a running Wayland session.
|
||||||
We will use the script `scripts/generate-alt-random-writes.py`:
|
We will use the script `scripts/generate-alt-random-writes.py`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
./utils/xtgettcap
|
||||||
./footclient --version
|
./footclient --version
|
||||||
foot_tmp_file=$(mktemp)
|
foot_tmp_file=$(mktemp)
|
||||||
./foot \
|
./foot \
|
||||||
|
|
@ -384,9 +387,10 @@ rm ${foot_tmp_file}
|
||||||
You should see a foot window open up, with random colored text. The
|
You should see a foot window open up, with random colored text. The
|
||||||
window should close after ~1-2s.
|
window should close after ~1-2s.
|
||||||
|
|
||||||
The first step, `./footclient --version` might seem unnecessary, but
|
The first step, `./utils/xtgettcap && ./footclient --version`
|
||||||
is needed to ensure we have _some_ profiling data for
|
might seem unnecessary, but is needed to ensure we have _some_
|
||||||
`footclient`. Without this, the final link phase will fail.
|
profiling data for **all** binaries we build. Without this, the final
|
||||||
|
link phase will fail.
|
||||||
|
|
||||||
|
|
||||||
##### Use the generated PGO data
|
##### Use the generated PGO data
|
||||||
|
|
@ -436,7 +440,7 @@ sed 's/@default_terminfo@/foot/g' foot.info | \
|
||||||
Where _”output-directory”_ **must** match the value passed to
|
Where _”output-directory”_ **must** match the value passed to
|
||||||
`-Dcustom-terminfo-install-location` in the foot build. If
|
`-Dcustom-terminfo-install-location` in the foot build. If
|
||||||
`-Dcustom-terminfo-install-location` has not been set, `-o
|
`-Dcustom-terminfo-install-location` has not been set, `-o
|
||||||
<output-directoty>` can simply be omitted.
|
<output-directory>` can simply be omitted.
|
||||||
|
|
||||||
Or, if packaging:
|
Or, if packaging:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -569,7 +569,7 @@ reported the same issue.
|
||||||
The report should contain the following:
|
The report should contain the following:
|
||||||
|
|
||||||
- Foot version (`foot --version`).
|
- Foot version (`foot --version`).
|
||||||
- Log output from foot (start foot from another terminal).
|
- Log output from foot (run `foot -d info` from another terminal).
|
||||||
- Which Wayland compositor (and version) you are running.
|
- Which Wayland compositor (and version) you are running.
|
||||||
- If reporting a crash, please try to provide a `bt full` backtrace
|
- If reporting a crash, please try to provide a `bt full` backtrace
|
||||||
with symbols.
|
with symbols.
|
||||||
|
|
|
||||||
4
client.c
4
client.c
|
|
@ -94,7 +94,7 @@ print_usage(const char *prog_name)
|
||||||
" -N,--no-wait detach the client process from the running terminal, exiting immediately\n"
|
" -N,--no-wait detach the client process from the running terminal, exiting immediately\n"
|
||||||
" -o,--override=[section.]key=value override configuration option\n"
|
" -o,--override=[section.]key=value override configuration option\n"
|
||||||
" -E, --client-environment exec shell using footclient's environment, instead of the server's\n"
|
" -E, --client-environment exec shell using footclient's environment, instead of the server's\n"
|
||||||
" -d,--log-level={info|warning|error|none} log level (info)\n"
|
" -d,--log-level={info|warning|error|none} log level (warning)\n"
|
||||||
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
|
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
|
||||||
" -v,--version show the version number and quit\n"
|
" -v,--version show the version number and quit\n"
|
||||||
" -e ignored (for compatibility with xterm -e)\n";
|
" -e ignored (for compatibility with xterm -e)\n";
|
||||||
|
|
@ -178,7 +178,7 @@ main(int argc, char *const *argv)
|
||||||
|
|
||||||
const char *custom_cwd = NULL;
|
const char *custom_cwd = NULL;
|
||||||
const char *server_socket_path = NULL;
|
const char *server_socket_path = NULL;
|
||||||
enum log_class log_level = LOG_CLASS_INFO;
|
enum log_class log_level = LOG_CLASS_WARNING;
|
||||||
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
||||||
bool hold = false;
|
bool hold = false;
|
||||||
bool client_environment = false;
|
bool client_environment = false;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ _foot()
|
||||||
cur=${COMP_WORDS[COMP_CWORD]}
|
cur=${COMP_WORDS[COMP_CWORD]}
|
||||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||||
|
|
||||||
# check if positional argument is completed
|
# Check if positional argument is completed
|
||||||
previous_words=( "${COMP_WORDS[@]}" )
|
previous_words=( "${COMP_WORDS[@]}" )
|
||||||
unset previous_words[-1]
|
unset previous_words[-1]
|
||||||
commands=$(compgen -c | grep -vFx "$(compgen -k)" | grep -vE '^([.:[]|foot)$' | sort -u)
|
commands=$(compgen -c | grep -vFx "$(compgen -k)" | grep -vE '^([.:[]|foot)$' | sort -u)
|
||||||
|
|
@ -43,41 +43,45 @@ _foot()
|
||||||
(( i++ ))
|
(( i++ ))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# positional argument found
|
# Positional argument found
|
||||||
offset=$i
|
offset=$i
|
||||||
fi
|
fi
|
||||||
(( i++ ))
|
(( i++ ))
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ ! -z "$offset" ]] ; then
|
if [[ ! -z "$offset" ]] ; then
|
||||||
# depends on bash_completion being available
|
# Depends on bash_completion being available
|
||||||
declare -F _command_offset >/dev/null || return 1
|
declare -F _command_offset >/dev/null || return 1
|
||||||
_command_offset $offset
|
_command_offset $offset
|
||||||
|
return 0
|
||||||
elif [[ ${cur} == --* ]] ; then
|
elif [[ ${cur} == --* ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${flags}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${flags}" -- ${cur}) )
|
||||||
elif [[ ${prev} =~ ^(--config|--print-pid|--server)$ ]] ; then
|
return 0
|
||||||
compopt -o default
|
|
||||||
elif [[ ${prev} == '--working-directory' ]] ; then
|
|
||||||
compopt -o dirnames
|
|
||||||
elif [[ ${prev} == '--term' ]] ; then
|
|
||||||
# check if toe is available
|
|
||||||
which toe > /dev/null || return 1
|
|
||||||
COMPREPLY=( $(compgen -W "$(toe -a | awk '$1 ~ /[+]/ {next}; {print $1}')" -- ${cur}) )
|
|
||||||
elif [[ ${prev} == '--font' ]] ; then
|
|
||||||
# check if fc-list is available
|
|
||||||
which fc-list > /dev/null || return 1
|
|
||||||
COMPREPLY=( $(compgen -W "$(fc-list : family | sed 's/,/\n/g' | uniq | tr -d ' ')" -- ${cur}) )
|
|
||||||
elif [[ ${prev} == '--log-level' ]] ; then
|
|
||||||
COMPREPLY=( $(compgen -W "none error warning info" -- ${cur}) )
|
|
||||||
elif [[ ${prev} == '--log-colorize' ]] ; then
|
|
||||||
COMPREPLY=( $(compgen -W "never always auto" -- ${cur}) )
|
|
||||||
elif [[ ${prev} =~ ^(--app-id|--help|--override|--title|--version|--window-size-chars|--window-size-pixels|--check-config)$ ]] ; then
|
|
||||||
: # don't autocomplete for these flags
|
|
||||||
else
|
|
||||||
# complete commands from $PATH
|
|
||||||
COMPREPLY=( $(compgen -c -- ${cur}) )
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case "$prev" in
|
||||||
|
--config|--print-pid|--server|-[cps])
|
||||||
|
compopt -o default ;;
|
||||||
|
--working-directory|-D)
|
||||||
|
compopt -o dirnames ;;
|
||||||
|
--term|-t)
|
||||||
|
command -v toe > /dev/null || return 1
|
||||||
|
COMPREPLY=( $(compgen -W "$(toe -a | awk '$1 !~ /[+]/ {print $1}')" -- ${cur}) ) ;;
|
||||||
|
--font|-f)
|
||||||
|
command -v fc-list > /dev/null || return 1
|
||||||
|
COMPREPLY=( $(compgen -W "$(fc-list : family | sed 's/,/\n/g' | uniq | tr -d ' ')" -- ${cur}) ) ;;
|
||||||
|
--log-level|-d)
|
||||||
|
COMPREPLY=( $(compgen -W "none error warning info" -- ${cur}) ) ;;
|
||||||
|
--log-colorize|-l)
|
||||||
|
COMPREPLY=( $(compgen -W "never always auto" -- ${cur}) ) ;;
|
||||||
|
--app-id|--help|--override|--title|--version|--window-size-chars|--window-size-pixels|--check-config|-[ahoTvWwC])
|
||||||
|
# Don't autocomplete for these flags
|
||||||
|
: ;;
|
||||||
|
*)
|
||||||
|
# Complete commands from $PATH
|
||||||
|
COMPREPLY=( $(compgen -c -- ${cur}) ) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ _footclient()
|
||||||
cur=${COMP_WORDS[COMP_CWORD]}
|
cur=${COMP_WORDS[COMP_CWORD]}
|
||||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||||
|
|
||||||
# check if positional argument is completed
|
# Check if positional argument is completed
|
||||||
previous_words=( "${COMP_WORDS[@]}" )
|
previous_words=( "${COMP_WORDS[@]}" )
|
||||||
unset previous_words[-1]
|
unset previous_words[-1]
|
||||||
commands=$(compgen -c | grep -vFx "$(compgen -k)" | grep -vE '^([.:[]|footclient)$' | sort -u)
|
commands=$(compgen -c | grep -vFx "$(compgen -k)" | grep -vE '^([.:[]|footclient)$' | sort -u)
|
||||||
|
|
@ -39,37 +39,42 @@ _footclient()
|
||||||
(( i++ ))
|
(( i++ ))
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# positional argument found
|
# Positional argument found
|
||||||
offset=$i
|
offset=$i
|
||||||
fi
|
fi
|
||||||
(( i++ ))
|
(( i++ ))
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ ! -z "$offset" ]] ; then
|
if [[ ! -z "$offset" ]] ; then
|
||||||
# depends on bash_completion being available
|
# Depends on bash_completion being available
|
||||||
declare -F _command_offset >/dev/null || return 1
|
declare -F _command_offset >/dev/null || return 1
|
||||||
_command_offset $offset
|
_command_offset $offset
|
||||||
|
return 0
|
||||||
elif [[ ${cur} == --* ]] ; then
|
elif [[ ${cur} == --* ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${flags}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${flags}" -- ${cur}) )
|
||||||
elif [[ ${prev} == '--server-socket' ]] ; then
|
return 0
|
||||||
compopt -o default
|
|
||||||
elif [[ ${prev} == '--working-directory' ]] ; then
|
|
||||||
compopt -o dirnames
|
|
||||||
elif [[ ${prev} == '--term' ]] ; then
|
|
||||||
# check if toe is available
|
|
||||||
which toe > /dev/null || return 1
|
|
||||||
COMPREPLY=( $(compgen -W "$(toe -a | awk '$1 ~ /[+]/ {next}; {print $1}')" -- ${cur}) )
|
|
||||||
elif [[ ${prev} == '--log-level' ]] ; then
|
|
||||||
COMPREPLY=( $(compgen -W "none error warning info" -- ${cur}) )
|
|
||||||
elif [[ ${prev} == '--log-colorize' ]] ; then
|
|
||||||
COMPREPLY=( $(compgen -W "never always auto" -- ${cur}) )
|
|
||||||
elif [[ ${prev} =~ ^(--app-id|--help|--override|--title|--version|--window-size-chars|--window-size-pixels|)$ ]] ; then
|
|
||||||
: # don't autocomplete for these flags
|
|
||||||
else
|
|
||||||
# complete commands from $PATH
|
|
||||||
COMPREPLY=( $(compgen -c -- ${cur}) )
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case "$prev" in
|
||||||
|
--server-socket|-s)
|
||||||
|
compopt -o default ;;
|
||||||
|
--working-directory|-D)
|
||||||
|
compopt -o dirnames ;;
|
||||||
|
--term|-t)
|
||||||
|
command -v toe > /dev/null || return 1
|
||||||
|
COMPREPLY=( $(compgen -W "$(toe -a | awk '$1 ~ /[+]/ {next}; {print $1}')" -- ${cur}) ) ;;
|
||||||
|
--log-level|-d)
|
||||||
|
COMPREPLY=( $(compgen -W "none error warning info" -- ${cur}) ) ;;
|
||||||
|
--log-colorize|-l)
|
||||||
|
COMPREPLY=( $(compgen -W "never always auto" -- ${cur}) ) ;;
|
||||||
|
--app-id|--help|--override|--title|--version|--window-size-chars|--window-size-pixels|-[ahoTvWw])
|
||||||
|
# Don't autocomplete for these flags
|
||||||
|
: ;;
|
||||||
|
*)
|
||||||
|
# Complete commands from $PATH
|
||||||
|
COMPREPLY=( $(compgen -c -- ${cur}) ) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ complete -c foot -x -s W -l window-size-chars
|
||||||
complete -c foot -F -s s -l server -d "run as server; open terminals by running footclient"
|
complete -c foot -F -s s -l server -d "run as server; open terminals by running footclient"
|
||||||
complete -c foot -s H -l hold -d "remain open after child process exits"
|
complete -c foot -s H -l hold -d "remain open after child process exits"
|
||||||
complete -c foot -r -s p -l print-pid -d "print PID to this file or FD when up and running (server mode only)"
|
complete -c foot -r -s p -l print-pid -d "print PID to this file or FD when up and running (server mode only)"
|
||||||
complete -c foot -x -s d -l log-level -a "info warning error none" -d "log-level (info)"
|
complete -c foot -x -s d -l log-level -a "info warning error none" -d "log-level (warning)"
|
||||||
complete -c foot -x -s l -l log-colorize -a "always never auto" -d "enable or disable colorization of log output on stderr"
|
complete -c foot -x -s l -l log-colorize -a "always never auto" -d "enable or disable colorization of log output on stderr"
|
||||||
complete -c foot -s S -l log-no-syslog -d "disable syslog logging (server mode only)"
|
complete -c foot -s S -l log-no-syslog -d "disable syslog logging (server mode only)"
|
||||||
complete -c foot -s v -l version -d "show the version number and quit"
|
complete -c foot -s v -l version -d "show the version number and quit"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ _arguments \
|
||||||
'(-s --server)'{-s,--server}'[run as server; open terminals by running footclient]:server:_files' \
|
'(-s --server)'{-s,--server}'[run as server; open terminals by running footclient]:server:_files' \
|
||||||
'(-H --hold)'{-H,--hold}'[remain open after child process exits]' \
|
'(-H --hold)'{-H,--hold}'[remain open after child process exits]' \
|
||||||
'(-p --print-pid)'{-p,--print-pid}'[print PID to this file or FD when up and running (server mode only)]:pidfile:_files' \
|
'(-p --print-pid)'{-p,--print-pid}'[print PID to this file or FD when up and running (server mode only)]:pidfile:_files' \
|
||||||
'(-d --log-level)'{-d,--log-level}'[log level (info)]:loglevel:(info warning error none)' \
|
'(-d --log-level)'{-d,--log-level}'[log level (warning)]:loglevel:(info warning error none)' \
|
||||||
'(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \
|
'(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \
|
||||||
'(-S --log-no-syslog)'{-s,--log-no-syslog}'[disable syslog logging (server mode only)]' \
|
'(-S --log-no-syslog)'{-s,--log-no-syslog}'[disable syslog logging (server mode only)]' \
|
||||||
'(-v --version)'{-v,--version}'[show the version number and quit]' \
|
'(-v --version)'{-v,--version}'[show the version number and quit]' \
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ _arguments \
|
||||||
'(-N --no-wait)'{-N,--no-wait}'[detach the client process from the running terminal, exiting immediately]' \
|
'(-N --no-wait)'{-N,--no-wait}'[detach the client process from the running terminal, exiting immediately]' \
|
||||||
'(-o --override)'{-o,--override}'[configuration option to override, in form SECTION.KEY=VALUE]:()' \
|
'(-o --override)'{-o,--override}'[configuration option to override, in form SECTION.KEY=VALUE]:()' \
|
||||||
'(-E --client-environment)'{-E,--client-environment}"[child process inherits footclient's environment, instead of the server's]" \
|
'(-E --client-environment)'{-E,--client-environment}"[child process inherits footclient's environment, instead of the server's]" \
|
||||||
'(-d --log-level)'{-d,--log-level}'[log level (info)]:loglevel:(info warning error none)' \
|
'(-d --log-level)'{-d,--log-level}'[log level (warning)]:loglevel:(info warning error none)' \
|
||||||
'(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \
|
'(-l --log-colorize)'{-l,--log-colorize}'[enable or disable colorization of log output on stderr]:logcolor:(never always auto)' \
|
||||||
'(-v --version)'{-v,--version}'[show the version number and quit]' \
|
'(-v --version)'{-v,--version}'[show the version number and quit]' \
|
||||||
'(-h --help)'{-h,--help}'[show help message and quit]' \
|
'(-h --help)'{-h,--help}'[show help message and quit]' \
|
||||||
|
|
|
||||||
138
config.c
138
config.c
|
|
@ -503,8 +503,48 @@ value_to_double(struct context *ctx, float *res)
|
||||||
static bool NOINLINE
|
static bool NOINLINE
|
||||||
value_to_str(struct context *ctx, char **res)
|
value_to_str(struct context *ctx, char **res)
|
||||||
{
|
{
|
||||||
|
char *copy = xstrdup(ctx->value);
|
||||||
|
char *end = copy + strlen(copy) - 1;
|
||||||
|
|
||||||
|
/* Un-quote
|
||||||
|
*
|
||||||
|
* Note: this is very simple; we only support the *entire* value
|
||||||
|
* being quoted. That is, no mid-value quotes. Both double and
|
||||||
|
* single quotes are supported.
|
||||||
|
*
|
||||||
|
* - key="value" OK
|
||||||
|
* - key=abc "quote" def NOT OK
|
||||||
|
* - key=’value’ OK
|
||||||
|
*
|
||||||
|
* Finally, we support escaping the quote character, and the
|
||||||
|
* escape character itself:
|
||||||
|
*
|
||||||
|
* - key="value \"quotes\""
|
||||||
|
* - key="backslash: \\"
|
||||||
|
*
|
||||||
|
* ONLY the "current" quote character can be escaped:
|
||||||
|
*
|
||||||
|
* key="value \'" NOt OK (both backslash and single quote is kept)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((copy[0] == '"' && *end == '"') ||
|
||||||
|
(copy[0] == '\'' && *end == '\''))
|
||||||
|
{
|
||||||
|
const char quote = copy[0];
|
||||||
|
*end = '\0';
|
||||||
|
|
||||||
|
memmove(copy, copy + 1, end - copy);
|
||||||
|
|
||||||
|
/* Un-escape */
|
||||||
|
for (char *p = copy; *p != '\0'; p++) {
|
||||||
|
if (p[0] == '\\' && (p[1] == '\\' || p[1] == quote)) {
|
||||||
|
memmove(p, p + 1, end - p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(*res);
|
free(*res);
|
||||||
*res = xstrdup(ctx->value);
|
*res = copy;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -612,7 +652,7 @@ value_to_pt_or_px(struct context *ctx, struct pt_or_px *res)
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
|
|
||||||
long value = strtol(s, &end, 10);
|
long value = strtol(s, &end, 10);
|
||||||
if (!(errno == 0 && end == s + len - 2)) {
|
if (!(len > 2 && errno == 0 && end == s + len - 2)) {
|
||||||
LOG_CONTEXTUAL_ERR("invalid px value (must be in the form 12px)");
|
LOG_CONTEXTUAL_ERR("invalid px value (must be in the form 12px)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -886,6 +926,31 @@ parse_section_main(struct context *ctx)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (strcmp(key, "font-size-adjustment") == 0) {
|
||||||
|
const size_t len = strlen(ctx->value);
|
||||||
|
if (len >= 1 && ctx->value[len - 1] == '%') {
|
||||||
|
errno = 0;
|
||||||
|
char *end = NULL;
|
||||||
|
|
||||||
|
float percent = strtof(ctx->value, &end);
|
||||||
|
if (!(len > 1 && errno == 0 && end == ctx->value + len - 1)) {
|
||||||
|
LOG_CONTEXTUAL_ERR(
|
||||||
|
"invalid percent value (must be in the form 10.5%%)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf->font_size_adjustment.percent = percent / 100.;
|
||||||
|
conf->font_size_adjustment.pt_or_px.pt = 0;
|
||||||
|
conf->font_size_adjustment.pt_or_px.px = 0;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
bool ret = value_to_pt_or_px(ctx, &conf->font_size_adjustment.pt_or_px);
|
||||||
|
if (ret)
|
||||||
|
conf->font_size_adjustment.percent = 0.;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (strcmp(key, "line-height") == 0)
|
else if (strcmp(key, "line-height") == 0)
|
||||||
return value_to_pt_or_px(ctx, &conf->line_height);
|
return value_to_pt_or_px(ctx, &conf->line_height);
|
||||||
|
|
||||||
|
|
@ -1413,6 +1478,9 @@ parse_section_csd(struct context *ctx)
|
||||||
static void
|
static void
|
||||||
free_binding_aux(struct binding_aux *aux)
|
free_binding_aux(struct binding_aux *aux)
|
||||||
{
|
{
|
||||||
|
if (!aux->master_copy)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (aux->type) {
|
switch (aux->type) {
|
||||||
case BINDING_AUX_NONE: break;
|
case BINDING_AUX_NONE: break;
|
||||||
case BINDING_AUX_PIPE: free_argv(&aux->pipe); break;
|
case BINDING_AUX_PIPE: free_argv(&aux->pipe); break;
|
||||||
|
|
@ -2256,21 +2324,22 @@ parse_section_environment(struct context *ctx)
|
||||||
{
|
{
|
||||||
struct config *conf = ctx->conf;
|
struct config *conf = ctx->conf;
|
||||||
const char *key = ctx->key;
|
const char *key = ctx->key;
|
||||||
const char *value = ctx->value;
|
|
||||||
|
|
||||||
|
/* Check for pre-existing env variable */
|
||||||
tll_foreach(conf->env_vars, it) {
|
tll_foreach(conf->env_vars, it) {
|
||||||
if (strcmp(it->item.name, key) == 0) {
|
if (strcmp(it->item.name, key) == 0)
|
||||||
free(it->item.value);
|
return value_to_str(ctx, &it->item.value);
|
||||||
it->item.value = xstrdup(value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct env_var var = {
|
/*
|
||||||
.name = xstrdup(key),
|
* No pre-existing variable - allocate a new one
|
||||||
.value = xstrdup(value),
|
*/
|
||||||
};
|
|
||||||
tll_push_back(conf->env_vars, var);
|
char *value = NULL;
|
||||||
|
if (!value_to_str(ctx, &value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tll_push_back(conf->env_vars, ((struct env_var){xstrdup(key), value}));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2847,6 +2916,7 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
},
|
},
|
||||||
.startup_mode = STARTUP_WINDOWED,
|
.startup_mode = STARTUP_WINDOWED,
|
||||||
.fonts = {{0}},
|
.fonts = {{0}},
|
||||||
|
.font_size_adjustment = {.percent = 0., .pt_or_px = {.pt = 0.5, .px = 0}},
|
||||||
.line_height = {.pt = 0, .px = -1},
|
.line_height = {.pt = 0, .px = -1},
|
||||||
.letter_spacing = {.pt = 0, .px = 0},
|
.letter_spacing = {.pt = 0, .px = 0},
|
||||||
.horizontal_letter_offset = {.pt = 0, .px = 0},
|
.horizontal_letter_offset = {.pt = 0, .px = 0},
|
||||||
|
|
@ -2938,7 +3008,7 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
#if defined(FOOT_GRAPHEME_CLUSTERING) && FOOT_GRAPHEME_CLUSTERING
|
#if defined(FOOT_GRAPHEME_CLUSTERING) && FOOT_GRAPHEME_CLUSTERING
|
||||||
.grapheme_shaping = fcft_caps & FCFT_CAPABILITY_GRAPHEME_SHAPING,
|
.grapheme_shaping = fcft_caps & FCFT_CAPABILITY_GRAPHEME_SHAPING,
|
||||||
#endif
|
#endif
|
||||||
.grapheme_width_method = GRAPHEME_WIDTH_WCSWIDTH,
|
.grapheme_width_method = GRAPHEME_WIDTH_DOUBLE,
|
||||||
.delayed_render_lower_ns = 500000, /* 0.5ms */
|
.delayed_render_lower_ns = 500000, /* 0.5ms */
|
||||||
.delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */
|
.delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */
|
||||||
.max_shm_pool_size = 512 * 1024 * 1024,
|
.max_shm_pool_size = 512 * 1024 * 1024,
|
||||||
|
|
@ -3322,20 +3392,48 @@ config_font_parse(const char *pattern, struct config_font *font)
|
||||||
if (pat == NULL)
|
if (pat == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First look for user specified {pixel}size option
|
||||||
|
* e.g. “font-name:size=12”
|
||||||
|
*/
|
||||||
|
|
||||||
double pt_size = -1.0;
|
double pt_size = -1.0;
|
||||||
FcPatternGetDouble(pat, FC_SIZE, 0, &pt_size);
|
FcResult have_pt_size = FcPatternGetDouble(pat, FC_SIZE, 0, &pt_size);
|
||||||
FcPatternRemove(pat, FC_SIZE, 0);
|
|
||||||
|
|
||||||
int px_size = -1;
|
int px_size = -1;
|
||||||
FcPatternGetInteger(pat, FC_PIXEL_SIZE, 0, &px_size);
|
FcResult have_px_size = FcPatternGetInteger(pat, FC_PIXEL_SIZE, 0, &px_size);
|
||||||
FcPatternRemove(pat, FC_PIXEL_SIZE, 0);
|
|
||||||
|
|
||||||
if (pt_size == -1. && px_size == -1)
|
if (have_pt_size != FcResultMatch && have_px_size != FcResultMatch) {
|
||||||
pt_size = 8.0;
|
/*
|
||||||
|
* Apply fontconfig config. Can’t do that until we’ve first
|
||||||
|
* checked for a user provided size, since we may end up with
|
||||||
|
* both “size” and “pixelsize” being set, and we don’t know
|
||||||
|
* which one takes priority.
|
||||||
|
*/
|
||||||
|
FcPattern *pat_copy = FcPatternDuplicate(pat);
|
||||||
|
if (pat_copy == NULL ||
|
||||||
|
!FcConfigSubstitute(NULL, pat_copy, FcMatchPattern))
|
||||||
|
{
|
||||||
|
LOG_WARN("%s: failed to do config substitution", pattern);
|
||||||
|
} else {
|
||||||
|
have_pt_size = FcPatternGetDouble(pat_copy, FC_SIZE, 0, &pt_size);
|
||||||
|
have_px_size = FcPatternGetInteger(pat_copy, FC_PIXEL_SIZE, 0, &px_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
FcPatternDestroy(pat_copy);
|
||||||
|
|
||||||
|
if (have_pt_size != FcResultMatch && have_px_size != FcResultMatch)
|
||||||
|
pt_size = 8.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcPatternRemove(pat, FC_SIZE, 0);
|
||||||
|
FcPatternRemove(pat, FC_PIXEL_SIZE, 0);
|
||||||
|
|
||||||
char *stripped_pattern = (char *)FcNameUnparse(pat);
|
char *stripped_pattern = (char *)FcNameUnparse(pat);
|
||||||
FcPatternDestroy(pat);
|
FcPatternDestroy(pat);
|
||||||
|
|
||||||
|
LOG_DBG("%s: pt-size=%.2f, px-size=%d", stripped_pattern, pt_size, px_size);
|
||||||
|
|
||||||
*font = (struct config_font){
|
*font = (struct config_font){
|
||||||
.pattern = stripped_pattern,
|
.pattern = stripped_pattern,
|
||||||
.pt_size = pt_size,
|
.pt_size = pt_size,
|
||||||
|
|
|
||||||
11
config.h
11
config.h
|
|
@ -22,6 +22,11 @@ struct pt_or_px {
|
||||||
float pt;
|
float pt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct font_size_adjustment {
|
||||||
|
struct pt_or_px pt_or_px;
|
||||||
|
float percent;
|
||||||
|
};
|
||||||
|
|
||||||
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
|
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
|
||||||
|
|
||||||
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
|
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
|
||||||
|
|
@ -69,11 +74,6 @@ enum key_binding_type {
|
||||||
MOUSE_BINDING,
|
MOUSE_BINDING,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config_key_binding_text {
|
|
||||||
char *text;
|
|
||||||
bool master_copy;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct config_key_binding {
|
struct config_key_binding {
|
||||||
int action; /* One of the varios bind_action_* enums from wayland.h */
|
int action; /* One of the varios bind_action_* enums from wayland.h */
|
||||||
struct config_key_modifiers modifiers;
|
struct config_key_modifiers modifiers;
|
||||||
|
|
@ -139,6 +139,7 @@ struct config {
|
||||||
|
|
||||||
enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware;
|
enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware;
|
||||||
struct config_font_list fonts[4];
|
struct config_font_list fonts[4];
|
||||||
|
struct font_size_adjustment font_size_adjustment;
|
||||||
|
|
||||||
/* Custom font metrics (-1 = use real font metrics) */
|
/* Custom font metrics (-1 = use real font metrics) */
|
||||||
struct pt_or_px line_height;
|
struct pt_or_px line_height;
|
||||||
|
|
|
||||||
27
csi.c
27
csi.c
|
|
@ -276,21 +276,6 @@ decset_decrst(struct terminal *term, unsigned param, bool enable)
|
||||||
enable ? CURSOR_KEYS_APPLICATION : CURSOR_KEYS_NORMAL;
|
enable ? CURSOR_KEYS_APPLICATION : CURSOR_KEYS_NORMAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
|
||||||
/* DECCOLM */
|
|
||||||
if (enable)
|
|
||||||
LOG_WARN("unimplemented: 132 column mode (DECCOLM)");
|
|
||||||
|
|
||||||
term_erase(term, 0, 0, term->rows - 1, term->cols - 1);
|
|
||||||
term_cursor_home(term);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
/* DECSCLM - Smooth scroll */
|
|
||||||
if (enable)
|
|
||||||
LOG_WARN("unimplemented: Smooth (Slow) Scroll (DECSCLM)");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
/* DECSCNM */
|
/* DECSCNM */
|
||||||
term->reverse = enable;
|
term->reverse = enable;
|
||||||
|
|
@ -558,8 +543,6 @@ decrqm(const struct terminal *term, unsigned param)
|
||||||
{
|
{
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 1: return decrpm(term->cursor_keys_mode == CURSOR_KEYS_APPLICATION);
|
case 1: return decrpm(term->cursor_keys_mode == CURSOR_KEYS_APPLICATION);
|
||||||
case 3: return DECRPM_PERMANENTLY_RESET;
|
|
||||||
case 4: return DECRPM_PERMANENTLY_RESET;
|
|
||||||
case 5: return decrpm(term->reverse);
|
case 5: return decrpm(term->reverse);
|
||||||
case 6: return decrpm(term->origin);
|
case 6: return decrpm(term->origin);
|
||||||
case 7: return decrpm(term->auto_margin);
|
case 7: return decrpm(term->auto_margin);
|
||||||
|
|
@ -601,8 +584,6 @@ xtsave(struct terminal *term, unsigned param)
|
||||||
{
|
{
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 1: term->xtsave.application_cursor_keys = term->cursor_keys_mode == CURSOR_KEYS_APPLICATION; break;
|
case 1: term->xtsave.application_cursor_keys = term->cursor_keys_mode == CURSOR_KEYS_APPLICATION; break;
|
||||||
case 3: break;
|
|
||||||
case 4: break;
|
|
||||||
case 5: term->xtsave.reverse = term->reverse; break;
|
case 5: term->xtsave.reverse = term->reverse; break;
|
||||||
case 6: term->xtsave.origin = term->origin; break;
|
case 6: term->xtsave.origin = term->origin; break;
|
||||||
case 7: term->xtsave.auto_margin = term->auto_margin; break;
|
case 7: term->xtsave.auto_margin = term->auto_margin; break;
|
||||||
|
|
@ -644,8 +625,6 @@ xtrestore(struct terminal *term, unsigned param)
|
||||||
bool enable;
|
bool enable;
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 1: enable = term->xtsave.application_cursor_keys; break;
|
case 1: enable = term->xtsave.application_cursor_keys; break;
|
||||||
case 3: return;
|
|
||||||
case 4: return;
|
|
||||||
case 5: enable = term->xtsave.reverse; break;
|
case 5: enable = term->xtsave.reverse; break;
|
||||||
case 6: enable = term->xtsave.origin; break;
|
case 6: enable = term->xtsave.origin; break;
|
||||||
case 7: enable = term->xtsave.auto_margin; break;
|
case 7: enable = term->xtsave.auto_margin; break;
|
||||||
|
|
@ -933,7 +912,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'L': {
|
case 'L': { /* IL */
|
||||||
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
||||||
term->grid->cursor.point.row >= term->scroll_region.end)
|
term->grid->cursor.point.row >= term->scroll_region.end)
|
||||||
break;
|
break;
|
||||||
|
|
@ -953,7 +932,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'M': {
|
case 'M': { /* DL */
|
||||||
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
if (term->grid->cursor.point.row < term->scroll_region.start ||
|
||||||
term->grid->cursor.point.row >= term->scroll_region.end)
|
term->grid->cursor.point.row >= term->scroll_region.end)
|
||||||
break;
|
break;
|
||||||
|
|
@ -1518,7 +1497,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
break; /* final == 'm' */
|
break; /* final == 'm' */
|
||||||
|
|
||||||
case 'n': {
|
case 'n': {
|
||||||
int resource = vt_param_get(term, 0, 2); /* Default is modifyFuncionKeys */
|
int resource = vt_param_get(term, 0, 2); /* Default is modifyFunctionKeys */
|
||||||
switch (resource) {
|
switch (resource) {
|
||||||
case 0: /* modifyKeyboard */
|
case 0: /* modifyKeyboard */
|
||||||
case 1: /* modifyCursorKeys */
|
case 1: /* modifyCursorKeys */
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ This document describes all the control sequences supported by foot.
|
||||||
|
|
||||||
[[ *Sequence*
|
[[ *Sequence*
|
||||||
:[ *Name*
|
:[ *Name*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| \\a
|
| \\a
|
||||||
: BEL
|
: BEL
|
||||||
: Depends on what *bell* in *foot.ini*(5) is set to.
|
: Depends on what *bell* in *foot.ini*(5) is set to.
|
||||||
|
|
@ -60,7 +60,7 @@ equivalent to 8-bit C1 controls.
|
||||||
[[ *Sequence*
|
[[ *Sequence*
|
||||||
:[ *Name*
|
:[ *Name*
|
||||||
:[ *Origin*
|
:[ *Origin*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| \\E 7
|
| \\E 7
|
||||||
: DECSC
|
: DECSC
|
||||||
: VT100
|
: VT100
|
||||||
|
|
@ -140,7 +140,7 @@ single CSI sequence by separating them with semicolons: *\\E[ 1;2;3
|
||||||
m*.
|
m*.
|
||||||
|
|
||||||
[[ *Parameter*
|
[[ *Parameter*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| 0
|
| 0
|
||||||
: Reset all attributes
|
: Reset all attributes
|
||||||
| 1
|
| 1
|
||||||
|
|
@ -223,7 +223,7 @@ following 4 escape sequences:
|
||||||
|
|
||||||
[[ *Sequence*
|
[[ *Sequence*
|
||||||
:[ *Name*
|
:[ *Name*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| \\E[ ? _Pm_ h
|
| \\E[ ? _Pm_ h
|
||||||
: DECSET
|
: DECSET
|
||||||
: Enable private mode
|
: Enable private mode
|
||||||
|
|
@ -243,7 +243,7 @@ that corresponds to one of the following modes:
|
||||||
|
|
||||||
[[ *Parameter*
|
[[ *Parameter*
|
||||||
:[ *Origin*
|
:[ *Origin*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| 1
|
| 1
|
||||||
: VT100
|
: VT100
|
||||||
: Cursor keys mode (DECCKM)
|
: Cursor keys mode (DECCKM)
|
||||||
|
|
@ -344,7 +344,7 @@ manipulation sequences. The generic format is:
|
||||||
|
|
||||||
[[ *Parameter 1*
|
[[ *Parameter 1*
|
||||||
:[ *Parameter 2*
|
:[ *Parameter 2*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| 11
|
| 11
|
||||||
: -
|
: -
|
||||||
: Report if window is iconified. Foot always reports *1* - not iconified.
|
: Report if window is iconified. Foot always reports *1* - not iconified.
|
||||||
|
|
@ -394,7 +394,7 @@ manipulation sequences. The generic format is:
|
||||||
[[ *Parameter*
|
[[ *Parameter*
|
||||||
:[ *Name*
|
:[ *Name*
|
||||||
:[ *Origin*
|
:[ *Origin*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| \\E[ _Ps_ c
|
| \\E[ _Ps_ c
|
||||||
: DA
|
: DA
|
||||||
: VT100
|
: VT100
|
||||||
|
|
@ -504,7 +504,7 @@ manipulation sequences. The generic format is:
|
||||||
| \\E[ = _Ps_ c
|
| \\E[ = _Ps_ c
|
||||||
: DA3
|
: DA3
|
||||||
: VT510
|
: VT510
|
||||||
: send tertiary device attributes. Foot responds with "FOOT", in
|
: Send tertiary device attributes. Foot responds with "FOOT", in
|
||||||
hexadecimal.
|
hexadecimal.
|
||||||
| \\E[ _Pm_ d
|
| \\E[ _Pm_ d
|
||||||
: VPA
|
: VPA
|
||||||
|
|
@ -595,7 +595,7 @@ All _OSC_ sequences begin with *\\E]*, sometimes abbreviated _OSC_.
|
||||||
|
|
||||||
[[ *Sequence*
|
[[ *Sequence*
|
||||||
:[ *Origin*
|
:[ *Origin*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| \\E] 0 ; _Pt_ \\E\\
|
| \\E] 0 ; _Pt_ \\E\\
|
||||||
: xterm
|
: xterm
|
||||||
: Set window icon and title to _Pt_ (foot does not support setting the
|
: Set window icon and title to _Pt_ (foot does not support setting the
|
||||||
|
|
@ -693,7 +693,7 @@ All _DCS_ sequences begin with *\\EP* (sometimes abbreviated _DCS_),
|
||||||
and are terminated by *\\E\\* (ST).
|
and are terminated by *\\E\\* (ST).
|
||||||
|
|
||||||
[[ *Sequence*
|
[[ *Sequence*
|
||||||
:[ *Description*
|
:< *Description*
|
||||||
| \\EP q <sixel data> \\E\\
|
| \\EP q <sixel data> \\E\\
|
||||||
: Emit a sixel image at the current cursor position
|
: Emit a sixel image at the current cursor position
|
||||||
| \\P $ q <query> \\E\\
|
| \\P $ q <query> \\E\\
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ the foot command line
|
||||||
|
|
||||||
*-d*,*--log-level*={*info*,*warning*,*error*,*none*}
|
*-d*,*--log-level*={*info*,*warning*,*error*,*none*}
|
||||||
Log level, used both for log output on stderr as well as
|
Log level, used both for log output on stderr as well as
|
||||||
syslog. Default: _info_.
|
syslog. Default: _warning_.
|
||||||
|
|
||||||
*-l*,*--log-colorize*=[{*never*,*always*,*auto*}]
|
*-l*,*--log-colorize*=[{*never*,*always*,*auto*}]
|
||||||
Enables or disables colorization of log output on stderr. Default:
|
Enables or disables colorization of log output on stderr. Default:
|
||||||
|
|
@ -543,10 +543,24 @@ In all other cases, the exit code is that of the client application
|
||||||
set according to either the *--term* command-line option or the
|
set according to either the *--term* command-line option or the
|
||||||
*term* config option in *foot.ini*(5).
|
*term* config option in *foot.ini*(5).
|
||||||
|
|
||||||
|
*PWD*
|
||||||
|
Current working directory (at the time of launching foot)
|
||||||
|
|
||||||
*COLORTERM*
|
*COLORTERM*
|
||||||
This variable is set to *truecolor*, to indicate to client
|
This variable is set to *truecolor*, to indicate to client
|
||||||
applications that 24-bit RGB colors are supported.
|
applications that 24-bit RGB colors are supported.
|
||||||
|
|
||||||
|
*TERM_PROGRAM*
|
||||||
|
Always set to *foot*. This can be used by client applications to
|
||||||
|
check which terminal is in use, but with the caveat that it may
|
||||||
|
have been inherited from a parent process in other terminals that
|
||||||
|
aren't known to set the variable.
|
||||||
|
|
||||||
|
*TERM_PROGRAM_VERSION*
|
||||||
|
Set to the foot version string, in the format _major_*.*_minor_*.*_patch_
|
||||||
|
or _major_*.*_minor_*.*_patch_*-*_revision_*-\g*_commit_ for inter-release
|
||||||
|
builds. The same caveat as for *TERM_PROGRAM* applies.
|
||||||
|
|
||||||
In addition to the variables listed above, custom environment
|
In addition to the variables listed above, custom environment
|
||||||
variables may be defined in *foot.ini*(5).
|
variables may be defined in *foot.ini*(5).
|
||||||
|
|
||||||
|
|
@ -561,7 +575,7 @@ the same issue.
|
||||||
The report should contain the following:
|
The report should contain the following:
|
||||||
|
|
||||||
- Foot version (*foot --version*).
|
- Foot version (*foot --version*).
|
||||||
- Log output from foot (start foot from another terminal).
|
- Log output from foot (run *foot -d info* from another terminal).
|
||||||
- Which Wayland compositor (and version) you are running.
|
- Which Wayland compositor (and version) you are running.
|
||||||
- If reporting a crash, please try to provide a *bt full* backtrace
|
- If reporting a crash, please try to provide a *bt full* backtrace
|
||||||
with symbols.
|
with symbols.
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,15 @@ in this order:
|
||||||
An example configuration file containing all options with their default value
|
An example configuration file containing all options with their default value
|
||||||
commented out will usually be installed to */etc/xdg/foot/foot.ini*.
|
commented out will usually be installed to */etc/xdg/foot/foot.ini*.
|
||||||
|
|
||||||
|
Options are set using KEY=VALUE pairs:
|
||||||
|
|
||||||
|
*\[colors\]*++
|
||||||
|
*background=000000*++
|
||||||
|
*foreground=ffffff*
|
||||||
|
|
||||||
|
Empty values (*KEY=*) are not supported. String options do allow the
|
||||||
|
empty string to be set, but it must be quoted: *KEY=""*)
|
||||||
|
|
||||||
# SECTION: main
|
# SECTION: main
|
||||||
|
|
||||||
*shell*
|
*shell*
|
||||||
|
|
@ -71,6 +80,19 @@ commented out will usually be installed to */etc/xdg/foot/foot.ini*.
|
||||||
Default: _monospace:size=8_ (*font*), _not set_ (*font-bold*,
|
Default: _monospace:size=8_ (*font*), _not set_ (*font-bold*,
|
||||||
*font-italic*, *font-bold-italic*).
|
*font-italic*, *font-bold-italic*).
|
||||||
|
|
||||||
|
*font-size-adjustment*
|
||||||
|
Amount, in _points_, _pixels_ or _percent_, to increment/decrement
|
||||||
|
the font size when zooming in our out.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
font-size-adjustment=0.5 # Adjust by 0.5 points
|
||||||
|
font-size-adjustment=10xp # Adjust by 10 pixels
|
||||||
|
font-size-adjustment=7.5% # Adjust by 7.5 percent
|
||||||
|
```
|
||||||
|
|
||||||
|
Default: _0.5_
|
||||||
|
|
||||||
*include*
|
*include*
|
||||||
Absolute path to configuration file to import.
|
Absolute path to configuration file to import.
|
||||||
|
|
||||||
|
|
@ -213,15 +235,19 @@ commented out will usually be installed to */etc/xdg/foot/foot.ini*.
|
||||||
Default: _0x0_.
|
Default: _0x0_.
|
||||||
|
|
||||||
*resize-delay-ms*
|
*resize-delay-ms*
|
||||||
Time, in milliseconds, of "idle time" before foot sends the new
|
|
||||||
window dimensions to the client application while doing an
|
Time, in milliseconds, of "idle time" before foot performs text
|
||||||
interactive resize of a foot window. Idle time in this context is
|
reflow, and sends the new window dimensions to the client
|
||||||
a period of time where the window size is not changing.
|
application while doing an interactive resize of a foot
|
||||||
|
window. Idle time in this context is a period of time where the
|
||||||
|
window size is not changing.
|
||||||
|
|
||||||
In other words, while you are fiddling with the window size, foot
|
In other words, while you are fiddling with the window size, foot
|
||||||
does not send the updated dimensions to the client. Only when you
|
does not send the updated dimensions to the client. It also does a
|
||||||
pause the fiddling for *resize-delay-ms* milliseconds is the
|
fast "truncating" resize of the grid, instead of actually
|
||||||
client updated.
|
reflowing the contents. Only when you pause the fiddling for
|
||||||
|
*resize-delay-ms* milliseconds is the client updated, and the
|
||||||
|
contents properly reflowed.
|
||||||
|
|
||||||
Emphasis is on _while_ here; as soon as the interactive resize
|
Emphasis is on _while_ here; as soon as the interactive resize
|
||||||
ends (i.e. when you let go of the window border), the final
|
ends (i.e. when you let go of the window border), the final
|
||||||
|
|
@ -339,7 +365,7 @@ Note: do not set *TERM* here; use the *term* option in the main
|
||||||
*urgent*
|
*urgent*
|
||||||
When set to _yes_, foot will signal urgency to the compositor
|
When set to _yes_, foot will signal urgency to the compositor
|
||||||
through the XDG activation protocol whenever *BEL* is received,
|
through the XDG activation protocol whenever *BEL* is received,
|
||||||
and the window does NOT have keyboard foccus.
|
and the window does NOT have keyboard focus.
|
||||||
|
|
||||||
If the compositor does not implement this protocol, the margins
|
If the compositor does not implement this protocol, the margins
|
||||||
will be painted in red instead.
|
will be painted in red instead.
|
||||||
|
|
@ -448,14 +474,13 @@ applications can change these at runtime.
|
||||||
by applications. Default: _no_.
|
by applications. Default: _no_.
|
||||||
|
|
||||||
*color*
|
*color*
|
||||||
Two RRGGBB values (i.e. plain old 6-digit hex values, without
|
Two space separated RRGGBB values (i.e. plain old 6-digit hex
|
||||||
prefix) specifying the foreground (text) and background (cursor)
|
values, without prefix) specifying the foreground (text) and
|
||||||
colors for the cursor.
|
background (cursor) colors for the cursor.
|
||||||
|
|
||||||
Default: _inverse foreground/background colors_.
|
Example: *ff0000 00ff00* (green cursor, red text)
|
||||||
|
|
||||||
Note that this value only applies to the block cursor. The other
|
Default: the regular foreground and background colors, reversed.
|
||||||
cursor styles are always rendered with the foreground color.
|
|
||||||
|
|
||||||
*beam-thickness*
|
*beam-thickness*
|
||||||
Thickness (width) of the beam styled cursor. The value is in
|
Thickness (width) of the beam styled cursor. The value is in
|
||||||
|
|
@ -551,7 +576,7 @@ can configure the background transparency with the _alpha_ option.
|
||||||
options are unconfigured). 24-bit RGB colors will typically fall
|
options are unconfigured). 24-bit RGB colors will typically fall
|
||||||
into this category.
|
into this category.
|
||||||
|
|
||||||
Note that applications can change the *regularN* and *brighN*
|
Note that applications can change the *regularN* and *brightN*
|
||||||
colors at runtime. However, they have no way of changing the
|
colors at runtime. However, they have no way of changing the
|
||||||
*dimN* colors. If an application has changed the *regularN*
|
*dimN* colors. If an application has changed the *regularN*
|
||||||
colors, foot will still use the corresponding *dimN* color, as
|
colors, foot will still use the corresponding *dimN* color, as
|
||||||
|
|
@ -939,7 +964,7 @@ Be careful; do not use single-letter keys that are also used in
|
||||||
original text.
|
original text.
|
||||||
|
|
||||||
But with e.g. OSC-8 URLs (the terminal version of HTML anchors,
|
But with e.g. OSC-8 URLs (the terminal version of HTML anchors,
|
||||||
i.e. "links"), the text on the screen can be something completey
|
i.e. "links"), the text on the screen can be something completely
|
||||||
different than the URL.
|
different than the URL.
|
||||||
|
|
||||||
This action toggles between showing and hiding the URL on the jump
|
This action toggles between showing and hiding the URL on the jump
|
||||||
|
|
@ -1235,7 +1260,7 @@ any of these options.
|
||||||
|
|
||||||
*max* uses the width of the largest codepoint in the cluster.
|
*max* uses the width of the largest codepoint in the cluster.
|
||||||
|
|
||||||
Default: _wcswidth_
|
Default: _double-width_
|
||||||
|
|
||||||
*font-monospace-warn*
|
*font-monospace-warn*
|
||||||
Boolean. When enabled, foot will use heuristics to try to verify
|
Boolean. When enabled, foot will use heuristics to try to verify
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ terminal has terminated.
|
||||||
|
|
||||||
*-d*,*--log-level*={*info*,*warning*,*error*,*none*}
|
*-d*,*--log-level*={*info*,*warning*,*error*,*none*}
|
||||||
Log level, used both for log output on stderr as well as
|
Log level, used both for log output on stderr as well as
|
||||||
syslog. Default: _info_.
|
syslog. Default: _warning_.
|
||||||
|
|
||||||
*-l*,*--log-colorize*=[{*never*,*always*,*auto*}]
|
*-l*,*--log-colorize*=[{*never*,*always*,*auto*}]
|
||||||
Enables or disables colorization of log output on stderr.
|
Enables or disables colorization of log output on stderr.
|
||||||
|
|
@ -89,7 +89,7 @@ terminal has terminated.
|
||||||
|
|
||||||
# EXIT STATUS
|
# EXIT STATUS
|
||||||
|
|
||||||
Footlient will exit with code 220 if there is a failure in footclient
|
Footclient will exit with code 220 if there is a failure in footclient
|
||||||
itself (for example, the server socket does not exist).
|
itself (for example, the server socket does not exist).
|
||||||
|
|
||||||
If *-N*,*--no-wait* is used, footclient exits with code 0 as soon as
|
If *-N*,*--no-wait* is used, footclient exits with code 0 as soon as
|
||||||
|
|
@ -158,6 +158,17 @@ terminfo entries manually, by copying *foot* and *foot-direct* to
|
||||||
This variable is set to *truecolor*, to indicate to client
|
This variable is set to *truecolor*, to indicate to client
|
||||||
applications that 24-bit RGB colors are supported.
|
applications that 24-bit RGB colors are supported.
|
||||||
|
|
||||||
|
*TERM_PROGRAM*
|
||||||
|
Always set to *foot*. This can be used by client applications to
|
||||||
|
check which terminal is in use, but with the caveat that it may
|
||||||
|
have been inherited from a parent process in other terminals that
|
||||||
|
aren't known to set the variable.
|
||||||
|
|
||||||
|
*TERM_PROGRAM_VERSION*
|
||||||
|
Set to the foot version string, in the format _major_*.*_minor_*.*_patch_
|
||||||
|
or _major_*.*_minor_*.*_patch_*-*_revision_*-\g*_commit_ for inter-release
|
||||||
|
builds. The same caveat as for *TERM_PROGRAM* applies.
|
||||||
|
|
||||||
In addition to the variables listed above, custom environment
|
In addition to the variables listed above, custom environment
|
||||||
variables may be defined in *foot.ini*(5).
|
variables may be defined in *foot.ini*(5).
|
||||||
|
|
||||||
|
|
|
||||||
19
foot.info
19
foot.info
|
|
@ -12,6 +12,10 @@
|
||||||
setaf=\E[%?%p1%{8}%<%t3%p1%d%e38\:2\:\:%p1%{65536}%/%d\:%p1%{256}%/%{255}%&%d\:%p1%{255}%&%d%;m,
|
setaf=\E[%?%p1%{8}%<%t3%p1%d%e38\:2\:\:%p1%{65536}%/%d\:%p1%{256}%/%{255}%&%d\:%p1%{255}%&%d%;m,
|
||||||
|
|
||||||
@default_terminfo@+base|foot base fragment,
|
@default_terminfo@+base|foot base fragment,
|
||||||
|
AX,
|
||||||
|
Tc,
|
||||||
|
XF,
|
||||||
|
XT,
|
||||||
am,
|
am,
|
||||||
bce,
|
bce,
|
||||||
bw,
|
bw,
|
||||||
|
|
@ -21,21 +25,24 @@
|
||||||
msgr,
|
msgr,
|
||||||
npc,
|
npc,
|
||||||
xenl,
|
xenl,
|
||||||
AX,
|
|
||||||
XT,
|
|
||||||
Tc,
|
|
||||||
cols#80,
|
cols#80,
|
||||||
it#8,
|
it#8,
|
||||||
lines#24,
|
lines#24,
|
||||||
pairs#0x10000,
|
pairs#0x10000,
|
||||||
|
BD=\E[?2004l,
|
||||||
|
BE=\E[?2004h,
|
||||||
Cr=\E]112\E\\,
|
Cr=\E]112\E\\,
|
||||||
Cs=\E]12;%p1%s\E\\,
|
Cs=\E]12;%p1%s\E\\,
|
||||||
E3=\E[3J,
|
E3=\E[3J,
|
||||||
Ms=\E]52;%p1%s;%p2%s\E\\,
|
Ms=\E]52;%p1%s;%p2%s\E\\,
|
||||||
|
PE=\E[201~,
|
||||||
|
PS=\E[200~,
|
||||||
|
RV=\E[>c,
|
||||||
Se=\E[ q,
|
Se=\E[ q,
|
||||||
Ss=\E[%p1%d q,
|
Ss=\E[%p1%d q,
|
||||||
Sync=\E[?2026%?%p1%{1}%-%tl%eh,
|
Sync=\E[?2026%?%p1%{1}%-%tl%eh,
|
||||||
XM=\E[?1006;1000%?%p1%{1}%=%th%el%;,
|
XM=\E[?1006;1000%?%p1%{1}%=%th%el%;,
|
||||||
|
XR=\E[>0q,
|
||||||
acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
|
acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
|
||||||
bel=^G,
|
bel=^G,
|
||||||
blink=\E[5m,
|
blink=\E[5m,
|
||||||
|
|
@ -79,7 +86,7 @@
|
||||||
indn=\E[%p1%dS,
|
indn=\E[%p1%dS,
|
||||||
initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
|
initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
|
||||||
invis=\E[8m,
|
invis=\E[8m,
|
||||||
is2=\E[!p\E[?3;4l\E[4l\E>,
|
is2=\E[!p\E[4l\E>,
|
||||||
kDC3=\E[3;3~,
|
kDC3=\E[3;3~,
|
||||||
kDC4=\E[3;4~,
|
kDC4=\E[3;4~,
|
||||||
kDC5=\E[3;5~,
|
kDC5=\E[3;5~,
|
||||||
|
|
@ -237,7 +244,8 @@
|
||||||
rmul=\E[24m,
|
rmul=\E[24m,
|
||||||
rmxx=\E[29m,
|
rmxx=\E[29m,
|
||||||
rs1=\Ec,
|
rs1=\Ec,
|
||||||
rs2=\E[!p\E[?3;4l\E[4l\E>,
|
rs2=\E[!p\E[4l\E>,
|
||||||
|
rv=\E\\[[0-9]+;[0-9]+;[0-9]+c,
|
||||||
sc=\E7,
|
sc=\E7,
|
||||||
setrgbb=\E[48\:2\:\:%p1%d\:%p2%d\:%p3%dm,
|
setrgbb=\E[48\:2\:\:%p1%d\:%p2%d\:%p3%dm,
|
||||||
setrgbf=\E[38\:2\:\:%p1%d\:%p2%d\:%p3%dm,
|
setrgbf=\E[38\:2\:\:%p1%d\:%p2%d\:%p3%dm,
|
||||||
|
|
@ -260,6 +268,7 @@
|
||||||
u9=\E[c,
|
u9=\E[c,
|
||||||
vpa=\E[%i%p1%dd,
|
vpa=\E[%i%p1%dd,
|
||||||
xm=\E[<%i%p3%d;%p1%d;%p2%d;%?%p4%tM%em%;,
|
xm=\E[<%i%p3%d;%p1%d;%p2%d;%?%p4%tM%em%;,
|
||||||
|
xr=\EP>\\|[ -~]+\E\\\\,
|
||||||
|
|
||||||
# XT,
|
# XT,
|
||||||
# AX,
|
# AX,
|
||||||
|
|
|
||||||
3
foot.ini
3
foot.ini
|
|
@ -12,6 +12,7 @@
|
||||||
# font-bold=<bold variant of regular font>
|
# font-bold=<bold variant of regular font>
|
||||||
# font-italic=<italic variant of regular font>
|
# font-italic=<italic variant of regular font>
|
||||||
# font-bold-italic=<bold+italic variant of regular font>
|
# font-bold-italic=<bold+italic variant of regular font>
|
||||||
|
# font-size-adjustment=0.5
|
||||||
# line-height=<font metrics>
|
# line-height=<font metrics>
|
||||||
# letter-spacing=0
|
# letter-spacing=0
|
||||||
# horizontal-letter-offset=0
|
# horizontal-letter-offset=0
|
||||||
|
|
@ -48,7 +49,7 @@
|
||||||
# lines=1000
|
# lines=1000
|
||||||
# multiplier=3.0
|
# multiplier=3.0
|
||||||
# indicator-position=relative
|
# indicator-position=relative
|
||||||
# indicator-format=
|
# indicator-format=""
|
||||||
|
|
||||||
[url]
|
[url]
|
||||||
# launch=xdg-open ${url}
|
# launch=xdg-open ${url}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ patch=$(echo "${new_version}" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\3/')
|
||||||
extra=$(echo "${new_version}" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9]+-g[a-z0-9]+) .*)?.*/\5/')
|
extra=$(echo "${new_version}" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9]+-g[a-z0-9]+) .*)?.*/\5/')
|
||||||
|
|
||||||
new_version="#define FOOT_VERSION \"${new_version}\"
|
new_version="#define FOOT_VERSION \"${new_version}\"
|
||||||
|
#define FOOT_VERSION_SHORT \"${git_version:-${default_version}}\"
|
||||||
#define FOOT_MAJOR ${major}
|
#define FOOT_MAJOR ${major}
|
||||||
#define FOOT_MINOR ${minor}
|
#define FOOT_MINOR ${minor}
|
||||||
#define FOOT_PATCH ${patch}
|
#define FOOT_PATCH ${patch}
|
||||||
|
|
|
||||||
11
grid.c
11
grid.c
|
|
@ -210,6 +210,8 @@ grid_snapshot(const struct grid *grid)
|
||||||
clone->offset = grid->offset;
|
clone->offset = grid->offset;
|
||||||
clone->view = grid->view;
|
clone->view = grid->view;
|
||||||
clone->cursor = grid->cursor;
|
clone->cursor = grid->cursor;
|
||||||
|
clone->saved_cursor = grid->saved_cursor;
|
||||||
|
clone->kitty_kbd = grid->kitty_kbd;
|
||||||
clone->rows = xcalloc(grid->num_rows, sizeof(clone->rows[0]));
|
clone->rows = xcalloc(grid->num_rows, sizeof(clone->rows[0]));
|
||||||
memset(&clone->scroll_damage, 0, sizeof(clone->scroll_damage));
|
memset(&clone->scroll_damage, 0, sizeof(clone->scroll_damage));
|
||||||
memset(&clone->sixel_images, 0, sizeof(clone->sixel_images));
|
memset(&clone->sixel_images, 0, sizeof(clone->sixel_images));
|
||||||
|
|
@ -285,6 +287,9 @@ grid_snapshot(const struct grid *grid)
|
||||||
void
|
void
|
||||||
grid_free(struct grid *grid)
|
grid_free(struct grid *grid)
|
||||||
{
|
{
|
||||||
|
if (grid == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int r = 0; r < grid->num_rows; r++)
|
for (int r = 0; r < grid->num_rows; r++)
|
||||||
grid_row_free(grid->rows[r]);
|
grid_row_free(grid->rows[r]);
|
||||||
|
|
||||||
|
|
@ -483,6 +488,8 @@ grid_resize_without_reflow(
|
||||||
grid->saved_cursor.point = saved_cursor;
|
grid->saved_cursor.point = saved_cursor;
|
||||||
|
|
||||||
grid->cur_row = new_grid[(grid->offset + cursor.row) & (new_rows - 1)];
|
grid->cur_row = new_grid[(grid->offset + cursor.row) & (new_rows - 1)];
|
||||||
|
xassert(grid->cur_row != NULL);
|
||||||
|
|
||||||
grid->cursor.lcf = false;
|
grid->cursor.lcf = false;
|
||||||
grid->saved_cursor.lcf = false;
|
grid->saved_cursor.lcf = false;
|
||||||
|
|
||||||
|
|
@ -786,7 +793,7 @@ grid_resize_and_reflow(
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set end-coordinate for this chunk, by finding the next
|
* Set end-coordinate for this chunk, by finding the next
|
||||||
* point-of-interrest on this row.
|
* point-of-interest on this row.
|
||||||
*
|
*
|
||||||
* If there are no more tracking points, or URI ranges,
|
* If there are no more tracking points, or URI ranges,
|
||||||
* the end-coordinate will be at the end of the row,
|
* the end-coordinate will be at the end of the row,
|
||||||
|
|
@ -1045,6 +1052,8 @@ grid_resize_and_reflow(
|
||||||
saved_cursor.col = min(saved_cursor.col, new_cols - 1);
|
saved_cursor.col = min(saved_cursor.col, new_cols - 1);
|
||||||
|
|
||||||
grid->cur_row = new_grid[(grid->offset + cursor.row) & (new_rows - 1)];
|
grid->cur_row = new_grid[(grid->offset + cursor.row) & (new_rows - 1)];
|
||||||
|
xassert(grid->cur_row != NULL);
|
||||||
|
|
||||||
grid->cursor.point = cursor;
|
grid->cursor.point = cursor;
|
||||||
grid->saved_cursor.point = saved_cursor;
|
grid->saved_cursor.point = saved_cursor;
|
||||||
|
|
||||||
|
|
|
||||||
41
input.c
41
input.c
|
|
@ -898,7 +898,7 @@ struct kbd_ctx {
|
||||||
const uint8_t *buf;
|
const uint8_t *buf;
|
||||||
size_t count;
|
size_t count;
|
||||||
} utf8;
|
} utf8;
|
||||||
uint32_t utf32;
|
uint32_t *utf32;
|
||||||
|
|
||||||
enum xkb_compose_status compose_status;
|
enum xkb_compose_status compose_status;
|
||||||
enum wl_keyboard_key_state key_state;
|
enum wl_keyboard_key_state key_state;
|
||||||
|
|
@ -1121,12 +1121,18 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term,
|
||||||
(seat->kbd.mod_num != XKB_MOD_INVALID ? 1 << seat->kbd.mod_num : 0);
|
(seat->kbd.mod_num != XKB_MOD_INVALID ? 1 << seat->kbd.mod_num : 0);
|
||||||
|
|
||||||
const xkb_keysym_t sym = ctx->sym;
|
const xkb_keysym_t sym = ctx->sym;
|
||||||
const uint32_t utf32 = ctx->utf32;
|
const uint32_t *utf32 = ctx->utf32;
|
||||||
const uint8_t *const utf8 = ctx->utf8.buf;
|
const uint8_t *const utf8 = ctx->utf8.buf;
|
||||||
|
|
||||||
const bool is_text = iswprint(utf32) && (effective & ~caps_num) == 0;
|
|
||||||
const size_t count = ctx->utf8.count;
|
const size_t count = ctx->utf8.count;
|
||||||
|
|
||||||
|
bool is_text = count > 0 && utf32 != NULL && (effective & ~caps_num) == 0;
|
||||||
|
for (size_t i = 0; utf32[i] != U'\0'; i++) {
|
||||||
|
if (!iswprint(utf32[i])) {
|
||||||
|
is_text = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const bool report_associated_text =
|
const bool report_associated_text =
|
||||||
(flags & KITTY_KBD_REPORT_ASSOCIATED) && is_text && !released;
|
(flags & KITTY_KBD_REPORT_ASSOCIATED) && is_text && !released;
|
||||||
|
|
||||||
|
|
@ -1245,7 +1251,7 @@ emit_escapes:
|
||||||
: sym;
|
: sym;
|
||||||
|
|
||||||
if (composed)
|
if (composed)
|
||||||
key = utf32;
|
key = utf32[0]; /* TODO: what if there are multiple codepoints? */
|
||||||
else {
|
else {
|
||||||
key = xkb_keysym_to_utf32(sym_to_use);
|
key = xkb_keysym_to_utf32(sym_to_use);
|
||||||
if (key == 0)
|
if (key == 0)
|
||||||
|
|
@ -1284,7 +1290,7 @@ emit_escapes:
|
||||||
} else
|
} else
|
||||||
event[0] = '\0';
|
event[0] = '\0';
|
||||||
|
|
||||||
char buf[64], *p = buf;
|
char buf[128], *p = buf;
|
||||||
size_t left = sizeof(buf);
|
size_t left = sizeof(buf);
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
|
|
||||||
|
|
@ -1316,8 +1322,16 @@ emit_escapes:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (report_associated_text) {
|
if (report_associated_text) {
|
||||||
bytes = snprintf(p, left, "%s;%u", !emit_mods ? ";" : "", utf32);
|
bytes = snprintf(p, left, "%s;%u", !emit_mods ? ";" : "", utf32[0]);
|
||||||
p += bytes; left -= bytes;
|
p += bytes; left -= bytes;
|
||||||
|
|
||||||
|
/* Additional text codepoints */
|
||||||
|
if (utf32[0] != U'\0') {
|
||||||
|
for (size_t i = 1; utf32[i] != U'\0'; i++) {
|
||||||
|
bytes = snprintf(p, left, ":%u", utf32[i]);
|
||||||
|
p += bytes; left -= bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = snprintf(p, left, "%c", final);
|
bytes = snprintf(p, left, "%c", final);
|
||||||
|
|
@ -1514,19 +1528,20 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
* and use a malloc:ed buffer when necessary */
|
* and use a malloc:ed buffer when necessary */
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
uint8_t *utf8 = count < sizeof(buf) ? buf : xmalloc(count + 1);
|
uint8_t *utf8 = count < sizeof(buf) ? buf : xmalloc(count + 1);
|
||||||
uint32_t utf32 = (uint32_t)-1;
|
uint32_t *utf32 = NULL;
|
||||||
|
|
||||||
if (composed) {
|
if (composed) {
|
||||||
xkb_compose_state_get_utf8(
|
xkb_compose_state_get_utf8(
|
||||||
seat->kbd.xkb_compose_state, (char *)utf8, count + 1);
|
seat->kbd.xkb_compose_state, (char *)utf8, count + 1);
|
||||||
|
|
||||||
char32_t wc;
|
if (count > 0)
|
||||||
if (mbrtoc32(&wc, (const char *)utf8, count, &(mbstate_t){0}) == count)
|
utf32 = ambstoc32((const char *)utf8);
|
||||||
utf32 = wc;
|
|
||||||
} else {
|
} else {
|
||||||
xkb_state_key_get_utf8(
|
xkb_state_key_get_utf8(
|
||||||
seat->kbd.xkb_state, key, (char *)utf8, count + 1);
|
seat->kbd.xkb_state, key, (char *)utf8, count + 1);
|
||||||
utf32 = xkb_state_key_get_utf32(seat->kbd.xkb_state, key);
|
|
||||||
|
utf32 = xcalloc(2, sizeof(utf32[0]));
|
||||||
|
utf32[0] = xkb_state_key_get_utf32(seat->kbd.xkb_state, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct kbd_ctx ctx = {
|
struct kbd_ctx ctx = {
|
||||||
|
|
@ -1563,6 +1578,8 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(utf32);
|
||||||
|
|
||||||
maybe_repeat:
|
maybe_repeat:
|
||||||
clock_gettime(
|
clock_gettime(
|
||||||
term->wl->presentation_clock_id, &term->render.input_time);
|
term->wl->presentation_clock_id, &term->render.input_time);
|
||||||
|
|
|
||||||
|
|
@ -350,6 +350,60 @@ maybe_repair_key_combo(const struct seat *seat,
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
key_cmp(struct key_binding a, struct key_binding b)
|
||||||
|
{
|
||||||
|
xassert(a.type == b.type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sort bindings such that bindings with the same symbol are
|
||||||
|
* sorted with the binding having the most modifiers comes first.
|
||||||
|
*
|
||||||
|
* This fixes an issue where the “wrong” key binding are triggered
|
||||||
|
* when used with “consumed” modifiers.
|
||||||
|
*
|
||||||
|
* For example: if Control+BackSpace is bound before
|
||||||
|
* Control+Shift+BackSpace, then the latter binding is never
|
||||||
|
* triggered.
|
||||||
|
*
|
||||||
|
* Why? Because Shift is a consumed modifier. This means
|
||||||
|
* Control+BackSpace is “the same” as Control+Shift+BackSpace.
|
||||||
|
*
|
||||||
|
* By sorting bindings with more modifiers first, we work around
|
||||||
|
* the problem. But note that it is *just* a workaround, and I’m
|
||||||
|
* not confident there aren’t cases where it doesn’t work.
|
||||||
|
*
|
||||||
|
* See https://codeberg.org/dnkl/foot/issues/1280
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int a_mod_count = __builtin_popcount(a.mods);
|
||||||
|
const int b_mod_count = __builtin_popcount(b.mods);
|
||||||
|
|
||||||
|
switch (a.type) {
|
||||||
|
case KEY_BINDING:
|
||||||
|
if (a.k.sym != b.k.sym)
|
||||||
|
return b.k.sym - a.k.sym;
|
||||||
|
return b_mod_count - a_mod_count;
|
||||||
|
|
||||||
|
case MOUSE_BINDING: {
|
||||||
|
if (a.m.button != b.m.button)
|
||||||
|
return b.m.button - a.m.button;
|
||||||
|
if (a_mod_count != b_mod_count)
|
||||||
|
return b_mod_count - a_mod_count;
|
||||||
|
return b.m.count - a.m.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BUG("invalid key binding type");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NOINLINE
|
||||||
|
sort_binding_list(key_binding_list_t *list)
|
||||||
|
{
|
||||||
|
tll_sort(*list, key_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
static void NOINLINE
|
static void NOINLINE
|
||||||
convert_key_binding(struct key_set *set,
|
convert_key_binding(struct key_set *set,
|
||||||
const struct config_key_binding *conf_binding,
|
const struct config_key_binding *conf_binding,
|
||||||
|
|
@ -371,6 +425,7 @@ convert_key_binding(struct key_set *set,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
tll_push_back(*bindings, binding);
|
tll_push_back(*bindings, binding);
|
||||||
|
sort_binding_list(bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -421,6 +476,7 @@ convert_mouse_binding(struct key_set *set,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
tll_push_back(set->public.mouse, binding);
|
tll_push_back(set->public.mouse, binding);
|
||||||
|
sort_binding_list(&set->public.mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
9
log.c
9
log.c
|
|
@ -15,7 +15,7 @@
|
||||||
#include "xsnprintf.h"
|
#include "xsnprintf.h"
|
||||||
|
|
||||||
static bool colorize = false;
|
static bool colorize = false;
|
||||||
static bool do_syslog = true;
|
static bool do_syslog = false;
|
||||||
static enum log_class log_level = LOG_CLASS_NONE;
|
static enum log_class log_level = LOG_CLASS_NONE;
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
|
|
@ -45,8 +45,13 @@ log_init(enum log_colorize _colorize, bool _do_syslog,
|
||||||
log_level = _log_level;
|
log_level = _log_level;
|
||||||
|
|
||||||
int slvl = log_level_map[_log_level].syslog_equivalent;
|
int slvl = log_level_map[_log_level].syslog_equivalent;
|
||||||
if (do_syslog && slvl != -1) {
|
if (slvl < 0)
|
||||||
|
do_syslog = false;
|
||||||
|
|
||||||
|
if (do_syslog) {
|
||||||
openlog(NULL, /*LOG_PID*/0, facility_map[syslog_facility]);
|
openlog(NULL, /*LOG_PID*/0, facility_map[syslog_facility]);
|
||||||
|
|
||||||
|
xassert(slvl >= 0);
|
||||||
setlogmask(LOG_UPTO(slvl));
|
setlogmask(LOG_UPTO(slvl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
main.c
13
main.c
|
|
@ -83,7 +83,7 @@ print_usage(const char *prog_name)
|
||||||
" Without PATH, $XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock will be used.\n"
|
" Without PATH, $XDG_RUNTIME_DIR/foot-$WAYLAND_DISPLAY.sock will be used.\n"
|
||||||
" -H,--hold remain open after child process exits\n"
|
" -H,--hold remain open after child process exits\n"
|
||||||
" -p,--print-pid=FILE|FD print PID to file or FD (only applicable in server mode)\n"
|
" -p,--print-pid=FILE|FD print PID to file or FD (only applicable in server mode)\n"
|
||||||
" -d,--log-level={info|warning|error|none} log level (info)\n"
|
" -d,--log-level={info|warning|error|none} log level (warning)\n"
|
||||||
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
|
" -l,--log-colorize=[{never|always|auto}] enable/disable colorization of log output on stderr\n"
|
||||||
" -s,--log-no-syslog disable syslog logging (only applicable in server mode)\n"
|
" -s,--log-no-syslog disable syslog logging (only applicable in server mode)\n"
|
||||||
" -v,--version show the version number and quit\n"
|
" -v,--version show the version number and quit\n"
|
||||||
|
|
@ -236,7 +236,7 @@ main(int argc, char *const *argv)
|
||||||
bool fullscreen = false;
|
bool fullscreen = false;
|
||||||
bool unlink_pid_file = false;
|
bool unlink_pid_file = false;
|
||||||
const char *pid_file = NULL;
|
const char *pid_file = NULL;
|
||||||
enum log_class log_level = LOG_CLASS_INFO;
|
enum log_class log_level = LOG_CLASS_WARNING;
|
||||||
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
enum log_colorize log_colorize = LOG_COLORIZE_AUTO;
|
||||||
bool log_syslog = true;
|
bool log_syslog = true;
|
||||||
user_notifications_t user_notifications = tll_init();
|
user_notifications_t user_notifications = tll_init();
|
||||||
|
|
@ -433,8 +433,13 @@ main(int argc, char *const *argv)
|
||||||
|
|
||||||
const char *locale = setlocale(LC_CTYPE, "");
|
const char *locale = setlocale(LC_CTYPE, "");
|
||||||
if (locale == NULL) {
|
if (locale == NULL) {
|
||||||
LOG_ERR("setlocale() failed");
|
/*
|
||||||
return ret;
|
* If the user has configured an invalid locale, or a name of a locale
|
||||||
|
* that does not exist on this system, then the above call may return
|
||||||
|
* NULL. We should just continue with the fallback method below.
|
||||||
|
*/
|
||||||
|
LOG_WARN("setlocale() failed");
|
||||||
|
locale = "C";
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("locale: %s", locale);
|
LOG_INFO("locale: %s", locale);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
project('foot', 'c',
|
project('foot', 'c',
|
||||||
version: '1.13.1',
|
version: '1.14.0',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
meson_version: '>=0.58.0',
|
meson_version: '>=0.58.0',
|
||||||
default_options: [
|
default_options: [
|
||||||
|
|
@ -110,7 +110,7 @@ if utf8proc.found()
|
||||||
add_project_arguments('-DFOOT_GRAPHEME_CLUSTERING=1', language: 'c')
|
add_project_arguments('-DFOOT_GRAPHEME_CLUSTERING=1', language: 'c')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
tllist = dependency('tllist', version: '>=1.0.4', fallback: 'tllist')
|
tllist = dependency('tllist', version: '>=1.1.0', fallback: 'tllist')
|
||||||
fcft = dependency('fcft', version: ['>=3.0.1', '<4.0.0'], fallback: 'fcft')
|
fcft = dependency('fcft', version: ['>=3.0.1', '<4.0.0'], fallback: 'fcft')
|
||||||
|
|
||||||
wayland_protocols_datadir = wayland_protocols.get_variable('pkgdatadir')
|
wayland_protocols_datadir = wayland_protocols.get_variable('pkgdatadir')
|
||||||
|
|
@ -331,6 +331,7 @@ endif
|
||||||
|
|
||||||
subdir('completions')
|
subdir('completions')
|
||||||
subdir('icons')
|
subdir('icons')
|
||||||
|
subdir('utils')
|
||||||
|
|
||||||
if (get_option('tests'))
|
if (get_option('tests'))
|
||||||
subdir('tests')
|
subdir('tests')
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@ Keywords=shell;prompt;command;commandline;
|
||||||
Name=Foot Server
|
Name=Foot Server
|
||||||
GenericName=Terminal
|
GenericName=Terminal
|
||||||
Comment=A wayland native terminal emulator (server)
|
Comment=A wayland native terminal emulator (server)
|
||||||
|
StartupWMClass=foot
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@ Keywords=shell;prompt;command;commandline;
|
||||||
Name=Foot
|
Name=Foot
|
||||||
GenericName=Terminal
|
GenericName=Terminal
|
||||||
Comment=A wayland native terminal emulator
|
Comment=A wayland native terminal emulator
|
||||||
|
StartupWMClass=foot
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<component type="desktop-application">
|
<component type="desktop-application">
|
||||||
<id>org.codeberg.dnkl.foot</id>
|
<id>org.codeberg.dnkl.foot</id>
|
||||||
<metadata_license>CC0-1.0</metadata_license>
|
<metadata_license>MIT</metadata_license>
|
||||||
<project_license>MIT</project_license>
|
<project_license>MIT</project_license>
|
||||||
<developer_name>dnkl</developer_name>
|
<developer_name>dnkl</developer_name>
|
||||||
<name>foot</name>
|
<name>foot</name>
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,4 @@ Keywords=shell;prompt;command;commandline;
|
||||||
Name=Foot Client
|
Name=Foot Client
|
||||||
GenericName=Terminal
|
GenericName=Terminal
|
||||||
Comment=A wayland native terminal emulator (client)
|
Comment=A wayland native terminal emulator (client)
|
||||||
|
StartupWMClass=foot
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ rm -f "${blddir}"/pgo-ok
|
||||||
# To ensure profiling data is generated in the build directory
|
# To ensure profiling data is generated in the build directory
|
||||||
cd "${blddir}"
|
cd "${blddir}"
|
||||||
|
|
||||||
|
"${blddir}"/utils/xtgettcap
|
||||||
"${blddir}"/footclient --version
|
"${blddir}"/footclient --version
|
||||||
"${blddir}"/foot \
|
"${blddir}"/foot \
|
||||||
--config=/dev/null \
|
--config=/dev/null \
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ rm -f "${blddir}"/pgo-ok
|
||||||
# To ensure profiling data is generated in the build directory
|
# To ensure profiling data is generated in the build directory
|
||||||
cd "${blddir}"
|
cd "${blddir}"
|
||||||
|
|
||||||
|
"${blddir}"/utils/xtgettcap
|
||||||
"${blddir}"/footclient --version
|
"${blddir}"/footclient --version
|
||||||
"${blddir}"/foot --version
|
"${blddir}"/foot --version
|
||||||
"${blddir}"/pgo "${pgo_data}"
|
"${blddir}"/pgo "${pgo_data}"
|
||||||
|
|
|
||||||
30
pgo/pgo.c
30
pgo/pgo.c
|
|
@ -228,10 +228,14 @@ main(int argc, const char *const *argv)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct row **rows = calloc(grid_row_count, sizeof(rows[0]));
|
struct row **normal_rows = calloc(grid_row_count, sizeof(normal_rows[0]));
|
||||||
|
struct row **alt_rows = calloc(grid_row_count, sizeof(alt_rows[0]));
|
||||||
|
|
||||||
for (int i = 0; i < grid_row_count; i++) {
|
for (int i = 0; i < grid_row_count; i++) {
|
||||||
rows[i] = calloc(1, sizeof(*rows[i]));
|
normal_rows[i] = calloc(1, sizeof(*normal_rows[i]));
|
||||||
rows[i]->cells = calloc(col_count, sizeof(rows[i]->cells[0]));
|
normal_rows[i]->cells = calloc(col_count, sizeof(normal_rows[i]->cells[0]));
|
||||||
|
alt_rows[i] = calloc(1, sizeof(*alt_rows[i]));
|
||||||
|
alt_rows[i]->cells = calloc(col_count, sizeof(alt_rows[i]->cells[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct config conf = {
|
struct config conf = {
|
||||||
|
|
@ -254,14 +258,14 @@ main(int argc, const char *const *argv)
|
||||||
.normal = {
|
.normal = {
|
||||||
.num_rows = grid_row_count,
|
.num_rows = grid_row_count,
|
||||||
.num_cols = col_count,
|
.num_cols = col_count,
|
||||||
.rows = rows,
|
.rows = normal_rows,
|
||||||
.cur_row = rows[0],
|
.cur_row = normal_rows[0],
|
||||||
},
|
},
|
||||||
.alt = {
|
.alt = {
|
||||||
.num_rows = grid_row_count,
|
.num_rows = grid_row_count,
|
||||||
.num_cols = col_count,
|
.num_cols = col_count,
|
||||||
.rows = rows,
|
.rows = alt_rows,
|
||||||
.cur_row = rows[0],
|
.cur_row = alt_rows[0],
|
||||||
},
|
},
|
||||||
.scale = 1,
|
.scale = 1,
|
||||||
.width = col_count * 8,
|
.width = col_count * 8,
|
||||||
|
|
@ -371,11 +375,17 @@ out:
|
||||||
tll_free(wayl.terms);
|
tll_free(wayl.terms);
|
||||||
|
|
||||||
for (int i = 0; i < grid_row_count; i++) {
|
for (int i = 0; i < grid_row_count; i++) {
|
||||||
free(rows[i]->cells);
|
if (normal_rows[i] != NULL)
|
||||||
free(rows[i]);
|
free(normal_rows[i]->cells);
|
||||||
|
free(normal_rows[i]);
|
||||||
|
|
||||||
|
if (alt_rows[i] != NULL)
|
||||||
|
free(alt_rows[i]->cells);
|
||||||
|
free(alt_rows[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(rows);
|
free(normal_rows);
|
||||||
|
free(alt_rows);
|
||||||
close(lower_fd);
|
close(lower_fd);
|
||||||
close(upper_fd);
|
close(upper_fd);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ do_pgo=no
|
||||||
CFLAGS="${CFLAGS-} -O3"
|
CFLAGS="${CFLAGS-} -O3"
|
||||||
|
|
||||||
case $(${CC-cc} --version) in
|
case $(${CC-cc} --version) in
|
||||||
*GCC*)
|
*Free\ Software\ Foundation*)
|
||||||
compiler=gcc
|
compiler=gcc
|
||||||
do_pgo=yes
|
do_pgo=yes
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
269
render.c
269
render.c
|
|
@ -420,6 +420,12 @@ cursor_colors_for_cell(const struct terminal *term, const struct cell *cell,
|
||||||
} else {
|
} else {
|
||||||
*cursor_color = *fg;
|
*cursor_color = *fg;
|
||||||
*text_color = *bg;
|
*text_color = *bg;
|
||||||
|
|
||||||
|
if (unlikely(text_color->alpha != 0xffff)) {
|
||||||
|
/* The *only* color that can have transparency is the
|
||||||
|
* default background color */
|
||||||
|
*text_color = color_hex_to_pixman(term->colors.bg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -639,17 +645,21 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (single == NULL && grapheme == NULL) {
|
if (single == NULL && grapheme == NULL) {
|
||||||
xassert(base != 0);
|
if (unlikely(base >= CELL_SPACER)) {
|
||||||
single = fcft_rasterize_char_utf32(font, base, term->font_subpixel);
|
|
||||||
if (single == NULL) {
|
|
||||||
glyph_count = 0;
|
glyph_count = 0;
|
||||||
cell_cols = 1;
|
cell_cols = 1;
|
||||||
} else {
|
} else {
|
||||||
glyph_count = 1;
|
xassert(base != 0);
|
||||||
glyphs = &single;
|
single = fcft_rasterize_char_utf32(font, base, term->font_subpixel);
|
||||||
cell_cols = single->cols;
|
if (single == NULL) {
|
||||||
|
glyph_count = 0;
|
||||||
|
cell_cols = 1;
|
||||||
|
} else {
|
||||||
|
glyph_count = 1;
|
||||||
|
glyphs = &single;
|
||||||
|
cell_cols = single->cols;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -919,14 +929,19 @@ static void
|
||||||
grid_render_scroll(struct terminal *term, struct buffer *buf,
|
grid_render_scroll(struct terminal *term, struct buffer *buf,
|
||||||
const struct damage *dmg)
|
const struct damage *dmg)
|
||||||
{
|
{
|
||||||
int height = (dmg->region.end - dmg->region.start - dmg->lines) * term->cell_height;
|
|
||||||
|
|
||||||
LOG_DBG(
|
LOG_DBG(
|
||||||
"damage: SCROLL: %d-%d by %d lines",
|
"damage: SCROLL: %d-%d by %d lines",
|
||||||
dmg->region.start, dmg->region.end, dmg->lines);
|
dmg->region.start, dmg->region.end, dmg->lines);
|
||||||
|
|
||||||
if (height <= 0)
|
const int region_size = dmg->region.end - dmg->region.start;
|
||||||
|
|
||||||
|
if (dmg->lines >= region_size) {
|
||||||
|
/* The entire scroll region will be scrolled out (i.e. replaced) */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int height = (region_size - dmg->lines) * term->cell_height;
|
||||||
|
xassert(height > 0);
|
||||||
|
|
||||||
#if TIME_SCROLL_DAMAGE
|
#if TIME_SCROLL_DAMAGE
|
||||||
struct timespec start_time;
|
struct timespec start_time;
|
||||||
|
|
@ -1027,14 +1042,19 @@ static void
|
||||||
grid_render_scroll_reverse(struct terminal *term, struct buffer *buf,
|
grid_render_scroll_reverse(struct terminal *term, struct buffer *buf,
|
||||||
const struct damage *dmg)
|
const struct damage *dmg)
|
||||||
{
|
{
|
||||||
int height = (dmg->region.end - dmg->region.start - dmg->lines) * term->cell_height;
|
|
||||||
|
|
||||||
LOG_DBG(
|
LOG_DBG(
|
||||||
"damage: SCROLL REVERSE: %d-%d by %d lines",
|
"damage: SCROLL REVERSE: %d-%d by %d lines",
|
||||||
dmg->region.start, dmg->region.end, dmg->lines);
|
dmg->region.start, dmg->region.end, dmg->lines);
|
||||||
|
|
||||||
if (height <= 0)
|
const int region_size = dmg->region.end - dmg->region.start;
|
||||||
|
|
||||||
|
if (dmg->lines >= region_size) {
|
||||||
|
/* The entire scroll region will be scrolled out (i.e. replaced) */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int height = (region_size - dmg->lines) * term->cell_height;
|
||||||
|
xassert(height > 0);
|
||||||
|
|
||||||
#if TIME_SCROLL_DAMAGE
|
#if TIME_SCROLL_DAMAGE
|
||||||
struct timespec start_time;
|
struct timespec start_time;
|
||||||
|
|
@ -3663,13 +3683,67 @@ tiocswinsz(struct terminal *term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
delayed_reflow_of_normal_grid(struct terminal *term)
|
||||||
|
{
|
||||||
|
if (term->interactive_resizing.grid == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xassert(term->interactive_resizing.new_rows > 0);
|
||||||
|
|
||||||
|
struct coord *const tracking_points[] = {
|
||||||
|
&term->selection.coords.start,
|
||||||
|
&term->selection.coords.end,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Reflow the original (since before the resize was started) grid,
|
||||||
|
* to the *current* dimensions */
|
||||||
|
grid_resize_and_reflow(
|
||||||
|
term->interactive_resizing.grid,
|
||||||
|
term->interactive_resizing.new_rows, term->normal.num_cols,
|
||||||
|
term->interactive_resizing.old_screen_rows, term->rows,
|
||||||
|
term->selection.coords.end.row >= 0 ? ALEN(tracking_points) : 0,
|
||||||
|
tracking_points);
|
||||||
|
|
||||||
|
/* Replace the current, truncated, “normal” grid with the
|
||||||
|
* correctly reflowed one */
|
||||||
|
grid_free(&term->normal);
|
||||||
|
term->normal = *term->interactive_resizing.grid;
|
||||||
|
free(term->interactive_resizing.grid);
|
||||||
|
|
||||||
|
term->hide_cursor = term->interactive_resizing.old_hide_cursor;
|
||||||
|
|
||||||
|
/* Reset */
|
||||||
|
term->interactive_resizing.grid = NULL;
|
||||||
|
term->interactive_resizing.old_screen_rows = 0;
|
||||||
|
term->interactive_resizing.new_rows = 0;
|
||||||
|
term->interactive_resizing.old_hide_cursor = false;
|
||||||
|
|
||||||
|
/* Invalidate render pointers */
|
||||||
|
shm_unref(term->render.last_buf);
|
||||||
|
term->render.last_buf = NULL;
|
||||||
|
term->render.last_cursor.row = NULL;
|
||||||
|
|
||||||
|
tll_free(term->normal.scroll_damage);
|
||||||
|
sixel_reflow_grid(term, &term->normal);
|
||||||
|
|
||||||
|
if (term->grid == &term->normal) {
|
||||||
|
term_damage_view(term);
|
||||||
|
render_refresh(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
term_ptmx_resume(term);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
fdm_tiocswinsz(struct fdm *fdm, int fd, int events, void *data)
|
fdm_tiocswinsz(struct fdm *fdm, int fd, int events, void *data)
|
||||||
{
|
{
|
||||||
struct terminal *term = data;
|
struct terminal *term = data;
|
||||||
|
|
||||||
if (events & EPOLLIN)
|
if (events & EPOLLIN) {
|
||||||
tiocswinsz(term);
|
tiocswinsz(term);
|
||||||
|
delayed_reflow_of_normal_grid(term);
|
||||||
|
}
|
||||||
|
|
||||||
if (term->window->resize_timeout_fd >= 0) {
|
if (term->window->resize_timeout_fd >= 0) {
|
||||||
fdm_del(fdm, term->window->resize_timeout_fd);
|
fdm_del(fdm, term->window->resize_timeout_fd);
|
||||||
|
|
@ -3686,6 +3760,7 @@ send_dimensions_to_client(struct terminal *term)
|
||||||
if (!win->is_resizing || term->conf->resize_delay_ms == 0) {
|
if (!win->is_resizing || term->conf->resize_delay_ms == 0) {
|
||||||
/* Send new dimensions to client immediately */
|
/* Send new dimensions to client immediately */
|
||||||
tiocswinsz(term);
|
tiocswinsz(term);
|
||||||
|
delayed_reflow_of_normal_grid(term);
|
||||||
|
|
||||||
/* And make sure to reset and deallocate a lingering timer */
|
/* And make sure to reset and deallocate a lingering timer */
|
||||||
if (win->resize_timeout_fd >= 0) {
|
if (win->resize_timeout_fd >= 0) {
|
||||||
|
|
@ -3716,7 +3791,10 @@ send_dimensions_to_client(struct terminal *term)
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
/* Reset timeout */
|
/* Reset timeout */
|
||||||
const struct itimerspec timeout = {
|
const struct itimerspec timeout = {
|
||||||
.it_value = {.tv_sec = 0, .tv_nsec = delay_ms * 1000000},
|
.it_value = {
|
||||||
|
.tv_sec = delay_ms / 1000,
|
||||||
|
.tv_nsec = (delay_ms % 1000) * 1000000,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (timerfd_settime(fd, 0, &timeout, NULL) < 0) {
|
if (timerfd_settime(fd, 0, &timeout, NULL) < 0) {
|
||||||
|
|
@ -3727,8 +3805,10 @@ send_dimensions_to_client(struct terminal *term)
|
||||||
successfully_scheduled = true;
|
successfully_scheduled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!successfully_scheduled)
|
if (!successfully_scheduled) {
|
||||||
tiocswinsz(term);
|
tiocswinsz(term);
|
||||||
|
delayed_reflow_of_normal_grid(term);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3815,9 +3895,9 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
const int min_cols = 2;
|
const int min_cols = 2;
|
||||||
const int min_rows = 1;
|
const int min_rows = 1;
|
||||||
|
|
||||||
/* Minimum window size */
|
/* Minimum window size (must be divisible by the scaling factor)*/
|
||||||
const int min_width = min_cols * term->cell_width;
|
const int min_width = (min_cols * term->cell_width + scale - 1) / scale * scale;
|
||||||
const int min_height = min_rows * term->cell_height;
|
const int min_height = (min_rows * term->cell_height + scale - 1) / scale * scale;
|
||||||
|
|
||||||
width = max(width, min_width);
|
width = max(width, min_width);
|
||||||
height = max(height, min_height);
|
height = max(height, min_height);
|
||||||
|
|
@ -3844,8 +3924,8 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
const uint32_t scrollback_lines = term->render.scrollback_lines;
|
const uint32_t scrollback_lines = term->render.scrollback_lines;
|
||||||
|
|
||||||
/* Screen rows/cols before resize */
|
/* Screen rows/cols before resize */
|
||||||
const int old_cols = term->cols;
|
int old_cols = term->cols;
|
||||||
const int old_rows = term->rows;
|
int old_rows = term->rows;
|
||||||
|
|
||||||
/* Screen rows/cols after resize */
|
/* Screen rows/cols after resize */
|
||||||
const int new_cols = (term->width - 2 * pad_x) / term->cell_width;
|
const int new_cols = (term->width - 2 * pad_x) / term->cell_width;
|
||||||
|
|
@ -3881,9 +3961,86 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
|
|
||||||
if (new_cols == old_cols && new_rows == old_rows) {
|
if (new_cols == old_cols && new_rows == old_rows) {
|
||||||
LOG_DBG("grid layout unaffected; skipping reflow");
|
LOG_DBG("grid layout unaffected; skipping reflow");
|
||||||
|
term->interactive_resizing.new_rows = new_normal_grid_rows;
|
||||||
goto damage_view;
|
goto damage_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since text reflow is slow, don’t do it *while* resizing. Only
|
||||||
|
* do it when done, or after “pausing” the resize for sufficiently
|
||||||
|
* long. We re-use the TIOCSWINSZ timer to handle this. See
|
||||||
|
* send_dimensions_to_client() and fdm_tiocswinsz().
|
||||||
|
*
|
||||||
|
* To be able to do the final reflow correctly, we need a copy of
|
||||||
|
* the original grid, before the resize started.
|
||||||
|
*/
|
||||||
|
if (term->window->is_resizing && term->conf->resize_delay_ms > 0) {
|
||||||
|
if (term->interactive_resizing.grid == NULL) {
|
||||||
|
term_ptmx_pause(term);
|
||||||
|
|
||||||
|
/* Stash the current ‘normal’ grid, as-is, to be used when
|
||||||
|
* doing the final reflow */
|
||||||
|
term->interactive_resizing.old_screen_rows = term->rows;
|
||||||
|
term->interactive_resizing.old_cols = term->cols;
|
||||||
|
term->interactive_resizing.old_hide_cursor = term->hide_cursor;
|
||||||
|
term->interactive_resizing.grid = xmalloc(sizeof(*term->interactive_resizing.grid));
|
||||||
|
*term->interactive_resizing.grid = term->normal;
|
||||||
|
term->interactive_resizing.selection_coords = term->selection.coords;
|
||||||
|
} else {
|
||||||
|
/* We’ll replace the current temporary grid, with a new
|
||||||
|
* one (again based on the original grid) */
|
||||||
|
grid_free(&term->normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grid *orig = term->interactive_resizing.grid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the current viewport (of the original grid) to a new
|
||||||
|
* grid that will be used during the resize. For now, throw
|
||||||
|
* away sixels and OSC-8 URLs. They’ll be "restored" when we
|
||||||
|
* do the final reflow.
|
||||||
|
*
|
||||||
|
* Note that OSC-8 URLs are perfectly ok to throw away; they
|
||||||
|
* cannot be interacted with during the resize. And, even if
|
||||||
|
* url.osc8-underline=always, the “underline” attribute is
|
||||||
|
* part of the cell, not the URI struct (and thus our faked
|
||||||
|
* grid will still render OSC-8 links underlined).
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* - sixels?
|
||||||
|
*/
|
||||||
|
struct grid g = {
|
||||||
|
.num_rows = 1 << (32 - __builtin_clz(term->interactive_resizing.old_screen_rows)),
|
||||||
|
.num_cols = term->interactive_resizing.old_cols,
|
||||||
|
.offset = 0,
|
||||||
|
.view = 0,
|
||||||
|
.cursor = orig->cursor,
|
||||||
|
.saved_cursor = orig->saved_cursor,
|
||||||
|
.rows = xcalloc(g.num_rows, sizeof(g.rows[0])),
|
||||||
|
.cur_row = NULL,
|
||||||
|
.scroll_damage = tll_init(),
|
||||||
|
.sixel_images = tll_init(),
|
||||||
|
.kitty_kbd = orig->kitty_kbd,
|
||||||
|
};
|
||||||
|
|
||||||
|
term->selection.coords.start.row -= orig->view;
|
||||||
|
term->selection.coords.end.row -= orig->view;
|
||||||
|
|
||||||
|
for (size_t i = 0, j = orig->view;
|
||||||
|
i < term->interactive_resizing.old_screen_rows;
|
||||||
|
i++, j = (j + 1) & (orig->num_rows - 1))
|
||||||
|
{
|
||||||
|
g.rows[i] = grid_row_alloc(g.num_cols, false);
|
||||||
|
memcpy(g.rows[i]->cells,
|
||||||
|
orig->rows[j]->cells,
|
||||||
|
g.num_cols * sizeof(g.rows[i]->cells[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
term->normal = g;
|
||||||
|
term->hide_cursor = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (term->grid == &term->alt)
|
if (term->grid == &term->alt)
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
else {
|
else {
|
||||||
|
|
@ -3903,16 +4060,51 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
* selection’s pivot point coordinates *must* be added to the
|
* selection’s pivot point coordinates *must* be added to the
|
||||||
* tracking points list.
|
* tracking points list.
|
||||||
*/
|
*/
|
||||||
struct coord *const tracking_points[] = {
|
|
||||||
&term->selection.coords.start,
|
|
||||||
&term->selection.coords.end,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Resize grids */
|
/* Resize grids */
|
||||||
grid_resize_and_reflow(
|
if (term->window->is_resizing && term->conf->resize_delay_ms > 0) {
|
||||||
&term->normal, new_normal_grid_rows, new_cols, old_rows, new_rows,
|
/* Simple truncating resize, *while* an interactive resize is
|
||||||
term->selection.coords.end.row >= 0 ? ALEN(tracking_points) : 0,
|
* ongoing. */
|
||||||
tracking_points);
|
xassert(term->interactive_resizing.grid != NULL);
|
||||||
|
xassert(new_normal_grid_rows > 0);
|
||||||
|
term->interactive_resizing.new_rows = new_normal_grid_rows;
|
||||||
|
|
||||||
|
grid_resize_without_reflow(
|
||||||
|
&term->normal, new_alt_grid_rows, new_cols,
|
||||||
|
term->interactive_resizing.old_screen_rows, new_rows);
|
||||||
|
} else {
|
||||||
|
/* Full text reflow */
|
||||||
|
|
||||||
|
if (term->interactive_resizing.grid != NULL) {
|
||||||
|
/* Throw away the current, truncated, “normal” grid, and
|
||||||
|
* use the original grid instead (from before the resize
|
||||||
|
* started) */
|
||||||
|
grid_free(&term->normal);
|
||||||
|
term->normal = *term->interactive_resizing.grid;
|
||||||
|
free(term->interactive_resizing.grid);
|
||||||
|
|
||||||
|
term->hide_cursor = term->interactive_resizing.old_hide_cursor;
|
||||||
|
term->selection.coords = term->interactive_resizing.selection_coords;
|
||||||
|
|
||||||
|
old_rows = term->interactive_resizing.old_screen_rows;
|
||||||
|
|
||||||
|
term->interactive_resizing.grid = NULL;
|
||||||
|
term->interactive_resizing.old_screen_rows = 0;
|
||||||
|
term->interactive_resizing.new_rows = 0;
|
||||||
|
term->interactive_resizing.old_hide_cursor = false;
|
||||||
|
term->interactive_resizing.selection_coords = (struct range){{-1, -1}, {-1, -1}};
|
||||||
|
term_ptmx_resume(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct coord *const tracking_points[] = {
|
||||||
|
&term->selection.coords.start,
|
||||||
|
&term->selection.coords.end,
|
||||||
|
};
|
||||||
|
|
||||||
|
grid_resize_and_reflow(
|
||||||
|
&term->normal, new_normal_grid_rows, new_cols, old_rows, new_rows,
|
||||||
|
term->selection.coords.end.row >= 0 ? ALEN(tracking_points) : 0,
|
||||||
|
tracking_points);
|
||||||
|
}
|
||||||
|
|
||||||
grid_resize_without_reflow(
|
grid_resize_without_reflow(
|
||||||
&term->alt, new_alt_grid_rows, new_cols, old_rows, new_rows);
|
&term->alt, new_alt_grid_rows, new_cols, old_rows, new_rows);
|
||||||
|
|
@ -3936,9 +4128,11 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
|
|
||||||
if (term->scroll_region.start >= term->rows)
|
if (term->scroll_region.start >= term->rows)
|
||||||
term->scroll_region.start = 0;
|
term->scroll_region.start = 0;
|
||||||
|
if (term->scroll_region.end > term->rows ||
|
||||||
if (term->scroll_region.end >= old_rows)
|
term->scroll_region.end >= old_rows)
|
||||||
|
{
|
||||||
term->scroll_region.end = term->rows;
|
term->scroll_region.end = term->rows;
|
||||||
|
}
|
||||||
|
|
||||||
term->render.last_cursor.row = NULL;
|
term->render.last_cursor.row = NULL;
|
||||||
|
|
||||||
|
|
@ -3956,12 +4150,6 @@ damage_view:
|
||||||
term->stashed_height = term->height;
|
term->stashed_height = term->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* TODO: doesn't include CSD title bar */
|
|
||||||
xdg_toplevel_set_min_size(
|
|
||||||
term->window->xdg_toplevel, min_width / scale, min_height / scale);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const bool title_shown = wayl_win_csd_titlebar_visible(term->window);
|
const bool title_shown = wayl_win_csd_titlebar_visible(term->window);
|
||||||
const bool border_shown = wayl_win_csd_borders_visible(term->window);
|
const bool border_shown = wayl_win_csd_borders_visible(term->window);
|
||||||
|
|
@ -3971,6 +4159,11 @@ damage_view:
|
||||||
const int border_width =
|
const int border_width =
|
||||||
border_shown ? term->conf->csd.border_width_visible : 0;
|
border_shown ? term->conf->csd.border_width_visible : 0;
|
||||||
|
|
||||||
|
xdg_toplevel_set_min_size(
|
||||||
|
term->window->xdg_toplevel,
|
||||||
|
min_width / scale + 2 * border_width,
|
||||||
|
min_height / scale + title_height + 2 * border_width);
|
||||||
|
|
||||||
xdg_surface_set_window_geometry(
|
xdg_surface_set_window_geometry(
|
||||||
term->window->xdg_surface,
|
term->window->xdg_surface,
|
||||||
-border_width,
|
-border_width,
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,25 @@ class StringCapability(Capability):
|
||||||
def __init__(self, name: str, value: str):
|
def __init__(self, name: str, value: str):
|
||||||
# Expand \E to literal ESC in non-parameterized capabilities
|
# Expand \E to literal ESC in non-parameterized capabilities
|
||||||
if '%' not in value:
|
if '%' not in value:
|
||||||
|
# Ensure e.g. \E7 doesn’t get translated to “\0337”, which
|
||||||
|
# would be interpreted as octal 337 by the C compiler
|
||||||
value = re.sub(r'\\E([0-7])', r'\\033" "\1', value)
|
value = re.sub(r'\\E([0-7])', r'\\033" "\1', value)
|
||||||
value = re.sub(r'\\E', r'\\033', value)
|
|
||||||
else:
|
|
||||||
# Need to double-escape \E in C string literals
|
|
||||||
value = value.replace('\\E', '\\\\E')
|
|
||||||
|
|
||||||
# Don’t escape ‘:’
|
# Replace \E with an actual escape
|
||||||
value = value.replace('\\:', ':')
|
value = re.sub(r'\\E', r'\\033', value)
|
||||||
|
|
||||||
|
# Don’t escape ‘:’
|
||||||
|
value = value.replace('\\:', ':')
|
||||||
|
|
||||||
|
else:
|
||||||
|
value = value.replace("\\", "\\\\")
|
||||||
|
# # Need to double-escape backslashes. These only occur in
|
||||||
|
# # ‘\E\’ combos. Note that \E itself is updated below
|
||||||
|
# value = value.replace('\\E\\\\', '\\E\\\\\\\\')
|
||||||
|
|
||||||
|
# # Need to double-escape \E in C string literals
|
||||||
|
# value = value.replace('\\E', '\\\\E')
|
||||||
|
|
||||||
|
|
||||||
super().__init__(name, value)
|
super().__init__(name, value)
|
||||||
|
|
||||||
|
|
|
||||||
13
selection.c
13
selection.c
|
|
@ -86,7 +86,7 @@ selection_on_rows(const struct terminal *term, int row_start, int row_end)
|
||||||
const int rel_row_start =
|
const int rel_row_start =
|
||||||
grid_row_abs_to_sb_precalc_sb_start(grid, sb_start, row_start);
|
grid_row_abs_to_sb_precalc_sb_start(grid, sb_start, row_start);
|
||||||
const int rel_row_end =
|
const int rel_row_end =
|
||||||
grid_row_abs_to_sb_precalc_sb_start(grid, sb_start, row_start);
|
grid_row_abs_to_sb_precalc_sb_start(grid, sb_start, row_end);
|
||||||
int rel_sel_start =
|
int rel_sel_start =
|
||||||
grid_row_abs_to_sb_precalc_sb_start(grid, sb_start, start->row);
|
grid_row_abs_to_sb_precalc_sb_start(grid, sb_start, start->row);
|
||||||
int rel_sel_end =
|
int rel_sel_end =
|
||||||
|
|
@ -133,13 +133,18 @@ selection_scroll_down(struct terminal *term, int rows)
|
||||||
{
|
{
|
||||||
xassert(term->selection.coords.end.row >= 0);
|
xassert(term->selection.coords.end.row >= 0);
|
||||||
|
|
||||||
|
const struct grid *grid = term->grid;
|
||||||
|
const struct range *sel = &term->selection.coords;
|
||||||
|
|
||||||
|
const int screen_end =
|
||||||
|
grid_row_abs_to_sb(grid, term->rows, grid->offset + term->rows - 1);
|
||||||
const int rel_row_start =
|
const int rel_row_start =
|
||||||
grid_row_abs_to_sb(term->grid, term->rows, term->selection.coords.start.row);
|
grid_row_abs_to_sb(term->grid, term->rows, sel->start.row);
|
||||||
const int rel_row_end =
|
const int rel_row_end =
|
||||||
grid_row_abs_to_sb(term->grid, term->rows, term->selection.coords.end.row);
|
grid_row_abs_to_sb(term->grid, term->rows, sel->end.row);
|
||||||
const int actual_end = max(rel_row_start, rel_row_end);
|
const int actual_end = max(rel_row_start, rel_row_end);
|
||||||
|
|
||||||
if (actual_end + rows <= term->grid->num_rows) {
|
if (actual_end > screen_end - rows) {
|
||||||
/* Part of the selection will be scrolled out, cancel it */
|
/* Part of the selection will be scrolled out, cancel it */
|
||||||
selection_cancel(term);
|
selection_cancel(term);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
150
sixel.c
150
sixel.c
|
|
@ -154,7 +154,7 @@ verify_list_order(const struct terminal *term)
|
||||||
int prev_col_count = 0;
|
int prev_col_count = 0;
|
||||||
|
|
||||||
/* To aid debugging */
|
/* To aid debugging */
|
||||||
size_t idx = 0;
|
size_t UNUSED idx = 0;
|
||||||
|
|
||||||
tll_foreach(term->grid->sixel_images, it) {
|
tll_foreach(term->grid->sixel_images, it) {
|
||||||
int row = grid_row_abs_to_sb(
|
int row = grid_row_abs_to_sb(
|
||||||
|
|
@ -838,85 +838,89 @@ sixel_cell_size_changed(struct terminal *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sixel_reflow(struct terminal *term)
|
sixel_reflow_grid(struct terminal *term, struct grid *grid)
|
||||||
{
|
{
|
||||||
struct grid *g = term->grid;
|
/* Meh - the sixel functions we call use term->grid... */
|
||||||
|
struct grid *active_grid = term->grid;
|
||||||
|
term->grid = grid;
|
||||||
|
|
||||||
for (size_t i = 0; i < 2; i++) {
|
/* Need the “real” list to be empty from the beginning */
|
||||||
struct grid *grid = i == 0 ? &term->normal : &term->alt;
|
tll(struct sixel) copy = tll_init();
|
||||||
|
tll_foreach(grid->sixel_images, it)
|
||||||
|
tll_push_back(copy, it->item);
|
||||||
|
tll_free(grid->sixel_images);
|
||||||
|
|
||||||
term->grid = grid;
|
tll_rforeach(copy, it) {
|
||||||
|
struct sixel *six = &it->item;
|
||||||
|
int start = six->pos.row;
|
||||||
|
int end = (start + six->rows - 1) & (grid->num_rows - 1);
|
||||||
|
|
||||||
/* Need the “real” list to be empty from the beginning */
|
if (end < start) {
|
||||||
tll(struct sixel) copy = tll_init();
|
/* Crosses scrollback wrap-around */
|
||||||
tll_foreach(grid->sixel_images, it)
|
/* TODO: split image */
|
||||||
tll_push_back(copy, it->item);
|
sixel_destroy(six);
|
||||||
tll_free(grid->sixel_images);
|
continue;
|
||||||
|
|
||||||
tll_rforeach(copy, it) {
|
|
||||||
struct sixel *six = &it->item;
|
|
||||||
int start = six->pos.row;
|
|
||||||
int end = (start + six->rows - 1) & (grid->num_rows - 1);
|
|
||||||
|
|
||||||
if (end < start) {
|
|
||||||
/* Crosses scrollback wrap-around */
|
|
||||||
/* TODO: split image */
|
|
||||||
sixel_destroy(six);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (six->rows > grid->num_rows) {
|
|
||||||
/* Image too large */
|
|
||||||
/* TODO: keep bottom part? */
|
|
||||||
sixel_destroy(six);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drop sixels that now cross the current scrollback end
|
|
||||||
* border. This is similar to a sixel that have been
|
|
||||||
* scrolled out */
|
|
||||||
/* TODO: should be possible to optimize this */
|
|
||||||
bool sixel_destroyed = false;
|
|
||||||
int last_row = -1;
|
|
||||||
|
|
||||||
for (int j = 0; j < six->rows; j++) {
|
|
||||||
int row_no = grid_row_abs_to_sb(
|
|
||||||
term->grid, term->rows, six->pos.row + j);
|
|
||||||
if (last_row != -1 && last_row >= row_no) {
|
|
||||||
sixel_destroy(six);
|
|
||||||
sixel_destroyed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_row = row_no;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sixel_destroyed) {
|
|
||||||
LOG_WARN("destroyed sixel that now crossed history");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sixels that didn’t overlap may now do so, which isn’t
|
|
||||||
* allowed of course */
|
|
||||||
_sixel_overwrite_by_rectangle(
|
|
||||||
term, six->pos.row, six->pos.col, six->rows, six->cols,
|
|
||||||
&it->item.pix, &it->item.opaque);
|
|
||||||
|
|
||||||
if (it->item.data != pixman_image_get_data(it->item.pix)) {
|
|
||||||
it->item.data = pixman_image_get_data(it->item.pix);
|
|
||||||
it->item.width = pixman_image_get_width(it->item.pix);
|
|
||||||
it->item.height = pixman_image_get_height(it->item.pix);
|
|
||||||
it->item.cols = (it->item.width + term->cell_width - 1) / term->cell_width;
|
|
||||||
it->item.rows = (it->item.height + term->cell_height - 1) / term->cell_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
sixel_insert(term, it->item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tll_free(copy);
|
if (six->rows > grid->num_rows) {
|
||||||
|
/* Image too large */
|
||||||
|
/* TODO: keep bottom part? */
|
||||||
|
sixel_destroy(six);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drop sixels that now cross the current scrollback end
|
||||||
|
* border. This is similar to a sixel that have been
|
||||||
|
* scrolled out */
|
||||||
|
/* TODO: should be possible to optimize this */
|
||||||
|
bool sixel_destroyed = false;
|
||||||
|
int last_row = -1;
|
||||||
|
|
||||||
|
for (int j = 0; j < six->rows; j++) {
|
||||||
|
int row_no = grid_row_abs_to_sb(
|
||||||
|
term->grid, term->rows, six->pos.row + j);
|
||||||
|
if (last_row != -1 && last_row >= row_no) {
|
||||||
|
sixel_destroy(six);
|
||||||
|
sixel_destroyed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_row = row_no;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sixel_destroyed) {
|
||||||
|
LOG_WARN("destroyed sixel that now crossed history");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sixels that didn’t overlap may now do so, which isn’t
|
||||||
|
* allowed of course */
|
||||||
|
_sixel_overwrite_by_rectangle(
|
||||||
|
term, six->pos.row, six->pos.col, six->rows, six->cols,
|
||||||
|
&it->item.pix, &it->item.opaque);
|
||||||
|
|
||||||
|
if (it->item.data != pixman_image_get_data(it->item.pix)) {
|
||||||
|
it->item.data = pixman_image_get_data(it->item.pix);
|
||||||
|
it->item.width = pixman_image_get_width(it->item.pix);
|
||||||
|
it->item.height = pixman_image_get_height(it->item.pix);
|
||||||
|
it->item.cols = (it->item.width + term->cell_width - 1) / term->cell_width;
|
||||||
|
it->item.rows = (it->item.height + term->cell_height - 1) / term->cell_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
sixel_insert(term, it->item);
|
||||||
}
|
}
|
||||||
|
|
||||||
term->grid = g;
|
tll_free(copy);
|
||||||
|
term->grid = active_grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sixel_reflow(struct terminal *term)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < 2; i++) {
|
||||||
|
struct grid *grid = i == 0 ? &term->normal : &term->alt;
|
||||||
|
sixel_reflow_grid(term, grid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1291,7 +1295,7 @@ sixel_add_many(struct terminal *term, uint8_t c, unsigned count)
|
||||||
if (unlikely(col + count - 1 >= width)) {
|
if (unlikely(col + count - 1 >= width)) {
|
||||||
resize_horizontally(term, col + count);
|
resize_horizontally(term, col + count);
|
||||||
width = term->sixel.image.width;
|
width = term->sixel.image.width;
|
||||||
count = min(count, width - col);
|
count = min(count, max(width - col, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t color = term->sixel.color;
|
uint32_t color = term->sixel.color;
|
||||||
|
|
|
||||||
4
sixel.h
4
sixel.h
|
|
@ -19,6 +19,10 @@ void sixel_scroll_up(struct terminal *term, int rows);
|
||||||
void sixel_scroll_down(struct terminal *term, int rows);
|
void sixel_scroll_down(struct terminal *term, int rows);
|
||||||
|
|
||||||
void sixel_cell_size_changed(struct terminal *term);
|
void sixel_cell_size_changed(struct terminal *term);
|
||||||
|
|
||||||
|
void sixel_reflow_grid(struct terminal *term, struct grid *grid);
|
||||||
|
|
||||||
|
/* Shortcut for sixel_reflow_grid(normal) + sixel_reflow_grid(alt) */
|
||||||
void sixel_reflow(struct terminal *term);
|
void sixel_reflow(struct terminal *term);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
14
slave.c
14
slave.c
|
|
@ -21,6 +21,7 @@
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
|
#include "version.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
@ -351,6 +352,8 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv,
|
||||||
}
|
}
|
||||||
|
|
||||||
setenv("TERM", term_env, 1);
|
setenv("TERM", term_env, 1);
|
||||||
|
setenv("TERM_PROGRAM", "foot", 1);
|
||||||
|
setenv("TERM_PROGRAM_VERSION", FOOT_VERSION_SHORT, 1);
|
||||||
setenv("COLORTERM", "truecolor", 1);
|
setenv("COLORTERM", "truecolor", 1);
|
||||||
setenv("PWD", cwd, 1);
|
setenv("PWD", cwd, 1);
|
||||||
|
|
||||||
|
|
@ -359,8 +362,15 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (extra_env_vars != NULL) {
|
if (extra_env_vars != NULL) {
|
||||||
tll_foreach(*extra_env_vars, it)
|
tll_foreach(*extra_env_vars, it) {
|
||||||
setenv(it->item.name, it->item.value, 1);
|
const char *name = it->item.name;
|
||||||
|
const char *value = it->item.value;
|
||||||
|
|
||||||
|
if (strlen(value) == 0)
|
||||||
|
unsetenv(name);
|
||||||
|
else
|
||||||
|
setenv(name, value, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char **_shell_argv = NULL;
|
char **_shell_argv = NULL;
|
||||||
|
|
|
||||||
192
terminal.c
192
terminal.c
|
|
@ -7,6 +7,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
@ -255,8 +256,18 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
|
||||||
cursor_blink_rearm_timer(term);
|
cursor_blink_rearm_timer(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unlikely(term->interactive_resizing.grid != NULL)) {
|
||||||
|
/*
|
||||||
|
* Don’t consume PTMX while we’re doing an interactive resize,
|
||||||
|
* since the ‘normal’ grid we’re currently using is a
|
||||||
|
* temporary one - all changes done to it will be lost when
|
||||||
|
* the interactive resize ends.
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t buf[24 * 1024];
|
uint8_t buf[24 * 1024];
|
||||||
const size_t max_iterations = !hup ? 10 : (size_t)-1ll;
|
const size_t max_iterations = !hup ? 10 : SIZE_MAX;
|
||||||
|
|
||||||
for (size_t i = 0; i < max_iterations && pollin; i++) {
|
for (size_t i = 0; i < max_iterations && pollin; i++) {
|
||||||
xassert(pollin);
|
xassert(pollin);
|
||||||
|
|
@ -278,6 +289,7 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xassert(term->interactive_resizing.grid == NULL);
|
||||||
vt_from_slave(term, buf, count);
|
vt_from_slave(term, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,6 +370,18 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
term_ptmx_pause(struct terminal *term)
|
||||||
|
{
|
||||||
|
return fdm_event_del(term->fdm, term->ptmx, EPOLLIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
term_ptmx_resume(struct terminal *term)
|
||||||
|
{
|
||||||
|
return fdm_event_add(term->fdm, term->ptmx, EPOLLIN);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
fdm_flash(struct fdm *fdm, int fd, int events, void *data)
|
fdm_flash(struct fdm *fdm, int fd, int events, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -680,6 +704,37 @@ free_custom_glyphs(struct fcft_glyph ***glyphs, size_t count)
|
||||||
*glyphs = NULL;
|
*glyphs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
term_line_height_update(struct terminal *term)
|
||||||
|
{
|
||||||
|
const struct config *conf = term->conf;
|
||||||
|
|
||||||
|
if (term->conf->line_height.px < 0) {
|
||||||
|
term->font_line_height.pt = 0;
|
||||||
|
term->font_line_height.px = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
|
||||||
|
|
||||||
|
const float font_original_pt_size =
|
||||||
|
conf->fonts[0].arr[0].px_size > 0
|
||||||
|
? conf->fonts[0].arr[0].px_size * 72. / dpi
|
||||||
|
: conf->fonts[0].arr[0].pt_size;
|
||||||
|
const float font_current_pt_size =
|
||||||
|
term->font_sizes[0][0].px_size > 0
|
||||||
|
? term->font_sizes[0][0].px_size * 72. / dpi
|
||||||
|
: term->font_sizes[0][0].pt_size;
|
||||||
|
|
||||||
|
const float change = font_current_pt_size / font_original_pt_size;
|
||||||
|
const float line_original_pt_size = conf->line_height.px > 0
|
||||||
|
? conf->line_height.px * 72. / dpi
|
||||||
|
: conf->line_height.pt;
|
||||||
|
|
||||||
|
term->font_line_height.px = 0;
|
||||||
|
term->font_line_height.pt = fmaxf(line_original_pt_size * change, 0.);
|
||||||
|
}
|
||||||
|
|
||||||
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])
|
||||||
{
|
{
|
||||||
|
|
@ -706,6 +761,8 @@ term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4])
|
||||||
fonts[0], U'M', term->font_subpixel);
|
fonts[0], U'M', term->font_subpixel);
|
||||||
int advance = M != NULL ? M->advance.x : term->fonts[0]->max_advance.x;
|
int advance = M != NULL ? M->advance.x : term->fonts[0]->max_advance.x;
|
||||||
|
|
||||||
|
term_line_height_update(term);
|
||||||
|
|
||||||
term->cell_width = advance +
|
term->cell_width = advance +
|
||||||
term_pt_or_px_as_pixels(term, &conf->letter_spacing);
|
term_pt_or_px_as_pixels(term, &conf->letter_spacing);
|
||||||
|
|
||||||
|
|
@ -889,7 +946,7 @@ term_pt_or_px_as_pixels(const struct terminal *term,
|
||||||
|
|
||||||
return pt_or_px->px == 0
|
return pt_or_px->px == 0
|
||||||
? round(pt_or_px->pt * scale * dpi / 72)
|
? round(pt_or_px->pt * scale * dpi / 72)
|
||||||
: pt_or_px->px;
|
: pt_or_px->px * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct font_load_data {
|
struct font_load_data {
|
||||||
|
|
@ -1054,7 +1111,6 @@ load_fonts_from_conf(struct terminal *term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
term->font_line_height = term->conf->line_height;
|
|
||||||
return reload_fonts(term);
|
return reload_fonts(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1274,7 +1330,6 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
||||||
.pt_size = font->pt_size, .px_size = font->px_size};
|
.pt_size = font->pt_size, .px_size = font->px_size};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
term->font_line_height = conf->line_height;
|
|
||||||
|
|
||||||
add_utmp_record(conf, reaper, ptmx);
|
add_utmp_record(conf, reaper, ptmx);
|
||||||
|
|
||||||
|
|
@ -1728,6 +1783,8 @@ term_destroy(struct terminal *term)
|
||||||
|
|
||||||
grid_free(&term->normal);
|
grid_free(&term->normal);
|
||||||
grid_free(&term->alt);
|
grid_free(&term->alt);
|
||||||
|
grid_free(term->interactive_resizing.grid);
|
||||||
|
free(term->interactive_resizing.grid);
|
||||||
|
|
||||||
free(term->foot_exe);
|
free(term->foot_exe);
|
||||||
free(term->cwd);
|
free(term->cwd);
|
||||||
|
|
@ -1978,39 +2035,71 @@ term_reset(struct terminal *term, bool hard)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
term_font_size_adjust(struct terminal *term, double amount)
|
term_font_size_adjust_by_points(struct terminal *term, float amount)
|
||||||
{
|
{
|
||||||
const struct config *conf = term->conf;
|
const struct config *conf = term->conf;
|
||||||
|
|
||||||
const float dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
|
const float dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
const struct config_font_list *font_list = &conf->fonts[i];
|
const struct config_font_list *font_list = &conf->fonts[i];
|
||||||
|
|
||||||
for (size_t j = 0; j < font_list->count; j++) {
|
for (size_t j = 0; j < font_list->count; j++) {
|
||||||
float old_pt_size = term->font_sizes[i][j].pt_size;
|
struct config_font *font = &term->font_sizes[i][j];
|
||||||
|
float old_pt_size = font->pt_size;
|
||||||
|
|
||||||
/*
|
if (font->px_size > 0)
|
||||||
* To ensure primary and user-configured fallback fonts are
|
old_pt_size = font->px_size * 72. / dpi;
|
||||||
* resizes by the same amount, convert pixel sizes to point
|
|
||||||
* sizes, and to the adjustment on point sizes only.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (term->font_sizes[i][j].px_size > 0)
|
font->pt_size = fmaxf(old_pt_size + amount, 0.);
|
||||||
old_pt_size = term->font_sizes[i][j].px_size * 72. / dpi;
|
font->px_size = -1;
|
||||||
|
|
||||||
term->font_sizes[i][j].pt_size = fmaxf(old_pt_size + amount, 0.);
|
|
||||||
term->font_sizes[i][j].px_size = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (term->font_line_height.px >= 0) {
|
return reload_fonts(term);
|
||||||
float old_pt_size = term->font_line_height.px > 0
|
}
|
||||||
? term->font_line_height.px * 72. / dpi
|
|
||||||
: term->font_line_height.pt;
|
|
||||||
|
|
||||||
term->font_line_height.px = 0;
|
static bool
|
||||||
term->font_line_height.pt = fmaxf(old_pt_size + amount, 0.);
|
term_font_size_adjust_by_pixels(struct terminal *term, int amount)
|
||||||
|
{
|
||||||
|
const struct config *conf = term->conf;
|
||||||
|
const float dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
const struct config_font_list *font_list = &conf->fonts[i];
|
||||||
|
|
||||||
|
for (size_t j = 0; j < font_list->count; j++) {
|
||||||
|
struct config_font *font = &term->font_sizes[i][j];
|
||||||
|
int old_px_size = font->px_size;
|
||||||
|
|
||||||
|
if (font->px_size <= 0)
|
||||||
|
old_px_size = font->pt_size * dpi / 72.;
|
||||||
|
|
||||||
|
font->px_size = max(old_px_size + amount, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reload_fonts(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
term_font_size_adjust_by_percent(struct terminal *term, bool increment, float percent)
|
||||||
|
{
|
||||||
|
const struct config *conf = term->conf;
|
||||||
|
const float multiplier = increment
|
||||||
|
? 1. + percent
|
||||||
|
: 1. / (1. + percent);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
const struct config_font_list *font_list = &conf->fonts[i];
|
||||||
|
|
||||||
|
for (size_t j = 0; j < font_list->count; j++) {
|
||||||
|
struct config_font *font = &term->font_sizes[i][j];
|
||||||
|
|
||||||
|
if (font->px_size > 0)
|
||||||
|
font->px_size = max(font->px_size * multiplier, 1);
|
||||||
|
else
|
||||||
|
font->pt_size = fmax(font->pt_size * multiplier, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return reload_fonts(term);
|
return reload_fonts(term);
|
||||||
|
|
@ -2019,19 +2108,29 @@ term_font_size_adjust(struct terminal *term, double amount)
|
||||||
bool
|
bool
|
||||||
term_font_size_increase(struct terminal *term)
|
term_font_size_increase(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (!term_font_size_adjust(term, 0.5))
|
const struct config *conf = term->conf;
|
||||||
return false;
|
const struct font_size_adjustment *inc_dec = &conf->font_size_adjustment;
|
||||||
|
|
||||||
return true;
|
if (inc_dec->percent > 0.)
|
||||||
|
return term_font_size_adjust_by_percent(term, true, inc_dec->percent);
|
||||||
|
else if (inc_dec->pt_or_px.px > 0)
|
||||||
|
return term_font_size_adjust_by_pixels(term, inc_dec->pt_or_px.px);
|
||||||
|
else
|
||||||
|
return term_font_size_adjust_by_points(term, inc_dec->pt_or_px.pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
term_font_size_decrease(struct terminal *term)
|
term_font_size_decrease(struct terminal *term)
|
||||||
{
|
{
|
||||||
if (!term_font_size_adjust(term, -0.5))
|
const struct config *conf = term->conf;
|
||||||
return false;
|
const struct font_size_adjustment *inc_dec = &conf->font_size_adjustment;
|
||||||
|
|
||||||
return true;
|
if (inc_dec->percent > 0.)
|
||||||
|
return term_font_size_adjust_by_percent(term, false, inc_dec->percent);
|
||||||
|
else if (inc_dec->pt_or_px.px > 0)
|
||||||
|
return term_font_size_adjust_by_pixels(term, -inc_dec->pt_or_px.px);
|
||||||
|
else
|
||||||
|
return term_font_size_adjust_by_points(term, -inc_dec->pt_or_px.pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -2153,15 +2252,20 @@ void
|
||||||
term_damage_scroll(struct terminal *term, enum damage_type damage_type,
|
term_damage_scroll(struct terminal *term, enum damage_type damage_type,
|
||||||
struct scroll_region region, int lines)
|
struct scroll_region region, int lines)
|
||||||
{
|
{
|
||||||
if (tll_length(term->grid->scroll_damage) > 0) {
|
if (likely(tll_length(term->grid->scroll_damage) > 0)) {
|
||||||
struct damage *dmg = &tll_back(term->grid->scroll_damage);
|
struct damage *dmg = &tll_back(term->grid->scroll_damage);
|
||||||
|
|
||||||
if (dmg->type == damage_type &&
|
if (likely(
|
||||||
dmg->region.start == region.start &&
|
dmg->type == damage_type &&
|
||||||
dmg->region.end == region.end)
|
dmg->region.start == region.start &&
|
||||||
|
dmg->region.end == region.end))
|
||||||
{
|
{
|
||||||
dmg->lines += lines;
|
/* Make sure we don’t overflow... */
|
||||||
return;
|
int new_line_count = (int)dmg->lines + lines;
|
||||||
|
if (likely(new_line_count <= UINT16_MAX)) {
|
||||||
|
dmg->lines = new_line_count;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct damage dmg = {
|
struct damage dmg = {
|
||||||
|
|
@ -2612,13 +2716,13 @@ term_scroll_partial(struct terminal *term, struct scroll_region region, int rows
|
||||||
erase_line(term, row);
|
erase_line(term, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
|
||||||
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
|
||||||
|
|
||||||
#if defined(_DEBUG)
|
#if defined(_DEBUG)
|
||||||
for (int r = 0; r < term->rows; r++)
|
for (int r = 0; r < term->rows; r++)
|
||||||
xassert(grid_row(term->grid, r) != NULL);
|
xassert(grid_row(term->grid, r) != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
term_damage_scroll(term, DAMAGE_SCROLL, region, rows);
|
||||||
|
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2652,6 +2756,18 @@ term_scroll_reverse_partial(struct terminal *term,
|
||||||
selection_scroll_down(term, rows);
|
selection_scroll_down(term, rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unallocate scrolled out lines */
|
||||||
|
for (int r = region.end - rows; r < region.end; r++) {
|
||||||
|
const int abs_r = grid_row_absolute(term->grid, r);
|
||||||
|
struct row *row = term->grid->rows[abs_r];
|
||||||
|
|
||||||
|
grid_row_free(row);
|
||||||
|
term->grid->rows[abs_r] = NULL;
|
||||||
|
|
||||||
|
if (term->render.last_cursor.row == row)
|
||||||
|
term->render.last_cursor.row = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sixel_scroll_down(term, rows);
|
sixel_scroll_down(term, rows);
|
||||||
|
|
||||||
bool view_follows = term->grid->view == term->grid->offset;
|
bool view_follows = term->grid->view == term->grid->offset;
|
||||||
|
|
|
||||||
14
terminal.h
14
terminal.h
|
|
@ -96,7 +96,7 @@ enum damage_type {DAMAGE_SCROLL, DAMAGE_SCROLL_REVERSE,
|
||||||
struct damage {
|
struct damage {
|
||||||
enum damage_type type;
|
enum damage_type type;
|
||||||
struct scroll_region region;
|
struct scroll_region region;
|
||||||
int lines;
|
uint16_t lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct row_uri_range {
|
struct row_uri_range {
|
||||||
|
|
@ -598,6 +598,15 @@ struct terminal {
|
||||||
struct timespec input_time;
|
struct timespec input_time;
|
||||||
} render;
|
} render;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct grid *grid; /* Original ‘normal’ grid, before resize started */
|
||||||
|
int old_screen_rows; /* term->rows before resize started */
|
||||||
|
int old_cols; /* term->cols before resize started */
|
||||||
|
int old_hide_cursor; /* term->hide_cursor before resize started */
|
||||||
|
int new_rows; /* New number of scrollback rows */
|
||||||
|
struct range selection_coords;
|
||||||
|
} interactive_resizing;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
enum {
|
enum {
|
||||||
SIXEL_DECSIXEL, /* DECSIXEL body part ", $, -, ? ... ~ */
|
SIXEL_DECSIXEL, /* DECSIXEL body part ", $, -, ? ... ~ */
|
||||||
|
|
@ -805,6 +814,9 @@ void term_collect_urls(struct terminal *term);
|
||||||
void term_osc8_open(struct terminal *term, uint64_t id, const char *uri);
|
void term_osc8_open(struct terminal *term, uint64_t id, const char *uri);
|
||||||
void term_osc8_close(struct terminal *term);
|
void term_osc8_close(struct terminal *term);
|
||||||
|
|
||||||
|
bool term_ptmx_pause(struct terminal *term);
|
||||||
|
bool term_ptmx_resume(struct terminal *term);
|
||||||
|
|
||||||
static inline void term_reset_grapheme_state(struct terminal *term)
|
static inline void term_reset_grapheme_state(struct terminal *term)
|
||||||
{
|
{
|
||||||
#if defined(FOOT_GRAPHEME_CLUSTERING)
|
#if defined(FOOT_GRAPHEME_CLUSTERING)
|
||||||
|
|
|
||||||
|
|
@ -467,6 +467,7 @@ test_section_main(void)
|
||||||
test_boolean(&ctx, &parse_section_main, "locked-title", &conf.locked_title);
|
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, "notify-focus-inhibit", &conf.notify_focus_inhibit);
|
||||||
|
|
||||||
|
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);
|
test_pt_or_px(&ctx, &parse_section_main, "line-height", &conf.line_height);
|
||||||
test_pt_or_px(&ctx, &parse_section_main, "letter-spacing", &conf.letter_spacing);
|
test_pt_or_px(&ctx, &parse_section_main, "letter-spacing", &conf.letter_spacing);
|
||||||
test_pt_or_px(&ctx, &parse_section_main, "horizontal-letter-offset", &conf.horizontal_letter_offset);
|
test_pt_or_px(&ctx, &parse_section_main, "horizontal-letter-offset", &conf.horizontal_letter_offset);
|
||||||
|
|
@ -894,7 +895,7 @@ enum collision_test_mode {
|
||||||
FAIL_DIFFERENT_ACTION,
|
FAIL_DIFFERENT_ACTION,
|
||||||
FAIL_DIFFERENT_ARGV,
|
FAIL_DIFFERENT_ARGV,
|
||||||
FAIL_MOUSE_OVERRIDE,
|
FAIL_MOUSE_OVERRIDE,
|
||||||
SUCCED_SAME_ACTION_AND_ARGV,
|
SUCCEED_SAME_ACTION_AND_ARGV,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -948,7 +949,7 @@ _test_binding_collisions(struct context *ctx,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FAIL_DIFFERENT_ARGV:
|
case FAIL_DIFFERENT_ARGV:
|
||||||
case SUCCED_SAME_ACTION_AND_ARGV:
|
case SUCCEED_SAME_ACTION_AND_ARGV:
|
||||||
bindings.arr[0].aux.type = BINDING_AUX_PIPE;
|
bindings.arr[0].aux.type = BINDING_AUX_PIPE;
|
||||||
bindings.arr[0].aux.master_copy = true;
|
bindings.arr[0].aux.master_copy = true;
|
||||||
bindings.arr[0].aux.pipe.args = xcalloc(
|
bindings.arr[0].aux.pipe.args = xcalloc(
|
||||||
|
|
@ -964,13 +965,13 @@ _test_binding_collisions(struct context *ctx,
|
||||||
bindings.arr[1].aux.pipe.args[0] = xstrdup("/usr/bin/foobar");
|
bindings.arr[1].aux.pipe.args[0] = xstrdup("/usr/bin/foobar");
|
||||||
bindings.arr[1].aux.pipe.args[1] = xstrdup("hello");
|
bindings.arr[1].aux.pipe.args[1] = xstrdup("hello");
|
||||||
|
|
||||||
if (test_mode == SUCCED_SAME_ACTION_AND_ARGV)
|
if (test_mode == SUCCEED_SAME_ACTION_AND_ARGV)
|
||||||
bindings.arr[1].aux.pipe.args[2] = xstrdup("world");
|
bindings.arr[1].aux.pipe.args[2] = xstrdup("world");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool expected_result =
|
bool expected_result =
|
||||||
test_mode == SUCCED_SAME_ACTION_AND_ARGV ? true : false;
|
test_mode == SUCCEED_SAME_ACTION_AND_ARGV ? true : false;
|
||||||
|
|
||||||
if (resolve_key_binding_collisions(
|
if (resolve_key_binding_collisions(
|
||||||
ctx->conf, ctx->section, map, &bindings, type) != expected_result)
|
ctx->conf, ctx->section, map, &bindings, type) != expected_result)
|
||||||
|
|
@ -1003,7 +1004,7 @@ test_binding_collisions(struct context *ctx,
|
||||||
{
|
{
|
||||||
_test_binding_collisions(ctx, max_action, map, type, FAIL_DIFFERENT_ACTION);
|
_test_binding_collisions(ctx, max_action, map, type, FAIL_DIFFERENT_ACTION);
|
||||||
_test_binding_collisions(ctx, max_action, map, type, FAIL_DIFFERENT_ARGV);
|
_test_binding_collisions(ctx, max_action, map, type, FAIL_DIFFERENT_ARGV);
|
||||||
_test_binding_collisions(ctx, max_action, map, type, SUCCED_SAME_ACTION_AND_ARGV);
|
_test_binding_collisions(ctx, max_action, map, type, SUCCEED_SAME_ACTION_AND_ARGV);
|
||||||
|
|
||||||
if (type == MOUSE_BINDING) {
|
if (type == MOUSE_BINDING) {
|
||||||
_test_binding_collisions(
|
_test_binding_collisions(
|
||||||
|
|
@ -1303,6 +1304,7 @@ test_section_tweak(void)
|
||||||
int
|
int
|
||||||
main(int argc, const char *const *argv)
|
main(int argc, const char *const *argv)
|
||||||
{
|
{
|
||||||
|
FcInit();
|
||||||
log_init(LOG_COLORIZE_AUTO, false, 0, LOG_CLASS_ERROR);
|
log_init(LOG_COLORIZE_AUTO, false, 0, LOG_CLASS_ERROR);
|
||||||
test_section_main();
|
test_section_main();
|
||||||
test_section_bell();
|
test_section_bell();
|
||||||
|
|
@ -1324,5 +1326,6 @@ main(int argc, const char *const *argv)
|
||||||
test_section_environment();
|
test_section_environment();
|
||||||
test_section_tweak();
|
test_section_tweak();
|
||||||
log_deinit();
|
log_deinit();
|
||||||
|
FcFini();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# https://github.com/romainl/Apprentice
|
# https://github.com/romainl/Apprentice
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Catppuccin
|
# Catppuccin
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
color=1A1826 D9E0EE
|
color=1A1826 D9E0EE
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
alpha=1.0
|
|
||||||
foreground=D9E0EE
|
foreground=D9E0EE
|
||||||
background=1E1D2F
|
background=1E1D2F
|
||||||
regular0=6E6C7E # black
|
regular0=6E6C7E # black
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Derp
|
# Derp
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
31
themes/deus
Normal file
31
themes/deus
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
# Deus
|
||||||
|
# Color palette based on: https://github.com/ajmwagar/vim-deus
|
||||||
|
|
||||||
|
[cursor]
|
||||||
|
color=2c323b eaeaea
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
background=2c323b
|
||||||
|
foreground=eaeaea
|
||||||
|
regular0=242a32
|
||||||
|
regular1=d54e53
|
||||||
|
regular2=98c379
|
||||||
|
regular3=e5c07b
|
||||||
|
regular4=83a598
|
||||||
|
regular5=c678dd
|
||||||
|
regular6=70c0ba
|
||||||
|
regular7=eaeaea
|
||||||
|
bright0=666666
|
||||||
|
bright1=ec3e45
|
||||||
|
bright2=90c966
|
||||||
|
bright3=edbf69
|
||||||
|
bright4=73ba9f
|
||||||
|
bright5=c858e9
|
||||||
|
bright6=2bcec2
|
||||||
|
bright7=ffffff
|
||||||
|
|
||||||
|
# Enable if prefer Deus colors instead of inverterd fg/bg for
|
||||||
|
# highlighting (mouse selection)
|
||||||
|
# selection-foreground=2c323b
|
||||||
|
# selection-background=eaeaea
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Dracula
|
# Dracula
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
color=282a36 f8f8f2
|
color=282a36 f8f8f2
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
alpha=1.0
|
|
||||||
foreground=f8f8f2
|
foreground=f8f8f2
|
||||||
background=282a36
|
background=282a36
|
||||||
regular0=000000 # black
|
regular0=000000 # black
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Gruvbox
|
# Gruvbox
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Gruvbox - Light
|
# Gruvbox - Light
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
[cursor]
|
[cursor]
|
||||||
color=141414 c9c9c9
|
color=141414 c9c9c9
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# JetBrains Darcula
|
# JetBrains Darcula
|
||||||
# Palette based on the same theme from https://github.com/dexpota/kitty-themes
|
# Palette based on the same theme from https://github.com/dexpota/kitty-themes
|
||||||
|
|
||||||
|
|
@ -5,7 +6,6 @@
|
||||||
color=202020 ffffff
|
color=202020 ffffff
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
#alpha=0.80
|
|
||||||
background=202020
|
background=202020
|
||||||
foreground=adadad
|
foreground=adadad
|
||||||
regular0=000000 # black
|
regular0=000000 # black
|
||||||
|
|
@ -24,5 +24,5 @@ bright4=6d9df1 # bright blue
|
||||||
bright5=fb82ff # bright magenta
|
bright5=fb82ff # bright magenta
|
||||||
bright6=60d3d1 # bright cyan
|
bright6=60d3d1 # bright cyan
|
||||||
bright7=eeeeee # bright white
|
bright7=eeeeee # bright white
|
||||||
selection-foreground=202020
|
# selection-foreground=202020
|
||||||
selection-background=1a3272
|
# selection-background=1a3272
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
color=111111 cccccc
|
color=111111 cccccc
|
||||||
|
|
||||||
|
|
|
||||||
40
themes/material-amber
Normal file
40
themes/material-amber
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
# Material Amber
|
||||||
|
# Based on material.io guidelines with Amber 50 background
|
||||||
|
|
||||||
|
# [cursor]
|
||||||
|
# color=fff8e1 21201d
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
foreground = 21201d
|
||||||
|
background = fff8e1
|
||||||
|
|
||||||
|
regular0 = 21201d # black
|
||||||
|
regular1 = cd4340 # red
|
||||||
|
regular2 = 498d49 # green
|
||||||
|
regular3 = fab32d # yellow
|
||||||
|
regular4 = 3378c4 # blue
|
||||||
|
regular5 = b83269 # magenta
|
||||||
|
regular6 = 21929a # cyan
|
||||||
|
regular7 = ffd7d7 # white
|
||||||
|
|
||||||
|
bright0 = 66635a # bright black
|
||||||
|
bright1 = dd7b72 # bright red
|
||||||
|
bright2 = 82ae78 # bright green
|
||||||
|
bright3 = fbc870 # bright yellow
|
||||||
|
bright4 = 73a0cd # bright blue
|
||||||
|
bright5 = ce6f8e # bright magenta
|
||||||
|
bright6 = 548c94 # bright cyan
|
||||||
|
bright7 = ffe1da # bright white
|
||||||
|
|
||||||
|
dim0 = 9e9a8c # dim black
|
||||||
|
dim1 = e9a99b # dim red
|
||||||
|
dim2 = b0c99f # dim green
|
||||||
|
dim3 = fdda9a # dim yellow
|
||||||
|
dim4 = a6c0d4 # dim blue
|
||||||
|
dim5 = e0a1ad # dim magenta
|
||||||
|
dim6 = 3c6064 # dim cyan
|
||||||
|
dim7 = ffe9dd # dim white
|
||||||
|
|
||||||
|
# selection-foreground=fff8e1
|
||||||
|
# selection-background=21201d
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Material
|
# Material
|
||||||
# From https://github.com/MartinSeeler/iterm2-material-design
|
# From https://github.com/MartinSeeler/iterm2-material-design
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
foreground=ECEFF1
|
foreground=ECEFF1
|
||||||
background=263238
|
background=263238
|
||||||
selection-foreground=ECEFF1
|
|
||||||
selection-background=607D8B
|
|
||||||
regular0=546E7A # black
|
regular0=546E7A # black
|
||||||
regular1=FF5252 # red
|
regular1=FF5252 # red
|
||||||
regular2=5CF19E # green
|
regular2=5CF19E # green
|
||||||
|
|
@ -22,3 +21,5 @@ bright4=80D8FF # bright blue
|
||||||
bright5=FF80AB # bright magenta
|
bright5=FF80AB # bright magenta
|
||||||
bright6=A7FDEB # bright cyan
|
bright6=A7FDEB # bright cyan
|
||||||
bright7=FFFFFF # bright white
|
bright7=FFFFFF # bright white
|
||||||
|
# selection-foreground=ECEFF1
|
||||||
|
# selection-background=607D8B
|
||||||
|
|
|
||||||
24
themes/modus-operandi
Normal file
24
themes/modus-operandi
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
#
|
||||||
|
# modus-operandi
|
||||||
|
# See: https://protesilaos.com/emacs/modus-themes
|
||||||
|
#
|
||||||
|
[colors]
|
||||||
|
background=ffffff
|
||||||
|
foreground=000000
|
||||||
|
regular0=000000
|
||||||
|
regular1=a60000
|
||||||
|
regular2=005e00
|
||||||
|
regular3=813e00
|
||||||
|
regular4=0031a9
|
||||||
|
regular5=721045
|
||||||
|
regular6=00538b
|
||||||
|
regular7=bfbfbf
|
||||||
|
bright0=595959
|
||||||
|
bright1=972500
|
||||||
|
bright2=315b00
|
||||||
|
bright3=70480f
|
||||||
|
bright4=2544bb
|
||||||
|
bright5=5317ac
|
||||||
|
bright6=005a5f
|
||||||
|
bright7=ffffff
|
||||||
25
themes/modus-vivendi
Normal file
25
themes/modus-vivendi
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
#
|
||||||
|
# modus-vivendi
|
||||||
|
# See: https://protesilaos.com/emacs/modus-themes
|
||||||
|
#
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
background=000000
|
||||||
|
foreground=ffffff
|
||||||
|
regular0=000000
|
||||||
|
regular1=ff8059
|
||||||
|
regular2=44bc44
|
||||||
|
regular3=d0bc00
|
||||||
|
regular4=2fafff
|
||||||
|
regular5=feacd0
|
||||||
|
regular6=00d3d0
|
||||||
|
regular7=bfbfbf
|
||||||
|
bright0=595959
|
||||||
|
bright1=ef8b50
|
||||||
|
bright2=70b900
|
||||||
|
bright3=c0c530
|
||||||
|
bright4=79a8ff
|
||||||
|
bright5=b6a0ff
|
||||||
|
bright6=6ae4b9
|
||||||
|
bright7=ffffff
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Monokai Pro
|
# Monokai Pro
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# moonfly
|
# moonfly
|
||||||
# Based on https://github.com/bluz71/vim-moonfly-colors
|
# Based on https://github.com/bluz71/vim-moonfly-colors
|
||||||
|
|
||||||
|
|
@ -7,8 +8,9 @@ color = 080808 9e9e9e
|
||||||
[colors]
|
[colors]
|
||||||
foreground = b2b2b2
|
foreground = b2b2b2
|
||||||
background = 080808
|
background = 080808
|
||||||
selection-foreground = 080808
|
|
||||||
selection-background = b2ceee
|
# selection-foreground = 080808
|
||||||
|
# selection-background = b2ceee
|
||||||
|
|
||||||
regular0 = 323437
|
regular0 = 323437
|
||||||
regular1 = ff5454
|
regular1 = ff5454
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# nightfly
|
# nightfly
|
||||||
# Based on https://github.com/bluz71/vim-nightfly-guicolors
|
# Based on https://github.com/bluz71/vim-nightfly-guicolors
|
||||||
|
|
||||||
|
|
@ -7,8 +8,9 @@ color = 080808 9ca1aa
|
||||||
[colors]
|
[colors]
|
||||||
foreground = acb4c2
|
foreground = acb4c2
|
||||||
background = 011627
|
background = 011627
|
||||||
selection-foreground = 080808
|
|
||||||
selection-background = b2ceee
|
# selection-foreground = 080808
|
||||||
|
# selection-background = b2ceee
|
||||||
|
|
||||||
regular0 = 1d3b53
|
regular0 = 1d3b53
|
||||||
regular1 = fc514e
|
regular1 = fc514e
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Nord
|
# theme: Nord
|
||||||
# author: Arctic Ice Studio <development@arcticicestudio.com>, Sven Greb <code@svengreb.de>
|
# author: Arctic Ice Studio <development@arcticicestudio.com>, Sven Greb <code@svengreb.de>
|
||||||
# description: „Nord“ — An arctic, north-bluish color palette
|
# description: „Nord“ — An arctic, north-bluish color palette
|
||||||
|
|
@ -11,8 +12,9 @@ color = 2e3440 d8dee9
|
||||||
[colors]
|
[colors]
|
||||||
foreground = d8dee9
|
foreground = d8dee9
|
||||||
background = 2e3440
|
background = 2e3440
|
||||||
#selection-foreground = d8dee9
|
|
||||||
#selection-background = 4c566a
|
# selection-foreground = d8dee9
|
||||||
|
# selection-background = 4c566a
|
||||||
|
|
||||||
regular0 = 3b4252
|
regular0 = 3b4252
|
||||||
regular1 = bf616a
|
regular1 = bf616a
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Nordiq
|
# Nordiq
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
27
themes/onedark
Normal file
27
themes/onedark
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# OneDark
|
||||||
|
# Palette based on the same theme from https://github.com/dexpota/kitty-themes
|
||||||
|
|
||||||
|
[cursor]
|
||||||
|
color=111111 cccccc
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
foreground=979eab
|
||||||
|
background=282c34
|
||||||
|
regular0=282c34 # black
|
||||||
|
regular1=e06c75 # red
|
||||||
|
regular2=98c379 # green
|
||||||
|
regular3=e5c07b # yellow
|
||||||
|
regular4=61afef # blue
|
||||||
|
regular5=be5046 # magenta
|
||||||
|
regular6=56b6c2 # cyan
|
||||||
|
regular7=979eab # white
|
||||||
|
bright0=393e48 # bright black
|
||||||
|
bright1=d19a66 # bright red
|
||||||
|
bright2=56b6c2 # bright green
|
||||||
|
bright3=e5c07b # bright yellow
|
||||||
|
bright4=61afef # bright blue
|
||||||
|
bright5=be5046 # bright magenta
|
||||||
|
bright6=56b6c2 # bright cyan
|
||||||
|
bright7=abb2bf # bright white
|
||||||
|
# selection-foreground=282c34
|
||||||
|
# selection-background=979eab
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
|
# -*- conf -*-
|
||||||
# PaperColorDark
|
# PaperColorDark
|
||||||
# Palette based on https://github.com/NLKNguyen/papercolor-theme
|
# Palette based on https://github.com/NLKNguyen/papercolor-theme
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
color=1c1c1c eeeeee
|
color=1c1c1c eeeeee
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
alpha=0.80
|
background=1c1c1c
|
||||||
background=1c1c1c
|
foreground=eeeeee
|
||||||
foreground=eeeeee
|
regular0=1c1c1c # black
|
||||||
regular0=1c1c1c # black
|
regular1=af005f # red
|
||||||
regular1=af005f # red
|
regular2=5faf00 # green
|
||||||
regular2=5faf00 # green
|
regular3=d7af5f # yellow
|
||||||
regular3=d7af5f # yellow
|
regular4=5fafd7 # blue
|
||||||
regular4=5fafd7 # blue
|
regular5=808080 # magenta
|
||||||
regular5=808080 # magenta
|
regular6=d7875f # cyan
|
||||||
regular6=d7875f # cyan
|
regular7=d0d0d0 # white
|
||||||
regular7=d0d0d0 # white
|
bright0=bcbcbc # bright black
|
||||||
bright0=bcbcbc # bright black
|
bright1=5faf5f # bright red
|
||||||
bright1=5faf5f # bright red
|
bright2=afd700 # bright green
|
||||||
bright2=afd700 # bright green
|
bright3=af87d7 # bright yellow
|
||||||
bright3=af87d7 # bright yellow
|
bright4=ffaf00 # bright blue
|
||||||
bright4=ffaf00 # bright blue
|
bright5=ff5faf # bright magenta
|
||||||
bright5=ff5faf # bright magenta
|
bright6=00afaf # bright cyan
|
||||||
bright6=00afaf # bright cyan
|
bright7=5f8787 # bright white
|
||||||
bright7=5f8787 # bright white
|
# selection-foreground=1c1c1c
|
||||||
#selection-foreground=1c1c1c
|
# selection-background=af87d7
|
||||||
#selection-background=af87d7
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
|
# -*- conf -*-
|
||||||
# PaperColor Light
|
# PaperColor Light
|
||||||
# Palette based on https://github.com/NLKNguyen/papercolor-theme
|
# Palette based on https://github.com/NLKNguyen/papercolor-theme
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
color=eeeeee 444444
|
color=eeeeee 444444
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
alpha=1.0
|
background=eeeeee
|
||||||
background=eeeeee
|
foreground=444444
|
||||||
foreground=444444
|
regular0=eeeeee # black
|
||||||
regular0=eeeeee # black
|
regular1=af0000 # red
|
||||||
regular1=af0000 # red
|
regular2=008700 # green
|
||||||
regular2=008700 # green
|
regular3=5f8700 # yellow
|
||||||
regular3=5f8700 # yellow
|
regular4=0087af # blue
|
||||||
regular4=0087af # blue
|
regular5=878787 # magenta
|
||||||
regular5=878787 # magenta
|
regular6=005f87 # cyan
|
||||||
regular6=005f87 # cyan
|
regular7=764e37 # white
|
||||||
regular7=764e37 # white
|
bright0=bcbcbc # bright black
|
||||||
bright0=bcbcbc # bright black
|
bright1=d70000 # bright red
|
||||||
bright1=d70000 # bright red
|
bright2=d70087 # bright green
|
||||||
bright2=d70087 # bright green
|
bright3=8700af # bright yellow
|
||||||
bright3=8700af # bright yellow
|
bright4=d75f00 # bright blue
|
||||||
bright4=d75f00 # bright blue
|
bright5=d75f00 # bright magenta
|
||||||
bright5=d75f00 # bright magenta
|
bright6=4c7a5d # bright cyan
|
||||||
bright6=4c7a5d # bright cyan
|
bright7=005faf # bright white
|
||||||
bright7=005faf # bright white
|
# selection-foreground=eeeeee
|
||||||
#selection-foreground=eeeeee
|
# selection-background=0087af
|
||||||
#selection-background=0087af
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: rezza
|
# theme: rezza
|
||||||
# author: Doug Whiteley (rezza)
|
# author: Doug Whiteley (rezza)
|
||||||
# original URL: http://metawire.org/~rezza/index.php
|
# original URL: http://metawire.org/~rezza/index.php
|
||||||
|
|
|
||||||
26
themes/rose-pine
Normal file
26
themes/rose-pine
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
# Rose-Piné
|
||||||
|
|
||||||
|
[cursor]
|
||||||
|
color=191724 e0def4
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
background=191724
|
||||||
|
foreground=e0def4
|
||||||
|
regular0=26233a # black
|
||||||
|
regular1=eb6f92 # red
|
||||||
|
regular2=31748f # green
|
||||||
|
regular3=f6c177 # yellow
|
||||||
|
regular4=9ccfd8 # blue
|
||||||
|
regular5=c4a7e7 # magenta
|
||||||
|
regular6=ebbcba # cyan
|
||||||
|
regular7=e0def4 # white
|
||||||
|
|
||||||
|
bright0=6e6a86 # bright black
|
||||||
|
bright1=eb6f92 # bright red
|
||||||
|
bright2=31748f # bright green
|
||||||
|
bright3=f6c177 # bright yellow
|
||||||
|
bright4=9ccfd8 # bright blue
|
||||||
|
bright5=c4a7e7 # bright magenta
|
||||||
|
bright6=ebbcba # bright cyan
|
||||||
|
bright7=e0def4 # bright white
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Selenized black
|
# Selenized black
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Selenized dark
|
# Selenized dark
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Selenized light
|
# Selenized light
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Selenized white
|
# Selenized white
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Solarized dark
|
# Solarized dark
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
@ -23,7 +24,7 @@ bright5= 6c71c4
|
||||||
bright6= 93a1a1
|
bright6= 93a1a1
|
||||||
bright7= fdf6e3
|
bright7= fdf6e3
|
||||||
|
|
||||||
## Enable if prefer solarized colors instead of inverterd fg/bg for
|
# Enable if prefer solarized colors instead of inverterd fg/bg for
|
||||||
## highlighting (mouse selection)
|
# highlighting (mouse selection)
|
||||||
# selection-foreground=93a1a1
|
# selection-foreground=93a1a1
|
||||||
# selection-background=073642
|
# selection-background=073642
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Solarized dark
|
# Solarized dark
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
@ -25,7 +26,7 @@ bright5= dc619d
|
||||||
bright6= 32c1b6
|
bright6= 32c1b6
|
||||||
bright7= ffffff
|
bright7= ffffff
|
||||||
|
|
||||||
## Enable if prefer solarized colors instead of inverterd fg/bg for
|
# Enable if prefer solarized colors instead of inverterd fg/bg for
|
||||||
## highlighting (mouse selection)
|
# highlighting (mouse selection)
|
||||||
# selection-foreground=93a1a1
|
# selection-foreground=93a1a1
|
||||||
# selection-background=073642
|
# selection-background=073642
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Solarized light
|
# Solarized light
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# Tango
|
# Tango
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Autumn
|
# theme: Tempus Autumn
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with a palette inspired by earthly colours (WCAG AA compliant)
|
# description: Dark theme with a palette inspired by earthly colours (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 958fdf
|
||||||
bright5 = ce7dc4
|
bright5 = ce7dc4
|
||||||
bright6 = 2fa6b7
|
bright6 = 2fa6b7
|
||||||
bright7 = a9a2a6
|
bright7 = a9a2a6
|
||||||
#selection-foreground = a8948a
|
# selection-foreground = a8948a
|
||||||
#selection-background = 36302a
|
# selection-background = 36302a
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Classic
|
# theme: Tempus Classic
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with warm hues (WCAG AA compliant)
|
# description: Dark theme with warm hues (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 8e9cc0
|
||||||
bright5 = d58888
|
bright5 = d58888
|
||||||
bright6 = 7aa880
|
bright6 = 7aa880
|
||||||
bright7 = aeadaf
|
bright7 = aeadaf
|
||||||
#selection-foreground = 949d9f
|
# selection-foreground = 949d9f
|
||||||
#selection-background = 312e30
|
# selection-background = 312e30
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Dawn
|
# theme: Tempus Dawn
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Light theme with a soft, slightly desaturated palette (WCAG AA compliant)
|
# description: Light theme with a soft, slightly desaturated palette (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 5c59b2
|
||||||
bright5 = 8e45a8
|
bright5 = 8e45a8
|
||||||
bright6 = 3f649c
|
bright6 = 3f649c
|
||||||
bright7 = eff0f2
|
bright7 = eff0f2
|
||||||
#selection-foreground = 676364
|
# selection-foreground = 676364
|
||||||
#selection-background = dee2e0
|
# selection-background = dee2e0
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Day
|
# theme: Tempus Day
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Light theme with warm colours (WCAG AA compliant)
|
# description: Light theme with warm colours (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 0f64c4
|
||||||
bright5 = 8050a7
|
bright5 = 8050a7
|
||||||
bright6 = 336c87
|
bright6 = 336c87
|
||||||
bright7 = f8f2e5
|
bright7 = f8f2e5
|
||||||
#selection-foreground = 68607d
|
# selection-foreground = 68607d
|
||||||
#selection-background = e7e3d7
|
# selection-background = e7e3d7
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Dusk
|
# theme: Tempus Dusk
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with a deep blue-ish, slightly desaturated palette (WCAG AA compliant)
|
# description: Dark theme with a deep blue-ish, slightly desaturated palette (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 9ca5de
|
||||||
bright5 = c69ac6
|
bright5 = c69ac6
|
||||||
bright6 = 8caeb6
|
bright6 = 8caeb6
|
||||||
bright7 = a2a8ba
|
bright7 = a2a8ba
|
||||||
#selection-foreground = a29899
|
# selection-foreground = a29899
|
||||||
#selection-background = 2c3150
|
# selection-background = 2c3150
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Fugit
|
# theme: Tempus Fugit
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Light, pleasant theme optimised for long writing/coding sessions (WCAG AA compliant)
|
# description: Light, pleasant theme optimised for long writing/coding sessions (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 485adf
|
||||||
bright5 = a234c0
|
bright5 = a234c0
|
||||||
bright6 = 00756a
|
bright6 = 00756a
|
||||||
bright7 = fff5f3
|
bright7 = fff5f3
|
||||||
#selection-foreground = 796271
|
# selection-foreground = 796271
|
||||||
#selection-background = efe6e4
|
# selection-background = efe6e4
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Future
|
# theme: Tempus Future
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with colours inspired by concept art of outer space (WCAG AAA compliant)
|
# description: Dark theme with colours inspired by concept art of outer space (WCAG AAA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 8ba7ea
|
||||||
bright5 = e08bd6
|
bright5 = e08bd6
|
||||||
bright6 = 2cbab6
|
bright6 = 2cbab6
|
||||||
bright7 = b4abac
|
bright7 = b4abac
|
||||||
#selection-foreground = a7a2c4
|
# selection-foreground = a7a2c4
|
||||||
#selection-background = 2b1329
|
# selection-background = 2b1329
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Night
|
# theme: Tempus Night
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: High contrast dark theme with bright colours (WCAG AAA compliant)
|
# description: High contrast dark theme with bright colours (WCAG AAA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 8cb4f0
|
||||||
bright5 = de99f0
|
bright5 = de99f0
|
||||||
bright6 = 00ca9a
|
bright6 = 00ca9a
|
||||||
bright7 = e0e0e0
|
bright7 = e0e0e0
|
||||||
#selection-foreground = c4bdaf
|
# selection-foreground = c4bdaf
|
||||||
#selection-background = 242536
|
# selection-background = 242536
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Past
|
# theme: Tempus Past
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Light theme inspired by old vaporwave concept art (WCAG AA compliant)
|
# description: Light theme inspired by old vaporwave concept art (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 5559bb
|
||||||
bright5 = b022a7
|
bright5 = b022a7
|
||||||
bright6 = 07707a
|
bright6 = 07707a
|
||||||
bright7 = f3f2f4
|
bright7 = f3f2f4
|
||||||
#selection-foreground = 80565d
|
# selection-foreground = 80565d
|
||||||
#selection-background = eae2de
|
# selection-background = eae2de
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Rift
|
# theme: Tempus Rift
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with a subdued palette on the green side of the spectrum (WCAG AA compliant)
|
# description: Dark theme with a subdued palette on the green side of the spectrum (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 56bdad
|
||||||
bright5 = cca0ba
|
bright5 = cca0ba
|
||||||
bright6 = 10c480
|
bright6 = 10c480
|
||||||
bright7 = bbbcbc
|
bright7 = bbbcbc
|
||||||
#selection-foreground = ab9aa9
|
# selection-foreground = ab9aa9
|
||||||
#selection-background = 283431
|
# selection-background = 283431
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Spring
|
# theme: Tempus Spring
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with a palette inspired by early spring colours (WCAG AA compliant)
|
# description: Dark theme with a palette inspired by early spring colours (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 70afef
|
||||||
bright5 = d095e2
|
bright5 = d095e2
|
||||||
bright6 = 3cbfaf
|
bright6 = 3cbfaf
|
||||||
bright7 = b5b8b7
|
bright7 = b5b8b7
|
||||||
#selection-foreground = 99afae
|
# selection-foreground = 99afae
|
||||||
#selection-background = 2a453d
|
# selection-background = 2a453d
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Summer
|
# theme: Tempus Summer
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with colours inspired by summer evenings by the sea (WCAG AA compliant)
|
# description: Dark theme with colours inspired by summer evenings by the sea (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 8599ef
|
||||||
bright5 = cc82d7
|
bright5 = cc82d7
|
||||||
bright6 = 2aacbf
|
bright6 = 2aacbf
|
||||||
bright7 = a0abae
|
bright7 = a0abae
|
||||||
#selection-foreground = 949cbf
|
# selection-foreground = 949cbf
|
||||||
#selection-background = 39304f
|
# selection-background = 39304f
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Tempest
|
# theme: Tempus Tempest
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: A green-scale, subtle theme for late night hackers (WCAG AAA compliant)
|
# description: A green-scale, subtle theme for late night hackers (WCAG AAA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 74e4cd
|
||||||
bright5 = d2d4aa
|
bright5 = d2d4aa
|
||||||
bright6 = 9bdfc4
|
bright6 = 9bdfc4
|
||||||
bright7 = b6e0ca
|
bright7 = b6e0ca
|
||||||
#selection-foreground = b0c8ca
|
# selection-foreground = b0c8ca
|
||||||
#selection-background = 323535
|
# selection-background = 323535
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Totus
|
# theme: Tempus Totus
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Light theme for prose or for coding in an open space (WCAG AAA compliant)
|
# description: Light theme for prose or for coding in an open space (WCAG AAA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 2d45b0
|
||||||
bright5 = 700dc9
|
bright5 = 700dc9
|
||||||
bright6 = 005289
|
bright6 = 005289
|
||||||
bright7 = ffffff
|
bright7 = ffffff
|
||||||
#selection-foreground = 5e4b4f
|
# selection-foreground = 5e4b4f
|
||||||
#selection-background = efefef
|
# selection-background = efefef
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Warp
|
# theme: Tempus Warp
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with a vibrant palette (WCAG AA compliant)
|
# description: Dark theme with a vibrant palette (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 8887f0
|
||||||
bright5 = d85cf2
|
bright5 = d85cf2
|
||||||
bright6 = 1da1af
|
bright6 = 1da1af
|
||||||
bright7 = a29fa0
|
bright7 = a29fa0
|
||||||
#selection-foreground = 968282
|
# selection-foreground = 968282
|
||||||
#selection-background = 261c2c
|
# selection-background = 261c2c
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# theme: Tempus Winter
|
# theme: Tempus Winter
|
||||||
# author: Protesilaos Stavrou (https://protesilaos.com)
|
# author: Protesilaos Stavrou (https://protesilaos.com)
|
||||||
# description: Dark theme with a palette inspired by winter nights at the city (WCAG AA compliant)
|
# description: Dark theme with a palette inspired by winter nights at the city (WCAG AA compliant)
|
||||||
|
|
@ -24,5 +25,5 @@ bright4 = 329fcb
|
||||||
bright5 = ca77c5
|
bright5 = ca77c5
|
||||||
bright6 = 1ba6a4
|
bright6 = 1ba6a4
|
||||||
bright7 = 8da3b8
|
bright7 = 8da3b8
|
||||||
#selection-foreground = 91959b
|
# selection-foreground = 91959b
|
||||||
#selection-background = 2a2e38
|
# selection-background = 2a2e38
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
background=e1e2e7
|
background=e1e2e7
|
||||||
foreground=3760bf
|
foreground=3760bf
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
background=1a1b26
|
background=1a1b26
|
||||||
foreground=c0caf5
|
foreground=c0caf5
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
background=24283b
|
background=24283b
|
||||||
foreground=c0caf5
|
foreground=c0caf5
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- conf -*-
|
||||||
# VisiBone
|
# VisiBone
|
||||||
|
|
||||||
[cursor]
|
[cursor]
|
||||||
|
|
|
||||||
25
themes/zenburn
Normal file
25
themes/zenburn
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
foreground=dcdccc
|
||||||
|
background=111111
|
||||||
|
|
||||||
|
## Normal/regular colors (color palette 0-7)
|
||||||
|
regular0=222222 # black
|
||||||
|
regular1=cc9393 # red
|
||||||
|
regular2=7f9f7f # green
|
||||||
|
regular3=d0bf8f # yellow
|
||||||
|
regular4=6ca0a3 # blue
|
||||||
|
regular5=dc8cc3 # magenta
|
||||||
|
regular6=93e0e3 # cyan
|
||||||
|
regular7=dcdccc # white
|
||||||
|
|
||||||
|
## Bright colors (color palette 8-15)
|
||||||
|
bright0=666666 # bright black
|
||||||
|
bright1=dca3a3 # bright red
|
||||||
|
bright2=bfebbf # bright green
|
||||||
|
bright3=f0dfaf # bright yellow
|
||||||
|
bright4=8cd0d3 # bright blue
|
||||||
|
bright5=fcace3 # bright magenta
|
||||||
|
bright6=b3ffff # bright cyan
|
||||||
|
bright7=ffffff # bright white
|
||||||
2
uri.c
2
uri.c
|
|
@ -159,7 +159,7 @@ uri_parse(const char *uri, size_t len,
|
||||||
char *p = decoded;
|
char *p = decoded;
|
||||||
|
|
||||||
size_t encoded_len = path_len;
|
size_t encoded_len = path_len;
|
||||||
size_t decoded_len = 0;
|
size_t UNUSED decoded_len = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Find next '%' */
|
/* Find next '%' */
|
||||||
|
|
|
||||||
32
url-mode.c
32
url-mode.c
|
|
@ -746,15 +746,18 @@ tag_cells_for_url(struct terminal *term, const struct url *url, bool value)
|
||||||
if (url->url_mode_dont_change_url_attr)
|
if (url->url_mode_dont_change_url_attr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
struct grid *grid = term->url_grid_snapshot;
|
||||||
|
xassert(grid != NULL);
|
||||||
|
|
||||||
const struct coord *start = &url->range.start;
|
const struct coord *start = &url->range.start;
|
||||||
const struct coord *end = &url->range.end;
|
const struct coord *end = &url->range.end;
|
||||||
|
|
||||||
size_t end_r = end->row & (term->grid->num_rows - 1);
|
size_t end_r = end->row & (grid->num_rows - 1);
|
||||||
|
|
||||||
size_t r = start->row & (term->grid->num_rows - 1);
|
size_t r = start->row & (grid->num_rows - 1);
|
||||||
size_t c = start->col;
|
size_t c = start->col;
|
||||||
|
|
||||||
struct row *row = term->grid->rows[r];
|
struct row *row = grid->rows[r];
|
||||||
row->dirty = true;
|
row->dirty = true;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
@ -766,10 +769,10 @@ tag_cells_for_url(struct terminal *term, const struct url *url, bool value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (++c >= term->cols) {
|
if (++c >= term->cols) {
|
||||||
r = (r + 1) & (term->grid->num_rows - 1);
|
r = (r + 1) & (grid->num_rows - 1);
|
||||||
c = 0;
|
c = 0;
|
||||||
|
|
||||||
row = term->grid->rows[r];
|
row = grid->rows[r];
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
/* Un-allocated scrollback. This most likely means a
|
/* Un-allocated scrollback. This most likely means a
|
||||||
* runaway OSC-8 URL. */
|
* runaway OSC-8 URL. */
|
||||||
|
|
@ -788,15 +791,6 @@ urls_render(struct terminal *term)
|
||||||
if (tll_length(win->term->urls) == 0)
|
if (tll_length(win->term->urls) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xassert(tll_length(win->urls) == 0);
|
|
||||||
tll_foreach(win->term->urls, it) {
|
|
||||||
struct wl_url url = {.url = &it->item};
|
|
||||||
wayl_win_subsurface_new(win, &url.surf, false);
|
|
||||||
|
|
||||||
tll_push_back(win->urls, url);
|
|
||||||
tag_cells_for_url(term, &it->item, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dirty the last cursor, to ensure it is erased */
|
/* Dirty the last cursor, to ensure it is erased */
|
||||||
{
|
{
|
||||||
struct row *cursor_row = term->render.last_cursor.row;
|
struct row *cursor_row = term->render.last_cursor.row;
|
||||||
|
|
@ -819,6 +813,15 @@ urls_render(struct terminal *term)
|
||||||
/* Snapshot the current grid */
|
/* Snapshot the current grid */
|
||||||
term->url_grid_snapshot = grid_snapshot(term->grid);
|
term->url_grid_snapshot = grid_snapshot(term->grid);
|
||||||
|
|
||||||
|
xassert(tll_length(win->urls) == 0);
|
||||||
|
tll_foreach(win->term->urls, it) {
|
||||||
|
struct wl_url url = {.url = &it->item};
|
||||||
|
wayl_win_subsurface_new(win, &url.surf, false);
|
||||||
|
|
||||||
|
tll_push_back(win->urls, url);
|
||||||
|
tag_cells_for_url(term, &it->item, true);
|
||||||
|
}
|
||||||
|
|
||||||
render_refresh_urls(term);
|
render_refresh_urls(term);
|
||||||
render_refresh(term);
|
render_refresh(term);
|
||||||
}
|
}
|
||||||
|
|
@ -860,7 +863,6 @@ urls_reset(struct terminal *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
tll_foreach(term->urls, it) {
|
tll_foreach(term->urls, it) {
|
||||||
tag_cells_for_url(term, &it->item, false);
|
|
||||||
url_destroy(&it->item);
|
url_destroy(&it->item);
|
||||||
tll_remove(term->urls, it);
|
tll_remove(term->urls, it);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
utils/meson.build
Normal file
1
utils/meson.build
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
executable('xtgettcap', 'xtgettcap.c')
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue