mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-03 07:15:29 -04:00
Merge branch 'master' into releases/1.17
This commit is contained in:
commit
385fc0078f
19 changed files with 341 additions and 29 deletions
34
CHANGELOG.md
34
CHANGELOG.md
|
|
@ -1,5 +1,6 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
* [Unreleased](#unreleased)
|
||||||
* [1.17.0](#1-17-0)
|
* [1.17.0](#1-17-0)
|
||||||
* [1.16.2](#1-16-2)
|
* [1.16.2](#1-16-2)
|
||||||
* [1.16.1](#1-16-1)
|
* [1.16.1](#1-16-1)
|
||||||
|
|
@ -49,6 +50,39 @@
|
||||||
* [1.2.0](#1-2-0)
|
* [1.2.0](#1-2-0)
|
||||||
|
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* `cursor.unfocused-style=unchanged|hollow|none` to `foot.ini`. The
|
||||||
|
default is `hollow` ([#1582][1582]).
|
||||||
|
* New key binding: `quit` ([#1475][1475]).
|
||||||
|
|
||||||
|
[1582]: https://codeberg.org/dnkl/foot/issues/1582
|
||||||
|
[1475]: https://codeberg.org/dnkl/foot/issues/1475
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
### Deprecated
|
||||||
|
### Removed
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* Log-level not respected by syslog.
|
||||||
|
* Regression: terminal shutting down when the PTY is closed by the
|
||||||
|
client application, which may be earlier than when the client
|
||||||
|
application exits ([#1666][1666]).
|
||||||
|
* When closing the window, send `SIGHUP` to the client application,
|
||||||
|
before sending `SIGTERM`. The signal sequence is now `SIGHUP`, wait,
|
||||||
|
`SIGTERM`, wait `SIGKILL`.
|
||||||
|
* Crash when receiving a `DECRQSS` request with more than 2 bytes in
|
||||||
|
the `q` parameter.
|
||||||
|
|
||||||
|
[1666]: https://codeberg.org/dnkl/foot/issues/1666
|
||||||
|
|
||||||
|
|
||||||
|
### Security
|
||||||
|
### Contributors
|
||||||
|
|
||||||
|
|
||||||
## 1.17.0
|
## 1.17.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
83
CODE_OF_CONDUCT.md
Normal file
83
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
# Foot Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||||
|
identity and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the overall
|
||||||
|
community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||||
|
any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email address,
|
||||||
|
without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
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
|
||||||
|
pattern of unacceptable behavior. That is to say, the scope of the Code of
|
||||||
|
Conduct does not necessarily extend into the distant past.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior
|
||||||
|
may be reported to the community leaders responsible for enforcement
|
||||||
|
at [daniel@ekloef.se](mailto:daniel@ekloef.se). All complaints will
|
||||||
|
be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
The consequences for Code of Conduct violations will be decided upon and
|
||||||
|
enforced by community leaders. These may include a formal warning, a temporary
|
||||||
|
ban from community spaces, a permanent ban from community spaces, etc.
|
||||||
|
|
||||||
|
There are no hard and fast rules for exactly what behavior in which space will
|
||||||
|
result in what consequences, it is up to the community leaders to enforce the
|
||||||
|
Code of Conduct in a way that they believe best promotes a healthy community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the
|
||||||
|
[Contributor Covenant](https://www.contributor-covenant.org/),
|
||||||
|
version 2.1, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
||||||
|
|
@ -37,6 +37,7 @@ The fast, lightweight and minimalistic Wayland terminal emulator.
|
||||||
1. [Programmatically checking if running in foot](#programmatically-checking-if-running-in-foot)
|
1. [Programmatically checking if running in foot](#programmatically-checking-if-running-in-foot)
|
||||||
1. [XTGETTCAP](#xtgettcap)
|
1. [XTGETTCAP](#xtgettcap)
|
||||||
1. [Credits](#Credits)
|
1. [Credits](#Credits)
|
||||||
|
1. [Code of Conduct](#code-of-conduct)
|
||||||
1. [Bugs](#bugs)
|
1. [Bugs](#bugs)
|
||||||
1. [Contact](#contact)
|
1. [Contact](#contact)
|
||||||
1. [IRC](#irc)
|
1. [IRC](#irc)
|
||||||
|
|
@ -304,7 +305,7 @@ when starting your Wayland compositor (i.e. logging in to your
|
||||||
desktop), and then run `footclient` instead of `foot` whenever you
|
desktop), and then run `footclient` instead of `foot` whenever you
|
||||||
want to launch a new terminal.
|
want to launch a new terminal.
|
||||||
|
|
||||||
Foot support socket activation, which means `foot --server` will only be
|
Foot supports socket activation, which means `foot --server` will only be
|
||||||
started the first time you'll run `footclient`. (systemd user units are
|
started the first time you'll run `footclient`. (systemd user units are
|
||||||
included, but it can work with other supervision suites).
|
included, but it can work with other supervision suites).
|
||||||
|
|
||||||
|
|
@ -644,6 +645,11 @@ queried capabilities are **always** sent. No queries are ever dropped.
|
||||||
contributing foot's [logo](icons/hicolor/48x48/apps/foot.png).
|
contributing foot's [logo](icons/hicolor/48x48/apps/foot.png).
|
||||||
|
|
||||||
|
|
||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
See [Code of Conduct](CODE_OF_CONDUCT.md)
|
||||||
|
|
||||||
|
|
||||||
# Bugs
|
# Bugs
|
||||||
|
|
||||||
Please report bugs to https://codeberg.org/dnkl/foot/issues
|
Please report bugs to https://codeberg.org/dnkl/foot/issues
|
||||||
|
|
|
||||||
12
config.c
12
config.c
|
|
@ -119,6 +119,7 @@ static const char *const binding_action_map[] = {
|
||||||
[BIND_ACTION_PROMPT_PREV] = "prompt-prev",
|
[BIND_ACTION_PROMPT_PREV] = "prompt-prev",
|
||||||
[BIND_ACTION_PROMPT_NEXT] = "prompt-next",
|
[BIND_ACTION_PROMPT_NEXT] = "prompt-next",
|
||||||
[BIND_ACTION_UNICODE_INPUT] = "unicode-input",
|
[BIND_ACTION_UNICODE_INPUT] = "unicode-input",
|
||||||
|
[BIND_ACTION_QUIT] = "quit",
|
||||||
|
|
||||||
/* Mouse-specific actions */
|
/* Mouse-specific actions */
|
||||||
[BIND_ACTION_SCROLLBACK_UP_MOUSE] = "scrollback-up-mouse",
|
[BIND_ACTION_SCROLLBACK_UP_MOUSE] = "scrollback-up-mouse",
|
||||||
|
|
@ -1383,6 +1384,16 @@ parse_section_cursor(struct context *ctx)
|
||||||
(int *)&conf->cursor.style);
|
(int *)&conf->cursor.style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (streq(key, "unfocused-style")) {
|
||||||
|
_Static_assert(sizeof(conf->cursor.unfocused_style) == sizeof(int),
|
||||||
|
"enum is not 32-bit");
|
||||||
|
|
||||||
|
return value_to_enum(
|
||||||
|
ctx,
|
||||||
|
(const char *[]){"unchanged", "hollow", "none", NULL},
|
||||||
|
(int *)&conf->cursor.unfocused_style);
|
||||||
|
}
|
||||||
|
|
||||||
else if (streq(key, "blink"))
|
else if (streq(key, "blink"))
|
||||||
return value_to_bool(ctx, &conf->cursor.blink);
|
return value_to_bool(ctx, &conf->cursor.blink);
|
||||||
|
|
||||||
|
|
@ -3090,6 +3101,7 @@ config_load(struct config *conf, const char *conf_path,
|
||||||
|
|
||||||
.cursor = {
|
.cursor = {
|
||||||
.style = CURSOR_BLOCK,
|
.style = CURSOR_BLOCK,
|
||||||
|
.unfocused_style = CURSOR_UNFOCUSED_HOLLOW,
|
||||||
.blink = false,
|
.blink = false,
|
||||||
.color = {
|
.color = {
|
||||||
.text = 0,
|
.text = 0,
|
||||||
|
|
|
||||||
6
config.h
6
config.h
|
|
@ -28,6 +28,11 @@ struct font_size_adjustment {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
|
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
|
||||||
|
enum cursor_unfocused_style {
|
||||||
|
CURSOR_UNFOCUSED_UNCHANGED,
|
||||||
|
CURSOR_UNFOCUSED_HOLLOW,
|
||||||
|
CURSOR_UNFOCUSED_NONE
|
||||||
|
};
|
||||||
|
|
||||||
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
|
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
|
||||||
|
|
||||||
|
|
@ -256,6 +261,7 @@ struct config {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
enum cursor_style style;
|
enum cursor_style style;
|
||||||
|
enum cursor_unfocused_style unfocused_style;
|
||||||
bool blink;
|
bool blink;
|
||||||
struct {
|
struct {
|
||||||
uint32_t text;
|
uint32_t text;
|
||||||
|
|
|
||||||
2
dcs.c
2
dcs.c
|
|
@ -239,7 +239,7 @@ decrqss_put(struct terminal *term, uint8_t c)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct vt *vt = &term->vt;
|
struct vt *vt = &term->vt;
|
||||||
if (vt->dcs.idx > 2)
|
if (vt->dcs.idx >= 2)
|
||||||
return;
|
return;
|
||||||
vt->dcs.data[vt->dcs.idx++] = c;
|
vt->dcs.data[vt->dcs.idx++] = c;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -500,6 +500,15 @@ applications can change these at runtime.
|
||||||
*beam* or *underline*. Note that this can be overridden by
|
*beam* or *underline*. Note that this can be overridden by
|
||||||
applications. Default: _block_.
|
applications. Default: _block_.
|
||||||
|
|
||||||
|
*unfocused-style*
|
||||||
|
Configures how the cursor is rendered when the terminal window is
|
||||||
|
unfocused. Possible values are:
|
||||||
|
|
||||||
|
- unchanged: render cursor in exactly the same way as when the
|
||||||
|
window has focus.
|
||||||
|
- hollow: render a block cursor, but hollowed out.
|
||||||
|
- none: do not display any cursor at all.
|
||||||
|
|
||||||
*blink*
|
*blink*
|
||||||
Boolean. Enables blinking cursor. Note that this can be overridden
|
Boolean. Enables blinking cursor. Note that this can be overridden
|
||||||
by applications. Default: _no_.
|
by applications. Default: _no_.
|
||||||
|
|
@ -916,6 +925,9 @@ e.g. *search-start=none*.
|
||||||
|
|
||||||
Default: _Control+Shift+u_.
|
Default: _Control+Shift+u_.
|
||||||
|
|
||||||
|
*quit*
|
||||||
|
Quit foot. Default: _none_.
|
||||||
|
|
||||||
# SECTION: search-bindings
|
# SECTION: search-bindings
|
||||||
|
|
||||||
This section lets you override the default key bindings used in
|
This section lets you override the default key bindings used in
|
||||||
|
|
|
||||||
1
foot.ini
1
foot.ini
|
|
@ -193,6 +193,7 @@
|
||||||
# clipboard-paste=Control+v Control+Shift+v Control+y XF86Paste
|
# clipboard-paste=Control+v Control+Shift+v Control+y XF86Paste
|
||||||
# primary-paste=Shift+Insert
|
# primary-paste=Shift+Insert
|
||||||
# unicode-input=none
|
# unicode-input=none
|
||||||
|
# quit=none
|
||||||
# scrollback-up-page=Shift+Page_Up
|
# scrollback-up-page=Shift+Page_Up
|
||||||
# scrollback-up-half-page=none
|
# scrollback-up-half-page=none
|
||||||
# scrollback-up-line=none
|
# scrollback-up-line=none
|
||||||
|
|
|
||||||
4
input.c
4
input.c
|
|
@ -444,6 +444,10 @@ execute_binding(struct seat *seat, struct terminal *term,
|
||||||
unicode_mode_activate(seat);
|
unicode_mode_activate(seat);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case BIND_ACTION_QUIT:
|
||||||
|
term_shutdown(term);
|
||||||
|
return true;
|
||||||
|
|
||||||
case BIND_ACTION_SELECT_BEGIN:
|
case BIND_ACTION_SELECT_BEGIN:
|
||||||
selection_start(
|
selection_start(
|
||||||
term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false);
|
term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ enum bind_action_normal {
|
||||||
BIND_ACTION_PROMPT_PREV,
|
BIND_ACTION_PROMPT_PREV,
|
||||||
BIND_ACTION_PROMPT_NEXT,
|
BIND_ACTION_PROMPT_NEXT,
|
||||||
BIND_ACTION_UNICODE_INPUT,
|
BIND_ACTION_UNICODE_INPUT,
|
||||||
|
BIND_ACTION_QUIT,
|
||||||
|
|
||||||
/* Mouse specific actions - i.e. they require a mouse coordinate */
|
/* Mouse specific actions - i.e. they require a mouse coordinate */
|
||||||
BIND_ACTION_SCROLLBACK_UP_MOUSE,
|
BIND_ACTION_SCROLLBACK_UP_MOUSE,
|
||||||
|
|
@ -53,7 +54,7 @@ enum bind_action_normal {
|
||||||
BIND_ACTION_SELECT_QUOTE,
|
BIND_ACTION_SELECT_QUOTE,
|
||||||
BIND_ACTION_SELECT_ROW,
|
BIND_ACTION_SELECT_ROW,
|
||||||
|
|
||||||
BIND_ACTION_KEY_COUNT = BIND_ACTION_UNICODE_INPUT + 1,
|
BIND_ACTION_KEY_COUNT = BIND_ACTION_QUIT + 1,
|
||||||
BIND_ACTION_COUNT = BIND_ACTION_SELECT_ROW + 1,
|
BIND_ACTION_COUNT = BIND_ACTION_SELECT_ROW + 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
3
log.c
3
log.c
|
|
@ -105,6 +105,9 @@ _sys_log(enum log_class log_class, const char *module,
|
||||||
if (!do_syslog)
|
if (!do_syslog)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (log_class > log_level)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Map our log level to syslog's level */
|
/* Map our log level to syslog's level */
|
||||||
int level = log_level_map[log_class].syslog_equivalent;
|
int level = log_level_map[log_class].syslog_equivalent;
|
||||||
|
|
||||||
|
|
|
||||||
27
render.c
27
render.c
|
|
@ -305,8 +305,8 @@ color_brighten(const struct terminal *term, uint32_t color)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_unfocused_block(const struct terminal *term, pixman_image_t *pix,
|
draw_hollow_block(const struct terminal *term, pixman_image_t *pix,
|
||||||
const pixman_color_t *color, int x, int y, int cell_cols)
|
const pixman_color_t *color, int x, int y, int cell_cols)
|
||||||
{
|
{
|
||||||
const int scale = (int)roundf(term->scale);
|
const int scale = (int)roundf(term->scale);
|
||||||
const int width = min(min(scale, term->cell_width), term->cell_height);
|
const int width = min(min(scale, term->cell_width), term->cell_height);
|
||||||
|
|
@ -429,10 +429,23 @@ draw_cursor(const struct terminal *term, const struct cell *cell,
|
||||||
|
|
||||||
switch (term->cursor_style) {
|
switch (term->cursor_style) {
|
||||||
case CURSOR_BLOCK:
|
case CURSOR_BLOCK:
|
||||||
if (unlikely(!term->kbd_focus))
|
if (unlikely(!term->kbd_focus)) {
|
||||||
draw_unfocused_block(term, pix, &cursor_color, x, y, cols);
|
switch (term->conf->cursor.unfocused_style) {
|
||||||
|
case CURSOR_UNFOCUSED_UNCHANGED:
|
||||||
|
break;
|
||||||
|
|
||||||
else if (likely(term->cursor_blink.state == CURSOR_BLINK_ON)) {
|
case CURSOR_UNFOCUSED_HOLLOW:
|
||||||
|
draw_hollow_block(term, pix, fg, x, y, cols);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case CURSOR_UNFOCUSED_NONE:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (likely(term->cursor_blink.state == CURSOR_BLINK_ON) ||
|
||||||
|
!term->kbd_focus)
|
||||||
|
{
|
||||||
*fg = text_color;
|
*fg = text_color;
|
||||||
pixman_image_fill_rectangles(
|
pixman_image_fill_rectangles(
|
||||||
PIXMAN_OP_SRC, pix, &cursor_color, 1,
|
PIXMAN_OP_SRC, pix, &cursor_color, 1,
|
||||||
|
|
@ -1513,7 +1526,7 @@ render_ime_preedit_for_seat(struct terminal *term, struct seat *seat,
|
||||||
/* Hollow cursor */
|
/* Hollow cursor */
|
||||||
if (start >= 0 && end <= term->cols) {
|
if (start >= 0 && end <= term->cols) {
|
||||||
int cols = end - start;
|
int cols = end - start;
|
||||||
draw_unfocused_block(term, buf->pix[0], &cursor_color, x, y, cols);
|
draw_hollow_block(term, buf->pix[0], &cursor_color, x, y, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
term_ime_set_cursor_rect(
|
term_ime_set_cursor_rect(
|
||||||
|
|
@ -3373,7 +3386,7 @@ render_search_box(struct terminal *term)
|
||||||
|
|
||||||
/* TODO: how do we handle a partially hidden rectangle? */
|
/* TODO: how do we handle a partially hidden rectangle? */
|
||||||
if (start >= 0 && end <= visible_cells) {
|
if (start >= 0 && end <= visible_cells) {
|
||||||
draw_unfocused_block(
|
draw_hollow_block(
|
||||||
term, buf->pix[0], &fg, x + start * term->cell_width, y, end - start);
|
term, buf->pix[0], &fg, x + start * term->cell_width, y, end - start);
|
||||||
}
|
}
|
||||||
term_ime_set_cursor_rect(term,
|
term_ime_set_cursor_rect(term,
|
||||||
|
|
|
||||||
86
terminal.c
86
terminal.c
|
|
@ -364,8 +364,20 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
|
||||||
del_utmp_record(term->conf, term->reaper, term->ptmx);
|
del_utmp_record(term->conf, term->reaper, term->ptmx);
|
||||||
fdm_del(fdm, fd);
|
fdm_del(fdm, fd);
|
||||||
term->ptmx = -1;
|
term->ptmx = -1;
|
||||||
if (!term->conf->hold_at_exit)
|
|
||||||
|
/*
|
||||||
|
* Normally, we do *not* want to shutdown when the PTY is
|
||||||
|
* closed. Instead, we want to wait for the client application
|
||||||
|
* to exit.
|
||||||
|
*
|
||||||
|
* However, when we're using a pre-existing PTY (the --pty
|
||||||
|
* option), there _is_ no client application. That is, foot
|
||||||
|
* does *not* fork+exec anything, and thus the only way to
|
||||||
|
* shutdown is to wait for the PTY to be closed.
|
||||||
|
*/
|
||||||
|
if (term->slave < 0 && !term->conf->hold_at_exit) {
|
||||||
term_shutdown(term);
|
term_shutdown(term);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1527,10 +1539,36 @@ fdm_terminate_timeout(struct fdm *fdm, int fd, int events, void *data)
|
||||||
struct terminal *term = data;
|
struct terminal *term = data;
|
||||||
xassert(!term->shutdown.client_has_terminated);
|
xassert(!term->shutdown.client_has_terminated);
|
||||||
|
|
||||||
LOG_DBG("slave (PID=%u) has not terminated, sending SIGKILL (%d)",
|
LOG_DBG("slave (PID=%u) has not terminated, sending %s (%d)",
|
||||||
term->slave, SIGKILL);
|
term->slave,
|
||||||
|
term->shutdown.next_signal == SIGTERM ? "SIGTERM"
|
||||||
|
: term->shutdown.next_signal == SIGKILL ? "SIGKILL"
|
||||||
|
: "<unknown>",
|
||||||
|
term->shutdown.next_signal);
|
||||||
|
|
||||||
|
kill(-term->slave, term->shutdown.next_signal);
|
||||||
|
|
||||||
|
switch (term->shutdown.next_signal) {
|
||||||
|
case SIGTERM:
|
||||||
|
term->shutdown.next_signal = SIGKILL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGKILL:
|
||||||
|
/* Disarm. Shouldn't be necessary, as we should be able to
|
||||||
|
shutdown completely after sending SIGKILL, before the next
|
||||||
|
timeout occurs). But lets play it safe... */
|
||||||
|
if (term->shutdown.terminate_timeout_fd >= 0) {
|
||||||
|
timerfd_settime(
|
||||||
|
term->shutdown.terminate_timeout_fd, 0,
|
||||||
|
&(const struct itimerspec){0}, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BUG("can only handle SIGTERM and SIGKILL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
kill(-term->slave, SIGKILL);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1571,11 +1609,18 @@ term_shutdown(struct terminal *term)
|
||||||
term->shutdown.client_has_terminated = true;
|
term->shutdown.client_has_terminated = true;
|
||||||
} else {
|
} else {
|
||||||
LOG_DBG("initiating asynchronous terminate of slave; "
|
LOG_DBG("initiating asynchronous terminate of slave; "
|
||||||
"sending SIGTERM to PID=%u", term->slave);
|
"sending SIGHUP to PID=%u", term->slave);
|
||||||
|
|
||||||
kill(-term->slave, SIGTERM);
|
kill(-term->slave, SIGHUP);
|
||||||
|
|
||||||
const struct itimerspec timeout = {.it_value = {.tv_sec = 60}};
|
/*
|
||||||
|
* Set up a timer, with an interval - on the first timeout
|
||||||
|
* we'll send SIGTERM. If the the client application still
|
||||||
|
* isn't terminating, we'll wait an additional interval,
|
||||||
|
* and then send SIGKILL.
|
||||||
|
*/
|
||||||
|
const struct itimerspec timeout = {.it_value = {.tv_sec = 30},
|
||||||
|
.it_interval = {.tv_sec = 30}};
|
||||||
|
|
||||||
int timeout_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
int timeout_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||||
if (timeout_fd < 0 ||
|
if (timeout_fd < 0 ||
|
||||||
|
|
@ -1590,6 +1635,7 @@ term_shutdown(struct terminal *term)
|
||||||
|
|
||||||
xassert(term->shutdown.terminate_timeout_fd < 0);
|
xassert(term->shutdown.terminate_timeout_fd < 0);
|
||||||
term->shutdown.terminate_timeout_fd = timeout_fd;
|
term->shutdown.terminate_timeout_fd = timeout_fd;
|
||||||
|
term->shutdown.next_signal = SIGTERM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1772,9 +1818,9 @@ term_destroy(struct terminal *term)
|
||||||
exit_status = term->shutdown.exit_status;
|
exit_status = term->shutdown.exit_status;
|
||||||
else {
|
else {
|
||||||
LOG_DBG("initiating blocking terminate of slave; "
|
LOG_DBG("initiating blocking terminate of slave; "
|
||||||
"sending SIGTERM to PID=%u", term->slave);
|
"sending SIGHUP to PID=%u", term->slave);
|
||||||
|
|
||||||
kill(-term->slave, SIGTERM);
|
kill(-term->slave, SIGHUP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we've closed the ptxm, and sent SIGTERM to the client
|
* we've closed the ptxm, and sent SIGTERM to the client
|
||||||
|
|
@ -1795,7 +1841,12 @@ term_destroy(struct terminal *term)
|
||||||
struct sigaction action = {.sa_handler = &sig_alarm};
|
struct sigaction action = {.sa_handler = &sig_alarm};
|
||||||
sigemptyset(&action.sa_mask);
|
sigemptyset(&action.sa_mask);
|
||||||
sigaction(SIGALRM, &action, NULL);
|
sigaction(SIGALRM, &action, NULL);
|
||||||
alarm(60);
|
|
||||||
|
/* Wait, then send SIGTERM, wait again, then send SIGKILL */
|
||||||
|
int next_signal = SIGTERM;
|
||||||
|
|
||||||
|
alarm_raised = 0;
|
||||||
|
alarm(30);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int r = waitpid(term->slave, &exit_status, 0);
|
int r = waitpid(term->slave, &exit_status, 0);
|
||||||
|
|
@ -1807,11 +1858,16 @@ term_destroy(struct terminal *term)
|
||||||
xassert(errno == EINTR);
|
xassert(errno == EINTR);
|
||||||
|
|
||||||
if (alarm_raised) {
|
if (alarm_raised) {
|
||||||
LOG_DBG(
|
LOG_DBG("slave (PID=%u) has not terminated yet, "
|
||||||
"slave (PID=%u) has not terminate yet, "
|
"sending: %s (%d)", term->slave,
|
||||||
"sending: SIGKILL (%d)", term->slave, SIGKILL);
|
next_signal == SIGTERM ? "SIGTERM" : "SIGKILL",
|
||||||
|
next_signal);
|
||||||
|
|
||||||
kill(-term->slave, SIGKILL);
|
kill(-term->slave, next_signal);
|
||||||
|
next_signal = SIGKILL;
|
||||||
|
|
||||||
|
alarm_raised = 0;
|
||||||
|
alarm(30);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2125,7 +2181,7 @@ term_fractional_scaling(const struct terminal *term)
|
||||||
bool
|
bool
|
||||||
term_preferred_buffer_scale(const struct terminal *term)
|
term_preferred_buffer_scale(const struct terminal *term)
|
||||||
{
|
{
|
||||||
return term->wl->has_wl_compositor_v6;
|
return term->wl->has_wl_compositor_v6 && term->window->preferred_buffer_scale > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -723,6 +723,7 @@ struct terminal {
|
||||||
bool client_has_terminated;
|
bool client_has_terminated;
|
||||||
int terminate_timeout_fd;
|
int terminate_timeout_fd;
|
||||||
int exit_status;
|
int exit_status;
|
||||||
|
int next_signal;
|
||||||
|
|
||||||
void (*cb)(void *data, int exit_code);
|
void (*cb)(void *data, int exit_code);
|
||||||
void *cb_data;
|
void *cb_data;
|
||||||
|
|
|
||||||
|
|
@ -635,6 +635,12 @@ test_section_cursor(void)
|
||||||
(const char *[]){"block", "beam", "underline"},
|
(const char *[]){"block", "beam", "underline"},
|
||||||
(int []){CURSOR_BLOCK, CURSOR_BEAM, CURSOR_UNDERLINE},
|
(int []){CURSOR_BLOCK, CURSOR_BEAM, CURSOR_UNDERLINE},
|
||||||
(int *)&conf.cursor.style);
|
(int *)&conf.cursor.style);
|
||||||
|
test_enum(
|
||||||
|
&ctx, &parse_section_cursor, "unfocused-style",
|
||||||
|
3,
|
||||||
|
(const char *[]){"unchanged", "hollow", "none"},
|
||||||
|
(int []){CURSOR_UNFOCUSED_UNCHANGED, CURSOR_UNFOCUSED_HOLLOW, CURSOR_UNFOCUSED_NONE},
|
||||||
|
(int *)&conf.cursor.unfocused_style);
|
||||||
test_boolean(&ctx, &parse_section_cursor, "blink", &conf.cursor.blink);
|
test_boolean(&ctx, &parse_section_cursor, "blink", &conf.cursor.blink);
|
||||||
test_pt_or_px(&ctx, &parse_section_cursor, "beam-thickness",
|
test_pt_or_px(&ctx, &parse_section_cursor, "beam-thickness",
|
||||||
&conf.cursor.beam_thickness);
|
&conf.cursor.beam_thickness);
|
||||||
|
|
|
||||||
25
themes/dracula-iterm
Normal file
25
themes/dracula-iterm
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
# Dracula iTerm2 variant
|
||||||
|
|
||||||
|
[cursor]
|
||||||
|
color=ffffff bbbbbb
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
foreground=f8f8f2
|
||||||
|
background=1e1f29
|
||||||
|
regular0=000000 # black
|
||||||
|
regular1=ff5555 # red
|
||||||
|
regular2=50fa7b # green
|
||||||
|
regular3=f1fa8c # yellow
|
||||||
|
regular4=bd93f9 # blue
|
||||||
|
regular5=ff79c6 # magenta
|
||||||
|
regular6=8be9fd # cyan
|
||||||
|
regular7=bbbbbb # white
|
||||||
|
bright0=555555 # bright black
|
||||||
|
bright1=ff5555 # bright red
|
||||||
|
bright2=50fa7b # bright green
|
||||||
|
bright3=f1fa8c # bright yellow
|
||||||
|
bright4=bd93f9 # bright blue
|
||||||
|
bright5=ff79c6 # bright magenta
|
||||||
|
bright6=8be9fd # bright cyan
|
||||||
|
bright7=ffffff # bright white
|
||||||
31
themes/noirblaze
Normal file
31
themes/noirblaze
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
# noirblaze-kitty
|
||||||
|
# https://github.com/n1ghtmare/noirblaze-kitty
|
||||||
|
|
||||||
|
|
||||||
|
[cursor]
|
||||||
|
color=121212 ff0088
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
foreground=d5d5d5
|
||||||
|
background=121212
|
||||||
|
|
||||||
|
# selection-foreground=121212
|
||||||
|
# selection-background=b0b0b0
|
||||||
|
|
||||||
|
regular0=121212 # black
|
||||||
|
regular1=ff0088 # red
|
||||||
|
regular2=00ff77 # green
|
||||||
|
regular3=ffffff # yellow
|
||||||
|
regular4=b0b0b0 # blue
|
||||||
|
regular5=7a7a7a # magenta
|
||||||
|
regular6=787878 # cyan
|
||||||
|
regular7=d5d5d5 # white
|
||||||
|
bright0=737373 # bright black
|
||||||
|
bright1=FD319E # bright red
|
||||||
|
bright2=FD319E # bright green
|
||||||
|
bright3=FDFDFD # bright yellow
|
||||||
|
bright4=BEBEBE # bright blue
|
||||||
|
bright5=939393 # bright magenta
|
||||||
|
bright6=919191 # bright cyan
|
||||||
|
bright7=f5f5f5 # bright white
|
||||||
22
themes/xterm
Normal file
22
themes/xterm
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# -*- conf -*-
|
||||||
|
# The default palette of xterm.
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
foreground=e5e5e5
|
||||||
|
background=000000
|
||||||
|
regular0=000000 # black
|
||||||
|
regular1=cd0000 # red
|
||||||
|
regular2=00cd00 # green
|
||||||
|
regular3=cdcd00 # yellow
|
||||||
|
regular4=0000ee # blue
|
||||||
|
regular5=cd00cd # magenta
|
||||||
|
regular6=00cdcd # cyan
|
||||||
|
regular7=e5e5e5 # white
|
||||||
|
bright0=7f7f7f # bright black
|
||||||
|
bright1=ff0000 # bright red
|
||||||
|
bright2=00ff00 # bright green
|
||||||
|
bright3=ffff00 # bright yellow
|
||||||
|
bright4=5c5cff # bright blue
|
||||||
|
bright5=ff00ff # bright magenta
|
||||||
|
bright6=00ffff # bright cyan
|
||||||
|
bright7=ffffff # bright white
|
||||||
|
|
@ -1738,10 +1738,6 @@ wayl_win_init(struct terminal *term, const char *token)
|
||||||
win->fractional_scale, &fractional_scale_listener, win);
|
win->fractional_scale, &fractional_scale_listener, win);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wayl->has_wl_compositor_v6) {
|
|
||||||
win->preferred_buffer_scale = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
win->xdg_surface = xdg_wm_base_get_xdg_surface(wayl->shell, win->surface.surf);
|
win->xdg_surface = xdg_wm_base_get_xdg_surface(wayl->shell, win->surface.surf);
|
||||||
xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, win);
|
xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, win);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue