mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
Compare commits
58 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c291194a4e | ||
|
|
0bf193ef81 | ||
|
|
6fbb9b7d3b | ||
|
|
3a2eb80d83 | ||
|
|
e2a989785a | ||
|
|
b78cc92322 | ||
|
|
42e04c5c87 | ||
|
|
53e8fbbdec | ||
|
|
bb6968c284 | ||
|
|
41679e64a8 | ||
|
|
b3cb180e44 | ||
|
|
ee682abac8 | ||
|
|
6ab2e2d9eb | ||
|
|
bbebe0f330 | ||
|
|
cb1e152d99 | ||
|
|
ca278398b1 | ||
|
|
4cb17f5ae6 | ||
|
|
aa26676c43 | ||
|
|
1caba0d993 | ||
|
|
cf2b390f6e | ||
|
|
4e96780eef | ||
|
|
15ebc433ba | ||
|
|
6e533231b0 | ||
|
|
ac6d7660dd | ||
|
|
65bd79b77d | ||
|
|
55f8388694 | ||
|
|
be19ca2b20 | ||
|
|
fc9625678f | ||
|
|
c9abab0807 | ||
|
|
5cb8ff2e9c | ||
|
|
1fce0e69f5 | ||
|
|
9728ada028 | ||
|
|
143f220527 | ||
|
|
5ae4955e83 | ||
|
|
71de0c45bc | ||
|
|
19466a21d8 | ||
|
|
5587604469 | ||
|
|
82e75851e4 | ||
|
|
e114a5f02f | ||
|
|
b44a62724c | ||
|
|
dc5a921d2c | ||
|
|
612adda384 | ||
|
|
dbf18ba444 | ||
|
|
96605bf52f | ||
|
|
7ed36c1033 | ||
|
|
371837ef7b | ||
|
|
e308a4733e | ||
|
|
fd88c6c61c | ||
|
|
299186a654 | ||
|
|
bb314425ef | ||
|
|
e43ea3676f | ||
|
|
bd994eda1c | ||
|
|
fac3994154 | ||
|
|
80951ab7a6 | ||
|
|
1dfa86c93a | ||
|
|
44a674edb8 | ||
|
|
c34f063307 | ||
|
|
363477fa0d |
135 changed files with 1466 additions and 536 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# -*- yaml -*-
|
||||
|
||||
steps:
|
||||
- name: codespell
|
||||
- name: pychecks
|
||||
when:
|
||||
- event: [manual, pull_request]
|
||||
- event: [push, tag]
|
||||
|
|
@ -11,10 +11,15 @@ steps:
|
|||
- apk add openssl
|
||||
- apk add python3
|
||||
- apk add py3-pip
|
||||
- python3 -m venv codespell-venv
|
||||
- source codespell-venv/bin/activate
|
||||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- python -m pip install --upgrade pip
|
||||
- pip install codespell
|
||||
- codespell -Lser,doas,zar README.md INSTALL.md CHANGELOG.md *.c *.h doc/*.scd
|
||||
- pip install mypy
|
||||
- pip install ruff
|
||||
- codespell
|
||||
- mypy
|
||||
- ruff check
|
||||
- deactivate
|
||||
|
||||
- name: subprojects
|
||||
|
|
|
|||
122
CHANGELOG.md
122
CHANGELOG.md
|
|
@ -1,5 +1,7 @@
|
|||
# Changelog
|
||||
|
||||
* [Unreleased](#unreleased)
|
||||
* [1.25.0](#1-25-0)
|
||||
* [1.24.0](#1-24-0)
|
||||
* [1.23.1](#1-23-1)
|
||||
* [1.23.0](#1-23-0)
|
||||
|
|
@ -65,6 +67,126 @@
|
|||
* [1.2.0](#1-2-0)
|
||||
|
||||
|
||||
## Unreleased
|
||||
### Added
|
||||
|
||||
* `toplevel-tag` option (and `--toplevel-tag` command line options to
|
||||
`foot` and `footclient`), allowing you to set a custom toplevel
|
||||
tag. The compositor must implement the new `xdg-toplevel-tag-v1`
|
||||
Wayland protocol ([#2212][2212]).
|
||||
* `[colors-dark]` section to `foot.ini`. Replaces `[colors]`.
|
||||
* `[colors-light]` section to `foot.ini`. Replaces `[colors2]`.
|
||||
* `XTGETTCAP`: added `query-os-name`, returning the OS foot is
|
||||
compiled for (e.g. _'Linux'_) ([#2209][2209]).
|
||||
|
||||
[2212]: https://codeberg.org/dnkl/foot/issues/2212
|
||||
[2209]: https://codeberg.org/dnkl/foot/issues/2209
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
* When enabling _"focus mode"_ (private mode 1004), foot now sends a
|
||||
focus event immediately, to inform the application what the current
|
||||
state is ([#2202][2202]).
|
||||
* Scrollback search is now case sensitive when the search string
|
||||
contains at least one upper case character.
|
||||
* Mouse tracking in SGR pixel mode no longer emits negative column/row
|
||||
pixel values ([#2226][2226]).
|
||||
* Foot now always uses ARGB SHM surfaces. In earlier versions, XRGB
|
||||
surfaces were used for opaque surfaces. Unfortunately, several
|
||||
compositors had issues when foot switched between ARGB and XRGB
|
||||
surfaces (for example when switching color theme, or toggling
|
||||
fullscreen).
|
||||
|
||||
[2202]: https://codeberg.org/dnkl/foot/issues/2202
|
||||
[2226]: https://codeberg.org/dnkl/foot/issues/2226
|
||||
|
||||
|
||||
### Deprecated
|
||||
|
||||
* `[colors]` section in `foot.ini`. Use `[colors-dark]` instead.
|
||||
* `[colors2]` section in `foot.ini`. Use `[colors-light]` instead.
|
||||
|
||||
|
||||
### Removed
|
||||
|
||||
* `cursor.color` config option (deprecated in 1.23.0). Use
|
||||
`colors-{dark,light}.cursor` instead.
|
||||
|
||||
|
||||
### Fixed
|
||||
|
||||
* Search mode: composing keys not ignored.
|
||||
* Crash when triple-clicking a soft-wrapped line and there is a quote
|
||||
character in the last column.
|
||||
* Crash when reverse-scrolling (terminfo capability `rin`) such that
|
||||
the current viewport ends up outside the scrollback ([#2232][2232]).
|
||||
* Regression: visual glitches in rare circumstances.
|
||||
* Key release events for shortcuts being sent to the client
|
||||
application (kitty keyboard protocol only) ([#2257][2257]).
|
||||
* Crash when application emits sixel RA with a height of 0, a width >
|
||||
0, and then starts writing sixel data ([#2267][2267]).
|
||||
* Crash if shutting down terminal instance while a "pre-apply damage"
|
||||
thread is running ([#2263][2263]).
|
||||
|
||||
[2232]: https://codeberg.org/dnkl/foot/issues/2232
|
||||
[2257]: https://codeberg.org/dnkl/foot/issues/2257
|
||||
[2267]: https://codeberg.org/dnkl/foot/issues/2267
|
||||
[2263]: https://codeberg.org/dnkl/foot/issues/2263
|
||||
|
||||
|
||||
### Security
|
||||
### Contributors
|
||||
|
||||
|
||||
## 1.25.0
|
||||
|
||||
### Added
|
||||
|
||||
* Performance increased and input latency decreased on compositors
|
||||
that do not release SHM buffers immediately ([#2188][2188]).
|
||||
* `colors{,2}.dim-blend-towards=black|white` option, allowing you to
|
||||
select towards which color to blend when dimming text. Defaults to
|
||||
`black` in `[colors]`, and `white` in `[colors2]` ([#2187][2187]).
|
||||
|
||||
[2188]: https://codeberg.org/dnkl/foot/issues/2188
|
||||
[2187]: https://codeberg.org/dnkl/foot/issues/2187
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
* SHM buffer sizes are now rounded up to nearest page size, and their
|
||||
stride is always an even multiple of 256 bytes (by default,
|
||||
configurable by setting `tweak.min-stride-alignment`). This allows
|
||||
compositor to directly import foot's SHM buffers to the GPU, with
|
||||
e.g. integrated graphics ([#2182][2182]).
|
||||
* Jump label colors in the modus-operandi theme, for improved
|
||||
readability.
|
||||
|
||||
[2182]: https://codeberg.org/dnkl/foot/issues/2182
|
||||
|
||||
|
||||
### Fixed
|
||||
|
||||
* URL labels misplaces when URL contains double-width characters
|
||||
([#2179][2179]).
|
||||
* One space too much consumed when copying (or pipe:ing) contents with
|
||||
tabs ([#2194][2194])
|
||||
* Ensure we render a new frame when changing fullscreen state. Before,
|
||||
this was automatically done if the window was also resized. But, it
|
||||
is possible for a compositor to change an application's fullscreen
|
||||
state without resizing the window.
|
||||
|
||||
[2179]: https://codeberg.org/dnkl/foot/issues/2179
|
||||
[2194]: https://codeberg.org/dnkl/foot/issues/2194
|
||||
|
||||
|
||||
### Contributors
|
||||
|
||||
* Charalampos Mitrodimas
|
||||
* Matthias Heyman
|
||||
|
||||
|
||||
## 1.24.0
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ decisions when appropriate.
|
|||
Participants in the foot community are expected to uphold the described
|
||||
standards not only in official community spaces (issue trackers, IRC channels,
|
||||
etc.) but in all public spaces. The Code of Conduct however does acknowledge
|
||||
that people are fallible and that it is possible to truely correct a past
|
||||
that people are fallible and that it is possible to truly correct a past
|
||||
pattern of unacceptable behavior. That is to say, the scope of the Code of
|
||||
Conduct does not necessarily extend into the distant past.
|
||||
|
||||
|
|
|
|||
|
|
@ -641,6 +641,10 @@ All replies are in `tigetstr()` format. That is, given the same
|
|||
capability name, foot's reply is identical to what `tigetstr()` would
|
||||
have returned.
|
||||
|
||||
In addition to queries for terminfo entries, the `query-os-name` query
|
||||
will be answered with a response of the form `uname=$(uname -s)`,
|
||||
where `$(uname -s)` is the name of the OS foot was compiled for.
|
||||
|
||||
|
||||
# Credits
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define LOG_MODULE "box-drawing"
|
||||
|
|
|
|||
22
char32.c
22
char32.c
|
|
@ -53,6 +53,14 @@ UNITTEST
|
|||
xassert(c32cmp(U"b", U"a") > 0);
|
||||
}
|
||||
|
||||
UNITTEST
|
||||
{
|
||||
xassert(c32ncmp(U"foo", U"foot", 3) == 0);
|
||||
xassert(c32ncmp(U"foot", U"FOOT", 4) > 0);
|
||||
xassert(c32ncmp(U"a", U"b", 1) < 0);
|
||||
xassert(c32ncmp(U"bb", U"aa", 2) > 0);
|
||||
}
|
||||
|
||||
UNITTEST
|
||||
{
|
||||
char32_t copy[16];
|
||||
|
|
@ -127,6 +135,20 @@ UNITTEST
|
|||
xassert(c32cmp(dst, U"foobar12345678") == 0);
|
||||
}
|
||||
|
||||
UNITTEST
|
||||
{
|
||||
xassert(!isc32upper(U'a'));
|
||||
xassert(isc32upper(U'A'));
|
||||
xassert(!isc32upper(U'a'));
|
||||
}
|
||||
|
||||
UNITTEST
|
||||
{
|
||||
xassert(hasc32upper(U"abc1A"));
|
||||
xassert(!hasc32upper(U"abc1_aaa"));
|
||||
xassert(!hasc32upper(U""));
|
||||
}
|
||||
|
||||
UNITTEST
|
||||
{
|
||||
char32_t *c = xc32dup(U"foobar");
|
||||
|
|
|
|||
15
char32.h
15
char32.h
|
|
@ -20,6 +20,10 @@ static inline int c32cmp(const char32_t *s1, const char32_t *s2) {
|
|||
return wcscmp((const wchar_t *)s1, (const wchar_t *)s2);
|
||||
}
|
||||
|
||||
static inline int c32ncmp(const char32_t *s1, const char32_t *s2, size_t n) {
|
||||
return wcsncmp((const wchar_t *)s1, (const wchar_t *)s2, n);
|
||||
}
|
||||
|
||||
static inline char32_t *c32ncpy(char32_t *dst, const char32_t *src, size_t n) {
|
||||
return (char32_t *)wcsncpy((wchar_t *)dst, (const wchar_t *)src, n);
|
||||
}
|
||||
|
|
@ -60,6 +64,10 @@ static inline char32_t toc32upper(char32_t c) {
|
|||
return (char32_t)towupper((wint_t)c);
|
||||
}
|
||||
|
||||
static inline bool isc32upper(char32_t c32) {
|
||||
return iswupper((wint_t)c32);
|
||||
}
|
||||
|
||||
static inline bool isc32space(char32_t c32) {
|
||||
return iswspace((wint_t)c32);
|
||||
}
|
||||
|
|
@ -72,6 +80,13 @@ static inline bool isc32graph(char32_t c32) {
|
|||
return iswgraph((wint_t)c32);
|
||||
}
|
||||
|
||||
static inline bool hasc32upper(const char32_t *s) {
|
||||
for (int i = 0; s[i] != '\0'; i++) {
|
||||
if (isc32upper(s[i])) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int c32width(char32_t c) {
|
||||
#if defined(FOOT_GRAPHEME_CLUSTERING)
|
||||
return utf8proc_charwidth((utf8proc_int32_t)c);
|
||||
|
|
|
|||
29
client.c
29
client.c
|
|
@ -1,12 +1,13 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
|
@ -76,6 +77,7 @@ print_usage(const char *prog_name)
|
|||
" -t,--term=TERM value to set the environment variable TERM to (" FOOT_DEFAULT_TERM ")\n"
|
||||
" -T,--title=TITLE initial window title (foot)\n"
|
||||
" -a,--app-id=ID window application ID (foot)\n"
|
||||
" --toplevel-tag=TAG set a custom toplevel tag\n"
|
||||
" -w,--window-size-pixels=WIDTHxHEIGHT initial width and height, in pixels\n"
|
||||
" -W,--window-size-chars=WIDTHxHEIGHT initial width and height, in characters\n"
|
||||
" -m,--maximized start in maximized mode\n"
|
||||
|
|
@ -137,6 +139,10 @@ send_string_list(int fd, const string_list_t *string_list)
|
|||
return true;
|
||||
}
|
||||
|
||||
enum {
|
||||
TOPLEVEL_TAG_OPTION = CHAR_MAX + 1,
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *const *argv)
|
||||
{
|
||||
|
|
@ -151,6 +157,7 @@ main(int argc, char *const *argv)
|
|||
{"term", required_argument, NULL, 't'},
|
||||
{"title", required_argument, NULL, 'T'},
|
||||
{"app-id", required_argument, NULL, 'a'},
|
||||
{"toplevel-tag", required_argument, NULL, TOPLEVEL_TAG_OPTION},
|
||||
{"window-size-pixels", required_argument, NULL, 'w'},
|
||||
{"window-size-chars", required_argument, NULL, 'W'},
|
||||
{"maximized", no_argument, NULL, 'm'},
|
||||
|
|
@ -220,6 +227,12 @@ main(int argc, char *const *argv)
|
|||
goto err;
|
||||
break;
|
||||
|
||||
case TOPLEVEL_TAG_OPTION:
|
||||
snprintf(buf, sizeof(buf), "toplevel-tag=%s", optarg);
|
||||
if (!push_string(&overrides, buf, &total_len))
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
if (!push_string(&overrides, "login-shell=yes", &total_len))
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ _foot()
|
|||
local cur prev flags word commands match previous_words i offset
|
||||
flags=(
|
||||
"--app-id"
|
||||
"--toplevel-tag"
|
||||
"--check-config"
|
||||
"--config"
|
||||
"--font"
|
||||
|
|
@ -40,7 +41,7 @@ _foot()
|
|||
for word in "${previous_words[@]}" ; do
|
||||
match=$(printf "$commands" | grep -Fx "$word" 2>/dev/null)
|
||||
if [[ ! -z "$match" ]] ; then
|
||||
if [[ ${COMP_WORDS[i-1]} =~ ^(--app-id|--config|--font|--log-level|--pty|--term|--title|--window-size-pixels|--window-size-chars|--working-directory)$ ]] ; then
|
||||
if [[ ${COMP_WORDS[i-1]} =~ ^(--app-id|--toplevel-tag|--config|--font|--log-level|--pty|--term|--title|--window-size-pixels|--window-size-chars|--working-directory)$ ]] ; then
|
||||
(( i++ ))
|
||||
continue
|
||||
fi
|
||||
|
|
@ -75,7 +76,7 @@ _foot()
|
|||
COMPREPLY=( $(compgen -W "none error warning info" -- ${cur}) ) ;;
|
||||
--log-colorize|-l)
|
||||
COMPREPLY=( $(compgen -W "never always auto" -- ${cur}) ) ;;
|
||||
--app-id|--help|--override|--pty|--title|--version|--window-size-chars|--window-size-pixels|--check-config|-[ahoTvWwC])
|
||||
--app-id|--toplevel-tag|--help|--override|--pty|--title|--version|--window-size-chars|--window-size-pixels|--check-config|-[ahoTvWwC])
|
||||
# Don't autocomplete for these flags
|
||||
: ;;
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ _footclient()
|
|||
local cur prev flags word commands match previous_words i offset
|
||||
flags=(
|
||||
"--app-id"
|
||||
"--toplevel-tag"
|
||||
"--fullscreen"
|
||||
"--help"
|
||||
"--hold"
|
||||
|
|
@ -35,7 +36,7 @@ _footclient()
|
|||
for word in "${previous_words[@]}" ; do
|
||||
match=$(printf "$commands" | grep -Fx "$word" 2>/dev/null)
|
||||
if [[ ! -z "$match" ]] ; then
|
||||
if [[ ${COMP_WORDS[i-1]} =~ ^(--app-id|--log-level|--server-socket|--term|--title|--window-size-pixels|--window-size-chars|--working-directory)$ ]] ; then
|
||||
if [[ ${COMP_WORDS[i-1]} =~ ^(--app-id|--toplevel-tag|--log-level|--server-socket|--term|--title|--window-size-pixels|--window-size-chars|--working-directory)$ ]] ; then
|
||||
(( i++ ))
|
||||
continue
|
||||
fi
|
||||
|
|
@ -67,7 +68,7 @@ _footclient()
|
|||
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])
|
||||
--app-id|--toplevel-tag|--help|--override|--title|--version|--window-size-chars|--window-size-pixels|-[ahoTvWw])
|
||||
# Don't autocomplete for these flags
|
||||
: ;;
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ complete -c foot -x -s f -l font -a "(fc-list : family | sed 's/,/
|
|||
complete -c foot -x -s t -l term -a '(find /usr/share/terminfo -type f -printf "%f\n")' -d "value to set the environment variable TERM to (foot)"
|
||||
complete -c foot -x -s T -l title -d "initial window title"
|
||||
complete -c foot -x -s a -l app-id -d "value to set the app-id property on the Wayland window to (foot)"
|
||||
complete -c foot -x -l toplevel-tag -d "value to set the toplevel-tag property on the Wayland window to"
|
||||
complete -c foot -s m -l maximized -d "start in maximized mode"
|
||||
complete -c foot -s F -l fullscreen -d "start in fullscreen mode"
|
||||
complete -c foot -s L -l login-shell -d "start shell as a login shell"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ complete -c footclient -x -a "(__fish_complete_subcom
|
|||
complete -c footclient -x -s t -l term -a '(find /usr/share/terminfo -type f -printf "%f\n")' -d "value to set the environment variable TERM to (foot)"
|
||||
complete -c footclient -x -s T -l title -d "initial window title"
|
||||
complete -c footclient -x -s a -l app-id -d "value to set the app-id property on the Wayland window to (foot)"
|
||||
complete -c footclient -x -l toplevel-tag -d "value to set the toplevel-tag property on the Wayland window to"
|
||||
complete -c footclient -s m -l maximized -d "start in maximized mode"
|
||||
complete -c footclient -s F -l fullscreen -d "start in fullscreen mode"
|
||||
complete -c footclient -s L -l login-shell -d "start shell as a login shell"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ _arguments \
|
|||
'(-t --term)'{-t,--term}'[value to set the environment variable TERM to (foot)]:term:->terms' \
|
||||
'(-T --title)'{-T,--title}'[initial window title]:()' \
|
||||
'(-a --app-id)'{-a,--app-id}'[value to set the app-id property on the Wayland window to (foot)]:()' \
|
||||
'--toplevel-tag=[value to set the toplevel-tag property on the Wayland window to]:()' \
|
||||
'(-m --maximized)'{-m,--maximized}'[start in maximized mode]' \
|
||||
'(-F --fullscreen)'{-F,--fullscreen}'[start in fullscreen mode]' \
|
||||
'(-L --login-shell)'{-L,--login-shell}'[start shell as a login shell]' \
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ _arguments \
|
|||
'(-t --term)'{-t,--term}'[value to set the environment variable TERM to (foot)]:term:->terms' \
|
||||
'(-T --title)'{-T,--title}'[initial window title]:()' \
|
||||
'(-a --app-id)'{-a,--app-id}'[value to set the app-id property on the Wayland window to (foot)]:()' \
|
||||
'--toplevel-tag=[value to set the toplevel-tag property on the Wayland window to]:()' \
|
||||
'(-m --maximized)'{-m,--maximized}'[start in maximized mode]' \
|
||||
'(-F --fullscreen)'{-F,--fullscreen}'[start in fullscreen mode]' \
|
||||
'(-L --login-shell)'{-L,--login-shell}'[start shell as a login shell]' \
|
||||
|
|
|
|||
171
config.c
171
config.c
|
|
@ -144,6 +144,8 @@ static const char *const binding_action_map[] = {
|
|||
[BIND_ACTION_REGEX_COPY] = "regex-copy",
|
||||
[BIND_ACTION_THEME_SWITCH_1] = "color-theme-switch-1",
|
||||
[BIND_ACTION_THEME_SWITCH_2] = "color-theme-switch-2",
|
||||
[BIND_ACTION_THEME_SWITCH_DARK] = "color-theme-switch-dark",
|
||||
[BIND_ACTION_THEME_SWITCH_LIGHT] = "color-theme-switch-light",
|
||||
[BIND_ACTION_THEME_TOGGLE] = "color-theme-toggle",
|
||||
|
||||
/* Mouse-specific actions */
|
||||
|
|
@ -923,6 +925,9 @@ parse_section_main(struct context *ctx)
|
|||
else if (streq(key, "app-id"))
|
||||
return value_to_str(ctx, &conf->app_id);
|
||||
|
||||
else if (streq(key, "toplevel-tag"))
|
||||
return value_to_str(ctx, &conf->toplevel_tag);
|
||||
|
||||
else if (streq(key, "initial-window-size-pixels")) {
|
||||
if (!value_to_dimensions(ctx, &conf->size.width, &conf->size.height))
|
||||
return false;
|
||||
|
|
@ -1115,8 +1120,40 @@ parse_section_main(struct context *ctx)
|
|||
sizeof(conf->initial_color_theme) == sizeof(int),
|
||||
"enum is not 32-bit");
|
||||
|
||||
return value_to_enum(ctx, (const char*[]){"1", "2", NULL},
|
||||
(int *)&conf->initial_color_theme);
|
||||
if (!value_to_enum(ctx, (const char*[]){
|
||||
"dark", "light", "1", "2", NULL},
|
||||
(int *)&conf->initial_color_theme))
|
||||
return false;
|
||||
|
||||
if (streq(ctx->value, "1")) {
|
||||
LOG_WARN("%s:%d: [main].initial-color-theme=1 deprecated, "
|
||||
"use [main].initial-color-theme=dark instead",
|
||||
ctx->path, ctx->lineno);
|
||||
|
||||
user_notification_add(
|
||||
&ctx->conf->notifications,
|
||||
USER_NOTIFICATION_DEPRECATED,
|
||||
xstrdup("[main].initial-color-theme=1: "
|
||||
"use [main].initial-color-theme=dark instead"));
|
||||
|
||||
conf->initial_color_theme = COLOR_THEME_DARK;
|
||||
}
|
||||
|
||||
else if (streq(ctx->value, "2")) {
|
||||
LOG_WARN("%s:%d: [main].initial-color-theme=2 deprecated, "
|
||||
"use [main].initial-color-theme=light instead",
|
||||
ctx->path, ctx->lineno);
|
||||
|
||||
user_notification_add(
|
||||
&ctx->conf->notifications,
|
||||
USER_NOTIFICATION_DEPRECATED,
|
||||
xstrdup("[main].initial-color-theme=2: "
|
||||
"use [main].initial-color-theme=light instead"));
|
||||
|
||||
conf->initial_color_theme = COLOR_THEME_LIGHT;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
else if (streq(key, "uppercase-regex-insert"))
|
||||
|
|
@ -1519,7 +1556,7 @@ parse_color_theme(struct context *ctx, struct color_theme *theme)
|
|||
return true;
|
||||
}
|
||||
|
||||
else if (strcmp(key, "alpha-mode") == 0) {
|
||||
else if (streq(key, "alpha-mode")) {
|
||||
_Static_assert(sizeof(theme->alpha_mode) == sizeof(int),
|
||||
"enum is not 32-bit");
|
||||
|
||||
|
|
@ -1529,6 +1566,16 @@ parse_color_theme(struct context *ctx, struct color_theme *theme)
|
|||
(int *)&theme->alpha_mode);
|
||||
}
|
||||
|
||||
else if (streq(key, "dim-blend-towards")) {
|
||||
_Static_assert(sizeof(theme->dim_blend_towards) == sizeof(int),
|
||||
"enum is not 32-bit");
|
||||
|
||||
return value_to_enum(
|
||||
ctx,
|
||||
(const char *[]){"black", "white", NULL},
|
||||
(int *)&theme->dim_blend_towards);
|
||||
}
|
||||
|
||||
else {
|
||||
LOG_CONTEXTUAL_ERR("not valid option");
|
||||
return false;
|
||||
|
|
@ -1542,16 +1589,44 @@ parse_color_theme(struct context *ctx, struct color_theme *theme)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_section_colors_dark(struct context *ctx)
|
||||
{
|
||||
return parse_color_theme(ctx, &ctx->conf->colors_dark);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_section_colors_light(struct context *ctx)
|
||||
{
|
||||
return parse_color_theme(ctx, &ctx->conf->colors_light);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_section_colors(struct context *ctx)
|
||||
{
|
||||
return parse_color_theme(ctx, &ctx->conf->colors);
|
||||
LOG_WARN("%s:%d: [colors]: deprecated; use [colors-dark] instead",
|
||||
ctx->path, ctx->lineno);
|
||||
|
||||
user_notification_add(
|
||||
&ctx->conf->notifications,
|
||||
USER_NOTIFICATION_DEPRECATED,
|
||||
xstrdup("[colors]: use [colors-dark] instead"));
|
||||
|
||||
return parse_color_theme(ctx, &ctx->conf->colors_dark);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_section_colors2(struct context *ctx)
|
||||
{
|
||||
return parse_color_theme(ctx, &ctx->conf->colors2);
|
||||
LOG_WARN("%s:%d: [colors2]: deprecated; use [colors-light] instead",
|
||||
ctx->path, ctx->lineno);
|
||||
|
||||
user_notification_add(
|
||||
&ctx->conf->notifications,
|
||||
USER_NOTIFICATION_DEPRECATED,
|
||||
xstrdup("[colors2]: use [colors-light] instead"));
|
||||
|
||||
return parse_color_theme(ctx, &ctx->conf->colors_light);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1586,28 +1661,6 @@ parse_section_cursor(struct context *ctx)
|
|||
else if (streq(key, "blink-rate"))
|
||||
return value_to_uint32(ctx, 10, &conf->cursor.blink.rate_ms);
|
||||
|
||||
else if (streq(key, "color")) {
|
||||
LOG_WARN("%s:%d: cursor.color: deprecated; use colors.cursor instead",
|
||||
ctx->path, ctx->lineno);
|
||||
|
||||
user_notification_add(
|
||||
&conf->notifications,
|
||||
USER_NOTIFICATION_DEPRECATED,
|
||||
xstrdup("cursor.color: use colors.cursor instead"));
|
||||
|
||||
if (!value_to_two_colors(
|
||||
ctx,
|
||||
&conf->colors.cursor.text,
|
||||
&conf->colors.cursor.cursor,
|
||||
false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
conf->colors.use_custom.cursor = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
else if (streq(key, "beam-thickness"))
|
||||
return value_to_pt_or_px(ctx, &conf->cursor.beam_thickness);
|
||||
|
||||
|
|
@ -2255,6 +2308,29 @@ parse_key_binding_section(struct context *ctx,
|
|||
aux.regex_name = regex_name;
|
||||
}
|
||||
|
||||
if (action_map == binding_action_map &&
|
||||
action >= BIND_ACTION_THEME_SWITCH_1 &&
|
||||
action <= BIND_ACTION_THEME_SWITCH_2)
|
||||
{
|
||||
const char *use_instead =
|
||||
action_map[action == BIND_ACTION_THEME_SWITCH_1
|
||||
? BIND_ACTION_THEME_SWITCH_DARK
|
||||
: BIND_ACTION_THEME_SWITCH_LIGHT];
|
||||
|
||||
const char *notif = action == BIND_ACTION_THEME_SWITCH_1
|
||||
? "[key-bindings].color-theme-switch-1: use [key-bindings].color-theme-switch-dark instead"
|
||||
: "[key-bindings].color-theme-switch-2: use [key-bindings].color-theme-switch-light instead";
|
||||
|
||||
LOG_WARN("%s:%d: [key-bindings].%s: deprecated, use %s instead",
|
||||
ctx->path, ctx->lineno,
|
||||
action_map[action], use_instead);
|
||||
|
||||
user_notification_add(
|
||||
&ctx->conf->notifications,
|
||||
USER_NOTIFICATION_DEPRECATED,
|
||||
xstrdup(notif));
|
||||
}
|
||||
|
||||
if (!value_to_key_combos(ctx, action, &aux, bindings, KEY_BINDING)) {
|
||||
free_binding_aux(&aux);
|
||||
return false;
|
||||
|
|
@ -2848,6 +2924,12 @@ parse_section_tweak(struct context *ctx)
|
|||
#endif
|
||||
}
|
||||
|
||||
else if (streq(key, "min-stride-alignment"))
|
||||
return value_to_uint32(ctx, 10, &conf->tweak.min_stride_alignment);
|
||||
|
||||
else if (streq(key, "pre-apply-damage"))
|
||||
return value_to_bool(ctx, &conf->tweak.preapply_damage);
|
||||
|
||||
else {
|
||||
LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
|
||||
return false;
|
||||
|
|
@ -2939,8 +3021,8 @@ enum section {
|
|||
SECTION_SCROLLBACK,
|
||||
SECTION_URL,
|
||||
SECTION_REGEX,
|
||||
SECTION_COLORS,
|
||||
SECTION_COLORS2,
|
||||
SECTION_COLORS_DARK,
|
||||
SECTION_COLORS_LIGHT,
|
||||
SECTION_CURSOR,
|
||||
SECTION_MOUSE,
|
||||
SECTION_CSD,
|
||||
|
|
@ -2952,6 +3034,11 @@ enum section {
|
|||
SECTION_ENVIRONMENT,
|
||||
SECTION_TWEAK,
|
||||
SECTION_TOUCH,
|
||||
|
||||
/* Deprecated */
|
||||
SECTION_COLORS,
|
||||
SECTION_COLORS2,
|
||||
|
||||
SECTION_COUNT,
|
||||
};
|
||||
|
||||
|
|
@ -2970,8 +3057,8 @@ static const struct {
|
|||
[SECTION_SCROLLBACK] = {&parse_section_scrollback, "scrollback"},
|
||||
[SECTION_URL] = {&parse_section_url, "url"},
|
||||
[SECTION_REGEX] = {&parse_section_regex, "regex", true},
|
||||
[SECTION_COLORS] = {&parse_section_colors, "colors"},
|
||||
[SECTION_COLORS2] = {&parse_section_colors2, "colors2"},
|
||||
[SECTION_COLORS_DARK] = {&parse_section_colors_dark, "colors-dark"},
|
||||
[SECTION_COLORS_LIGHT] = {&parse_section_colors_light, "colors-light"},
|
||||
[SECTION_CURSOR] = {&parse_section_cursor, "cursor"},
|
||||
[SECTION_MOUSE] = {&parse_section_mouse, "mouse"},
|
||||
[SECTION_CSD] = {&parse_section_csd, "csd"},
|
||||
|
|
@ -2983,6 +3070,10 @@ static const struct {
|
|||
[SECTION_ENVIRONMENT] = {&parse_section_environment, "environment"},
|
||||
[SECTION_TWEAK] = {&parse_section_tweak, "tweak"},
|
||||
[SECTION_TOUCH] = {&parse_section_touch, "touch"},
|
||||
|
||||
/* Deprecated */
|
||||
[SECTION_COLORS] = {&parse_section_colors, "colors"},
|
||||
[SECTION_COLORS2] = {&parse_section_colors2, "colors2"},
|
||||
};
|
||||
|
||||
static_assert(ALEN(section_info) == SECTION_COUNT, "section info array size mismatch");
|
||||
|
|
@ -3355,6 +3446,7 @@ config_load(struct config *conf, const char *conf_path,
|
|||
.shell = get_shell(),
|
||||
.title = xstrdup("foot"),
|
||||
.app_id = (as_server ? xstrdup("footclient") : xstrdup("foot")),
|
||||
.toplevel_tag = xstrdup(""),
|
||||
.word_delimiters = xc32dup(U",│`|:\"'()[]{}<>"),
|
||||
.size = {
|
||||
.type = CONF_SIZE_PX,
|
||||
|
|
@ -3415,13 +3507,14 @@ config_load(struct config *conf, const char *conf_path,
|
|||
},
|
||||
.multiplier = 3.,
|
||||
},
|
||||
.colors = {
|
||||
.colors_dark = {
|
||||
.fg = default_foreground,
|
||||
.bg = default_background,
|
||||
.flash = 0x7f7f00,
|
||||
.flash_alpha = 0x7fff,
|
||||
.alpha = 0xffff,
|
||||
.alpha_mode = ALPHA_MODE_DEFAULT,
|
||||
.dim_blend_towards = DIM_BLEND_TOWARDS_BLACK,
|
||||
.selection_fg = 0x80000000, /* Use default bg */
|
||||
.selection_bg = 0x80000000, /* Use default fg */
|
||||
.cursor = {
|
||||
|
|
@ -3434,7 +3527,7 @@ config_load(struct config *conf, const char *conf_path,
|
|||
.url = false,
|
||||
},
|
||||
},
|
||||
.initial_color_theme = COLOR_THEME1,
|
||||
.initial_color_theme = COLOR_THEME_DARK,
|
||||
.cursor = {
|
||||
.style = CURSOR_BLOCK,
|
||||
.unfocused_style = CURSOR_UNFOCUSED_HOLLOW,
|
||||
|
|
@ -3496,6 +3589,8 @@ config_load(struct config *conf, const char *conf_path,
|
|||
.font_monospace_warn = true,
|
||||
.sixel = true,
|
||||
.surface_bit_depth = SHM_BITS_AUTO,
|
||||
.min_stride_alignment = 256,
|
||||
.preapply_damage = true,
|
||||
},
|
||||
|
||||
.touch = {
|
||||
|
|
@ -3512,9 +3607,11 @@ config_load(struct config *conf, const char *conf_path,
|
|||
.notifications = tll_init(),
|
||||
};
|
||||
|
||||
memcpy(conf->colors.table, default_color_table, sizeof(default_color_table));
|
||||
memcpy(conf->colors.sixel, default_sixel_colors, sizeof(default_sixel_colors));
|
||||
memcpy(&conf->colors2, &conf->colors, sizeof(conf->colors));
|
||||
memcpy(conf->colors_dark.table, default_color_table, sizeof(default_color_table));
|
||||
memcpy(conf->colors_dark.sixel, default_sixel_colors, sizeof(default_sixel_colors));
|
||||
memcpy(&conf->colors_light, &conf->colors_dark, sizeof(conf->colors_dark));
|
||||
conf->colors_light.dim_blend_towards = DIM_BLEND_TOWARDS_WHITE;
|
||||
|
||||
parse_modifiers(XKB_MOD_NAME_SHIFT, 5, &conf->mouse.selection_override_modifiers);
|
||||
|
||||
tokenize_cmdline(
|
||||
|
|
@ -3802,6 +3899,7 @@ config_clone(const struct config *old)
|
|||
conf->shell = xstrdup(old->shell);
|
||||
conf->title = xstrdup(old->title);
|
||||
conf->app_id = xstrdup(old->app_id);
|
||||
conf->toplevel_tag = xstrdup(old->toplevel_tag);
|
||||
conf->word_delimiters = xc32dup(old->word_delimiters);
|
||||
conf->scrollback.indicator.text = xc32dup(old->scrollback.indicator.text);
|
||||
conf->server_socket_path = xstrdup(old->server_socket_path);
|
||||
|
|
@ -3901,6 +3999,7 @@ config_free(struct config *conf)
|
|||
free(conf->shell);
|
||||
free(conf->title);
|
||||
free(conf->app_id);
|
||||
free(conf->toplevel_tag);
|
||||
free(conf->word_delimiters);
|
||||
spawn_template_free(&conf->bell.command);
|
||||
free(conf->scrollback.indicator.text);
|
||||
|
|
|
|||
18
config.h
18
config.h
|
|
@ -145,6 +145,11 @@ struct color_theme {
|
|||
uint32_t dim[8];
|
||||
uint32_t sixel[16];
|
||||
|
||||
enum {
|
||||
DIM_BLEND_TOWARDS_BLACK,
|
||||
DIM_BLEND_TOWARDS_WHITE,
|
||||
} dim_blend_towards;
|
||||
|
||||
enum {
|
||||
ALPHA_MODE_DEFAULT,
|
||||
ALPHA_MODE_MATCHING,
|
||||
|
|
@ -190,8 +195,10 @@ struct color_theme {
|
|||
};
|
||||
|
||||
enum which_color_theme {
|
||||
COLOR_THEME1,
|
||||
COLOR_THEME2,
|
||||
COLOR_THEME_DARK,
|
||||
COLOR_THEME_LIGHT,
|
||||
COLOR_THEME_1, /* Deprecated */
|
||||
COLOR_THEME_2, /* Deprecated */
|
||||
};
|
||||
|
||||
enum shm_bit_depth {
|
||||
|
|
@ -214,6 +221,7 @@ struct config {
|
|||
char *shell;
|
||||
char *title;
|
||||
char *app_id;
|
||||
char *toplevel_tag;
|
||||
char32_t *word_delimiters;
|
||||
bool login_shell;
|
||||
bool locked_title;
|
||||
|
|
@ -321,8 +329,8 @@ struct config {
|
|||
|
||||
tll(struct custom_regex) custom_regexes;
|
||||
|
||||
struct color_theme colors;
|
||||
struct color_theme colors2;
|
||||
struct color_theme colors_dark;
|
||||
struct color_theme colors_light;
|
||||
enum which_color_theme initial_color_theme;
|
||||
|
||||
struct {
|
||||
|
|
@ -435,6 +443,8 @@ struct config {
|
|||
bool font_monospace_warn;
|
||||
bool sixel;
|
||||
enum shm_bit_depth surface_bit_depth;
|
||||
uint32_t min_stride_alignment;
|
||||
bool preapply_damage;
|
||||
} tweak;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
18
csi.c
18
csi.c
|
|
@ -117,9 +117,9 @@ csi_sgr(struct terminal *term)
|
|||
style > UNDERLINE_SINGLE;
|
||||
break;
|
||||
}
|
||||
|
||||
term_update_ascii_printer(term);
|
||||
}
|
||||
} else
|
||||
term->bits_affecting_ascii_printer.underline_style = false;
|
||||
term_update_ascii_printer(term);
|
||||
break;
|
||||
}
|
||||
case 5: term->vt.attrs.blink = true; break;
|
||||
|
|
@ -422,6 +422,8 @@ decset_decrst(struct terminal *term, unsigned param, bool enable)
|
|||
|
||||
case 1004:
|
||||
term->focus_events = enable;
|
||||
if (enable)
|
||||
term_to_slave(term, term->kbd_focus ? "\033[I" : "\033[O", 3);
|
||||
break;
|
||||
|
||||
case 1005:
|
||||
|
|
@ -1576,7 +1578,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
int chars = snprintf(
|
||||
reply, sizeof(reply),
|
||||
"\033[?997;%dn",
|
||||
term->colors.active_theme == COLOR_THEME1 ? 1 : 2);
|
||||
term->colors.active_theme == COLOR_THEME_DARK ? 1 : 2);
|
||||
|
||||
term_to_slave(term, reply, chars);
|
||||
break;
|
||||
|
|
@ -1642,10 +1644,10 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
* 64 - vt520
|
||||
* 65 - vt525
|
||||
*
|
||||
* Param 2 - firmware version
|
||||
* xterm uses its version number. We use an xterm
|
||||
* version number too, since e.g. Emacs uses this to
|
||||
* determine level of support.
|
||||
* Param 2 - firmware version xterm uses its version
|
||||
* number. We do to, in the format "MAJORMINORPATCH",
|
||||
* where all three version numbers are always two
|
||||
* digits. So e.g. 1.25.0 is reported as 012500.
|
||||
*
|
||||
* We report ourselves as a VT220. This must be
|
||||
* synchronized with the primary DA response.
|
||||
|
|
|
|||
|
|
@ -67,6 +67,11 @@ the foot command line
|
|||
Value to set the *app-id* property on the Wayland window
|
||||
to. Default: _foot_ (normal mode), or _footclient_ (server mode).
|
||||
|
||||
*toplevel-tag*=_TAG_
|
||||
Value to set the *toplevel-tag* property on the Wayland window
|
||||
to. The compositor can use this value for session management,
|
||||
window rules etc. Default: _not set_
|
||||
|
||||
*-m*,*--maximized*
|
||||
Start in maximized mode. If both *--maximized* and *--fullscreen*
|
||||
are specified, the _last_ one takes precedence.
|
||||
|
|
@ -252,9 +257,6 @@ These keyboard shortcuts affect the search selection:
|
|||
*ctrl*+*shift*+*left*
|
||||
Extend current selection to the left to the last word boundary.
|
||||
|
||||
*ctrl*+*shift*+*w*
|
||||
Extend the current selection to the right to the last whitespace.
|
||||
|
||||
*shift*+*down*
|
||||
Extend current selection down one line
|
||||
|
||||
|
|
@ -693,8 +695,8 @@ variables to unset may be defined in *foot.ini*(5).
|
|||
|
||||
The following signals have special meaning in foot:
|
||||
|
||||
- SIGUSR1: switch to color theme 1 (i.e. use the *[colors]* section).
|
||||
- SIGUSR2: switch to color theme 2 (i.e. use the *[colors2]* section).
|
||||
- SIGUSR1: switch to the dark color theme (*[colors-dark]*).
|
||||
- SIGUSR2: switch to the light color theme (*[colors-light]*).
|
||||
|
||||
Note: you can send SIGUSR1/SIGUSR2 to a *foot --server* process too,
|
||||
in which case all client instances will switch theme. Furthermore, all
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ commented out will usually be installed to */etc/xdg/foot/foot.ini*.
|
|||
|
||||
Options are set using KEY=VALUE pairs:
|
||||
|
||||
*\[colors\]*++
|
||||
*\[colors-dark\]*++
|
||||
*background=000000*++
|
||||
*foreground=ffffff*
|
||||
|
||||
|
|
@ -371,12 +371,12 @@ empty string to be set, but it must be quoted: *KEY=""*)
|
|||
Default: _yes_
|
||||
|
||||
*initial-color-theme*
|
||||
Selects which color theme to use, *1*, or *2*.
|
||||
Selects which color theme to use, *dark*, or *light*.
|
||||
|
||||
*1* uses the colors defined in the *colors* section, while *2*
|
||||
uses the colors from the *colors2* section.
|
||||
*dark* uses the colors defined in the *colors-dark* section, while
|
||||
*light* uses the colors from the *colors-light* section.
|
||||
|
||||
Use the *color-theme-switch-1*, *color-theme-switch-2* and
|
||||
Use the *color-theme-switch-dark*, *color-theme-switch-light* and
|
||||
*color-theme-toggle* key bindings to switch between the two themes
|
||||
at runtime, or send SIGUSR1/SIGUSR2 to the foot process (see
|
||||
*foot*(1) for details).
|
||||
|
|
@ -429,6 +429,11 @@ empty string to be set, but it must be quoted: *KEY=""*)
|
|||
apply window management rules. Default: _foot_ (normal mode), or
|
||||
_footclient_ (server mode).
|
||||
|
||||
*toplevel-tag*
|
||||
Value to set the *toplevel-tag* property on the Wayland window
|
||||
to. The compositor can use this value for session management,
|
||||
window rules etc. Default: _not set_
|
||||
|
||||
*bold-text-in-bright*
|
||||
Semi-boolean. When enabled, bold text is rendered in a brighter
|
||||
color (in addition to using a bold font). The color is brightened
|
||||
|
|
@ -982,19 +987,24 @@ applications can change these at runtime.
|
|||
|
||||
Default: _400_.
|
||||
|
||||
# SECTION: colors
|
||||
# SECTION: colors-dark, colors-light
|
||||
|
||||
This section controls the 16 ANSI colors, the default foreground and
|
||||
background colors, and the extended 256 color palette. Note that
|
||||
These two sections controls the 16 ANSI colors, the default foreground
|
||||
and background colors, and the extended 256 color palette. Note that
|
||||
applications can change these at runtime.
|
||||
|
||||
The colors are in RRGGBB format (i.e. plain old 6-digit hex values,
|
||||
without prefix). That is, they do *not* have an alpha component. You
|
||||
can configure the background transparency with the _alpha_ option.
|
||||
|
||||
In the context of private mode 2031 (Dark and Light Mode detection),
|
||||
the primary theme (i.e. the *colors* section) is considered to be the
|
||||
dark theme (since the default theme is dark).
|
||||
*colors-dark* is intended to define a dark color theme, and
|
||||
*colors-light* is intended to define a light color theme. You can
|
||||
switch between them using the *color-theme-switch-dark*,
|
||||
*color-theme-switch-light* and *color-theme-toggle* key bindings, or
|
||||
by sending SIGUSR1/SIGUSR2 to the foot process.
|
||||
|
||||
The default theme used is *colors-dark*, unless
|
||||
*initial-color-theme=light* has been set.
|
||||
|
||||
*cursor*
|
||||
Two space separated RRGGBB values (i.e. plain old 6-digit hex
|
||||
|
|
@ -1031,7 +1041,8 @@ dark theme (since the default theme is dark).
|
|||
a color value, and a "dim" attribute.
|
||||
|
||||
By default, foot implements this by blending the current color
|
||||
with black. This is a generic approach that applies to both
|
||||
with black or white, depending on what the *dim-blend-towards*
|
||||
option is set to . This is a generic approach that applies to both
|
||||
colors from the 256-color palette, as well as 24-bit RGB colors.
|
||||
|
||||
You can change this behavior by setting the *dimN* options. When
|
||||
|
|
@ -1086,6 +1097,14 @@ dark theme (since the default theme is dark).
|
|||
|
||||
Default: _default_
|
||||
|
||||
*dim-blend-towards*
|
||||
Which color to blend towards when "auto" dimming a color (see
|
||||
*dim0*..*dim7* above). One of *black* or *white*. Blending towards
|
||||
black makes the text darker, while blending towards white makes it
|
||||
whiter (but still dimmer than normal text).
|
||||
|
||||
Default: _black_ (*colors-dark*), _white_ (*colors-light*)
|
||||
|
||||
*selection-foreground*, *selection-background*
|
||||
Foreground (text) and background color to use in selected
|
||||
text. Default: _inverse foreground/background_.
|
||||
|
|
@ -1121,19 +1140,6 @@ dark theme (since the default theme is dark).
|
|||
Flash translucency. A value in the range 0.0-1.0, where 0.0 means
|
||||
completely transparent, and 1.0 is opaque. Default: _0.5_.
|
||||
|
||||
# SECTION: colors2
|
||||
|
||||
This section defines an alternative color theme. It has the exact same
|
||||
keys as the *colors* section. The default values are the same.
|
||||
|
||||
Note that values are not inherited. That is, if you set a value in
|
||||
*colors*, but not in *colors2*, the value from *colors* is not
|
||||
inherited by *colors2*.
|
||||
|
||||
In the context of private mode 2031 (Dark and Light Mode detection),
|
||||
the alternative theme (i.e. the *colors2* section) is considered to be
|
||||
the light theme (since the default, the primary theme, is dark).
|
||||
|
||||
# SECTION: csd
|
||||
|
||||
This section controls the look of the _CSDs_ (Client Side
|
||||
|
|
@ -1440,16 +1446,16 @@ e.g. *search-start=none*.
|
|||
|
||||
Default: _Control+Shift+u_.
|
||||
|
||||
*color-theme-switch-1*, *color-theme-switch-2*, *color-theme-toggle*
|
||||
Switch between the primary color theme (defined in the *colors*
|
||||
section), and the alternative color theme (defined in the
|
||||
*colors2* section).
|
||||
*color-theme-switch-dark*, *color-theme-switch-dark*, *color-theme-toggle*
|
||||
Switch between the dark color theme (defined in the *colors-dark*
|
||||
section), and the light color theme (defined in the *colors-light*
|
||||
section).
|
||||
|
||||
*color-theme-switch-1* applies the primary color theme regardless
|
||||
*color-theme-switch-dark* applies the dark color theme regardless
|
||||
of which color theme is currently active.
|
||||
|
||||
*color-theme-switch-2* applies the alternative color theme regardless
|
||||
of which color theme is currently active.
|
||||
*color-theme-switch-light* applies the light color theme
|
||||
regardless of which color theme is currently active.
|
||||
|
||||
*color-theme-toggle* toggles between the primary and alternative
|
||||
color themes.
|
||||
|
|
@ -2031,6 +2037,32 @@ any of these options.
|
|||
|
||||
Default: _512_. Maximum allowed: _2048_ (2GB).
|
||||
|
||||
*min-stride-alignment*
|
||||
This option controls the minimum stride alignment, in bytes, when
|
||||
allocating SHM buffers.
|
||||
|
||||
In some circumstances, a compositor can import foot's SHM buffers
|
||||
directly to the GPU, without copying the buffer to GPU memory
|
||||
(typically on integrated graphics). Different drivers have
|
||||
different requirements for this, and one of those requirements is
|
||||
typically the stride alignment. At the time of writing, AMD GPUs
|
||||
require 256-byte alignment.
|
||||
|
||||
Note that doing a direct import typically disables immediate
|
||||
buffer release (if the compositor supports that), which means foot
|
||||
has to double buffer. This adds a performance penalty in foot, but
|
||||
the overall system performance should still be better.
|
||||
|
||||
If you are not using integrated graphics, or if the compositor
|
||||
does not support GPU direct imports, this option has close to zero
|
||||
impact. You can save a small amount of memory by setting this to
|
||||
0.
|
||||
|
||||
Ultimately, it is up to the compositor to decide whether to do
|
||||
immediate buffer releases, or try to optimize GPU imports.
|
||||
|
||||
Default: _256_
|
||||
|
||||
*sixel*
|
||||
Boolean. When enabled, foot will process sixel images. Default:
|
||||
_yes_
|
||||
|
|
@ -2067,6 +2099,41 @@ any of these options.
|
|||
|
||||
Default: _auto_
|
||||
|
||||
*pre-apply-damage*
|
||||
Boolean. When enabled, foot will attempt to "pre-apply" the damage
|
||||
from the last frame when foot is forced to double-buffer
|
||||
(i.e. when the compositor does not release SHM buffers
|
||||
immediately). All text after this assumes the compositor is not
|
||||
releasing buffers immediately.
|
||||
|
||||
When this option is disabled, each time foot needs to render a
|
||||
frame, it has to first copy over areas that changed in the last
|
||||
frame (i.e. all changes between the last two frames). This is
|
||||
basically a *memcpy*(3), which can be slow if the changed area is
|
||||
large. It is also done on the main thread, which means foot cannot
|
||||
do anything else at the same time; no other rendering, no VT
|
||||
parsing. After the changes have been brought over to the new
|
||||
frame, foot proceeds with rendering the cells that has changed
|
||||
between the last frame and the new frame.
|
||||
|
||||
When this option is enabled, the changes between the last two frames
|
||||
are brought over to what will become the next frame before foot
|
||||
starts rendering the next frame. As soon as the compositor
|
||||
releases the previous buffer (typically right after foot has
|
||||
pushed a new frame), foot kicks off a thread that copies over the
|
||||
changes to the newly released buffer. Since this is done in a
|
||||
thread, foot can continue processing input at the same
|
||||
time. Later, when it is time to render a new frame, the changes
|
||||
have already been transferred, and foot can immediately start with
|
||||
the actual rendering.
|
||||
|
||||
Thus, having this option enabled improves both performance
|
||||
(copying the last two frames' changes is threaded), and improves
|
||||
input latency (rending the next frame no longer has to first bring
|
||||
over the changes between the last two frames).
|
||||
|
||||
Default: _yes_
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*foot*(1), *footclient*(1)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ terminal has terminated.
|
|||
Value to set the *app-id* property on the Wayland window
|
||||
to. Default: _foot_ (normal mode), or _footclient_ (server mode).
|
||||
|
||||
*toplevel-tag*=_TAG_
|
||||
Value to set the *toplevel-tag* property on the Wayland window
|
||||
to. The compositor can use this value for session management,
|
||||
window rules etc. Default: _not set_
|
||||
|
||||
*-w*,*--window-size-pixels*=_WIDTHxHEIGHT_
|
||||
Set initial window width and height, in pixels. Default: _700x500_.
|
||||
|
||||
|
|
@ -193,8 +198,8 @@ variables to unset may be defined in *foot.ini*(5).
|
|||
|
||||
The following signals have special meaning in footclient:
|
||||
|
||||
- SIGUSR1: switch to color theme 1 (i.e. use the *[colors]* section).
|
||||
- SIGUSR2: switch to color theme 2 (i.e. use the *[colors2]* section).
|
||||
- SIGUSR1: switch to the dark color theme (*[colors-dark]*).
|
||||
- SIGUSR2: switch to the light color theme (*[colors-light]*).
|
||||
|
||||
When sending SIGUSR1/SIGUSR2 to a footclient instance, the theme is
|
||||
changed in that instance only. This is different from when you send
|
||||
|
|
|
|||
|
|
@ -256,8 +256,8 @@ extract_one(const struct terminal *term, const struct row *row,
|
|||
}
|
||||
}
|
||||
|
||||
xassert(next_tab_stop >= col);
|
||||
ctx->tab_spaces_left = next_tab_stop - col;
|
||||
if (next_tab_stop > col)
|
||||
ctx->tab_spaces_left = next_tab_stop - col - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ const char version_and_features[] =
|
|||
" -graphemes"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_XDG_TOPLEVEL_TAG)
|
||||
" +toplevel-tag"
|
||||
#else
|
||||
" -toplevel-tag"
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
" +assertions"
|
||||
#else
|
||||
|
|
|
|||
9
foot.ini
9
foot.ini
|
|
@ -24,7 +24,7 @@
|
|||
# dpi-aware=no
|
||||
# gamma-correct-blending=no
|
||||
|
||||
# initial-color-theme=1
|
||||
# initial-color-theme=dark
|
||||
# initial-window-size-pixels=700x500 # Or,
|
||||
# initial-window-size-chars=<COLSxROWS>
|
||||
# initial-window-mode=windowed
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
[touch]
|
||||
# long-press-delay=400
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
# alpha=1.0
|
||||
# alpha-mode=default # Can be `default`, `matching` or `all`
|
||||
# background=242424
|
||||
|
|
@ -132,6 +132,7 @@
|
|||
# bright7=ffffff # bright white
|
||||
|
||||
## dimmed colors (see foot.ini(5) man page)
|
||||
# dim-blend-towards=black
|
||||
# dim0=<not set>
|
||||
# ...
|
||||
# dim7=<not-set>
|
||||
|
|
@ -168,8 +169,10 @@
|
|||
# search-box-match=<regular0> <regular3> # black-on-yellow
|
||||
# urls=<regular3>
|
||||
|
||||
[colors2]
|
||||
[colors-light]
|
||||
# Alternative color theme, see man page foot.ini(5)
|
||||
# Same builtin defaults as [color], except for:
|
||||
# dim-blend-towards=white
|
||||
|
||||
[csd]
|
||||
# preferred=server
|
||||
|
|
|
|||
67
input.c
67
input.c
|
|
@ -120,10 +120,14 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
|
||||
case BIND_ACTION_SCROLLBACK_UP_MOUSE:
|
||||
if (term->grid == &term->alt) {
|
||||
if (term->alt_scrolling)
|
||||
if (term->alt_scrolling) {
|
||||
alternate_scroll(seat, amount, BTN_BACK);
|
||||
} else
|
||||
cmd_scrollback_up(term, amount);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
cmd_scrollback_up(term, amount);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case BIND_ACTION_SCROLLBACK_DOWN_PAGE:
|
||||
|
|
@ -149,10 +153,14 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
|
||||
case BIND_ACTION_SCROLLBACK_DOWN_MOUSE:
|
||||
if (term->grid == &term->alt) {
|
||||
if (term->alt_scrolling)
|
||||
if (term->alt_scrolling) {
|
||||
alternate_scroll(seat, amount, BTN_FORWARD);
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
cmd_scrollback_down(term, amount);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case BIND_ACTION_SCROLLBACK_HOME:
|
||||
|
|
@ -486,11 +494,13 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
return true;
|
||||
|
||||
case BIND_ACTION_THEME_SWITCH_1:
|
||||
term_theme_switch_to_1(term);
|
||||
case BIND_ACTION_THEME_SWITCH_DARK:
|
||||
term_theme_switch_to_dark(term);
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_THEME_SWITCH_2:
|
||||
term_theme_switch_to_2(term);
|
||||
case BIND_ACTION_THEME_SWITCH_LIGHT:
|
||||
term_theme_switch_to_light(term);
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_THEME_TOGGLE:
|
||||
|
|
@ -533,7 +543,7 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
case BIND_ACTION_SELECT_QUOTE:
|
||||
selection_start(
|
||||
term, seat->mouse.col, seat->mouse.row, SELECTION_QUOTE_WISE, false);
|
||||
break;
|
||||
return true;
|
||||
|
||||
case BIND_ACTION_SELECT_ROW:
|
||||
selection_start(
|
||||
|
|
@ -576,23 +586,20 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
/* Verify keymap is in a format we understand */
|
||||
switch ((enum wl_keyboard_keymap_format)format) {
|
||||
case WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP:
|
||||
close(fd);
|
||||
return;
|
||||
goto err;
|
||||
|
||||
case WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_WARN("unrecognized keymap format: %u", format);
|
||||
close(fd);
|
||||
return;
|
||||
goto err;
|
||||
}
|
||||
|
||||
char *map_str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (map_str == MAP_FAILED) {
|
||||
LOG_ERRNO("failed to mmap keyboard keymap");
|
||||
close(fd);
|
||||
return;
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (map_str[size - 1] == '\0')
|
||||
|
|
@ -605,6 +612,8 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
|
||||
}
|
||||
|
||||
munmap(map_str, size);
|
||||
|
||||
if (seat->kbd.xkb_keymap != NULL) {
|
||||
seat->kbd.xkb_state = xkb_state_new(seat->kbd.xkb_keymap);
|
||||
|
||||
|
|
@ -685,10 +694,10 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
seat->kbd.key_arrow_down = xkb_keymap_key_by_name(seat->kbd.xkb_keymap, "DOWN");
|
||||
}
|
||||
|
||||
munmap(map_str, size);
|
||||
close(fd);
|
||||
|
||||
key_binding_load_keymap(wayl->key_binding_manager, seat);
|
||||
|
||||
err:
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1596,6 +1605,9 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
if (released)
|
||||
stop_repeater(seat, key);
|
||||
|
||||
if (pressed)
|
||||
seat->kbd.last_shortcut_sym = XKB_KEYSYM_MAX + 1;
|
||||
|
||||
bool should_repeat =
|
||||
pressed && xkb_keymap_key_repeats(seat->kbd.xkb_keymap, key);
|
||||
|
||||
|
|
@ -1697,6 +1709,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
if (bind->k.sym == raw_syms[i] &&
|
||||
execute_binding(seat, term, bind, serial, 1))
|
||||
{
|
||||
seat->kbd.last_shortcut_sym = sym;
|
||||
goto maybe_repeat;
|
||||
}
|
||||
}
|
||||
|
|
@ -1710,6 +1723,7 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
bind->mods == (mods & ~consumed) &&
|
||||
execute_binding(seat, term, bind, serial, 1))
|
||||
{
|
||||
seat->kbd.last_shortcut_sym = sym;
|
||||
goto maybe_repeat;
|
||||
}
|
||||
}
|
||||
|
|
@ -1725,12 +1739,31 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
if (code->item == key &&
|
||||
execute_binding(seat, term, bind, serial, 1))
|
||||
{
|
||||
seat->kbd.last_shortcut_sym = sym;
|
||||
goto maybe_repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (released && seat->kbd.last_shortcut_sym == sym) {
|
||||
/*
|
||||
* Don't process a release event, if it corresponds to a
|
||||
* triggered shortcut.
|
||||
*
|
||||
* 1. If we consumed a key (press) event, we shouldn't emit an
|
||||
* escape for its release event.
|
||||
* 2. Ignoring the incorrectness of doing so; this also caused
|
||||
* us to reset the viewport.
|
||||
*
|
||||
* Background: if the kitty keyboard protocol was enabled,
|
||||
* then the viewport was instantly reset to the bottom, after
|
||||
* scrolling up.
|
||||
*/
|
||||
//seat->kbd.last_shortcut_sym = XKB_KEYSYM_MAX + 1;
|
||||
goto maybe_repeat;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keys generating escape sequences
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ enum bind_action_normal {
|
|||
BIND_ACTION_REGEX_COPY,
|
||||
BIND_ACTION_THEME_SWITCH_1,
|
||||
BIND_ACTION_THEME_SWITCH_2,
|
||||
BIND_ACTION_THEME_SWITCH_DARK,
|
||||
BIND_ACTION_THEME_SWITCH_LIGHT,
|
||||
BIND_ACTION_THEME_TOGGLE,
|
||||
|
||||
/* Mouse specific actions - i.e. they require a mouse coordinate */
|
||||
|
|
|
|||
16
main.c
16
main.c
|
|
@ -59,14 +59,14 @@ fdm_sigusr(struct fdm *fdm, int signo, void *data)
|
|||
|
||||
if (ctx->server != NULL) {
|
||||
if (signo == SIGUSR1)
|
||||
server_global_theme_switch_to_1(ctx->server);
|
||||
server_global_theme_switch_to_dark(ctx->server);
|
||||
else
|
||||
server_global_theme_switch_to_2(ctx->server);
|
||||
server_global_theme_switch_to_light(ctx->server);
|
||||
} else {
|
||||
if (signo == SIGUSR1)
|
||||
term_theme_switch_to_1(ctx->term);
|
||||
term_theme_switch_to_dark(ctx->term);
|
||||
else
|
||||
term_theme_switch_to_2(ctx->term);
|
||||
term_theme_switch_to_light(ctx->term);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -84,6 +84,7 @@ print_usage(const char *prog_name)
|
|||
" -t,--term=TERM value to set the environment variable TERM to (" FOOT_DEFAULT_TERM ")\n"
|
||||
" -T,--title=TITLE initial window title (foot)\n"
|
||||
" -a,--app-id=ID window application ID (foot)\n"
|
||||
" --toplevel-tag=TAG set a custom toplevel tag\n"
|
||||
" -m,--maximized start in maximized mode\n"
|
||||
" -F,--fullscreen start in fullscreen mode\n"
|
||||
" -L,--login-shell start shell as a login shell\n"
|
||||
|
|
@ -185,6 +186,7 @@ sanitize_signals(void)
|
|||
|
||||
enum {
|
||||
PTY_OPTION = CHAR_MAX + 1,
|
||||
TOPLEVEL_TAG_OPTION = CHAR_MAX + 2,
|
||||
};
|
||||
|
||||
int
|
||||
|
|
@ -214,6 +216,7 @@ main(int argc, char *const *argv)
|
|||
{"term", required_argument, NULL, 't'},
|
||||
{"title", required_argument, NULL, 'T'},
|
||||
{"app-id", required_argument, NULL, 'a'},
|
||||
{"toplevel-tag", required_argument, NULL, TOPLEVEL_TAG_OPTION},
|
||||
{"login-shell", no_argument, NULL, 'L'},
|
||||
{"working-directory", required_argument, NULL, 'D'},
|
||||
{"font", required_argument, NULL, 'f'},
|
||||
|
|
@ -285,6 +288,10 @@ main(int argc, char *const *argv)
|
|||
tll_push_back(overrides, xstrjoin("app-id=", optarg));
|
||||
break;
|
||||
|
||||
case TOPLEVEL_TAG_OPTION:
|
||||
tll_push_back(overrides, xstrjoin("toplevel-tag=", optarg));
|
||||
break;
|
||||
|
||||
case 'D': {
|
||||
struct stat st;
|
||||
if (stat(optarg, &st) < 0 || !(st.st_mode & S_IFDIR)) {
|
||||
|
|
@ -597,6 +604,7 @@ main(int argc, char *const *argv)
|
|||
}
|
||||
|
||||
shm_set_max_pool_size(conf.tweak.max_shm_pool_size);
|
||||
shm_set_min_stride_alignment(conf.tweak.min_stride_alignment);
|
||||
|
||||
if ((fdm = fdm_init()) == NULL)
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
project('foot', 'c',
|
||||
version: '1.24.0',
|
||||
version: '1.25.0',
|
||||
license: 'MIT',
|
||||
meson_version: '>=0.59.0',
|
||||
default_options: [
|
||||
|
|
@ -182,7 +182,12 @@ wl_proto_xml = [
|
|||
wayland_protocols_datadir / 'staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml',
|
||||
wayland_protocols_datadir / 'staging/xdg-system-bell/xdg-system-bell-v1.xml',
|
||||
wayland_protocols_datadir / 'staging/color-management/color-management-v1.xml',
|
||||
]
|
||||
]
|
||||
|
||||
if (wayland_protocols.version().version_compare('>=1.43'))
|
||||
wl_proto_xml += [wayland_protocols_datadir / 'staging/xdg-toplevel-tag/xdg-toplevel-tag-v1.xml']
|
||||
add_project_arguments('-DHAVE_XDG_TOPLEVEL_TAG=1', language: 'c')
|
||||
endif
|
||||
|
||||
foreach prot : wl_proto_xml
|
||||
wl_proto_headers += custom_target(
|
||||
|
|
|
|||
2
notify.c
2
notify.c
|
|
@ -114,7 +114,7 @@ consume_stdout(struct notification *notif, bool eof)
|
|||
while (left > 0) {
|
||||
line = data;
|
||||
size_t len = left;
|
||||
char *eol = memchr(line, '\n', left);
|
||||
char *eol = (char *)memchr(line, '\n', left);
|
||||
|
||||
if (eol != NULL) {
|
||||
*eol = '\0';
|
||||
|
|
|
|||
54
osc.c
54
osc.c
|
|
@ -513,7 +513,7 @@ osc_uri(struct terminal *term, char *string)
|
|||
key_value = strtok_r(NULL, ":", &ctx))
|
||||
{
|
||||
const char *key = key_value;
|
||||
char *operator = strchr(key_value, '=');
|
||||
char *operator = (char *)strchr(key_value, '=');
|
||||
|
||||
if (operator == NULL)
|
||||
continue;
|
||||
|
|
@ -525,12 +525,14 @@ osc_uri(struct terminal *term, char *string)
|
|||
id = sdbm_hash(value);
|
||||
}
|
||||
|
||||
LOG_DBG("OSC-8: URL=%s, id=%" PRIu64, uri, id);
|
||||
|
||||
if (uri[0] == '\0')
|
||||
if (uri[0] == '\0') {
|
||||
LOG_DBG("OSC-8: close");
|
||||
term_osc8_close(term);
|
||||
else
|
||||
} else {
|
||||
LOG_DBG("OSC-8: URL=%s, id=%" PRIu64, uri, id);
|
||||
term_osc8_open(term, id, uri);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1459,9 +1461,9 @@ osc_dispatch(struct terminal *term)
|
|||
case 11:
|
||||
term->colors.bg = color;
|
||||
if (!have_alpha) {
|
||||
alpha = term->colors.active_theme == COLOR_THEME1
|
||||
? term->conf->colors.alpha
|
||||
: term->conf->colors2.alpha;
|
||||
alpha = term->colors.active_theme == COLOR_THEME_DARK
|
||||
? term->conf->colors_dark.alpha
|
||||
: term->conf->colors_light.alpha;
|
||||
}
|
||||
|
||||
const bool changed = term->colors.alpha != alpha;
|
||||
|
|
@ -1516,9 +1518,9 @@ osc_dispatch(struct terminal *term)
|
|||
/* Reset Color Number 'c' (whole table if no parameter) */
|
||||
|
||||
const struct color_theme *theme =
|
||||
term->colors.active_theme == COLOR_THEME1
|
||||
? &term->conf->colors
|
||||
: &term->conf->colors2;
|
||||
term->colors.active_theme == COLOR_THEME_DARK
|
||||
? &term->conf->colors_dark
|
||||
: &term->conf->colors_light;
|
||||
|
||||
if (string[0] == '\0') {
|
||||
LOG_DBG("resetting all colors");
|
||||
|
|
@ -1559,9 +1561,9 @@ osc_dispatch(struct terminal *term)
|
|||
LOG_DBG("resetting foreground color");
|
||||
|
||||
const struct color_theme *theme =
|
||||
term->colors.active_theme == COLOR_THEME1
|
||||
? &term->conf->colors
|
||||
: &term->conf->colors2;
|
||||
term->colors.active_theme == COLOR_THEME_DARK
|
||||
? &term->conf->colors_dark
|
||||
: &term->conf->colors_light;
|
||||
|
||||
term->colors.fg = theme->fg;
|
||||
term_damage_color(term, COLOR_DEFAULT, 0);
|
||||
|
|
@ -1571,9 +1573,9 @@ osc_dispatch(struct terminal *term)
|
|||
LOG_DBG("resetting background color");
|
||||
|
||||
const struct color_theme *theme =
|
||||
term->colors.active_theme == COLOR_THEME1
|
||||
? &term->conf->colors
|
||||
: &term->conf->colors2;
|
||||
term->colors.active_theme == COLOR_THEME_DARK
|
||||
? &term->conf->colors_dark
|
||||
: &term->conf->colors_light;
|
||||
|
||||
bool alpha_changed = term->colors.alpha != theme->alpha;
|
||||
|
||||
|
|
@ -1594,14 +1596,14 @@ osc_dispatch(struct terminal *term)
|
|||
LOG_DBG("resetting cursor color");
|
||||
|
||||
const struct color_theme *theme =
|
||||
term->colors.active_theme == COLOR_THEME1
|
||||
? &term->conf->colors
|
||||
: &term->conf->colors2;
|
||||
term->colors.active_theme == COLOR_THEME_DARK
|
||||
? &term->conf->colors_dark
|
||||
: &term->conf->colors_light;
|
||||
|
||||
term->colors.cursor_fg = theme->cursor.text;
|
||||
term->colors.cursor_bg = theme->cursor.cursor;
|
||||
|
||||
if (term->conf->colors.use_custom.cursor) {
|
||||
if (term->conf->colors_dark.use_custom.cursor) {
|
||||
term->colors.cursor_fg |= 1u << 31;
|
||||
term->colors.cursor_bg |= 1u << 31;
|
||||
}
|
||||
|
|
@ -1614,9 +1616,9 @@ osc_dispatch(struct terminal *term)
|
|||
LOG_DBG("resetting selection background color");
|
||||
|
||||
const struct color_theme *theme =
|
||||
term->colors.active_theme == COLOR_THEME1
|
||||
? &term->conf->colors
|
||||
: &term->conf->colors2;
|
||||
term->colors.active_theme == COLOR_THEME_DARK
|
||||
? &term->conf->colors_dark
|
||||
: &term->conf->colors_light;
|
||||
|
||||
term->colors.selection_bg = theme->selection_bg;
|
||||
break;
|
||||
|
|
@ -1626,9 +1628,9 @@ osc_dispatch(struct terminal *term)
|
|||
LOG_DBG("resetting selection foreground color");
|
||||
|
||||
const struct color_theme *theme =
|
||||
term->colors.active_theme == COLOR_THEME1
|
||||
? &term->conf->colors
|
||||
: &term->conf->colors2;
|
||||
term->colors.active_theme == COLOR_THEME_DARK
|
||||
? &term->conf->colors_dark
|
||||
: &term->conf->colors_light;
|
||||
|
||||
term->colors.selection_fg = theme->selection_fg;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ void render_refresh_icon(struct terminal *term) {}
|
|||
|
||||
void render_overlay(struct terminal *term) {}
|
||||
|
||||
void render_buffer_release_callback(struct buffer *buf, void *data) {}
|
||||
|
||||
bool
|
||||
render_xcursor_is_valid(const struct seat *seat, const char *cursor)
|
||||
{
|
||||
|
|
@ -206,7 +208,8 @@ enum shm_bit_depth shm_chain_bit_depth(const struct buffer_chain *chain) { retur
|
|||
struct buffer_chain *
|
||||
shm_chain_new(
|
||||
struct wayland *wayl, bool scrollable, size_t pix_instances,
|
||||
enum shm_bit_depth desired_bit_depth)
|
||||
enum shm_bit_depth desired_bit_depth,
|
||||
void (*release_cb)(struct buffer *buf, void *data), void *cb_data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
10
pyproject.toml
Normal file
10
pyproject.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[tool.pyright]
|
||||
strict = ['scripts']
|
||||
|
||||
[tool.mypy]
|
||||
files = '$MYPY_CONFIG_FILE_DIR/scripts'
|
||||
strict = true
|
||||
|
||||
[tool.codespell]
|
||||
skip = 'pyproject.toml,./subprojects,./pkg,./src,./bld,foot.info,./unicode,./venv'
|
||||
ignore-regex = 'terminfo capability `rin`|\* Simon Ser|\* \[zar\]\(https://codeberg.org/zar\)|iterm theme|iterm.toml|iterm/OneHalfDark.itermcolors'
|
||||
280
render.c
280
render.c
|
|
@ -293,7 +293,7 @@ static inline uint32_t
|
|||
color_dim(const struct terminal *term, uint32_t color)
|
||||
{
|
||||
const struct config *conf = term->conf;
|
||||
const uint8_t custom_dim = conf->colors.use_custom.dim;
|
||||
const uint8_t custom_dim = conf->colors_dark.use_custom.dim;
|
||||
|
||||
if (unlikely(custom_dim != 0)) {
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
|
|
@ -302,7 +302,7 @@ color_dim(const struct terminal *term, uint32_t color)
|
|||
|
||||
if (term->colors.table[0 + i] == color) {
|
||||
/* "Regular" color, return the corresponding "dim" */
|
||||
return conf->colors.dim[i];
|
||||
return conf->colors_dark.dim[i];
|
||||
}
|
||||
|
||||
else if (term->colors.table[8 + i] == color) {
|
||||
|
|
@ -312,7 +312,14 @@ color_dim(const struct terminal *term, uint32_t color)
|
|||
}
|
||||
}
|
||||
|
||||
return color_blend_towards(color, 0x00000000, conf->dim.amount);
|
||||
const struct color_theme *theme = term->colors.active_theme == COLOR_THEME_DARK
|
||||
? &conf->colors_dark
|
||||
: &conf->colors_light;
|
||||
|
||||
return color_blend_towards(
|
||||
color,
|
||||
theme->dim_blend_towards == DIM_BLEND_TOWARDS_BLACK ? 0x00000000 : 0x00ffffff,
|
||||
conf->dim.amount);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
|
|
@ -769,7 +776,7 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
}
|
||||
|
||||
else if (!term->window->is_fullscreen && term->colors.alpha != 0xffff) {
|
||||
switch (term->conf->colors.alpha_mode) {
|
||||
switch (term->conf->colors_dark.alpha_mode) {
|
||||
case ALPHA_MODE_DEFAULT: {
|
||||
if (cell->attrs.bg_src == COLOR_DEFAULT) {
|
||||
alpha = term->colors.alpha;
|
||||
|
|
@ -1168,8 +1175,8 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
|
||||
if (unlikely(cell->attrs.url)) {
|
||||
pixman_color_t url_color = color_hex_to_pixman(
|
||||
term->conf->colors.use_custom.url
|
||||
? term->conf->colors.url
|
||||
term->conf->colors_dark.use_custom.url
|
||||
? term->conf->colors_dark.url
|
||||
: term->colors.table[3],
|
||||
gamma_correct);
|
||||
draw_underline(term, pix, font, &url_color, x, y, cell_cols);
|
||||
|
|
@ -1984,8 +1991,8 @@ render_overlay(struct terminal *term)
|
|||
|
||||
case OVERLAY_FLASH:
|
||||
color = color_hex_to_pixman_with_alpha(
|
||||
term->conf->colors.flash,
|
||||
term->conf->colors.flash_alpha,
|
||||
term->conf->colors_dark.flash,
|
||||
term->conf->colors_dark.flash_alpha,
|
||||
wayl_do_linear_blending(term->wl, term->conf));
|
||||
break;
|
||||
|
||||
|
|
@ -2005,7 +2012,7 @@ render_overlay(struct terminal *term)
|
|||
}
|
||||
|
||||
struct buffer *buf = shm_get_buffer(
|
||||
term->render.chains.overlay, term->width, term->height, true);
|
||||
term->render.chains.overlay, term->width, term->height);
|
||||
pixman_image_set_clip_region32(buf->pix[0], NULL);
|
||||
|
||||
/* Bounding rectangle of damaged areas - for wl_surface_damage_buffer() */
|
||||
|
|
@ -2224,6 +2231,56 @@ render_worker_thread(void *_ctx)
|
|||
|
||||
case -2:
|
||||
return 0;
|
||||
|
||||
case -3: {
|
||||
if (term->conf->tweak.render_timer != RENDER_TIMER_NONE)
|
||||
clock_gettime(CLOCK_MONOTONIC, &term->render.workers.preapplied_damage.start);
|
||||
|
||||
mtx_lock(&term->render.workers.preapplied_damage.lock);
|
||||
buf = term->render.workers.preapplied_damage.buf;
|
||||
xassert(buf != NULL);
|
||||
|
||||
if (likely(term->render.last_buf != NULL)) {
|
||||
mtx_unlock(&term->render.workers.preapplied_damage.lock);
|
||||
|
||||
pixman_region32_t dmg;
|
||||
pixman_region32_init(&dmg);
|
||||
|
||||
if (buf->age == 0)
|
||||
; /* No need to do anything */
|
||||
else if (buf->age == 1)
|
||||
pixman_region32_copy(&dmg,
|
||||
&term->render.last_buf->dirty[0]);
|
||||
else
|
||||
pixman_region32_init_rect(&dmg, 0, 0, buf->width,
|
||||
buf->height);
|
||||
|
||||
pixman_image_set_clip_region32(buf->pix[my_id], &dmg);
|
||||
pixman_image_composite32(PIXMAN_OP_SRC,
|
||||
term->render.last_buf->pix[my_id],
|
||||
NULL, buf->pix[my_id], 0, 0, 0, 0, 0,
|
||||
0, buf->width, buf->height);
|
||||
|
||||
pixman_region32_fini(&dmg);
|
||||
|
||||
buf->age = 0;
|
||||
shm_unref(term->render.last_buf);
|
||||
shm_addref(buf);
|
||||
term->render.last_buf = buf;
|
||||
|
||||
mtx_lock(&term->render.workers.preapplied_damage.lock);
|
||||
}
|
||||
|
||||
term->render.workers.preapplied_damage.buf = NULL;
|
||||
cnd_signal(&term->render.workers.preapplied_damage.cond);
|
||||
mtx_unlock(&term->render.workers.preapplied_damage.lock);
|
||||
|
||||
if (term->conf->tweak.render_timer != RENDER_TIMER_NONE)
|
||||
clock_gettime(CLOCK_MONOTONIC, &term->render.workers.preapplied_damage.stop);
|
||||
|
||||
frame_done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -2231,6 +2288,22 @@ render_worker_thread(void *_ctx)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
render_wait_for_preapply_damage(struct terminal *term)
|
||||
{
|
||||
if (!term->render.preapply_last_frame_damage)
|
||||
return;
|
||||
if (term->render.workers.preapplied_damage.buf == NULL)
|
||||
return;
|
||||
|
||||
mtx_lock(&term->render.workers.preapplied_damage.lock);
|
||||
while (term->render.workers.preapplied_damage.buf != NULL) {
|
||||
cnd_wait(&term->render.workers.preapplied_damage.cond,
|
||||
&term->render.workers.preapplied_damage.lock);
|
||||
}
|
||||
mtx_unlock(&term->render.workers.preapplied_damage.lock);
|
||||
}
|
||||
|
||||
struct csd_data
|
||||
get_csd_data(const struct terminal *term, enum csd_surface surf_idx)
|
||||
{
|
||||
|
|
@ -2437,10 +2510,10 @@ render_csd_title(struct terminal *term, const struct csd_data *info,
|
|||
|
||||
uint32_t bg = term->conf->csd.color.title_set
|
||||
? term->conf->csd.color.title
|
||||
: 0xffu << 24 | term->conf->colors.fg;
|
||||
: 0xffu << 24 | term->conf->colors_dark.fg;
|
||||
uint32_t fg = term->conf->csd.color.buttons_set
|
||||
? term->conf->csd.color.buttons
|
||||
: term->conf->colors.bg;
|
||||
: term->conf->colors_dark.bg;
|
||||
|
||||
if (!term->visual_focus) {
|
||||
bg = color_dim(term, bg);
|
||||
|
|
@ -2534,7 +2607,7 @@ render_csd_border(struct terminal *term, enum csd_surface surf_idx,
|
|||
uint32_t _color =
|
||||
conf->csd.color.border_set ? conf->csd.color.border :
|
||||
conf->csd.color.title_set ? conf->csd.color.title :
|
||||
0xffu << 24 | term->conf->colors.fg;
|
||||
0xffu << 24 | term->conf->colors_dark.fg;
|
||||
if (!term->visual_focus)
|
||||
_color = color_dim(term, _color);
|
||||
|
||||
|
|
@ -2554,7 +2627,7 @@ static pixman_color_t
|
|||
get_csd_button_fg_color(const struct terminal *term)
|
||||
{
|
||||
const struct config *conf = term->conf;
|
||||
uint32_t _color = conf->colors.bg;
|
||||
uint32_t _color = conf->colors_dark.bg;
|
||||
uint16_t alpha = 0xffff;
|
||||
|
||||
if (conf->csd.color.buttons_set) {
|
||||
|
|
@ -2799,7 +2872,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx,
|
|||
|
||||
switch (surf_idx) {
|
||||
case CSD_SURF_MINIMIZE:
|
||||
_color = term->conf->colors.table[4]; /* blue */
|
||||
_color = term->conf->colors_dark.table[4]; /* blue */
|
||||
is_set = term->conf->csd.color.minimize_set;
|
||||
conf_color = &term->conf->csd.color.minimize;
|
||||
is_active = term->active_surface == TERM_SURF_BUTTON_MINIMIZE &&
|
||||
|
|
@ -2807,7 +2880,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx,
|
|||
break;
|
||||
|
||||
case CSD_SURF_MAXIMIZE:
|
||||
_color = term->conf->colors.table[2]; /* green */
|
||||
_color = term->conf->colors_dark.table[2]; /* green */
|
||||
is_set = term->conf->csd.color.maximize_set;
|
||||
conf_color = &term->conf->csd.color.maximize;
|
||||
is_active = term->active_surface == TERM_SURF_BUTTON_MAXIMIZE &&
|
||||
|
|
@ -2815,7 +2888,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx,
|
|||
break;
|
||||
|
||||
case CSD_SURF_CLOSE:
|
||||
_color = term->conf->colors.table[1]; /* red */
|
||||
_color = term->conf->colors_dark.table[1]; /* red */
|
||||
is_set = term->conf->csd.color.close_set;
|
||||
conf_color = &term->conf->csd.color.quit;
|
||||
is_active = term->active_surface == TERM_SURF_BUTTON_CLOSE &&
|
||||
|
|
@ -2897,7 +2970,7 @@ render_csd(struct terminal *term)
|
|||
}
|
||||
|
||||
struct buffer *bufs[CSD_SURF_COUNT];
|
||||
shm_get_many(term->render.chains.csd, CSD_SURF_COUNT, widths, heights, bufs, true);
|
||||
shm_get_many(term->render.chains.csd, CSD_SURF_COUNT, widths, heights, bufs);
|
||||
|
||||
for (size_t i = CSD_SURF_LEFT; i <= CSD_SURF_BOTTOM; i++)
|
||||
render_csd_border(term, i, &infos[i], bufs[i]);
|
||||
|
|
@ -3037,16 +3110,16 @@ render_scrollback_position(struct terminal *term)
|
|||
}
|
||||
|
||||
struct buffer_chain *chain = term->render.chains.scrollback_indicator;
|
||||
struct buffer *buf = shm_get_buffer(chain, width, height, false);
|
||||
struct buffer *buf = shm_get_buffer(chain, width, height);
|
||||
|
||||
wl_subsurface_set_position(
|
||||
win->scrollback_indicator.sub, roundf(x / scale), roundf(y / scale));
|
||||
|
||||
uint32_t fg = term->colors.table[0];
|
||||
uint32_t bg = term->colors.table[8 + 4];
|
||||
if (term->conf->colors.use_custom.scrollback_indicator) {
|
||||
fg = term->conf->colors.scrollback_indicator.fg;
|
||||
bg = term->conf->colors.scrollback_indicator.bg;
|
||||
if (term->conf->colors_dark.use_custom.scrollback_indicator) {
|
||||
fg = term->conf->colors_dark.scrollback_indicator.fg;
|
||||
bg = term->conf->colors_dark.scrollback_indicator.bg;
|
||||
}
|
||||
|
||||
render_osd(
|
||||
|
|
@ -3080,7 +3153,7 @@ render_render_timer(struct terminal *term, struct timespec render_time)
|
|||
height = roundf(scale * ceilf(height / scale));
|
||||
|
||||
struct buffer_chain *chain = term->render.chains.render_timer;
|
||||
struct buffer *buf = shm_get_buffer(chain, width, height, false);
|
||||
struct buffer *buf = shm_get_buffer(chain, width, height);
|
||||
|
||||
wl_subsurface_set_position(
|
||||
win->render_timer.sub,
|
||||
|
|
@ -3113,14 +3186,6 @@ force_full_repaint(struct terminal *term, struct buffer *buf)
|
|||
static void
|
||||
reapply_old_damage(struct terminal *term, struct buffer *new, struct buffer *old)
|
||||
{
|
||||
static int counter = 0;
|
||||
static bool have_warned = false;
|
||||
if (!have_warned && ++counter > 5) {
|
||||
LOG_WARN("compositor is not releasing buffers immediately; "
|
||||
"expect lower rendering performance");
|
||||
have_warned = true;
|
||||
}
|
||||
|
||||
if (new->age > 1) {
|
||||
memcpy(new->data, old->data, new->height * new->stride);
|
||||
return;
|
||||
|
|
@ -3251,7 +3316,18 @@ grid_render(struct terminal *term)
|
|||
if (term->shutdown.in_progress)
|
||||
return;
|
||||
|
||||
struct timespec start_time, start_double_buffering = {0}, stop_double_buffering = {0};
|
||||
struct timespec start_time;
|
||||
struct timespec start_wait_preapply = {0}, stop_wait_preapply = {0};
|
||||
struct timespec start_double_buffering = {0}, stop_double_buffering = {0};
|
||||
|
||||
/* Might be a thread doing pre-applied damage */
|
||||
if (unlikely(term->render.preapply_last_frame_damage &&
|
||||
term->render.workers.preapplied_damage.buf != NULL))
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC, &start_wait_preapply);
|
||||
render_wait_for_preapply_damage(term);
|
||||
clock_gettime(CLOCK_MONOTONIC, &stop_wait_preapply);
|
||||
}
|
||||
|
||||
if (term->conf->tweak.render_timer != RENDER_TIMER_NONE)
|
||||
clock_gettime(CLOCK_MONOTONIC, &start_time);
|
||||
|
|
@ -3260,15 +3336,14 @@ grid_render(struct terminal *term)
|
|||
xassert(term->height > 0);
|
||||
|
||||
struct buffer_chain *chain = term->render.chains.grid;
|
||||
bool use_alpha = !term->window->is_fullscreen &&
|
||||
term->colors.alpha != 0xffff;
|
||||
struct buffer *buf = shm_get_buffer(
|
||||
chain, term->width, term->height, use_alpha);
|
||||
struct buffer *buf = shm_get_buffer(chain, term->width, term->height);
|
||||
|
||||
/* Dirty old and current cursor cell, to ensure they're repainted */
|
||||
dirty_old_cursor(term);
|
||||
dirty_cursor(term);
|
||||
|
||||
LOG_DBG("buffer age: %u (%p)", buf->age, (void *)buf);
|
||||
|
||||
if (term->render.last_buf == NULL ||
|
||||
term->render.last_buf->width != buf->width ||
|
||||
term->render.last_buf->height != buf->height ||
|
||||
|
|
@ -3285,9 +3360,27 @@ grid_render(struct terminal *term)
|
|||
xassert(term->render.last_buf->width == buf->width);
|
||||
xassert(term->render.last_buf->height == buf->height);
|
||||
|
||||
if (++term->render.frames_since_last_immediate_release > 10) {
|
||||
static bool have_warned = false;
|
||||
|
||||
if (!term->render.preapply_last_frame_damage &&
|
||||
term->conf->tweak.preapply_damage &&
|
||||
term->render.workers.count > 0)
|
||||
{
|
||||
LOG_INFO("enabling pre-applied frame damage");
|
||||
term->render.preapply_last_frame_damage = true;
|
||||
} else if (!have_warned && !term->render.preapply_last_frame_damage) {
|
||||
LOG_WARN("compositor is not releasing buffers immediately; "
|
||||
"expect lower rendering performance");
|
||||
have_warned = true;
|
||||
}
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start_double_buffering);
|
||||
reapply_old_damage(term, buf, term->render.last_buf);
|
||||
clock_gettime(CLOCK_MONOTONIC, &stop_double_buffering);
|
||||
} else if (!term->render.preapply_last_frame_damage) {
|
||||
term->render.frames_since_last_immediate_release = 0;
|
||||
}
|
||||
|
||||
if (term->render.last_buf != NULL) {
|
||||
|
|
@ -3515,27 +3608,40 @@ grid_render(struct terminal *term)
|
|||
struct timespec end_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &end_time);
|
||||
|
||||
struct timespec wait_time;
|
||||
timespec_sub(&stop_wait_preapply, &start_wait_preapply, &wait_time);
|
||||
|
||||
struct timespec render_time;
|
||||
timespec_sub(&end_time, &start_time, &render_time);
|
||||
|
||||
struct timespec double_buffering_time;
|
||||
timespec_sub(&stop_double_buffering, &start_double_buffering, &double_buffering_time);
|
||||
|
||||
struct timespec preapply_damage;
|
||||
timespec_sub(&term->render.workers.preapplied_damage.stop,
|
||||
&term->render.workers.preapplied_damage.start,
|
||||
&preapply_damage);
|
||||
|
||||
struct timespec total_render_time;
|
||||
timespec_add(&render_time, &double_buffering_time, &total_render_time);
|
||||
timespec_add(&wait_time, &total_render_time, &total_render_time);
|
||||
|
||||
switch (term->conf->tweak.render_timer) {
|
||||
case RENDER_TIMER_LOG:
|
||||
case RENDER_TIMER_BOTH:
|
||||
LOG_INFO(
|
||||
"frame rendered in %lds %9ldns "
|
||||
"(%lds %9ldns rendering, %lds %9ldns double buffering)",
|
||||
"(%lds %9ldns wait, %lds %9ldns rendering, %lds %9ldns double buffering) not included: %lds %ldns pre-apply damage",
|
||||
(long)total_render_time.tv_sec,
|
||||
total_render_time.tv_nsec,
|
||||
(long)wait_time.tv_sec,
|
||||
wait_time.tv_nsec,
|
||||
(long)render_time.tv_sec,
|
||||
render_time.tv_nsec,
|
||||
(long)double_buffering_time.tv_sec,
|
||||
double_buffering_time.tv_nsec);
|
||||
double_buffering_time.tv_nsec,
|
||||
(long)preapply_damage.tv_sec,
|
||||
preapply_damage.tv_nsec);
|
||||
break;
|
||||
|
||||
case RENDER_TIMER_OSD:
|
||||
|
|
@ -3678,7 +3784,7 @@ render_search_box(struct terminal *term)
|
|||
size_t glyph_offset = term->render.search_glyph_offset;
|
||||
|
||||
struct buffer_chain *chain = term->render.chains.search;
|
||||
struct buffer *buf = shm_get_buffer(chain, width, height, true);
|
||||
struct buffer *buf = shm_get_buffer(chain, width, height);
|
||||
|
||||
pixman_region32_t clip;
|
||||
pixman_region32_init_rect(&clip, 0, 0, width, height);
|
||||
|
|
@ -3690,18 +3796,18 @@ render_search_box(struct terminal *term)
|
|||
|
||||
const bool is_match = term->search.match_len == text_len;
|
||||
const bool custom_colors = is_match
|
||||
? term->conf->colors.use_custom.search_box_match
|
||||
: term->conf->colors.use_custom.search_box_no_match;
|
||||
? term->conf->colors_dark.use_custom.search_box_match
|
||||
: term->conf->colors_dark.use_custom.search_box_no_match;
|
||||
|
||||
/* Background - yellow on empty/match, red on mismatch (default) */
|
||||
const bool gamma_correct = wayl_do_linear_blending(term->wl, term->conf);
|
||||
const pixman_color_t color = color_hex_to_pixman(
|
||||
is_match
|
||||
? (custom_colors
|
||||
? term->conf->colors.search_box.match.bg
|
||||
? term->conf->colors_dark.search_box.match.bg
|
||||
: term->colors.table[3])
|
||||
: (custom_colors
|
||||
? term->conf->colors.search_box.no_match.bg
|
||||
? term->conf->colors_dark.search_box.no_match.bg
|
||||
: term->colors.table[1]),
|
||||
gamma_correct);
|
||||
|
||||
|
|
@ -3723,8 +3829,8 @@ render_search_box(struct terminal *term)
|
|||
pixman_color_t fg = color_hex_to_pixman(
|
||||
custom_colors
|
||||
? (is_match
|
||||
? term->conf->colors.search_box.match.fg
|
||||
: term->conf->colors.search_box.no_match.fg)
|
||||
? term->conf->colors_dark.search_box.match.fg
|
||||
: term->conf->colors_dark.search_box.no_match.fg)
|
||||
: term->colors.table[0],
|
||||
gamma_correct);
|
||||
|
||||
|
|
@ -4143,13 +4249,13 @@ render_urls(struct terminal *term)
|
|||
|
||||
struct buffer_chain *chain = term->render.chains.url;
|
||||
struct buffer *bufs[render_count];
|
||||
shm_get_many(chain, render_count, widths, heights, bufs, false);
|
||||
shm_get_many(chain, render_count, widths, heights, bufs);
|
||||
|
||||
uint32_t fg = term->conf->colors.use_custom.jump_label
|
||||
? term->conf->colors.jump_label.fg
|
||||
uint32_t fg = term->conf->colors_dark.use_custom.jump_label
|
||||
? term->conf->colors_dark.jump_label.fg
|
||||
: term->colors.table[0];
|
||||
uint32_t bg = term->conf->colors.use_custom.jump_label
|
||||
? term->conf->colors.jump_label.bg
|
||||
uint32_t bg = term->conf->colors_dark.use_custom.jump_label
|
||||
? term->conf->colors_dark.jump_label.bg
|
||||
: term->colors.table[3];
|
||||
|
||||
for (size_t i = 0; i < render_count; i++) {
|
||||
|
|
@ -4295,6 +4401,7 @@ delayed_reflow_of_normal_grid(struct terminal *term)
|
|||
term->interactive_resizing.old_hide_cursor = false;
|
||||
|
||||
/* Invalidate render pointers */
|
||||
render_wait_for_preapply_damage(term);
|
||||
shm_unref(term->render.last_buf);
|
||||
term->render.last_buf = NULL;
|
||||
term->render.last_cursor.row = NULL;
|
||||
|
|
@ -4869,6 +4976,7 @@ damage_view:
|
|||
tll_free(term->normal.scroll_damage);
|
||||
tll_free(term->alt.scroll_damage);
|
||||
|
||||
render_wait_for_preapply_damage(term);
|
||||
shm_unref(term->render.last_buf);
|
||||
term->render.last_buf = NULL;
|
||||
term_damage_view(term);
|
||||
|
|
@ -5267,3 +5375,77 @@ render_xcursor_set(struct seat *seat, struct terminal *term,
|
|||
seat->pointer.xcursor_pending = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
render_buffer_release_callback(struct buffer *buf, void *data)
|
||||
{
|
||||
/*
|
||||
* Called from shm.c when a buffer is released
|
||||
*
|
||||
* We use it to pre-apply last-frame's damage to it, when we're
|
||||
* forced to double buffer (compositor doesn't release buffers
|
||||
* immediately).
|
||||
*
|
||||
* The timeline is thus:
|
||||
* 1. We render and push a new frame
|
||||
* 2. Some (hopefully short) time after that, the compositor releases the previous buffer
|
||||
* 3. We're called, and kick off the thread that copies the changes from (1) to the just freed buffer
|
||||
* 4. Time passes....
|
||||
* 5. The compositor calls our frame callback, signalling to us that it's time to start rendering the next frame
|
||||
* 6. Hopefully, our thread is already done with copying the changes, otherwise we stall, waiting for it
|
||||
* 7. We render the frame as if the compositor does immediate releases.
|
||||
*
|
||||
* What's the gain? Reduced latency, by applying the previous
|
||||
* frame's damage as soon as possible, we shorten the time it
|
||||
* takes to render the frame after the frame callback.
|
||||
*
|
||||
* This means the compositor can, in theory, push the frame
|
||||
* callback closer to the vblank deadline, and thus reduce input
|
||||
* latency. Not all compositors (most, in fact?) don't adapt like
|
||||
* this, unfortunately. But some allows the user to manually
|
||||
* configure the deadline.
|
||||
*/
|
||||
struct terminal *term = data;
|
||||
|
||||
if (likely(buf->age != 1))
|
||||
return;
|
||||
|
||||
if (likely(!term->render.preapply_last_frame_damage))
|
||||
return;
|
||||
|
||||
if (term->render.last_buf == NULL)
|
||||
return;
|
||||
|
||||
if (term->render.last_buf->age != 0)
|
||||
return;
|
||||
|
||||
if (buf->width != term->render.last_buf->width)
|
||||
return;
|
||||
|
||||
if (buf->height != term->render.last_buf->height)
|
||||
return;
|
||||
|
||||
xassert(term->render.workers.count > 0);
|
||||
xassert(term->render.last_buf != NULL);
|
||||
|
||||
xassert(term->render.last_buf->age == 0);
|
||||
xassert(term->render.last_buf != buf);
|
||||
|
||||
mtx_lock(&term->render.workers.preapplied_damage.lock);
|
||||
if (term->render.workers.preapplied_damage.buf != NULL) {
|
||||
mtx_unlock(&term->render.workers.preapplied_damage.lock);
|
||||
return;
|
||||
}
|
||||
|
||||
xassert(term->render.workers.preapplied_damage.buf == NULL);
|
||||
term->render.workers.preapplied_damage.buf = buf;
|
||||
term->render.workers.preapplied_damage.start = (struct timespec){0};
|
||||
term->render.workers.preapplied_damage.stop = (struct timespec){0};
|
||||
mtx_unlock(&term->render.workers.preapplied_damage.lock);
|
||||
|
||||
mtx_lock(&term->render.workers.lock);
|
||||
sem_post(&term->render.workers.start);
|
||||
xassert(tll_length(term->render.workers.queue) == 0);
|
||||
tll_push_back(term->render.workers.queue, -3);
|
||||
mtx_unlock(&term->render.workers.lock);
|
||||
}
|
||||
|
|
|
|||
3
render.h
3
render.h
|
|
@ -47,3 +47,6 @@ struct csd_data {
|
|||
};
|
||||
|
||||
struct csd_data get_csd_data(const struct terminal *term, enum csd_surface surf_idx);
|
||||
|
||||
void render_buffer_release_callback(struct buffer *buf, void *data);
|
||||
void render_wait_for_preapply_damage(struct terminal *term);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import termios
|
|||
from datetime import datetime
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('files', type=argparse.FileType('rb'), nargs='+')
|
||||
parser.add_argument('--iterations', type=int, default=20)
|
||||
|
|
@ -24,12 +24,12 @@ def main():
|
|||
termios.TIOCGWINSZ,
|
||||
struct.pack('HHHH', 0, 0, 0, 0)))
|
||||
|
||||
times = {name: [] for name in [f.name for f in args.files]}
|
||||
times: dict[str, list[float]] = {name: [] for name in [f.name for f in args.files]}
|
||||
|
||||
for f in args.files:
|
||||
bench_bytes = f.read()
|
||||
|
||||
for i in range(args.iterations):
|
||||
for _ in range(args.iterations):
|
||||
start = datetime.now()
|
||||
sys.stdout.buffer.write(bench_bytes)
|
||||
stop = datetime.now()
|
||||
|
|
@ -48,4 +48,4 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import struct
|
|||
import sys
|
||||
import termios
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
class ColorVariant(enum.IntEnum):
|
||||
NONE = enum.auto()
|
||||
|
|
@ -17,7 +19,7 @@ class ColorVariant(enum.IntEnum):
|
|||
RGB = enum.auto()
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'out', type=argparse.FileType(mode='w'), nargs='?', help='name of output file')
|
||||
|
|
@ -38,10 +40,16 @@ def main():
|
|||
opts = parser.parse_args()
|
||||
out = opts.out if opts.out is not None else sys.stdout
|
||||
|
||||
lines: int | None = None
|
||||
cols: int | None = None
|
||||
width: int | None = None
|
||||
height: int | None = None
|
||||
|
||||
if opts.rows is None or opts.cols is None:
|
||||
try:
|
||||
def dummy(*args):
|
||||
def dummy(*args: Any) -> None:
|
||||
"""Need a handler installed for sigwait() to trigger."""
|
||||
_ = args
|
||||
pass
|
||||
signal.signal(signal.SIGWINCH, dummy)
|
||||
|
||||
|
|
@ -53,6 +61,9 @@ def main():
|
|||
termios.TIOCGWINSZ,
|
||||
struct.pack('HHHH', 0, 0, 0, 0)))
|
||||
|
||||
assert width is not None
|
||||
assert height is not None
|
||||
|
||||
if width > 0 and height > 0:
|
||||
break
|
||||
|
||||
|
|
@ -71,9 +82,11 @@ def main():
|
|||
|
||||
if opts.rows is not None:
|
||||
lines = opts.rows
|
||||
assert lines is not None
|
||||
height = 15 * lines # PGO helper binary hardcodes cell height to 15px
|
||||
if opts.cols is not None:
|
||||
cols = opts.cols
|
||||
assert cols is not None
|
||||
width = 8 * cols # PGO help binary hardcodes cell width to 8px
|
||||
|
||||
if lines is None or cols is None or height is None or width is None:
|
||||
|
|
@ -190,8 +203,8 @@ def main():
|
|||
# The sixel 'alphabet'
|
||||
sixels = '?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
|
||||
|
||||
last_pos = None
|
||||
last_size = None
|
||||
last_pos: tuple[int, int] | None = None
|
||||
last_size: tuple[int, int] = 0, 0
|
||||
|
||||
for _ in range(20):
|
||||
if last_pos is not None and random.randrange(2):
|
||||
|
|
@ -254,4 +267,4 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from typing import Dict, Union
|
||||
|
||||
|
||||
class Capability:
|
||||
def __init__(self, name: str, value: Union[bool, int, str]):
|
||||
def __init__(self, name: str, value: bool | int | str):
|
||||
self._name = name
|
||||
self._value = value
|
||||
|
||||
|
|
@ -17,25 +15,37 @@ class Capability:
|
|||
return self._name
|
||||
|
||||
@property
|
||||
def value(self) -> Union[bool, int, str]:
|
||||
def value(self) -> bool | int | str:
|
||||
return self._value
|
||||
|
||||
def __lt__(self, other):
|
||||
def __lt__(self, other: object) -> bool:
|
||||
if not isinstance(other, Capability):
|
||||
return NotImplemented
|
||||
return self._name < other._name
|
||||
|
||||
def __le__(self, other):
|
||||
def __le__(self, other: object) -> bool:
|
||||
if not isinstance(other, Capability):
|
||||
return NotImplemented
|
||||
return self._name <= other._name
|
||||
|
||||
def __eq__(self, other):
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, Capability):
|
||||
return NotImplemented
|
||||
return self._name == other._name
|
||||
|
||||
def __ne__(self, other):
|
||||
return self._name != other._name
|
||||
def __ne__(self, other: object) -> bool:
|
||||
if not isinstance(other, Capability):
|
||||
return NotImplemented
|
||||
return bool(self._name != other._name)
|
||||
|
||||
def __gt__(self, other):
|
||||
return self._name > other._name
|
||||
def __gt__(self, other: object) -> bool:
|
||||
if not isinstance(other, Capability):
|
||||
return NotImplemented
|
||||
return bool(self._name > other._name)
|
||||
|
||||
def __ge__(self, other):
|
||||
def __ge__(self, other: object) -> bool:
|
||||
if not isinstance(other, Capability):
|
||||
return NotImplemented
|
||||
return self._name >= other._name
|
||||
|
||||
|
||||
|
|
@ -53,7 +63,7 @@ class StringCapability(Capability):
|
|||
# see terminfo(5) for valid escape sequences
|
||||
|
||||
# Control characters
|
||||
def translate_ctrl_chr(m):
|
||||
def translate_ctrl_chr(m: re.Match[str]) -> str:
|
||||
ctrl = m.group(1)
|
||||
if ctrl == '?':
|
||||
return '\\x7f'
|
||||
|
|
@ -85,7 +95,7 @@ class Fragment:
|
|||
def __init__(self, name: str, description: str):
|
||||
self._name = name
|
||||
self._description = description
|
||||
self._caps = {}
|
||||
self._caps = dict[str, Capability]()
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
|
|
@ -96,18 +106,18 @@ class Fragment:
|
|||
return self._description
|
||||
|
||||
@property
|
||||
def caps(self) -> Dict[str, Capability]:
|
||||
def caps(self) -> dict[str, Capability]:
|
||||
return self._caps
|
||||
|
||||
def add_capability(self, cap: Capability):
|
||||
def add_capability(self, cap: Capability) -> None:
|
||||
assert cap.name not in self._caps
|
||||
self._caps[cap.name] = cap
|
||||
|
||||
def del_capability(self, name: str):
|
||||
def del_capability(self, name: str) -> None:
|
||||
del self._caps[name]
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('source_entry_name')
|
||||
parser.add_argument('source', type=argparse.FileType('r'))
|
||||
|
|
@ -120,15 +130,15 @@ def main():
|
|||
source = opts.source
|
||||
target = opts.target
|
||||
|
||||
lines = []
|
||||
for l in source.readlines():
|
||||
l = l.strip()
|
||||
if l.startswith('#'):
|
||||
lines = list[str]()
|
||||
for line in source.readlines():
|
||||
line = line.strip()
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
lines.append(l)
|
||||
lines.append(line)
|
||||
|
||||
fragments = {}
|
||||
cur_fragment = None
|
||||
fragments = dict[str, Fragment]()
|
||||
cur_fragment: Fragment | None = None
|
||||
|
||||
for m in re.finditer(
|
||||
r'(?P<name>(?P<entry_name>[-+\w@]+)\|(?P<entry_desc>.+?),)|'
|
||||
|
|
@ -147,17 +157,20 @@ def main():
|
|||
|
||||
elif m.group('bool_cap') is not None:
|
||||
name = m.group('bool_name')
|
||||
assert cur_fragment is not None
|
||||
cur_fragment.add_capability(BoolCapability(name))
|
||||
|
||||
elif m.group('int_cap') is not None:
|
||||
name = m.group('int_name')
|
||||
value = int(m.group('int_val'), 0)
|
||||
cur_fragment.add_capability(IntCapability(name, value))
|
||||
int_value = int(m.group('int_val'), 0)
|
||||
assert cur_fragment is not None
|
||||
cur_fragment.add_capability(IntCapability(name, int_value))
|
||||
|
||||
elif m.group('str_cap') is not None:
|
||||
name = m.group('str_name')
|
||||
value = m.group('str_val')
|
||||
cur_fragment.add_capability(StringCapability(name, value))
|
||||
str_value = m.group('str_val')
|
||||
assert cur_fragment is not None
|
||||
cur_fragment.add_capability(StringCapability(name, str_value))
|
||||
|
||||
else:
|
||||
assert False
|
||||
|
|
@ -166,6 +179,9 @@ def main():
|
|||
for frag in fragments.values():
|
||||
for cap in frag.caps.values():
|
||||
if cap.name == 'use':
|
||||
assert isinstance(cap, StringCapability)
|
||||
assert isinstance(cap.value, str)
|
||||
|
||||
use_frag = fragments[cap.value]
|
||||
for use_cap in use_frag.caps.values():
|
||||
frag.add_capability(use_cap)
|
||||
|
|
@ -185,8 +201,9 @@ def main():
|
|||
entry.add_capability(StringCapability('TN', target_entry_name))
|
||||
entry.add_capability(StringCapability('name', target_entry_name))
|
||||
entry.add_capability(IntCapability('RGB', 8)) # 8 bits per channel
|
||||
entry.add_capability(StringCapability('query-os-name', os.uname().sysname))
|
||||
|
||||
terminfo_parts = []
|
||||
terminfo_parts = list[str]()
|
||||
for cap in sorted(entry.caps.values()):
|
||||
name = cap.name
|
||||
value = str(cap.value)
|
||||
|
|
@ -210,4 +227,4 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
|
||||
class Codepoint:
|
||||
def __init__(self, start: int, end: None|int = None):
|
||||
def __init__(self, start: int, end: None | int = None):
|
||||
self.start = start
|
||||
self.end = start if end is None else end
|
||||
self.vs15 = False
|
||||
|
|
@ -15,7 +14,7 @@ class Codepoint:
|
|||
return f'{self.start:x}-{self.end:x}, vs15={self.vs15}, vs16={self.vs16}'
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('input', type=argparse.FileType('r'))
|
||||
parser.add_argument('output', type=argparse.FileType('w'))
|
||||
|
|
@ -100,4 +99,4 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import argparse
|
||||
import math
|
||||
import sys
|
||||
|
||||
|
||||
# Note: we use a pure gamma 2.2 function, rather than the piece-wise
|
||||
|
|
@ -17,7 +16,7 @@ def linear_to_srgb(f: float) -> float:
|
|||
return math.pow(f, 1 / 2.2)
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('c_output', type=argparse.FileType('w'))
|
||||
parser.add_argument('h_output', type=argparse.FileType('w'))
|
||||
|
|
@ -68,4 +67,4 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
main()
|
||||
|
|
|
|||
12
search.c
12
search.c
|
|
@ -283,8 +283,13 @@ matches_cell(const struct terminal *term, const struct cell *cell, size_t search
|
|||
if (composed == NULL && base == 0 && term->search.buf[search_ofs] == U' ')
|
||||
return 1;
|
||||
|
||||
if (c32ncasecmp(&base, &term->search.buf[search_ofs], 1) != 0)
|
||||
return -1;
|
||||
if (hasc32upper(term->search.buf)) {
|
||||
if (c32ncmp(&base, &term->search.buf[search_ofs], 1) != 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (c32ncasecmp(&base, &term->search.buf[search_ofs], 1) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (composed != NULL) {
|
||||
if (search_ofs + composed->count > term->search.len)
|
||||
|
|
@ -1479,7 +1484,8 @@ search_input(struct seat *seat, struct terminal *term,
|
|||
count = xkb_compose_state_get_utf8(
|
||||
seat->kbd.xkb_compose_state, (char *)buf, sizeof(buf));
|
||||
xkb_compose_state_reset(seat->kbd.xkb_compose_state);
|
||||
} else if (compose_status == XKB_COMPOSE_CANCELLED) {
|
||||
} else if (compose_status == XKB_COMPOSE_CANCELLED ||
|
||||
compose_status == XKB_COMPOSE_COMPOSING) {
|
||||
count = 0;
|
||||
} else {
|
||||
count = xkb_state_key_get_utf8(
|
||||
|
|
|
|||
13
selection.c
13
selection.c
|
|
@ -19,6 +19,7 @@
|
|||
#include "char32.h"
|
||||
#include "commands.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "extract.h"
|
||||
#include "grid.h"
|
||||
#include "misc.h"
|
||||
|
|
@ -558,9 +559,15 @@ selection_find_quote_left(struct terminal *term, struct coord *pos,
|
|||
if (*quote_char == '\0' ? (wc == '"' || wc == '\'')
|
||||
: wc == *quote_char)
|
||||
{
|
||||
pos->row = next_row;
|
||||
pos->col = next_col + 1;
|
||||
xassert(pos->col < term->cols);
|
||||
xassert(next_col + 1 <= term->cols);
|
||||
if (next_col + 1 == term->cols) {
|
||||
xassert(next_row < pos->row);
|
||||
pos->row = next_row + 1;
|
||||
pos->col = 0;
|
||||
} else {
|
||||
pos->row = next_row;
|
||||
pos->col = next_col + 1;
|
||||
}
|
||||
|
||||
*quote_char = wc;
|
||||
return true;
|
||||
|
|
|
|||
20
server.c
20
server.c
|
|
@ -182,11 +182,11 @@ fdm_client(struct fdm *fdm, int fd, int events, void *data)
|
|||
|
||||
switch (sigusr.signo) {
|
||||
case SIGUSR1:
|
||||
term_theme_switch_to_1(client->instance->terminal);
|
||||
term_theme_switch_to_dark(client->instance->terminal);
|
||||
break;
|
||||
|
||||
case SIGUSR2:
|
||||
term_theme_switch_to_2(client->instance->terminal);
|
||||
term_theme_switch_to_light(client->instance->terminal);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -670,21 +670,21 @@ server_destroy(struct server *server)
|
|||
}
|
||||
|
||||
void
|
||||
server_global_theme_switch_to_1(struct server *server)
|
||||
server_global_theme_switch_to_dark(struct server *server)
|
||||
{
|
||||
server->conf->initial_color_theme = COLOR_THEME1;
|
||||
server->conf->initial_color_theme = COLOR_THEME_DARK;
|
||||
tll_foreach(server->clients, it)
|
||||
term_theme_switch_to_1(it->item->instance->terminal);
|
||||
term_theme_switch_to_dark(it->item->instance->terminal);
|
||||
tll_foreach(server->terminals, it)
|
||||
term_theme_switch_to_1(it->item->terminal);
|
||||
term_theme_switch_to_dark(it->item->terminal);
|
||||
}
|
||||
|
||||
void
|
||||
server_global_theme_switch_to_2(struct server *server)
|
||||
server_global_theme_switch_to_light(struct server *server)
|
||||
{
|
||||
server->conf->initial_color_theme = COLOR_THEME2;
|
||||
server->conf->initial_color_theme = COLOR_THEME_LIGHT;
|
||||
tll_foreach(server->clients, it)
|
||||
term_theme_switch_to_2(it->item->instance->terminal);
|
||||
term_theme_switch_to_light(it->item->instance->terminal);
|
||||
tll_foreach(server->terminals, it)
|
||||
term_theme_switch_to_2(it->item->terminal);
|
||||
term_theme_switch_to_light(it->item->terminal);
|
||||
}
|
||||
|
|
|
|||
4
server.h
4
server.h
|
|
@ -10,5 +10,5 @@ struct server *server_init(struct config *conf, struct fdm *fdm,
|
|||
struct reaper *reaper, struct wayland *wayl);
|
||||
void server_destroy(struct server *server);
|
||||
|
||||
void server_global_theme_switch_to_1(struct server *server);
|
||||
void server_global_theme_switch_to_2(struct server *server);
|
||||
void server_global_theme_switch_to_dark(struct server *server);
|
||||
void server_global_theme_switch_to_light(struct server *server);
|
||||
|
|
|
|||
131
shm.c
131
shm.c
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <pixman.h>
|
||||
|
||||
#include <fcft/stride.h>
|
||||
#include <tllist.h>
|
||||
|
||||
#define LOG_MODULE "shm"
|
||||
|
|
@ -21,6 +20,7 @@
|
|||
#include "log.h"
|
||||
#include "debug.h"
|
||||
#include "macros.h"
|
||||
#include "stride.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#if !defined(MAP_UNINITIALIZED)
|
||||
|
|
@ -61,6 +61,8 @@ static off_t max_pool_size = 512 * 1024 * 1024;
|
|||
static bool can_punch_hole = false;
|
||||
static bool can_punch_hole_initialized = false;
|
||||
|
||||
static size_t min_stride_alignment = 0;
|
||||
|
||||
struct buffer_pool {
|
||||
int fd; /* memfd */
|
||||
struct wl_shm_pool *wl_pool;
|
||||
|
|
@ -82,9 +84,11 @@ struct buffer_private {
|
|||
struct buffer_pool *pool;
|
||||
off_t offset; /* Offset into memfd where data begins */
|
||||
size_t size;
|
||||
bool with_alpha;
|
||||
|
||||
bool scrollable;
|
||||
|
||||
void (*release_cb)(struct buffer *buf, void *data);
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
struct buffer_chain {
|
||||
|
|
@ -93,11 +97,11 @@ struct buffer_chain {
|
|||
size_t pix_instances;
|
||||
bool scrollable;
|
||||
|
||||
pixman_format_code_t pixman_fmt_without_alpha;
|
||||
enum wl_shm_format shm_format_without_alpha;
|
||||
pixman_format_code_t pixman_fmt;
|
||||
enum wl_shm_format shm_format;
|
||||
|
||||
pixman_format_code_t pixman_fmt_with_alpha;
|
||||
enum wl_shm_format shm_format_with_alpha;
|
||||
void (*release_cb)(struct buffer *buf, void *data);
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
static tll(struct buffer_private *) deferred;
|
||||
|
|
@ -113,6 +117,12 @@ shm_set_max_pool_size(off_t _max_pool_size)
|
|||
max_pool_size = _max_pool_size;
|
||||
}
|
||||
|
||||
void
|
||||
shm_set_min_stride_alignment(size_t _min_stride_alignment)
|
||||
{
|
||||
min_stride_alignment = _min_stride_alignment;
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_destroy_dont_close(struct buffer *buf)
|
||||
{
|
||||
|
|
@ -224,6 +234,10 @@ buffer_release(void *data, struct wl_buffer *wl_buffer)
|
|||
xassert(found);
|
||||
if (!found)
|
||||
LOG_WARN("deferred delete: buffer not on the 'deferred' list");
|
||||
} else {
|
||||
if (buffer->release_cb != NULL) {
|
||||
buffer->release_cb(&buffer->public, buffer->cb_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +245,6 @@ static const struct wl_buffer_listener buffer_listener = {
|
|||
.release = &buffer_release,
|
||||
};
|
||||
|
||||
#if __SIZEOF_POINTER__ == 8
|
||||
static size_t
|
||||
page_size(void)
|
||||
{
|
||||
|
|
@ -248,7 +261,6 @@ page_size(void)
|
|||
xassert(size > 0);
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
instantiate_offset(struct buffer_private *buf, off_t new_offset)
|
||||
|
|
@ -269,9 +281,7 @@ instantiate_offset(struct buffer_private *buf, off_t new_offset)
|
|||
wl_buf = wl_shm_pool_create_buffer(
|
||||
pool->wl_pool, new_offset,
|
||||
buf->public.width, buf->public.height, buf->public.stride,
|
||||
buf->with_alpha
|
||||
? buf->chain->shm_format_with_alpha
|
||||
: buf->chain->shm_format_without_alpha);
|
||||
buf->chain->shm_format);
|
||||
|
||||
if (wl_buf == NULL) {
|
||||
LOG_ERR("failed to create SHM buffer");
|
||||
|
|
@ -281,9 +291,7 @@ instantiate_offset(struct buffer_private *buf, off_t new_offset)
|
|||
/* One pixman image for each worker thread (do we really need multiple?) */
|
||||
for (size_t i = 0; i < buf->public.pix_instances; i++) {
|
||||
pix[i] = pixman_image_create_bits_no_clear(
|
||||
buf->with_alpha
|
||||
? buf->chain->pixman_fmt_with_alpha
|
||||
: buf->chain->pixman_fmt_without_alpha,
|
||||
buf->chain->pixman_fmt,
|
||||
buf->public.width, buf->public.height,
|
||||
(uint32_t *)mmapped, buf->public.stride);
|
||||
|
||||
|
|
@ -318,8 +326,7 @@ err:
|
|||
static void NOINLINE
|
||||
get_new_buffers(struct buffer_chain *chain, size_t count,
|
||||
int widths[static count], int heights[static count],
|
||||
struct buffer *bufs[static count], bool with_alpha,
|
||||
bool immediate_purge)
|
||||
struct buffer *bufs[static count], bool immediate_purge)
|
||||
{
|
||||
xassert(count == 1 || !chain->scrollable);
|
||||
/*
|
||||
|
|
@ -338,10 +345,14 @@ get_new_buffers(struct buffer_chain *chain, size_t count,
|
|||
size_t total_size = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
stride[i] = stride_for_format_and_width(
|
||||
with_alpha
|
||||
? chain->pixman_fmt_with_alpha
|
||||
: chain->pixman_fmt_without_alpha,
|
||||
widths[i]);
|
||||
chain->pixman_fmt, widths[i]);
|
||||
|
||||
if (min_stride_alignment > 0) {
|
||||
const size_t m = min_stride_alignment;
|
||||
stride[i] = (stride[i] + m - 1) / m * m;
|
||||
}
|
||||
|
||||
xassert(min_stride_alignment == 0 || stride[i] % min_stride_alignment == 0);
|
||||
sizes[i] = stride[i] * heights[i];
|
||||
total_size += sizes[i];
|
||||
}
|
||||
|
|
@ -383,9 +394,11 @@ get_new_buffers(struct buffer_chain *chain, size_t count,
|
|||
goto err;
|
||||
}
|
||||
|
||||
const size_t page_sz = page_size();
|
||||
|
||||
#if __SIZEOF_POINTER__ == 8
|
||||
off_t offset = chain->scrollable && max_pool_size > 0
|
||||
? (max_pool_size / 4) & ~(page_size() - 1)
|
||||
? (max_pool_size / 4) & ~(page_sz - 1)
|
||||
: 0;
|
||||
off_t memfd_size = chain->scrollable && max_pool_size > 0
|
||||
? max_pool_size
|
||||
|
|
@ -395,7 +408,8 @@ get_new_buffers(struct buffer_chain *chain, size_t count,
|
|||
off_t memfd_size = total_size;
|
||||
#endif
|
||||
|
||||
xassert(chain->scrollable || (offset == 0 && memfd_size == total_size));
|
||||
/* Page align */
|
||||
memfd_size = (memfd_size + page_sz - 1) & ~(page_sz - 1);
|
||||
|
||||
LOG_DBG("memfd-size: %lu, initial offset: %lu", memfd_size, offset);
|
||||
|
||||
|
|
@ -427,6 +441,9 @@ get_new_buffers(struct buffer_chain *chain, size_t count,
|
|||
memfd_size = total_size;
|
||||
chain->scrollable = false;
|
||||
|
||||
/* Page align */
|
||||
memfd_size = (memfd_size + page_sz - 1) & ~(page_sz - 1);
|
||||
|
||||
if (ftruncate(pool_fd, memfd_size) < 0) {
|
||||
LOG_ERRNO("failed to set size of SHM backing memory file");
|
||||
goto err;
|
||||
|
|
@ -492,11 +509,12 @@ get_new_buffers(struct buffer_chain *chain, size_t count,
|
|||
.chain = chain,
|
||||
.ref_count = immediate_purge ? 0 : 1,
|
||||
.busy = true,
|
||||
.with_alpha = with_alpha,
|
||||
.pool = pool,
|
||||
.offset = 0,
|
||||
.size = sizes[i],
|
||||
.scrollable = chain->scrollable,
|
||||
.release_cb = chain->release_cb,
|
||||
.cb_data = chain->cb_data,
|
||||
};
|
||||
|
||||
if (!instantiate_offset(buf, offset)) {
|
||||
|
|
@ -562,13 +580,13 @@ shm_did_not_use_buf(struct buffer *_buf)
|
|||
void
|
||||
shm_get_many(struct buffer_chain *chain, size_t count,
|
||||
int widths[static count], int heights[static count],
|
||||
struct buffer *bufs[static count], bool with_alpha)
|
||||
struct buffer *bufs[static count])
|
||||
{
|
||||
get_new_buffers(chain, count, widths, heights, bufs, with_alpha, true);
|
||||
get_new_buffers(chain, count, widths, heights, bufs, true);
|
||||
}
|
||||
|
||||
struct buffer *
|
||||
shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alpha)
|
||||
shm_get_buffer(struct buffer_chain *chain, int width, int height)
|
||||
{
|
||||
LOG_DBG(
|
||||
"chain=%p: looking for a reusable %dx%d buffer "
|
||||
|
|
@ -579,9 +597,7 @@ shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alph
|
|||
tll_foreach(chain->bufs, it) {
|
||||
struct buffer_private *buf = it->item;
|
||||
|
||||
if (buf->public.width != width || buf->public.height != height ||
|
||||
with_alpha != buf->with_alpha)
|
||||
{
|
||||
if (buf->public.width != width || buf->public.height != height) {
|
||||
LOG_DBG("purging mismatching buffer %p", (void *)buf);
|
||||
if (buffer_unref_no_remove_from_chain(buf))
|
||||
tll_remove(chain->bufs, it);
|
||||
|
|
@ -597,9 +613,9 @@ shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alph
|
|||
else
|
||||
#endif
|
||||
{
|
||||
if (cached == NULL)
|
||||
if (cached == NULL) {
|
||||
cached = buf;
|
||||
else {
|
||||
} else {
|
||||
/* We have multiple buffers eligible for
|
||||
* reuse. Pick the "youngest" one, and mark the
|
||||
* other one for purging */
|
||||
|
|
@ -632,7 +648,7 @@ shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alph
|
|||
}
|
||||
|
||||
struct buffer *ret;
|
||||
get_new_buffers(chain, 1, &width, &height, &ret, with_alpha, false);
|
||||
get_new_buffers(chain, 1, &width, &height, &ret, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -975,13 +991,11 @@ shm_unref(struct buffer *_buf)
|
|||
|
||||
struct buffer_chain *
|
||||
shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
|
||||
enum shm_bit_depth desired_bit_depth)
|
||||
enum shm_bit_depth desired_bit_depth,
|
||||
void (*release_cb)(struct buffer *buf, void *data), void *cb_data)
|
||||
{
|
||||
pixman_format_code_t pixman_fmt_without_alpha = PIXMAN_x8r8g8b8;
|
||||
enum wl_shm_format shm_fmt_without_alpha = WL_SHM_FORMAT_XRGB8888;
|
||||
|
||||
pixman_format_code_t pixman_fmt_with_alpha = PIXMAN_a8r8g8b8;
|
||||
enum wl_shm_format shm_fmt_with_alpha = WL_SHM_FORMAT_ARGB8888;
|
||||
pixman_format_code_t pixman_fmt = PIXMAN_a8r8g8b8;
|
||||
enum wl_shm_format shm_fmt = WL_SHM_FORMAT_ARGB8888;
|
||||
|
||||
static bool have_logged = false;
|
||||
static bool have_logged_10_fallback = false;
|
||||
|
|
@ -990,12 +1004,9 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
|
|||
static bool have_logged_16_fallback = false;
|
||||
|
||||
if (desired_bit_depth == SHM_BITS_16) {
|
||||
if (wayl->shm_have_abgr161616 && wayl->shm_have_xbgr161616) {
|
||||
pixman_fmt_without_alpha = PIXMAN_a16b16g16r16;
|
||||
shm_fmt_without_alpha = WL_SHM_FORMAT_XBGR16161616;
|
||||
|
||||
pixman_fmt_with_alpha = PIXMAN_a16b16g16r16;
|
||||
shm_fmt_with_alpha = WL_SHM_FORMAT_ABGR16161616;
|
||||
if (wayl->shm_have_abgr161616) {
|
||||
pixman_fmt = PIXMAN_a16b16g16r16;
|
||||
shm_fmt = WL_SHM_FORMAT_ABGR16161616;
|
||||
|
||||
if (!have_logged) {
|
||||
have_logged = true;
|
||||
|
|
@ -1013,15 +1024,10 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (desired_bit_depth >= SHM_BITS_10 &&
|
||||
pixman_fmt_with_alpha == PIXMAN_a8r8g8b8)
|
||||
{
|
||||
if (wayl->shm_have_argb2101010 && wayl->shm_have_xrgb2101010) {
|
||||
pixman_fmt_without_alpha = PIXMAN_x2r10g10b10;
|
||||
shm_fmt_without_alpha = WL_SHM_FORMAT_XRGB2101010;
|
||||
|
||||
pixman_fmt_with_alpha = PIXMAN_a2r10g10b10;
|
||||
shm_fmt_with_alpha = WL_SHM_FORMAT_ARGB2101010;
|
||||
if (desired_bit_depth >= SHM_BITS_10 && pixman_fmt == PIXMAN_a8r8g8b8) {
|
||||
if (wayl->shm_have_argb2101010) {
|
||||
pixman_fmt = PIXMAN_a2r10g10b10;
|
||||
shm_fmt = WL_SHM_FORMAT_ARGB2101010;
|
||||
|
||||
if (!have_logged) {
|
||||
have_logged = true;
|
||||
|
|
@ -1029,12 +1035,9 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
|
|||
}
|
||||
}
|
||||
|
||||
else if (wayl->shm_have_abgr2101010 && wayl->shm_have_xbgr2101010) {
|
||||
pixman_fmt_without_alpha = PIXMAN_x2b10g10r10;
|
||||
shm_fmt_without_alpha = WL_SHM_FORMAT_XBGR2101010;
|
||||
|
||||
pixman_fmt_with_alpha = PIXMAN_a2b10g10r10;
|
||||
shm_fmt_with_alpha = WL_SHM_FORMAT_ABGR2101010;
|
||||
else if (wayl->shm_have_abgr2101010) {
|
||||
pixman_fmt = PIXMAN_a2b10g10r10;
|
||||
shm_fmt = WL_SHM_FORMAT_ABGR2101010;
|
||||
|
||||
if (!have_logged) {
|
||||
have_logged = true;
|
||||
|
|
@ -1066,11 +1069,11 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
|
|||
.pix_instances = pix_instances,
|
||||
.scrollable = scrollable,
|
||||
|
||||
.pixman_fmt_without_alpha = pixman_fmt_without_alpha,
|
||||
.shm_format_without_alpha = shm_fmt_without_alpha,
|
||||
.pixman_fmt = pixman_fmt,
|
||||
.shm_format = shm_fmt,
|
||||
|
||||
.pixman_fmt_with_alpha = pixman_fmt_with_alpha,
|
||||
.shm_format_with_alpha = shm_fmt_with_alpha,
|
||||
.release_cb = release_cb,
|
||||
.cb_data = cb_data,
|
||||
};
|
||||
return chain;
|
||||
}
|
||||
|
|
@ -1094,7 +1097,7 @@ shm_chain_free(struct buffer_chain *chain)
|
|||
enum shm_bit_depth
|
||||
shm_chain_bit_depth(const struct buffer_chain *chain)
|
||||
{
|
||||
const pixman_format_code_t fmt = chain->pixman_fmt_with_alpha;
|
||||
const pixman_format_code_t fmt = chain->pixman_fmt;
|
||||
|
||||
return fmt == PIXMAN_a8r8g8b8
|
||||
? SHM_BITS_8
|
||||
|
|
|
|||
11
shm.h
11
shm.h
|
|
@ -42,12 +42,16 @@ struct buffer {
|
|||
};
|
||||
|
||||
void shm_fini(void);
|
||||
|
||||
/* TODO: combine into shm_init() */
|
||||
void shm_set_max_pool_size(off_t max_pool_size);
|
||||
void shm_set_min_stride_alignment(size_t min_stride_alignment);
|
||||
|
||||
struct buffer_chain;
|
||||
struct buffer_chain *shm_chain_new(
|
||||
struct wayland *wayl, bool scrollable, size_t pix_instances,
|
||||
enum shm_bit_depth desired_bit_depth);
|
||||
enum shm_bit_depth desired_bit_depth,
|
||||
void (*release_cb)(struct buffer *buf, void *data), void *cb_data);
|
||||
void shm_chain_free(struct buffer_chain *chain);
|
||||
|
||||
enum shm_bit_depth shm_chain_bit_depth(const struct buffer_chain *chain);
|
||||
|
|
@ -61,8 +65,7 @@ enum shm_bit_depth shm_chain_bit_depth(const struct buffer_chain *chain);
|
|||
*
|
||||
* A newly allocated buffer has an age of 1234.
|
||||
*/
|
||||
struct buffer *shm_get_buffer(
|
||||
struct buffer_chain *chain, int width, int height, bool with_alpha);
|
||||
struct buffer *shm_get_buffer(struct buffer_chain *chain, int width, int height);
|
||||
/*
|
||||
* Returns many buffers, described by 'info', all sharing the same SHM
|
||||
* buffer pool.
|
||||
|
|
@ -80,7 +83,7 @@ struct buffer *shm_get_buffer(
|
|||
void shm_get_many(
|
||||
struct buffer_chain *chain, size_t count,
|
||||
int widths[static count], int heights[static count],
|
||||
struct buffer *bufs[static count], bool with_alpha);
|
||||
struct buffer *bufs[static count]);
|
||||
|
||||
void shm_did_not_use_buf(struct buffer *buf);
|
||||
|
||||
|
|
|
|||
13
sixel.c
13
sixel.c
|
|
@ -125,19 +125,19 @@ sixel_init(struct terminal *term, int p1, int p2, int p3)
|
|||
* that assumes 32-bit pixels).
|
||||
*/
|
||||
if (shm_chain_bit_depth(term->render.chains.grid) >= SHM_BITS_10) {
|
||||
if (term->wl->shm_have_argb2101010 && term->wl->shm_have_xrgb2101010) {
|
||||
if (term->wl->shm_have_argb2101010) {
|
||||
term->sixel.use_10bit = true;
|
||||
term->sixel.pixman_fmt = PIXMAN_a2r10g10b10;
|
||||
}
|
||||
|
||||
else if (term->wl->shm_have_abgr2101010 && term->wl->shm_have_xbgr2101010) {
|
||||
else if (term->wl->shm_have_abgr2101010) {
|
||||
term->sixel.use_10bit = true;
|
||||
term->sixel.pixman_fmt = PIXMAN_a2b10g10r10;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t active_palette_entries = min(
|
||||
ALEN(term->conf->colors.sixel), term->sixel.palette_size);
|
||||
ALEN(term->conf->colors_dark.sixel), term->sixel.palette_size);
|
||||
|
||||
if (term->sixel.use_private_palette) {
|
||||
xassert(term->sixel.private_palette == NULL);
|
||||
|
|
@ -145,7 +145,7 @@ sixel_init(struct terminal *term, int p1, int p2, int p3)
|
|||
term->sixel.palette_size, sizeof(term->sixel.private_palette[0]));
|
||||
|
||||
memcpy(
|
||||
term->sixel.private_palette, term->conf->colors.sixel,
|
||||
term->sixel.private_palette, term->conf->colors_dark.sixel,
|
||||
active_palette_entries * sizeof(term->sixel.private_palette[0]));
|
||||
|
||||
if (term->sixel.linear_blending || term->sixel.use_10bit) {
|
||||
|
|
@ -164,7 +164,7 @@ sixel_init(struct terminal *term, int p1, int p2, int p3)
|
|||
term->sixel.palette_size, sizeof(term->sixel.shared_palette[0]));
|
||||
|
||||
memcpy(
|
||||
term->sixel.shared_palette, term->conf->colors.sixel,
|
||||
term->sixel.shared_palette, term->conf->colors_dark.sixel,
|
||||
active_palette_entries * sizeof(term->sixel.shared_palette[0]));
|
||||
|
||||
if (term->sixel.linear_blending || term->sixel.use_10bit) {
|
||||
|
|
@ -1559,6 +1559,9 @@ resize(struct terminal *term, int new_width_mutable, int new_height_mutable)
|
|||
new_height_mutable = term->sixel.max_height;
|
||||
}
|
||||
|
||||
if (unlikely(new_height_mutable == 0)) {
|
||||
new_height_mutable = 6 * term->sixel.pan;
|
||||
}
|
||||
|
||||
uint32_t *old_data = term->sixel.image.data;
|
||||
const int old_width = term->sixel.image.width;
|
||||
|
|
|
|||
90
terminal.c
90
terminal.c
|
|
@ -719,6 +719,9 @@ initialize_render_workers(struct terminal *term)
|
|||
goto err_sem_destroy;
|
||||
}
|
||||
|
||||
mtx_init(&term->render.workers.preapplied_damage.lock, mtx_plain);
|
||||
cnd_init(&term->render.workers.preapplied_damage.cond);
|
||||
|
||||
term->render.workers.threads = xcalloc(
|
||||
term->render.workers.count, sizeof(term->render.workers.threads[0]));
|
||||
|
||||
|
|
@ -1268,8 +1271,10 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
|||
|
||||
const struct color_theme *theme = NULL;
|
||||
switch (conf->initial_color_theme) {
|
||||
case COLOR_THEME1: theme = &conf->colors; break;
|
||||
case COLOR_THEME2: theme = &conf->colors2; break;
|
||||
case COLOR_THEME_DARK: theme = &conf->colors_dark; break;
|
||||
case COLOR_THEME_LIGHT: theme = &conf->colors_light; break;
|
||||
case COLOR_THEME_1: BUG("COLOR_THEME_1 should not be used"); break;
|
||||
case COLOR_THEME_2: BUG("COLOR_THEME_2 should not be used"); break;
|
||||
}
|
||||
|
||||
/* Initialize configure-based terminal attributes */
|
||||
|
|
@ -1356,13 +1361,13 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
|||
.render = {
|
||||
.chains = {
|
||||
.grid = shm_chain_new(wayl, true, 1 + conf->render_worker_count,
|
||||
desired_bit_depth),
|
||||
.search = shm_chain_new(wayl, false, 1 ,desired_bit_depth),
|
||||
.scrollback_indicator = shm_chain_new(wayl, false, 1, desired_bit_depth),
|
||||
.render_timer = shm_chain_new(wayl, false, 1, desired_bit_depth),
|
||||
.url = shm_chain_new(wayl, false, 1, desired_bit_depth),
|
||||
.csd = shm_chain_new(wayl, false, 1, desired_bit_depth),
|
||||
.overlay = shm_chain_new(wayl, false, 1, desired_bit_depth),
|
||||
desired_bit_depth, &render_buffer_release_callback, term),
|
||||
.search = shm_chain_new(wayl, false, 1 ,desired_bit_depth, NULL, NULL),
|
||||
.scrollback_indicator = shm_chain_new(wayl, false, 1, desired_bit_depth, NULL, NULL),
|
||||
.render_timer = shm_chain_new(wayl, false, 1, desired_bit_depth, NULL, NULL),
|
||||
.url = shm_chain_new(wayl, false, 1, desired_bit_depth, NULL, NULL),
|
||||
.csd = shm_chain_new(wayl, false, 1, desired_bit_depth, NULL, NULL),
|
||||
.overlay = shm_chain_new(wayl, false, 1, desired_bit_depth, NULL, NULL),
|
||||
},
|
||||
.scrollback_lines = conf->scrollback.lines,
|
||||
.app_sync_updates.timer_fd = app_sync_updates_fd,
|
||||
|
|
@ -1893,6 +1898,8 @@ term_destroy(struct terminal *term)
|
|||
}
|
||||
}
|
||||
free(term->render.workers.threads);
|
||||
mtx_destroy(&term->render.workers.preapplied_damage.lock);
|
||||
cnd_destroy(&term->render.workers.preapplied_damage.cond);
|
||||
mtx_destroy(&term->render.workers.lock);
|
||||
sem_destroy(&term->render.workers.start);
|
||||
sem_destroy(&term->render.workers.done);
|
||||
|
|
@ -2172,8 +2179,10 @@ term_reset(struct terminal *term, bool hard)
|
|||
const struct color_theme *theme = NULL;
|
||||
|
||||
switch (term->conf->initial_color_theme) {
|
||||
case COLOR_THEME1: theme = &term->conf->colors; break;
|
||||
case COLOR_THEME2: theme = &term->conf->colors2; break;
|
||||
case COLOR_THEME_DARK: theme = &term->conf->colors_dark; break;
|
||||
case COLOR_THEME_LIGHT: theme = &term->conf->colors_light; break;
|
||||
case COLOR_THEME_1: BUG("COLOR_THEME_1 should not be used"); break;
|
||||
case COLOR_THEME_2: BUG("COLOR_THEME_2 should not be used"); break;
|
||||
}
|
||||
|
||||
term->flash.active = false;
|
||||
|
|
@ -3160,11 +3169,17 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
|
||||
sixel_scroll_down(term, rows);
|
||||
|
||||
bool view_follows = term->grid->view == term->grid->offset;
|
||||
const bool view_follows = term->grid->view == term->grid->offset;
|
||||
term->grid->offset -= rows;
|
||||
term->grid->offset += term->grid->num_rows;
|
||||
term->grid->offset &= term->grid->num_rows - 1;
|
||||
|
||||
/* How many lines from the scrollback start is the current viewport? */
|
||||
const int view_sb_start_distance = grid_row_abs_to_sb(
|
||||
term->grid, term->rows, term->grid->view);
|
||||
const int offset_sb_start_distance = grid_row_abs_to_sb(
|
||||
term->grid, term->rows, term->grid->offset);
|
||||
|
||||
xassert(term->grid->offset >= 0);
|
||||
xassert(term->grid->offset < term->grid->num_rows);
|
||||
|
||||
|
|
@ -3172,6 +3187,11 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
term_damage_scroll(term, DAMAGE_SCROLL_REVERSE, region, rows);
|
||||
selection_view_up(term, term->grid->offset);
|
||||
term->grid->view = term->grid->offset;
|
||||
} else if (unlikely(view_sb_start_distance > offset_sb_start_distance)) {
|
||||
/* Part of current view is being scrolled out */
|
||||
int new_view = term->grid->offset;
|
||||
selection_view_up(term, new_view);
|
||||
term->grid->view = new_view;
|
||||
}
|
||||
|
||||
/* Bottom non-scrolling region */
|
||||
|
|
@ -3188,11 +3208,16 @@ term_scroll_reverse_partial(struct terminal *term,
|
|||
erase_line(term, row);
|
||||
}
|
||||
|
||||
if (unlikely(view_sb_start_distance > offset_sb_start_distance))
|
||||
term_damage_view(term);
|
||||
|
||||
term->grid->cur_row = grid_row(term->grid, term->grid->cursor.point.row);
|
||||
|
||||
#if defined(_DEBUG)
|
||||
for (int r = 0; r < term->rows; r++)
|
||||
xassert(grid_row(term->grid, r) != NULL);
|
||||
for (int r = 0; r < term->rows; r++)
|
||||
xassert(grid_row_in_view(term->grid, r) != NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -3399,10 +3424,13 @@ report_mouse_click(struct terminal *term, int encoded_button, int row, int col,
|
|||
encoded_button, col + 1, row + 1, release ? 'm' : 'M');
|
||||
break;
|
||||
|
||||
case MOUSE_SGR_PIXELS:
|
||||
case MOUSE_SGR_PIXELS: {
|
||||
const int bounded_col = max(col_pixels, 0);
|
||||
const int bounded_row = max(row_pixels, 0);
|
||||
snprintf(response, sizeof(response), "\033[<%d;%d;%d%c",
|
||||
encoded_button, col_pixels + 1, row_pixels + 1, release ? 'm' : 'M');
|
||||
encoded_button, bounded_col + 1, bounded_row + 1, release ? 'm' : 'M');
|
||||
break;
|
||||
}
|
||||
|
||||
case MOUSE_URXVT:
|
||||
snprintf(response, sizeof(response), "\033[%d;%d;%dM",
|
||||
|
|
@ -4005,9 +4033,11 @@ term_print(struct terminal *term, char32_t wc, int width, bool insert_mode_disab
|
|||
cell->wc = term->vt.last_printed = wc;
|
||||
cell->attrs = term->vt.attrs;
|
||||
|
||||
if (term->vt.osc8.uri != NULL) {
|
||||
grid_row_uri_range_put(
|
||||
row, col, term->vt.osc8.uri, term->vt.osc8.id);
|
||||
if (unlikely(term->vt.osc8.uri != NULL)) {
|
||||
for (int i = 0; i < width && (col + i) < term->cols; i++) {
|
||||
grid_row_uri_range_put(
|
||||
row, col + i, term->vt.osc8.uri, term->vt.osc8.id);
|
||||
}
|
||||
|
||||
switch (term->conf->url.osc8_underline) {
|
||||
case OSC8_UNDERLINE_ALWAYS:
|
||||
|
|
@ -4716,13 +4746,13 @@ term_send_size_notification(struct terminal *term)
|
|||
}
|
||||
|
||||
void
|
||||
term_theme_switch_to_1(struct terminal *term)
|
||||
term_theme_switch_to_dark(struct terminal *term)
|
||||
{
|
||||
if (term->colors.active_theme == COLOR_THEME1)
|
||||
if (term->colors.active_theme == COLOR_THEME_DARK)
|
||||
return;
|
||||
|
||||
term_theme_apply(term, &term->conf->colors);
|
||||
term->colors.active_theme = COLOR_THEME1;
|
||||
term_theme_apply(term, &term->conf->colors_dark);
|
||||
term->colors.active_theme = COLOR_THEME_DARK;
|
||||
|
||||
wayl_win_alpha_changed(term->window);
|
||||
term_font_subpixel_changed(term);
|
||||
|
|
@ -4736,13 +4766,13 @@ term_theme_switch_to_1(struct terminal *term)
|
|||
}
|
||||
|
||||
void
|
||||
term_theme_switch_to_2(struct terminal *term)
|
||||
term_theme_switch_to_light(struct terminal *term)
|
||||
{
|
||||
if (term->colors.active_theme == COLOR_THEME2)
|
||||
if (term->colors.active_theme == COLOR_THEME_LIGHT)
|
||||
return;
|
||||
|
||||
term_theme_apply(term, &term->conf->colors2);
|
||||
term->colors.active_theme = COLOR_THEME2;
|
||||
term_theme_apply(term, &term->conf->colors_light);
|
||||
term->colors.active_theme = COLOR_THEME_LIGHT;
|
||||
|
||||
wayl_win_alpha_changed(term->window);
|
||||
term_font_subpixel_changed(term);
|
||||
|
|
@ -4758,15 +4788,15 @@ term_theme_switch_to_2(struct terminal *term)
|
|||
void
|
||||
term_theme_toggle(struct terminal *term)
|
||||
{
|
||||
if (term->colors.active_theme == COLOR_THEME1) {
|
||||
term_theme_apply(term, &term->conf->colors2);
|
||||
term->colors.active_theme = COLOR_THEME2;
|
||||
if (term->colors.active_theme == COLOR_THEME_DARK) {
|
||||
term_theme_apply(term, &term->conf->colors_light);
|
||||
term->colors.active_theme = COLOR_THEME_LIGHT;
|
||||
|
||||
if (term->report_theme_changes)
|
||||
term_to_slave(term, "\033[?997;2n", 9);
|
||||
} else {
|
||||
term_theme_apply(term, &term->conf->colors);
|
||||
term->colors.active_theme = COLOR_THEME1;
|
||||
term_theme_apply(term, &term->conf->colors_dark);
|
||||
term->colors.active_theme = COLOR_THEME_DARK;
|
||||
|
||||
if (term->report_theme_changes)
|
||||
term_to_slave(term, "\033[?997;1n", 9);
|
||||
|
|
|
|||
14
terminal.h
14
terminal.h
|
|
@ -706,6 +706,14 @@ struct terminal {
|
|||
tll(int) queue;
|
||||
thrd_t *threads;
|
||||
struct buffer *buf;
|
||||
|
||||
struct {
|
||||
mtx_t lock;
|
||||
cnd_t cond;
|
||||
struct buffer *buf;
|
||||
struct timespec start;
|
||||
struct timespec stop;
|
||||
} preapplied_damage;
|
||||
} workers;
|
||||
|
||||
/* Last rendered cursor position */
|
||||
|
|
@ -716,6 +724,8 @@ struct terminal {
|
|||
} last_cursor;
|
||||
|
||||
struct buffer *last_buf; /* Buffer we rendered to last time */
|
||||
size_t frames_since_last_immediate_release;
|
||||
bool preapply_last_frame_damage;
|
||||
|
||||
enum overlay_style last_overlay_style;
|
||||
struct buffer *last_overlay_buf;
|
||||
|
|
@ -984,8 +994,8 @@ void term_enable_size_notifications(struct terminal *term);
|
|||
void term_disable_size_notifications(struct terminal *term);
|
||||
void term_send_size_notification(struct terminal *term);
|
||||
|
||||
void term_theme_switch_to_1(struct terminal *term);
|
||||
void term_theme_switch_to_2(struct terminal *term);
|
||||
void term_theme_switch_to_dark(struct terminal *term);
|
||||
void term_theme_switch_to_light(struct terminal *term);
|
||||
void term_theme_toggle(struct terminal *term);
|
||||
|
||||
static inline void term_reset_grapheme_state(struct terminal *term)
|
||||
|
|
|
|||
|
|
@ -482,6 +482,7 @@ test_section_main(void)
|
|||
test_string(&ctx, &parse_section_main, "shell", &conf.shell);
|
||||
test_string(&ctx, &parse_section_main, "term", &conf.term);
|
||||
test_string(&ctx, &parse_section_main, "app-id", &conf.app_id);
|
||||
test_string(&ctx, &parse_section_main, "toplevel-tag", &conf.toplevel_tag);
|
||||
test_string(&ctx, &parse_section_main, "utmp-helper", &conf.utmp_helper_path);
|
||||
|
||||
test_c32string(&ctx, &parse_section_main, "word-delimiters", &conf.word_delimiters);
|
||||
|
|
@ -520,6 +521,14 @@ test_section_main(void)
|
|||
(int []){STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN},
|
||||
(int *)&conf.startup_mode);
|
||||
|
||||
test_enum(
|
||||
&ctx, &parse_section_main, "initial-color-theme",
|
||||
2,
|
||||
(const char *[]){"dark", "light", "1", "2"},
|
||||
(int []){COLOR_THEME_DARK, COLOR_THEME_LIGHT,
|
||||
COLOR_THEME_DARK, COLOR_THEME_LIGHT},
|
||||
(int *)&conf.initial_color_theme);
|
||||
|
||||
/* TODO: font (custom) */
|
||||
/* TODO: include (custom) */
|
||||
/* TODO: bold-text-in-bright (enum/boolean) */
|
||||
|
|
@ -694,73 +703,157 @@ test_section_touch(void)
|
|||
}
|
||||
|
||||
static void
|
||||
test_section_colors(void)
|
||||
test_section_colors_dark(void)
|
||||
{
|
||||
struct config conf = {0};
|
||||
struct context ctx = {
|
||||
.conf = &conf, .section = "colors", .path = "unittest"};
|
||||
.conf = &conf, .section = "colors-dark", .path = "unittest"};
|
||||
|
||||
test_invalid_key(&ctx, &parse_section_colors, "invalid-key");
|
||||
|
||||
test_color(&ctx, &parse_section_colors, "foreground", false, &conf.colors.fg);
|
||||
test_color(&ctx, &parse_section_colors, "background", false, &conf.colors.bg);
|
||||
test_color(&ctx, &parse_section_colors, "regular0", false, &conf.colors.table[0]);
|
||||
test_color(&ctx, &parse_section_colors, "regular1", false, &conf.colors.table[1]);
|
||||
test_color(&ctx, &parse_section_colors, "regular2", false, &conf.colors.table[2]);
|
||||
test_color(&ctx, &parse_section_colors, "regular3", false, &conf.colors.table[3]);
|
||||
test_color(&ctx, &parse_section_colors, "regular4", false, &conf.colors.table[4]);
|
||||
test_color(&ctx, &parse_section_colors, "regular5", false, &conf.colors.table[5]);
|
||||
test_color(&ctx, &parse_section_colors, "regular6", false, &conf.colors.table[6]);
|
||||
test_color(&ctx, &parse_section_colors, "regular7", false, &conf.colors.table[7]);
|
||||
test_color(&ctx, &parse_section_colors, "bright0", false, &conf.colors.table[8]);
|
||||
test_color(&ctx, &parse_section_colors, "bright1", false, &conf.colors.table[9]);
|
||||
test_color(&ctx, &parse_section_colors, "bright2", false, &conf.colors.table[10]);
|
||||
test_color(&ctx, &parse_section_colors, "bright3", false, &conf.colors.table[11]);
|
||||
test_color(&ctx, &parse_section_colors, "bright4", false, &conf.colors.table[12]);
|
||||
test_color(&ctx, &parse_section_colors, "bright5", false, &conf.colors.table[13]);
|
||||
test_color(&ctx, &parse_section_colors, "bright6", false, &conf.colors.table[14]);
|
||||
test_color(&ctx, &parse_section_colors, "bright7", false, &conf.colors.table[15]);
|
||||
test_color(&ctx, &parse_section_colors, "dim0", false, &conf.colors.dim[0]);
|
||||
test_color(&ctx, &parse_section_colors, "dim1", false, &conf.colors.dim[1]);
|
||||
test_color(&ctx, &parse_section_colors, "dim2", false, &conf.colors.dim[2]);
|
||||
test_color(&ctx, &parse_section_colors, "dim3", false, &conf.colors.dim[3]);
|
||||
test_color(&ctx, &parse_section_colors, "dim4", false, &conf.colors.dim[4]);
|
||||
test_color(&ctx, &parse_section_colors, "dim5", false, &conf.colors.dim[5]);
|
||||
test_color(&ctx, &parse_section_colors, "dim6", false, &conf.colors.dim[6]);
|
||||
test_color(&ctx, &parse_section_colors, "dim7", false, &conf.colors.dim[7]);
|
||||
test_color(&ctx, &parse_section_colors, "selection-foreground", false, &conf.colors.selection_fg);
|
||||
test_color(&ctx, &parse_section_colors, "selection-background", false, &conf.colors.selection_bg);
|
||||
test_color(&ctx, &parse_section_colors, "urls", false, &conf.colors.url);
|
||||
test_two_colors(&ctx, &parse_section_colors, "jump-labels", false,
|
||||
&conf.colors.jump_label.fg,
|
||||
&conf.colors.jump_label.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors, "scrollback-indicator", false,
|
||||
&conf.colors.scrollback_indicator.fg,
|
||||
&conf.colors.scrollback_indicator.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors, "search-box-no-match", false,
|
||||
&conf.colors.search_box.no_match.fg,
|
||||
&conf.colors.search_box.no_match.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors, "search-box-match", false,
|
||||
&conf.colors.search_box.match.fg,
|
||||
&conf.colors.search_box.match.bg);
|
||||
test_color(&ctx, &parse_section_colors_dark, "foreground", false, &conf.colors_dark.fg);
|
||||
test_color(&ctx, &parse_section_colors_dark, "background", false, &conf.colors_dark.bg);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular0", false, &conf.colors_dark.table[0]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular1", false, &conf.colors_dark.table[1]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular2", false, &conf.colors_dark.table[2]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular3", false, &conf.colors_dark.table[3]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular4", false, &conf.colors_dark.table[4]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular5", false, &conf.colors_dark.table[5]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular6", false, &conf.colors_dark.table[6]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "regular7", false, &conf.colors_dark.table[7]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright0", false, &conf.colors_dark.table[8]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright1", false, &conf.colors_dark.table[9]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright2", false, &conf.colors_dark.table[10]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright3", false, &conf.colors_dark.table[11]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright4", false, &conf.colors_dark.table[12]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright5", false, &conf.colors_dark.table[13]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright6", false, &conf.colors_dark.table[14]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "bright7", false, &conf.colors_dark.table[15]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim0", false, &conf.colors_dark.dim[0]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim1", false, &conf.colors_dark.dim[1]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim2", false, &conf.colors_dark.dim[2]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim3", false, &conf.colors_dark.dim[3]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim4", false, &conf.colors_dark.dim[4]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim5", false, &conf.colors_dark.dim[5]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim6", false, &conf.colors_dark.dim[6]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "dim7", false, &conf.colors_dark.dim[7]);
|
||||
test_color(&ctx, &parse_section_colors_dark, "selection-foreground", false, &conf.colors_dark.selection_fg);
|
||||
test_color(&ctx, &parse_section_colors_dark, "selection-background", false, &conf.colors_dark.selection_bg);
|
||||
test_color(&ctx, &parse_section_colors_dark, "urls", false, &conf.colors_dark.url);
|
||||
test_two_colors(&ctx, &parse_section_colors_dark, "jump-labels", false,
|
||||
&conf.colors_dark.jump_label.fg,
|
||||
&conf.colors_dark.jump_label.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors_dark, "scrollback-indicator", false,
|
||||
&conf.colors_dark.scrollback_indicator.fg,
|
||||
&conf.colors_dark.scrollback_indicator.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors_dark, "search-box-no-match", false,
|
||||
&conf.colors_dark.search_box.no_match.fg,
|
||||
&conf.colors_dark.search_box.no_match.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors_dark, "search-box-match", false,
|
||||
&conf.colors_dark.search_box.match.fg,
|
||||
&conf.colors_dark.search_box.match.bg);
|
||||
|
||||
test_two_colors(&ctx, &parse_section_colors, "cursor", false,
|
||||
&conf.colors.cursor.text,
|
||||
&conf.colors.cursor.cursor);
|
||||
test_two_colors(&ctx, &parse_section_colors_dark, "cursor", false,
|
||||
&conf.colors_dark.cursor.text,
|
||||
&conf.colors_dark.cursor.cursor);
|
||||
|
||||
test_enum(&ctx, &parse_section_colors, "alpha-mode", 3,
|
||||
test_enum(&ctx, &parse_section_colors_dark, "alpha-mode", 3,
|
||||
(const char *[]){"default", "matching", "all"},
|
||||
(int []){ALPHA_MODE_DEFAULT, ALPHA_MODE_MATCHING, ALPHA_MODE_ALL},
|
||||
(int *)&conf.colors.alpha_mode);
|
||||
(int *)&conf.colors_dark.alpha_mode);
|
||||
|
||||
test_enum(&ctx, &parse_section_colors_dark, "dim-blend-towards", 2,
|
||||
(const char *[]){"black", "white"},
|
||||
(int []){DIM_BLEND_TOWARDS_BLACK, DIM_BLEND_TOWARDS_WHITE},
|
||||
(int *)&conf.colors_dark.dim_blend_towards);
|
||||
|
||||
for (size_t i = 0; i < 255; i++) {
|
||||
char key_name[4];
|
||||
sprintf(key_name, "%zu", i);
|
||||
test_color(&ctx, &parse_section_colors, key_name, false,
|
||||
&conf.colors.table[i]);
|
||||
test_color(&ctx, &parse_section_colors_dark, key_name, false,
|
||||
&conf.colors_dark.table[i]);
|
||||
}
|
||||
|
||||
test_invalid_key(&ctx, &parse_section_colors, "256");
|
||||
test_invalid_key(&ctx, &parse_section_colors_dark, "256");
|
||||
|
||||
/* TODO: alpha (float in range 0-1, converted to uint16_t) */
|
||||
|
||||
config_free(&conf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_section_colors_light(void)
|
||||
{
|
||||
struct config conf = {0};
|
||||
struct context ctx = {
|
||||
.conf = &conf, .section = "colors-light", .path = "unittest"};
|
||||
|
||||
test_invalid_key(&ctx, &parse_section_colors, "invalid-key");
|
||||
|
||||
test_color(&ctx, &parse_section_colors_light, "foreground", false, &conf.colors_light.fg);
|
||||
test_color(&ctx, &parse_section_colors_light, "background", false, &conf.colors_light.bg);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular0", false, &conf.colors_light.table[0]);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular1", false, &conf.colors_light.table[1]);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular2", false, &conf.colors_light.table[2]);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular3", false, &conf.colors_light.table[3]);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular4", false, &conf.colors_light.table[4]);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular5", false, &conf.colors_light.table[5]);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular6", false, &conf.colors_light.table[6]);
|
||||
test_color(&ctx, &parse_section_colors_light, "regular7", false, &conf.colors_light.table[7]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright0", false, &conf.colors_light.table[8]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright1", false, &conf.colors_light.table[9]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright2", false, &conf.colors_light.table[10]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright3", false, &conf.colors_light.table[11]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright4", false, &conf.colors_light.table[12]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright5", false, &conf.colors_light.table[13]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright6", false, &conf.colors_light.table[14]);
|
||||
test_color(&ctx, &parse_section_colors_light, "bright7", false, &conf.colors_light.table[15]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim0", false, &conf.colors_light.dim[0]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim1", false, &conf.colors_light.dim[1]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim2", false, &conf.colors_light.dim[2]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim3", false, &conf.colors_light.dim[3]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim4", false, &conf.colors_light.dim[4]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim5", false, &conf.colors_light.dim[5]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim6", false, &conf.colors_light.dim[6]);
|
||||
test_color(&ctx, &parse_section_colors_light, "dim7", false, &conf.colors_light.dim[7]);
|
||||
test_color(&ctx, &parse_section_colors_light, "selection-foreground", false, &conf.colors_light.selection_fg);
|
||||
test_color(&ctx, &parse_section_colors_light, "selection-background", false, &conf.colors_light.selection_bg);
|
||||
test_color(&ctx, &parse_section_colors_light, "urls", false, &conf.colors_light.url);
|
||||
test_two_colors(&ctx, &parse_section_colors_light, "jump-labels", false,
|
||||
&conf.colors_light.jump_label.fg,
|
||||
&conf.colors_light.jump_label.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors_light, "scrollback-indicator", false,
|
||||
&conf.colors_light.scrollback_indicator.fg,
|
||||
&conf.colors_light.scrollback_indicator.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors_light, "search-box-no-match", false,
|
||||
&conf.colors_light.search_box.no_match.fg,
|
||||
&conf.colors_light.search_box.no_match.bg);
|
||||
test_two_colors(&ctx, &parse_section_colors_light, "search-box-match", false,
|
||||
&conf.colors_light.search_box.match.fg,
|
||||
&conf.colors_light.search_box.match.bg);
|
||||
|
||||
test_two_colors(&ctx, &parse_section_colors_light, "cursor", false,
|
||||
&conf.colors_light.cursor.text,
|
||||
&conf.colors_light.cursor.cursor);
|
||||
|
||||
test_enum(&ctx, &parse_section_colors_light, "alpha-mode", 3,
|
||||
(const char *[]){"default", "matching", "all"},
|
||||
(int []){ALPHA_MODE_DEFAULT, ALPHA_MODE_MATCHING, ALPHA_MODE_ALL},
|
||||
(int *)&conf.colors_light.alpha_mode);
|
||||
|
||||
test_enum(&ctx, &parse_section_colors_light, "dim-blend-towards", 2,
|
||||
(const char *[]){"black", "white"},
|
||||
(int []){DIM_BLEND_TOWARDS_BLACK, DIM_BLEND_TOWARDS_WHITE},
|
||||
(int *)&conf.colors_light.dim_blend_towards);
|
||||
|
||||
for (size_t i = 0; i < 255; i++) {
|
||||
char key_name[4];
|
||||
sprintf(key_name, "%zu", i);
|
||||
test_color(&ctx, &parse_section_colors_light, key_name, false,
|
||||
&conf.colors_light.table[i]);
|
||||
}
|
||||
|
||||
test_invalid_key(&ctx, &parse_section_colors_light, "256");
|
||||
|
||||
/* TODO: alpha (float in range 0-1, converted to uint16_t) */
|
||||
|
||||
|
|
@ -1413,6 +1506,9 @@ test_section_tweak(void)
|
|||
test_float(&ctx, &parse_section_tweak, "bold-text-in-bright-amount",
|
||||
&conf.bold_in_bright.amount);
|
||||
|
||||
test_uint32(&ctx, &parse_section_tweak, "min-stride-alignment",
|
||||
&conf.tweak.min_stride_alignment);
|
||||
|
||||
#if 0 /* Must be equal to, or less than INT32_MAX */
|
||||
test_uint32(&ctx, &parse_section_tweak, "max-shm-pool-size-mb",
|
||||
&conf.tweak.max_shm_pool_size);
|
||||
|
|
@ -1435,7 +1531,8 @@ main(int argc, const char *const *argv)
|
|||
test_section_cursor();
|
||||
test_section_mouse();
|
||||
test_section_touch();
|
||||
test_section_colors();
|
||||
test_section_colors_dark();
|
||||
test_section_colors_light();
|
||||
test_section_csd();
|
||||
test_section_key_bindings();
|
||||
test_section_key_bindings_collisions();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Aero root theme
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=1a1a1a 9fd5f5
|
||||
foreground=dedeef
|
||||
background=1a1a1a
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Alacritty
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 181818 56d8c9
|
||||
background= 181818
|
||||
foreground= d8d8d8
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# https://github.com/romainl/Apprentice
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=262626 6c6c6c
|
||||
foreground=bcbcbc
|
||||
background=262626
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# theme: Ayu Mirage
|
||||
# description: a theme based on Ayu Mirage for Sublime Text (original: https://github.com/dempfi/ayu)
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = ffcc66 665a44
|
||||
foreground = cccac2
|
||||
background = 242936
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# _*_ conf _*_
|
||||
# Catppuccin Frappe
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
foreground=c6d0f5
|
||||
background=303446
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
# _*_ conf _*_
|
||||
# Catppuccin Latte
|
||||
|
||||
[colors]
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
|
||||
[colors-light]
|
||||
foreground=4c4f69
|
||||
background=eff1f5
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# _*_ conf _*_
|
||||
# Catppuccin Macchiato
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
foreground=cad3f5
|
||||
background=24273a
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# _*_ conf _*_
|
||||
# Catppuccin Mocha
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
foreground=cdd6f4
|
||||
background=1e1e2e
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# author: ayushnix (https://sr.ht/~ayushnix)
|
||||
# description: A dark theme with bright cyberpunk colors (WCAG AAA compliant)
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 181818 cdcdcd
|
||||
foreground = cdcdcd
|
||||
background = 181818
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Derp
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=000000 ffffff
|
||||
foreground=ffffff
|
||||
background=000000
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Deus
|
||||
# Color palette based on: https://github.com/ajmwagar/vim-deus
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=2c323b eaeaea
|
||||
background=2c323b
|
||||
foreground=eaeaea
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Dracula
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=282a36 f8f8f2
|
||||
foreground=f8f8f2
|
||||
background=282a36
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Dracula iTerm2 variant
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=ffffff bbbbbb
|
||||
foreground=f8f8f2
|
||||
background=1e1f29
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@
|
|||
# text and the white background.
|
||||
# author: Eugen Rahaian <eugen@rah.ro>
|
||||
|
||||
[colors]
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
|
||||
[colors-light]
|
||||
cursor=ffffff 515151
|
||||
background= ffffff
|
||||
foreground= 000000
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Gruvbox
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
background=282828
|
||||
foreground=ebdbb2
|
||||
regular0=282828
|
||||
|
|
@ -21,7 +21,7 @@ bright5=d3869b
|
|||
bright6=8ec07c
|
||||
bright7=ebdbb2
|
||||
|
||||
[colors2]
|
||||
[colors-light]
|
||||
background=fbf1c7
|
||||
foreground=3c3836
|
||||
regular0=fbf1c7
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Gruvbox
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
background=282828
|
||||
foreground=ebdbb2
|
||||
regular0=282828
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
# -*- conf -*-
|
||||
# Gruvbox - Light
|
||||
|
||||
[colors]
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
|
||||
[colors-light]
|
||||
background=fbf1c7
|
||||
foreground=3c3836
|
||||
regular0=fbf1c7
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- conf -*-
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=141414 c9c9c9
|
||||
foreground=c9c9c9
|
||||
background=141414
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# this foot theme is based on alacritty iterm theme:
|
||||
# https://github.com/alacritty/alacritty-theme/blob/master/themes/iterm.toml
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
foreground=fffbf6
|
||||
background=101421
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# JetBrains Darcula
|
||||
# Palette based on the same theme from https://github.com/dexpota/kitty-themes
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=202020 ffffff
|
||||
background=202020
|
||||
foreground=adadad
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- conf -*-
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=111111 cccccc
|
||||
foreground=dddddd
|
||||
background=000000
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
# Material Amber
|
||||
# Based on material.io guidelines with Amber 50 background
|
||||
|
||||
[colors]
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
|
||||
[colors-light]
|
||||
cursor=fff8e1 21201d
|
||||
foreground = 21201d
|
||||
background = fff8e1
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Material
|
||||
# From https://github.com/MartinSeeler/iterm2-material-design
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
foreground=ECEFF1
|
||||
background=263238
|
||||
regular0=546E7A # black
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
# modus-operandi
|
||||
# See: https://protesilaos.com/emacs/modus-themes
|
||||
#
|
||||
[colors]
|
||||
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
|
||||
[colors-light]
|
||||
background=ffffff
|
||||
foreground=000000
|
||||
regular0=000000
|
||||
|
|
@ -22,3 +26,5 @@ bright4=2544bb
|
|||
bright5=5317ac
|
||||
bright6=005a5f
|
||||
bright7=ffffff
|
||||
|
||||
jump-labels=dce0e8 0000ff
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
# See: https://protesilaos.com/emacs/modus-themes
|
||||
#
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
background=000000
|
||||
foreground=ffffff
|
||||
regular0=000000
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
# See: https://protesilaos.com/emacs/modus-themes
|
||||
#
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
background=0d0e1c
|
||||
foreground=ffffff
|
||||
regular0=000000
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Molokai
|
||||
# Based on zhou13's at https://github.com/zhou13/molokai-terminal/blob/master/xterm/Xresources
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
background=1B1D1E
|
||||
foreground=CCCCCC
|
||||
regular0=1B1D1E
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Monokai Pro
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
background=2D2A2E
|
||||
foreground=FCFCFA
|
||||
regular0=403E41
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# moonfly
|
||||
# Based on https://github.com/bluz71/vim-moonfly-colors
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 080808 9e9e9e
|
||||
foreground = b2b2b2
|
||||
background = 080808
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# https://xcolors.net/neon
|
||||
#
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
foreground=f8f8f8
|
||||
background=171717
|
||||
regular0=171717
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# _*_ conf _*_
|
||||
# Night Owl
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=011627 80a4c2
|
||||
foreground=d6deeb
|
||||
background=011627
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# nightfly
|
||||
# Based on https://github.com/bluz71/vim-nightfly-guicolors
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 080808 9ca1aa
|
||||
foreground = acb4c2
|
||||
background = 011627
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# https://github.com/n1ghtmare/noirblaze-kitty
|
||||
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=121212 ff0088
|
||||
foreground=d5d5d5
|
||||
background=121212
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# this specific foot theme is based on nord-alacritty:
|
||||
# https://github.com/arcticicestudio/nord-alacritty/blob/develop/src/nord.yml
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 2e3440 d8dee9
|
||||
foreground = d8dee9
|
||||
background = 2e3440
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Nordiq
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=eeeeee 9f515a
|
||||
foreground=dbdee9
|
||||
background=0e1420
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# Uses the dark color palette from the default Neovim color scheme
|
||||
# See: https://github.com/neovim/neovim/blob/fb6c059dc55c8d594102937be4dd70f5ff51614a/src/nvim/highlight_group.c#L419
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=14161b e0e2ea # NvimDarkGrey2 NvimLightGrey2
|
||||
foreground=e0e2ea # NvimLightGrey2
|
||||
background=14161b # NvimDarkGrey2
|
||||
|
|
@ -29,7 +29,7 @@ bright5=ffcaff # NvimLightMagenta
|
|||
bright6=8cf8f7 # NvimLightCyan
|
||||
bright7=eef1f8 # NvimLightGrey1
|
||||
|
||||
[colors2]
|
||||
[colors-light]
|
||||
cursor=e0e2ea 14161b # NvimLightGrey2 NvimDarkGrey2
|
||||
foreground=14161b # NvimDarkGrey2
|
||||
background=e0e2ea # NvimLightGrey2
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# Uses the dark color palette from the default Neovim color scheme
|
||||
# See: https://github.com/neovim/neovim/blob/fb6c059dc55c8d594102937be4dd70f5ff51614a/src/nvim/highlight_group.c#L419
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=14161b e0e2ea # NvimDarkGrey2 NvimLightGrey2
|
||||
foreground=e0e2ea # NvimLightGrey2
|
||||
background=14161b # NvimDarkGrey2
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@
|
|||
# Uses the light color palette from the default Neovim color scheme
|
||||
# See: https://github.com/neovim/neovim/blob/fb6c059dc55c8d594102937be4dd70f5ff51614a/src/nvim/highlight_group.c#L334
|
||||
|
||||
[colors]
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
|
||||
[colors-light]
|
||||
cursor=e0e2ea 14161b # NvimLightGrey2 NvimDarkGrey2
|
||||
foreground=14161b # NvimDarkGrey2
|
||||
background=e0e2ea # NvimLightGrey2
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# OneDark
|
||||
# Palette based on the same theme from https://github.com/dexpota/kitty-themes
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=111111 cccccc
|
||||
foreground=979eab
|
||||
background=282c34
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
# + cursor colors from:
|
||||
# https://github.com/sonph/onehalf/blob/master/iterm/OneHalfDark.itermcolors
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=dcdfe4 a3b3cc
|
||||
foreground=dcdfe4
|
||||
background=282c34
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# http://panda.siamak.me/
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
# alpha=1.0
|
||||
background=1D1E20
|
||||
foreground=F0F0F0
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# PaperColorDark
|
||||
# Palette based on https://github.com/NLKNguyen/papercolor-theme
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=1c1c1c eeeeee
|
||||
background=1c1c1c
|
||||
foreground=eeeeee
|
||||
|
|
@ -25,7 +25,7 @@ bright7=5f8787 # bright white
|
|||
# selection-foreground=1c1c1c
|
||||
# selection-background=af87d7
|
||||
|
||||
[colors2]
|
||||
[colors-light]
|
||||
cursor=eeeeee 444444
|
||||
background=eeeeee
|
||||
foreground=444444
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# PaperColorDark
|
||||
# Palette based on https://github.com/NLKNguyen/papercolor-theme
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=1c1c1c eeeeee
|
||||
background=1c1c1c
|
||||
foreground=eeeeee
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
# PaperColor Light
|
||||
# Palette based on https://github.com/NLKNguyen/papercolor-theme
|
||||
|
||||
[colors]
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
xs
|
||||
[colors-light]
|
||||
cursor=eeeeee 444444
|
||||
background=eeeeee
|
||||
foreground=444444
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Based on Poimandres color theme for kitti terminal emulator
|
||||
# https://github.com/ubmit/poimandres-kitty
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=1b1e28 ffffff
|
||||
foreground=a6accd
|
||||
background=1b1e28
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
# and also posted here:
|
||||
# https://forums.debian.net/viewtopic.php?t=29981
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
foreground = cccccc
|
||||
background = 191911
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Rosé Pine
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=191724 e0def4
|
||||
background=191724
|
||||
foreground=e0def4
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
# -*- conf -*-
|
||||
# Rosé Pine Dawn
|
||||
|
||||
[colors]
|
||||
[main]
|
||||
initial-color-theme=light
|
||||
|
||||
|
||||
[colors-light]
|
||||
cursor=faf4ed 575279
|
||||
background=faf4ed
|
||||
foreground=575279
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Rosé Pine Moon
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor=232136 e0def4
|
||||
background=232136
|
||||
foreground=e0def4
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Selenized dark
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 103c48 53d6c7
|
||||
background= 103c48
|
||||
foreground= adbcbc
|
||||
|
|
@ -24,7 +24,7 @@ bright5= ff84cd
|
|||
bright6= 53d6c7
|
||||
bright7= cad8d9
|
||||
|
||||
[colors2]
|
||||
[colors-light]
|
||||
cursor=fbf3db 00978a
|
||||
background= fbf3db
|
||||
foreground= 53676d
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Selenized black
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 181818 56d8c9
|
||||
background= 181818
|
||||
foreground= b9b9b9
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- conf -*-
|
||||
# Selenized dark
|
||||
|
||||
[colors]
|
||||
[colors-dark]
|
||||
cursor = 103c48 53d6c7
|
||||
background= 103c48
|
||||
foreground= adbcbc
|
||||
|
|
|
|||
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