Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2024-10-01 10:01:10 +01:00
commit 157d748949
9 changed files with 123 additions and 49 deletions

View File

@ -73,11 +73,13 @@ cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after,
if (args_has(args, 'K')) {
if (tc == NULL)
return (item);
event = xmalloc(sizeof *event);
event = xcalloc(1, sizeof *event);
event->key = key|KEYC_SENT;
memset(&event->m, 0, sizeof event->m);
if (server_client_handle_key(tc, event) == 0)
if (server_client_handle_key(tc, event) == 0) {
free(event->buf);
free(event);
}
return (item);
}

View File

@ -498,9 +498,12 @@ input_key_vt10x(struct bufferevent *bev, key_code key)
return (0);
}
/* Prevent TAB and RET from being swallowed by C0 remapping logic. */
/*
* Prevent TAB, CR and LF from being swallowed by the C0 remapping
* logic.
*/
onlykey = key & KEYC_MASK_KEY;
if (onlykey == '\r' || onlykey == '\t')
if (onlykey == '\r' || onlykey == '\n' || onlykey == '\t')
key &= ~KEYC_CTRL;
/*

View File

@ -182,6 +182,20 @@ screen_reset_tabs(struct screen *s)
bit_set(s->tabs, i);
}
/* Set default cursor style and colour from options. */
void
screen_set_default_cursor(struct screen *s, struct options *oo)
{
int c;
c = options_get_number(oo, "cursor-colour");
s->default_ccolour = c;
c = options_get_number(oo, "cursor-style");
s->default_mode = 0;
screen_set_cursor_style(c, &s->default_cstyle, &s->default_mode);
}
/* Set screen cursor style and mode. */
void
screen_set_cursor_style(u_int style, enum screen_cursor_style *cstyle,

View File

@ -42,8 +42,6 @@ static void server_client_check_modes(struct client *);
static void server_client_set_title(struct client *);
static void server_client_set_path(struct client *);
static void server_client_reset_state(struct client *);
static int server_client_is_bracket_pasting(struct client *, key_code);
static int server_client_assume_paste(struct session *);
static void server_client_update_latest(struct client *);
static void server_client_dispatch(struct imsg *, void *);
@ -1797,18 +1795,18 @@ out:
/* Is this a bracket paste key? */
static int
server_client_is_bracket_pasting(struct client *c, key_code key)
server_client_is_bracket_paste(struct client *c, key_code key)
{
if (key == KEYC_PASTE_START) {
c->flags |= CLIENT_BRACKETPASTING;
log_debug("%s: bracket paste on", c->name);
return (1);
return (0);
}
if (key == KEYC_PASTE_END) {
c->flags &= ~CLIENT_BRACKETPASTING;
log_debug("%s: bracket paste off", c->name);
return (1);
return (0);
}
return !!(c->flags & CLIENT_BRACKETPASTING);
@ -1816,25 +1814,29 @@ server_client_is_bracket_pasting(struct client *c, key_code key)
/* Is this fast enough to probably be a paste? */
static int
server_client_assume_paste(struct session *s)
server_client_is_assume_paste(struct client *c)
{
struct session *s = c->session;
struct timeval tv;
int t;
if (c->flags & CLIENT_BRACKETPASTING)
return (0);
if ((t = options_get_number(s->options, "assume-paste-time")) == 0)
return (0);
timersub(&s->activity_time, &s->last_activity_time, &tv);
timersub(&c->activity_time, &c->last_activity_time, &tv);
if (tv.tv_sec == 0 && tv.tv_usec < t * 1000) {
log_debug("session %s pasting (flag %d)", s->name,
!!(s->flags & SESSION_PASTING));
if (s->flags & SESSION_PASTING)
if (c->flags & CLIENT_ASSUMEPASTING)
return (1);
s->flags |= SESSION_PASTING;
c->flags |= CLIENT_ASSUMEPASTING;
log_debug("%s: assume paste on", c->name);
return (0);
}
log_debug("session %s not pasting", s->name);
s->flags &= ~SESSION_PASTING;
if (c->flags & CLIENT_ASSUMEPASTING) {
c->flags &= ~CLIENT_ASSUMEPASTING;
log_debug("%s: assume paste off", c->name);
}
return (0);
}
@ -1887,6 +1889,8 @@ server_client_key_callback(struct cmdq_item *item, void *data)
wl = s->curw;
/* Update the activity timer. */
memcpy(&c->last_activity_time, &c->activity_time,
sizeof c->last_activity_time);
if (gettimeofday(&c->activity_time, NULL) != 0)
fatal("gettimeofday failed");
session_update_activity(s, &c->activity_time);
@ -1924,14 +1928,16 @@ server_client_key_callback(struct cmdq_item *item, void *data)
goto forward_key;
/* Forward if bracket pasting. */
if (server_client_is_bracket_pasting(c, key))
goto forward_key;
if (server_client_is_bracket_paste (c, key))
goto paste_key;
/* Treat everything as a regular key when pasting is detected. */
if (!KEYC_IS_MOUSE(key) &&
key != KEYC_FOCUS_IN &&
key != KEYC_FOCUS_OUT &&
(~key & KEYC_SENT) &&
server_client_assume_paste(s))
goto forward_key;
server_client_is_assume_paste(c))
goto paste_key;
/*
* Work out the current key table. If the pane is in a mode, use
@ -2100,10 +2106,20 @@ forward_key:
goto out;
if (wp != NULL)
window_pane_key(wp, c, s, wl, key, m);
goto out;
paste_key:
if (c->flags & CLIENT_READONLY)
goto out;
if (event->buf != NULL)
window_pane_paste(wp, event->buf, event->len);
key = KEYC_NONE;
goto out;
out:
if (s != NULL && key != KEYC_FOCUS_OUT)
server_client_update_latest(c);
free(event->buf);
free(event);
return (CMD_RETURN_NORMAL);
}
@ -2517,12 +2533,14 @@ server_client_click_timer(__unused int fd, __unused short events, void *data)
* Waiting for a third click that hasn't happened, so this must
* have been a double click.
*/
event = xmalloc(sizeof *event);
event = xcalloc(1, sizeof *event);
event->key = KEYC_DOUBLECLICK;
memcpy(&event->m, &c->click_event, sizeof event->m);
if (!server_client_handle_key(c, event))
if (!server_client_handle_key(c, event)) {
free(event->buf);
free(event);
}
}
c->flags &= ~(CLIENT_DOUBLECLICK|CLIENT_TRIPLECLICK);
}

View File

@ -270,19 +270,16 @@ session_lock_timer(__unused int fd, __unused short events, void *arg)
void
session_update_activity(struct session *s, struct timeval *from)
{
struct timeval *last = &s->last_activity_time;
struct timeval tv;
memcpy(last, &s->activity_time, sizeof *last);
if (from == NULL)
gettimeofday(&s->activity_time, NULL);
else
memcpy(&s->activity_time, from, sizeof s->activity_time);
log_debug("session $%u %s activity %lld.%06d (last %lld.%06d)", s->id,
log_debug("session $%u %s activity %lld.%06d", s->id,
s->name, (long long)s->activity_time.tv_sec,
(int)s->activity_time.tv_usec, (long long)last->tv_sec,
(int)last->tv_usec);
(int)s->activity_time.tv_usec);
if (evtimer_initialized(&s->lock_timer))
evtimer_del(&s->lock_timer);

10
tmux.h
View File

@ -1342,8 +1342,7 @@ struct session {
struct options *options;
#define SESSION_PASTING 0x1
#define SESSION_ALERTED 0x2
#define SESSION_ALERTED 0x1
int flags;
u_int attached;
@ -1423,6 +1422,9 @@ struct mouse_event {
struct key_event {
key_code key;
struct mouse_event m;
char *buf;
size_t len;
};
/* Terminal definition. */
@ -1840,6 +1842,7 @@ struct client {
struct timeval creation_time;
struct timeval activity_time;
struct timeval last_activity_time;
struct environ *environ;
struct format_job_tree *jobs;
@ -1906,6 +1909,7 @@ struct client {
#define CLIENT_WINDOWSIZECHANGED 0x400000000ULL
#define CLIENT_CLIPBOARDBUFFER 0x800000000ULL
#define CLIENT_BRACKETPASTING 0x1000000000ULL
#define CLIENT_ASSUMEPASTING 0x2000000000ULL
#define CLIENT_ALLREDRAWFLAGS \
(CLIENT_REDRAWWINDOW| \
CLIENT_REDRAWSTATUS| \
@ -3058,6 +3062,7 @@ void screen_reinit(struct screen *);
void screen_free(struct screen *);
void screen_reset_tabs(struct screen *);
void screen_reset_hyperlinks(struct screen *);
void screen_set_default_cursor(struct screen *, struct options *);
void screen_set_cursor_style(u_int, enum screen_cursor_style *, int *);
void screen_set_cursor_colour(struct screen *, int);
int screen_set_title(struct screen *, const char *);
@ -3145,6 +3150,7 @@ void window_pane_reset_mode_all(struct window_pane *);
int window_pane_key(struct window_pane *, struct client *,
struct session *, struct winlink *, key_code,
struct mouse_event *);
void window_pane_paste(struct window_pane *, char *, size_t);
int window_pane_visible(struct window_pane *);
int window_pane_exited(struct window_pane *);
u_int window_pane_search(struct window_pane *, const char *, int,

View File

@ -944,9 +944,6 @@ complete_key:
if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace)
key = (key & KEYC_MASK_MODIFIERS)|KEYC_BSPACE;
/* Remove data from buffer. */
evbuffer_drain(tty->in, size);
/* Remove key timer. */
if (event_initialized(&tty->key_timer))
evtimer_del(&tty->key_timer);
@ -965,12 +962,22 @@ complete_key:
/* Fire the key. */
if (key != KEYC_UNKNOWN) {
event = xmalloc(sizeof *event);
event = xcalloc(1, sizeof *event);
event->key = key;
memcpy(&event->m, &m, sizeof event->m);
if (!server_client_handle_key(c, event))
event->buf = xmalloc(size);
event->len = size;
memcpy (event->buf, buf, event->len);
if (!server_client_handle_key(c, event)) {
free(event->buf);
free(event);
}
}
/* Remove data from buffer. */
evbuffer_drain(tty->in, size);
return (1);

View File

@ -417,6 +417,7 @@ window_copy_common_init(struct window_mode_entry *wme)
data->jumpchar = NULL;
screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0);
screen_set_default_cursor(&data->screen, global_w_options);
data->modekeys = options_get_number(wp->window->options, "mode-keys");
evtimer_set(&data->dragtimer, window_copy_scroll_timer, wme);

View File

@ -1164,6 +1164,24 @@ window_pane_reset_mode_all(struct window_pane *wp)
window_pane_reset_mode(wp);
}
static void
window_pane_copy_paste(struct window_pane *wp, char *buf, size_t len)
{
struct window_pane *loop;
TAILQ_FOREACH(loop, &wp->window->panes, entry) {
if (loop != wp &&
TAILQ_EMPTY(&loop->modes) &&
loop->fd != -1 &&
(~loop->flags & PANE_INPUTOFF) &&
window_pane_visible(loop) &&
options_get_number(loop->options, "synchronize-panes")) {
log_debug("%s: %.*s", __func__, (int)len, buf);
bufferevent_write(loop->event, buf, len);
}
}
}
static void
window_pane_copy_key(struct window_pane *wp, key_code key)
{
@ -1180,6 +1198,22 @@ window_pane_copy_key(struct window_pane *wp, key_code key)
}
}
void
window_pane_paste(struct window_pane *wp, char *buf, size_t len)
{
if (!TAILQ_EMPTY(&wp->modes))
return;
if (wp->fd == -1 || wp->flags & PANE_INPUTOFF)
return;
log_debug("%s: %.*s", __func__, (int)len, buf);
bufferevent_write(wp->event, buf, len);
if (options_get_number(wp->options, "synchronize-panes"))
window_pane_copy_paste(wp, buf, len);
}
int
window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
struct winlink *wl, key_code key, struct mouse_event *m)
@ -1662,15 +1696,7 @@ window_set_fill_character(struct window *w)
void
window_pane_default_cursor(struct window_pane *wp)
{
struct screen *s = wp->screen;
int c;
c = options_get_number(wp->options, "cursor-colour");
s->default_ccolour = c;
c = options_get_number(wp->options, "cursor-style");
s->default_mode = 0;
screen_set_cursor_style(c, &s->default_cstyle, &s->default_mode);
screen_set_default_cursor(wp->screen, wp->options);
}
int