Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-02-12 11:10:01 +00:00
17 changed files with 204 additions and 98 deletions

View File

@@ -58,29 +58,31 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
struct args *args = cmd_get_args(self); struct args *args = cmd_get_args(self);
struct client *tc = cmdq_get_target_client(item); struct client *tc = cmdq_get_target_client(item);
struct paste_buffer *pb; struct paste_buffer *pb;
char *bufdata, *cause; char *bufname, *bufdata = NULL, *cause = NULL;
const char *bufname, *olddata; const char *olddata;
size_t bufsize, newsize; size_t bufsize = 0, newsize;
bufname = args_get(args, 'b'); if (args_get(args, 'b') == NULL)
if (bufname == NULL)
pb = NULL; pb = NULL;
else else {
bufname = xstrdup(args_get(args, 'b'));
pb = paste_get_name(bufname); pb = paste_get_name(bufname);
}
if (cmd_get_entry(self) == &cmd_delete_buffer_entry) { if (cmd_get_entry(self) == &cmd_delete_buffer_entry) {
if (pb == NULL) { if (pb == NULL) {
if (bufname != NULL) { if (bufname != NULL) {
cmdq_error(item, "unknown buffer: %s", bufname); cmdq_error(item, "unknown buffer: %s", bufname);
return (CMD_RETURN_ERROR); goto fail;
} }
pb = paste_get_top(&bufname); pb = paste_get_top(&bufname);
} }
if (pb == NULL) { if (pb == NULL) {
cmdq_error(item, "no buffer"); cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR); goto fail;
} }
paste_free(pb); paste_free(pb);
free(bufname);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
@@ -88,32 +90,28 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
if (pb == NULL) { if (pb == NULL) {
if (bufname != NULL) { if (bufname != NULL) {
cmdq_error(item, "unknown buffer: %s", bufname); cmdq_error(item, "unknown buffer: %s", bufname);
return (CMD_RETURN_ERROR); goto fail;
} }
pb = paste_get_top(&bufname); pb = paste_get_top(&bufname);
} }
if (pb == NULL) { if (pb == NULL) {
cmdq_error(item, "no buffer"); cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR); goto fail;
} }
if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) { if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) {
cmdq_error(item, "%s", cause); cmdq_error(item, "%s", cause);
free(cause); goto fail;
return (CMD_RETURN_ERROR);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
if (args_count(args) != 1) { if (args_count(args) != 1) {
cmdq_error(item, "no data specified"); cmdq_error(item, "no data specified");
return (CMD_RETURN_ERROR); goto fail;
} }
if ((newsize = strlen(args_string(args, 0))) == 0) if ((newsize = strlen(args_string(args, 0))) == 0)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
bufsize = 0;
bufdata = NULL;
if (args_has(args, 'a') && pb != NULL) { if (args_has(args, 'a') && pb != NULL) {
olddata = paste_buffer_data(pb, &bufsize); olddata = paste_buffer_data(pb, &bufsize);
bufdata = xmalloc(bufsize); bufdata = xmalloc(bufsize);
@@ -126,12 +124,16 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
if (paste_set(bufdata, bufsize, bufname, &cause) != 0) { if (paste_set(bufdata, bufsize, bufname, &cause) != 0) {
cmdq_error(item, "%s", cause); cmdq_error(item, "%s", cause);
free(bufdata); goto fail;
free(cause);
return (CMD_RETURN_ERROR);
} }
if (args_has(args, 'w') && tc != NULL) if (args_has(args, 'w') && tc != NULL)
tty_set_selection(&tc->tty, "", bufdata, bufsize); tty_set_selection(&tc->tty, "", bufdata, bufsize);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
fail:
free(bufdata);
free(bufname);
free(cause);
return (CMD_RETURN_ERROR);
} }

View File

@@ -610,7 +610,7 @@ control_append_data(struct client *c, struct control_pane *cp, uint64_t age,
struct evbuffer *message, struct window_pane *wp, size_t size) struct evbuffer *message, struct window_pane *wp, size_t size)
{ {
u_char *new_data; u_char *new_data;
size_t new_size; size_t new_size, start;
u_int i; u_int i;
if (message == NULL) { if (message == NULL) {
@@ -629,10 +629,16 @@ control_append_data(struct client *c, struct control_pane *cp, uint64_t age,
if (new_size < size) if (new_size < size)
fatalx("not enough data: %zu < %zu", new_size, size); fatalx("not enough data: %zu < %zu", new_size, size);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
if (new_data[i] < ' ' || new_data[i] == '\\') if (new_data[i] < ' ' || new_data[i] == '\\') {
evbuffer_add_printf(message, "\\%03o", new_data[i]); evbuffer_add_printf(message, "\\%03o", new_data[i]);
else } else {
evbuffer_add_printf(message, "%c", new_data[i]); start = i;
while (i + 1 < size &&
new_data[i + 1] >= ' ' &&
new_data[i + 1] != '\\')
i++;
evbuffer_add(message, new_data + start, i - start + 1);
}
} }
window_pane_update_used_data(wp, &cp->offset, size); window_pane_update_used_data(wp, &cp->offset, size);
return (message); return (message);

View File

@@ -2012,8 +2012,10 @@ format_cb_pane_bottom(struct format_tree *ft)
static void * static void *
format_cb_pane_dead(struct format_tree *ft) format_cb_pane_dead(struct format_tree *ft)
{ {
if (ft->wp != NULL) { struct window_pane *wp = ft->wp;
if (ft->wp->fd == -1)
if (wp != NULL) {
if (wp->fd == -1 && (wp->flags & PANE_STATUSREADY))
return (xstrdup("1")); return (xstrdup("1"));
return (xstrdup("0")); return (xstrdup("0"));
} }

75
input.c
View File

@@ -101,6 +101,7 @@ struct input_ctx {
struct bufferevent *event; struct bufferevent *event;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
struct colour_palette *palette; struct colour_palette *palette;
struct client *c;
struct input_cell cell; struct input_cell cell;
struct input_cell old_cell; struct input_cell old_cell;
@@ -854,7 +855,7 @@ input_restore_state(struct input_ctx *ictx)
/* Initialise input parser. */ /* Initialise input parser. */
struct input_ctx * struct input_ctx *
input_init(struct window_pane *wp, struct bufferevent *bev, input_init(struct window_pane *wp, struct bufferevent *bev,
struct colour_palette *palette) struct colour_palette *palette, struct client *c)
{ {
struct input_ctx *ictx; struct input_ctx *ictx;
@@ -862,6 +863,7 @@ input_init(struct window_pane *wp, struct bufferevent *bev,
ictx->wp = wp; ictx->wp = wp;
ictx->event = bev; ictx->event = bev;
ictx->palette = palette; ictx->palette = palette;
ictx->c = c;
ictx->input_space = INPUT_BUF_START; ictx->input_space = INPUT_BUF_START;
ictx->input_buf = xmalloc(INPUT_BUF_START); ictx->input_buf = xmalloc(INPUT_BUF_START);
@@ -3110,31 +3112,28 @@ input_osc_52_reply(struct input_ctx *ictx)
input_add_request(ictx, INPUT_REQUEST_CLIPBOARD, ictx->input_end); input_add_request(ictx, INPUT_REQUEST_CLIPBOARD, ictx->input_end);
} }
/* Handle the OSC 52 sequence for setting the clipboard. */ /*
static void * Parse and decode OSC 52 clipboard data. Returns 0 on failure or if handled
input_osc_52(struct input_ctx *ictx, const char *p) * as a query. On success, returns 1 and sets *out, *outlen, and *flags (caller
* must free *out).
*/
static int
input_osc_52_parse(struct input_ctx *ictx, const char *p, u_char **out,
int *outlen, char *flags)
{ {
struct window_pane *wp = ictx->wp;
size_t len;
char *end; char *end;
u_char *out; size_t len;
int outlen, state; const char *allow = "cpqs01234567";
struct screen_write_ctx ctx;
const char* allow = "cpqs01234567";
char flags[sizeof "cpqs01234567"] = "";
u_int i, j = 0; u_int i, j = 0;
if (wp == NULL) if (options_get_number(global_options, "set-clipboard") != 2)
return; return (0);
state = options_get_number(global_options, "set-clipboard");
if (state != 2)
return;
if ((end = strchr(p, ';')) == NULL) if ((end = strchr(p, ';')) == NULL)
return; return (0);
end++; end++;
if (*end == '\0') if (*end == '\0')
return; return (0);
log_debug("%s: %s", __func__, end); log_debug("%s: %s", __func__, end);
for (i = 0; p + i != end; i++) { for (i = 0; p + i != end; i++) {
@@ -3145,25 +3144,53 @@ input_osc_52(struct input_ctx *ictx, const char *p)
if (strcmp(end, "?") == 0) { if (strcmp(end, "?") == 0) {
input_osc_52_reply(ictx); input_osc_52_reply(ictx);
return; return (0);
} }
len = (strlen(end) / 4) * 3; len = (strlen(end) / 4) * 3;
if (len == 0) if (len == 0)
return (0);
*out = xmalloc(len);
if ((*outlen = b64_pton(end, *out, len)) == -1) {
free(*out);
*out = NULL;
return (0);
}
return (1);
}
/* Handle the OSC 52 sequence for setting the clipboard. */
static void
input_osc_52(struct input_ctx *ictx, const char *p)
{
struct window_pane *wp = ictx->wp;
struct screen_write_ctx ctx;
u_char *out;
int outlen;
char flags[sizeof "cpqs01234567"] = "";
if (!input_osc_52_parse(ictx, p, &out, &outlen, flags))
return; return;
out = xmalloc(len); if (wp == NULL) {
if ((outlen = b64_pton(end, out, len)) == -1) { /* Popup window. */
if (ictx->c == NULL) {
free(out); free(out);
return; return;
} }
tty_set_selection(&ictx->c->tty, flags, out, outlen);
paste_add(NULL, out, outlen);
} else {
/* Normal window. */
screen_write_start_pane(&ctx, wp, NULL); screen_write_start_pane(&ctx, wp, NULL);
screen_write_setselection(&ctx, flags, out, outlen); screen_write_setselection(&ctx, flags, out, outlen);
screen_write_stop(&ctx); screen_write_stop(&ctx);
notify_pane("pane-set-clipboard", wp); notify_pane("pane-set-clipboard", wp);
paste_add(NULL, out, outlen); paste_add(NULL, out, outlen);
}
free(out);
} }
/* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */ /* Handle the OSC 104 sequence for unsetting (multiple) palette entries. */
@@ -3434,7 +3461,7 @@ input_cancel_requests(struct client *c)
{ {
struct input_request *ir, *ir1; struct input_request *ir, *ir1;
TAILQ_FOREACH_SAFE(ir, &c->input_requests, entry, ir1) TAILQ_FOREACH_SAFE(ir, &c->input_requests, centry, ir1)
input_free_request(ir); input_free_request(ir);
} }

View File

@@ -297,12 +297,12 @@ key_bindings_remove_table(const char *name)
table = key_bindings_get_table(name, 0); table = key_bindings_get_table(name, 0);
if (table != NULL) { if (table != NULL) {
RB_REMOVE(key_tables, &key_tables, table); RB_REMOVE(key_tables, &key_tables, table);
key_bindings_unref_table(table);
}
TAILQ_FOREACH(c, &clients, entry) { TAILQ_FOREACH(c, &clients, entry) {
if (c->keytable == table) if (c->keytable == table)
server_client_set_key_table(c, NULL); server_client_set_key_table(c, NULL);
} }
key_bindings_unref_table(table);
}
} }
void void

View File

@@ -106,7 +106,7 @@ paste_is_empty(void)
/* Get the most recent automatic buffer. */ /* Get the most recent automatic buffer. */
struct paste_buffer * struct paste_buffer *
paste_get_top(const char **name) paste_get_top(char **name)
{ {
struct paste_buffer *pb; struct paste_buffer *pb;
@@ -116,7 +116,7 @@ paste_get_top(const char **name)
if (pb == NULL) if (pb == NULL)
return (NULL); return (NULL);
if (name != NULL) if (name != NULL)
*name = pb->name; *name = xstrdup(pb->name);
return (pb); return (pb);
} }

View File

@@ -850,7 +850,7 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px,
pd->job = job_run(shellcmd, argc, argv, env, s, cwd, pd->job = job_run(shellcmd, argc, argv, env, s, cwd,
popup_job_update_cb, popup_job_complete_cb, NULL, pd, popup_job_update_cb, popup_job_complete_cb, NULL, pd,
JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy); JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy);
pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette); pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette, c);
server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb, server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb,
popup_draw_cb, popup_key_cb, popup_free_cb, popup_resize_cb, pd); popup_draw_cb, popup_key_cb, popup_free_cb, popup_resize_cb, pd);

View File

@@ -250,7 +250,7 @@ skip:
/* Return whether a suitable size was found. */ /* Return whether a suitable size was found. */
if (type == WINDOW_SIZE_MANUAL) { if (type == WINDOW_SIZE_MANUAL) {
log_debug("%s: type is manual", __func__); log_debug("%s: type is manual", __func__);
return (1); return (w != NULL);
} }
if (type == WINDOW_SIZE_LARGEST) { if (type == WINDOW_SIZE_LARGEST) {
log_debug("%s: type is largest", __func__); log_debug("%s: type is largest", __func__);

View File

@@ -2708,15 +2708,28 @@ server_client_loop(void)
struct client *c; struct client *c;
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
struct window_mode_entry *wme;
/* Check for window resize. This is done before redrawing. */ /* Check for window resize. This is done before redrawing. */
RB_FOREACH(w, windows, &windows) RB_FOREACH(w, windows, &windows)
server_client_check_window_resize(w); server_client_check_window_resize(w);
/* Notify modes that pane styles may have changed. */
RB_FOREACH(w, windows, &windows) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->flags & PANE_STYLECHANGED) {
wme = TAILQ_FIRST(&wp->modes);
if (wme != NULL &&
wme->mode->style_changed != NULL)
wme->mode->style_changed(wme);
}
}
}
/* Check clients. */ /* Check clients. */
TAILQ_FOREACH(c, &clients, entry) { TAILQ_FOREACH(c, &clients, entry) {
server_client_check_exit(c); server_client_check_exit(c);
if (c->session != NULL) { if (c->session != NULL && c->session->curw != NULL) {
server_client_check_modes(c); server_client_check_modes(c);
server_client_check_redraw(c); server_client_check_redraw(c);
server_client_reset_state(c); server_client_reset_state(c);

40
sort.c
View File

@@ -197,23 +197,25 @@ sort_pane_cmp(const void *a0, const void *b0)
case SORT_CREATION: case SORT_CREATION:
result = a->id - b->id; result = a->id - b->id;
break; break;
case SORT_INDEX:
case SORT_NAME:
case SORT_ORDER:
case SORT_SIZE: case SORT_SIZE:
case SORT_END: result = a->sx * a->sy - b->sx * b->sy;
break; break;
} case SORT_INDEX:
if (result == 0) {
/*
* Panes don't have names, so use number order for any other
* sort field.
*/
window_pane_index(a, &ai); window_pane_index(a, &ai);
window_pane_index(b, &bi); window_pane_index(b, &bi);
result = ai - bi; result = ai - bi;
break;
case SORT_NAME:
result = strcmp(a->screen->title, b->screen->title);
break;
case SORT_ORDER:
case SORT_END:
break;
} }
if (result == 0)
result = strcmp(a->screen->title, b->screen->title);
if (sort_crit->reversed) if (sort_crit->reversed)
result = -result; result = -result;
return (result); return (result);
@@ -235,6 +237,16 @@ sort_winlink_cmp(const void *a0, const void *b0)
case SORT_INDEX: case SORT_INDEX:
result = wla->idx - wlb->idx; result = wla->idx - wlb->idx;
break; break;
case SORT_CREATION:
if (timercmp(&wa->creation_time, &wb->creation_time, >)) {
result = -1;
break;
}
if (timercmp(&wa->creation_time, &wb->creation_time, <)) {
result = 1;
break;
}
break;
case SORT_ACTIVITY: case SORT_ACTIVITY:
if (timercmp(&wa->activity_time, &wb->activity_time, >)) { if (timercmp(&wa->activity_time, &wb->activity_time, >)) {
result = -1; result = -1;
@@ -248,9 +260,10 @@ sort_winlink_cmp(const void *a0, const void *b0)
case SORT_NAME: case SORT_NAME:
result = strcmp(wa->name, wb->name); result = strcmp(wa->name, wb->name);
break; break;
case SORT_CREATION:
case SORT_ORDER:
case SORT_SIZE: case SORT_SIZE:
result = wa->sx * wa->sy - wb->sx * wb->sy;
break;
case SORT_ORDER:
case SORT_END: case SORT_END:
break; break;
} }
@@ -295,7 +308,8 @@ sort_order_from_string(const char* order)
return (SORT_CREATION); return (SORT_CREATION);
if (strcasecmp(order, "index") == 0) if (strcasecmp(order, "index") == 0)
return (SORT_INDEX); return (SORT_INDEX);
if (strcasecmp(order, "name") == 0) if (strcasecmp(order, "name") == 0 ||
strcasecmp(order, "title") == 0)
return (SORT_NAME); return (SORT_NAME);
if (strcasecmp(order, "order") == 0) if (strcasecmp(order, "order") == 0)
return (SORT_ORDER); return (SORT_ORDER);

10
tmux.1
View File

@@ -3092,7 +3092,11 @@ See the
section. section.
.Fl O .Fl O
specifies the sort order: one of specifies the sort order: one of
.Ql name , .Ql name
(title),
.Ql index ,
.Ql size
(area),
.Ql creation .Ql creation
(time), or (time), or
.Ql activity .Ql activity
@@ -3125,6 +3129,10 @@ section.
specifies the sort order: one of specifies the sort order: one of
.Ql index , .Ql index ,
.Ql name , .Ql name ,
.Ql size
(area),
.Ql creation
(time),
or or
.Ql activity .Ql activity
(time). (time).

6
tmux.h
View File

@@ -1101,6 +1101,7 @@ struct window_mode {
void (*free)(struct window_mode_entry *); void (*free)(struct window_mode_entry *);
void (*resize)(struct window_mode_entry *, u_int, u_int); void (*resize)(struct window_mode_entry *, u_int, u_int);
void (*update)(struct window_mode_entry *); void (*update)(struct window_mode_entry *);
void (*style_changed)(struct window_mode_entry *);
void (*key)(struct window_mode_entry *, struct client *, void (*key)(struct window_mode_entry *, struct client *,
struct session *, struct winlink *, key_code, struct session *, struct winlink *, key_code,
struct mouse_event *); struct mouse_event *);
@@ -1285,6 +1286,7 @@ struct window {
struct event offset_timer; struct event offset_timer;
struct timeval activity_time; struct timeval activity_time;
struct timeval creation_time;
struct window_pane *active; struct window_pane *active;
struct window_panes last_panes; struct window_panes last_panes;
@@ -2353,7 +2355,7 @@ time_t paste_buffer_created(struct paste_buffer *);
const char *paste_buffer_data(struct paste_buffer *, size_t *); const char *paste_buffer_data(struct paste_buffer *, size_t *);
struct paste_buffer *paste_walk(struct paste_buffer *); struct paste_buffer *paste_walk(struct paste_buffer *);
int paste_is_empty(void); int paste_is_empty(void);
struct paste_buffer *paste_get_top(const char **); struct paste_buffer *paste_get_top(char **);
struct paste_buffer *paste_get_name(const char *); struct paste_buffer *paste_get_name(const char *);
void paste_free(struct paste_buffer *); void paste_free(struct paste_buffer *);
void paste_add(const char *, char *, size_t); void paste_add(const char *, char *, size_t);
@@ -3055,7 +3057,7 @@ void recalculate_sizes_now(int);
/* input.c */ /* input.c */
#define INPUT_BUF_DEFAULT_SIZE 1048576 #define INPUT_BUF_DEFAULT_SIZE 1048576
struct input_ctx *input_init(struct window_pane *, struct bufferevent *, struct input_ctx *input_init(struct window_pane *, struct bufferevent *,
struct colour_palette *); struct colour_palette *, struct client *);
void input_free(struct input_ctx *); void input_free(struct input_ctx *);
void input_reset(struct input_ctx *, int); void input_reset(struct input_ctx *, int);
struct evbuffer *input_pending(struct input_ctx *); struct evbuffer *input_pending(struct input_ctx *);

View File

@@ -262,10 +262,12 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
else else
next_state = TTY_DRAW_LINE_NEW1; next_state = TTY_DRAW_LINE_NEW1;
} }
log_debug("%s: cell %u empty %u, bg %u; state: current %s, " if (log_get_level() != 0) {
"next %s", __func__, px + i, empty, gcp->bg, log_debug("%s: cell %u empty %u, bg %u; state: "
tty_draw_line_states[current_state], "current %s, next %s", __func__, px + i, empty,
gcp->bg, tty_draw_line_states[current_state],
tty_draw_line_states[next_state]); tty_draw_line_states[next_state]);
}
/* If the state has changed, flush any collected data. */ /* If the state has changed, flush any collected data. */
if (next_state != current_state) { if (next_state != current_state) {

View File

@@ -1377,6 +1377,10 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
/* Convert from base64. */ /* Convert from base64. */
needed = (end / 4) * 3; needed = (end / 4) * 3;
if (needed == 0) {
free(copy);
return (0);
}
out = xmalloc(needed); out = xmalloc(needed);
if ((outlen = b64_pton(copy, out, len)) == -1) { if ((outlen = b64_pton(copy, out, len)) == -1) {
free(out); free(out);
@@ -1612,8 +1616,10 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
} }
if (i == (sizeof tmp) - 1) if (i == (sizeof tmp) - 1)
return (-1); return (-1);
tmp[i - 1] = '\0';
*size = 5 + i; *size = 5 + i;
if (i == 0)
return (0);
tmp[i - 1] = '\0';
/* Add terminal features. */ /* Add terminal features. */
if (strncmp(tmp, "iTerm2 ", 7) == 0) if (strncmp(tmp, "iTerm2 ", 7) == 0)
@@ -1686,11 +1692,13 @@ tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size,
} }
if (i == (sizeof tmp) - 1) if (i == (sizeof tmp) - 1)
return (-1); return (-1);
*size = 6 + i;
if (i == 0)
return (0);
if (tmp[i - 1] == '\033') if (tmp[i - 1] == '\033')
tmp[i - 1] = '\0'; tmp[i - 1] = '\0';
else else
tmp[i] = '\0'; tmp[i] = '\0';
*size = 6 + i;
/* Work out the colour. */ /* Work out the colour. */
n = colour_parseX11(tmp); n = colour_parseX11(tmp);
@@ -1755,11 +1763,13 @@ tty_keys_palette(struct tty *tty, const char *buf, size_t len, size_t *size)
} }
if (i == (sizeof tmp) - 1) if (i == (sizeof tmp) - 1)
return (-1); return (-1);
*size = 5 + i;
if (i == 0)
return (0);
if (tmp[i - 1] == '\033') if (tmp[i - 1] == '\033')
tmp[i - 1] = '\0'; tmp[i - 1] = '\0';
else else
tmp[i] = '\0'; tmp[i] = '\0';
*size = 5 + i;
/* Parse index. */ /* Parse index. */
idx = strtol(tmp, &endptr, 10); idx = strtol(tmp, &endptr, 10);

4
tty.c
View File

@@ -633,7 +633,8 @@ tty_add(struct tty *tty, const char *buf, size_t len)
if (tty_log_fd != -1) if (tty_log_fd != -1)
write(tty_log_fd, buf, len); write(tty_log_fd, buf, len);
if (tty->flags & TTY_STARTED) if ((tty->flags & TTY_STARTED) &&
!event_pending(&tty->event_out, EV_WRITE, NULL))
event_add(&tty->event_out, NULL); event_add(&tty->event_out, NULL);
} }
@@ -2185,7 +2186,6 @@ tty_cell(struct tty *tty, const struct grid_cell *gc,
/* If it is a single character, write with putc to handle ACS. */ /* If it is a single character, write with putc to handle ACS. */
if (gcp->data.size == 1) { if (gcp->data.size == 1) {
tty_attributes(tty, gcp, defaults, palette, hl);
if (*gcp->data.data < 0x20 || *gcp->data.data == 0x7f) if (*gcp->data.data < 0x20 || *gcp->data.data == 0x7f)
return; return;
tty_putc(tty, *gcp->data.data); tty_putc(tty, *gcp->data.data);

View File

@@ -51,6 +51,7 @@ static void window_copy_redraw_selection(struct window_mode_entry *, u_int);
static void window_copy_redraw_lines(struct window_mode_entry *, u_int, static void window_copy_redraw_lines(struct window_mode_entry *, u_int,
u_int); u_int);
static void window_copy_redraw_screen(struct window_mode_entry *); static void window_copy_redraw_screen(struct window_mode_entry *);
static void window_copy_style_changed(struct window_mode_entry *);
static void window_copy_write_line(struct window_mode_entry *, static void window_copy_write_line(struct window_mode_entry *,
struct screen_write_ctx *, u_int); struct screen_write_ctx *, u_int);
static void window_copy_write_lines(struct window_mode_entry *, static void window_copy_write_lines(struct window_mode_entry *,
@@ -158,6 +159,7 @@ const struct window_mode window_copy_mode = {
.init = window_copy_init, .init = window_copy_init,
.free = window_copy_free, .free = window_copy_free,
.resize = window_copy_resize, .resize = window_copy_resize,
.style_changed = window_copy_style_changed,
.key_table = window_copy_key_table, .key_table = window_copy_key_table,
.command = window_copy_command, .command = window_copy_command,
.formats = window_copy_formats, .formats = window_copy_formats,
@@ -170,6 +172,7 @@ const struct window_mode window_view_mode = {
.init = window_copy_view_init, .init = window_copy_view_init,
.free = window_copy_free, .free = window_copy_free,
.resize = window_copy_resize, .resize = window_copy_resize,
.style_changed = window_copy_style_changed,
.key_table = window_copy_key_table, .key_table = window_copy_key_table,
.command = window_copy_command, .command = window_copy_command,
.formats = window_copy_formats, .formats = window_copy_formats,
@@ -491,7 +494,7 @@ window_copy_view_init(struct window_mode_entry *wme,
data->backing = xmalloc(sizeof *data->backing); data->backing = xmalloc(sizeof *data->backing);
screen_init(data->backing, sx, screen_size_y(base), UINT_MAX); screen_init(data->backing, sx, screen_size_y(base), UINT_MAX);
data->ictx = input_init(NULL, NULL, NULL); data->ictx = input_init(NULL, NULL, NULL, NULL);
data->mx = data->cx; data->mx = data->cx;
data->my = screen_hsize(data->backing) + data->cy - data->oy; data->my = screen_hsize(data->backing) + data->cy - data->oy;
data->showmark = 0; data->showmark = 0;
@@ -4268,6 +4271,9 @@ window_copy_clear_marks(struct window_mode_entry *wme)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
data->searchcount = -1;
data->searchmore = 0;
free(data->searchmark); free(data->searchmark);
data->searchmark = NULL; data->searchmark = NULL;
} }
@@ -4595,6 +4601,16 @@ window_copy_redraw_screen(struct window_mode_entry *wme)
window_copy_redraw_lines(wme, 0, screen_size_y(&data->screen)); window_copy_redraw_lines(wme, 0, screen_size_y(&data->screen));
} }
static void
window_copy_style_changed(struct window_mode_entry *wme)
{
struct window_copy_mode_data *data = wme->data;
if (data->screen.sel != NULL)
window_copy_set_selection(wme, 0, 1);
window_copy_redraw_screen(wme);
}
static void static void
window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin, window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin,
int no_reset) int no_reset)
@@ -5036,9 +5052,9 @@ static void
window_copy_append_selection(struct window_mode_entry *wme) window_copy_append_selection(struct window_mode_entry *wme)
{ {
struct window_pane *wp = wme->wp; struct window_pane *wp = wme->wp;
char *buf; char *buf, *bufname = NULL;
struct paste_buffer *pb; struct paste_buffer *pb;
const char *bufdata, *bufname = NULL; const char *bufdata;
size_t len, bufsize; size_t len, bufsize;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
@@ -5063,6 +5079,7 @@ window_copy_append_selection(struct window_mode_entry *wme)
} }
if (paste_set(buf, len, bufname, NULL) != 0) if (paste_set(buf, len, bufname, NULL) != 0)
free(buf); free(buf);
free(bufname);
} }
static void static void

View File

@@ -328,6 +328,9 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
RB_INSERT(windows, &windows, w); RB_INSERT(windows, &windows, w);
window_set_fill_character(w); window_set_fill_character(w);
if (gettimeofday(&w->creation_time, NULL) != 0)
fatal("gettimeofday failed");
window_update_activity(w); window_update_activity(w);
log_debug("%s: @%u create %ux%u (%ux%u)", __func__, w->id, sx, sy, log_debug("%s: @%u create %ux%u (%ux%u)", __func__, w->id, sx, sy,
@@ -1068,7 +1071,7 @@ window_pane_set_event(struct window_pane *wp)
NULL, window_pane_error_callback, wp); NULL, window_pane_error_callback, wp);
if (wp->event == NULL) if (wp->event == NULL)
fatalx("out of memory"); fatalx("out of memory");
wp->ictx = input_init(wp, wp->event, &wp->palette); wp->ictx = input_init(wp, wp->event, &wp->palette, NULL);
bufferevent_enable(wp->event, EV_READ|EV_WRITE); bufferevent_enable(wp->event, EV_READ|EV_WRITE);
} }