mirror of
https://github.com/tmux/tmux.git
synced 2025-01-12 03:08:46 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
a06cf900c7
@ -66,6 +66,8 @@ cmd_refresh_client_update_offset(struct client *tc, const char *value)
|
||||
control_set_pane_on(tc, wp);
|
||||
else if (strcmp(colon, "off") == 0)
|
||||
control_set_pane_off(tc, wp);
|
||||
else if (strcmp(colon, "continue") == 0)
|
||||
control_continue_pane(tc, wp);
|
||||
|
||||
out:
|
||||
free(copy);
|
||||
@ -168,7 +170,7 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
|
||||
}
|
||||
tty_set_size(&tc->tty, x, y, 0, 0);
|
||||
tc->flags |= CLIENT_SIZECHANGED;
|
||||
recalculate_sizes();
|
||||
recalculate_sizes_now(1);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
|
63
control.c
63
control.c
@ -65,6 +65,7 @@ struct control_pane {
|
||||
|
||||
int flags;
|
||||
#define CONTROL_PANE_OFF 0x1
|
||||
#define CONTROL_PANE_PAUSED 0x2
|
||||
|
||||
int pending_flag;
|
||||
TAILQ_ENTRY(control_pane) pending_entry;
|
||||
@ -153,6 +154,19 @@ control_add_pane(struct client *c, struct window_pane *wp)
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/* Discard output for a pane. */
|
||||
static void
|
||||
control_discard_pane(struct client *c, struct control_pane *cp)
|
||||
{
|
||||
struct control_state *cs = c->control_state;
|
||||
struct control_block *cb, *cb1;
|
||||
|
||||
TAILQ_FOREACH_SAFE(cb, &cp->blocks, entry, cb1) {
|
||||
TAILQ_REMOVE(&cp->blocks, cb, entry);
|
||||
control_free_block(cs, cb);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get actual pane for this client. */
|
||||
static struct window_pane *
|
||||
control_window_pane(struct client *c, u_int pane)
|
||||
@ -197,7 +211,7 @@ control_pane_offset(struct client *c, struct window_pane *wp, int *off)
|
||||
}
|
||||
|
||||
cp = control_get_pane(c, wp);
|
||||
if (cp == NULL) {
|
||||
if (cp == NULL || (cp->flags & CONTROL_PANE_PAUSED)) {
|
||||
*off = 0;
|
||||
return (NULL);
|
||||
}
|
||||
@ -216,7 +230,7 @@ control_set_pane_on(struct client *c, struct window_pane *wp)
|
||||
struct control_pane *cp;
|
||||
|
||||
cp = control_get_pane(c, wp);
|
||||
if (cp != NULL) {
|
||||
if (cp != NULL && (cp->flags & CONTROL_PANE_OFF)) {
|
||||
cp->flags &= ~CONTROL_PANE_OFF;
|
||||
memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
|
||||
memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
|
||||
@ -233,6 +247,21 @@ control_set_pane_off(struct client *c, struct window_pane *wp)
|
||||
cp->flags |= CONTROL_PANE_OFF;
|
||||
}
|
||||
|
||||
/* Continue a paused pane. */
|
||||
void
|
||||
control_continue_pane(struct client *c, struct window_pane *wp)
|
||||
{
|
||||
struct control_pane *cp;
|
||||
|
||||
cp = control_get_pane(c, wp);
|
||||
if (cp != NULL && (cp->flags & CONTROL_PANE_PAUSED)) {
|
||||
cp->flags &= ~CONTROL_PANE_PAUSED;
|
||||
memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
|
||||
memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
|
||||
control_write(c, "%%continue %%%u", wp->id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write a line. */
|
||||
static void
|
||||
control_vwrite(struct client *c, const char *fmt, va_list ap)
|
||||
@ -285,6 +314,7 @@ control_write_output(struct client *c, struct window_pane *wp)
|
||||
struct control_pane *cp;
|
||||
struct control_block *cb;
|
||||
size_t new_size;
|
||||
uint64_t t;
|
||||
|
||||
if (winlink_find_by_window(&c->session->windows, wp->window) == NULL)
|
||||
return;
|
||||
@ -296,8 +326,22 @@ control_write_output(struct client *c, struct window_pane *wp)
|
||||
return;
|
||||
}
|
||||
cp = control_add_pane(c, wp);
|
||||
if (cp->flags & CONTROL_PANE_OFF)
|
||||
if (cp->flags & (CONTROL_PANE_OFF|CONTROL_PANE_PAUSED))
|
||||
goto ignore;
|
||||
if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
|
||||
cb = TAILQ_FIRST(&cp->blocks);
|
||||
if (cb != NULL) {
|
||||
t = get_timer();
|
||||
log_debug("%s: %s: %%%u is %lld behind", __func__,
|
||||
c->name, wp->id, (long long)t - cb->t);
|
||||
if (cb->t < t - c->pause_age) {
|
||||
cp->flags |= CONTROL_PANE_PAUSED;
|
||||
control_discard_pane(c, cp);
|
||||
control_write(c, "%%pause %%%u", wp->id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window_pane_get_new_data(wp, &cp->queued, &new_size);
|
||||
if (new_size == 0)
|
||||
@ -585,20 +629,15 @@ control_start(struct client *c)
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush all output for a client that is detaching. */
|
||||
/* Discard all output for a client. */
|
||||
void
|
||||
control_flush(struct client *c)
|
||||
control_discard(struct client *c)
|
||||
{
|
||||
struct control_state *cs = c->control_state;
|
||||
struct control_pane *cp;
|
||||
struct control_block *cb, *cb1;
|
||||
|
||||
RB_FOREACH(cp, control_panes, &cs->panes) {
|
||||
TAILQ_FOREACH_SAFE(cb, &cp->blocks, entry, cb1) {
|
||||
TAILQ_REMOVE(&cp->blocks, cb, entry);
|
||||
control_free_block(cs, cb);
|
||||
}
|
||||
}
|
||||
RB_FOREACH(cp, control_panes, &cs->panes)
|
||||
control_discard_pane(c, cp);
|
||||
}
|
||||
|
||||
/* Stop control mode. */
|
||||
|
16
resize.c
16
resize.c
@ -227,7 +227,7 @@ done:
|
||||
}
|
||||
|
||||
void
|
||||
recalculate_size(struct window *w)
|
||||
recalculate_size(struct window *w, int now)
|
||||
{
|
||||
struct session *s;
|
||||
struct client *c;
|
||||
@ -348,10 +348,10 @@ recalculate_size(struct window *w)
|
||||
break;
|
||||
}
|
||||
if (w->flags & WINDOW_RESIZE) {
|
||||
if (changed && w->new_sx == sx && w->new_sy == sy)
|
||||
if (!now && changed && w->new_sx == sx && w->new_sy == sy)
|
||||
changed = 0;
|
||||
} else {
|
||||
if (changed && w->sx == sx && w->sy == sy)
|
||||
if (!now && changed && w->sx == sx && w->sy == sy)
|
||||
changed = 0;
|
||||
}
|
||||
|
||||
@ -360,7 +360,7 @@ recalculate_size(struct window *w)
|
||||
return;
|
||||
}
|
||||
log_debug("%s: @%u new size %u,%u", __func__, w->id, sx, sy);
|
||||
if (type == WINDOW_SIZE_MANUAL)
|
||||
if (now || type == WINDOW_SIZE_MANUAL)
|
||||
resize_window(w, sx, sy, xpixel, ypixel);
|
||||
else {
|
||||
w->new_sx = sx;
|
||||
@ -375,6 +375,12 @@ recalculate_size(struct window *w)
|
||||
|
||||
void
|
||||
recalculate_sizes(void)
|
||||
{
|
||||
recalculate_sizes_now(0);
|
||||
}
|
||||
|
||||
void
|
||||
recalculate_sizes_now(int now)
|
||||
{
|
||||
struct session *s;
|
||||
struct client *c;
|
||||
@ -407,5 +413,5 @@ recalculate_sizes(void)
|
||||
|
||||
/* Walk each window and adjust the size. */
|
||||
RB_FOREACH(w, windows, &windows)
|
||||
recalculate_size(w);
|
||||
recalculate_size(w, now);
|
||||
}
|
||||
|
@ -1091,7 +1091,7 @@ server_client_update_latest(struct client *c)
|
||||
w->latest = c;
|
||||
|
||||
if (options_get_number(w->options, "window-size") == WINDOW_SIZE_LATEST)
|
||||
recalculate_size(w);
|
||||
recalculate_size(w, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1539,7 +1539,7 @@ server_client_check_pane_buffer(struct window_pane *wp)
|
||||
__func__, c->name, wpo->used - wp->base_offset, new_size,
|
||||
wp->id);
|
||||
if (new_size > SERVER_CLIENT_PANE_LIMIT) {
|
||||
control_flush(c);
|
||||
control_discard(c);
|
||||
c->flags |= CLIENT_EXIT;
|
||||
}
|
||||
if (wpo->used < minimum)
|
||||
@ -1783,7 +1783,7 @@ server_client_check_exit(struct client *c)
|
||||
return;
|
||||
|
||||
if (c->flags & CLIENT_CONTROL) {
|
||||
control_flush(c);
|
||||
control_discard(c);
|
||||
if (!control_all_done(c))
|
||||
return;
|
||||
}
|
||||
@ -2364,6 +2364,23 @@ server_client_get_cwd(struct client *c, struct session *s)
|
||||
return ("/");
|
||||
}
|
||||
|
||||
/* Get control client flags. */
|
||||
static uint64_t
|
||||
server_client_control_flags(struct client *c, const char *next)
|
||||
{
|
||||
if (strcmp(next, "pause-after") == 0) {
|
||||
c->pause_age = 0;
|
||||
return (CLIENT_CONTROL_PAUSEAFTER);
|
||||
}
|
||||
if (sscanf(next, "pause-after=%u", &c->pause_age) == 1) {
|
||||
c->pause_age *= 1000;
|
||||
return (CLIENT_CONTROL_PAUSEAFTER);
|
||||
}
|
||||
if (strcmp(next, "no-output") == 0)
|
||||
return (CLIENT_CONTROL_NOOUTPUT);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Set client flags. */
|
||||
void
|
||||
server_client_set_flags(struct client *c, const char *flags)
|
||||
@ -2378,11 +2395,10 @@ server_client_set_flags(struct client *c, const char *flags)
|
||||
if (not)
|
||||
next++;
|
||||
|
||||
flag = 0;
|
||||
if (c->flags & CLIENT_CONTROL) {
|
||||
if (strcmp(next, "no-output") == 0)
|
||||
flag = CLIENT_CONTROL_NOOUTPUT;
|
||||
}
|
||||
if (c->flags & CLIENT_CONTROL)
|
||||
flag = server_client_control_flags(c, next);
|
||||
else
|
||||
flag = 0;
|
||||
if (strcmp(next, "read-only") == 0)
|
||||
flag = CLIENT_READONLY;
|
||||
else if (strcmp(next, "ignore-size") == 0)
|
||||
@ -2407,7 +2423,8 @@ server_client_set_flags(struct client *c, const char *flags)
|
||||
const char *
|
||||
server_client_get_flags(struct client *c)
|
||||
{
|
||||
static char s[256];
|
||||
static char s[256];
|
||||
char tmp[32];
|
||||
|
||||
*s = '\0';
|
||||
if (c->flags & CLIENT_ATTACHED)
|
||||
@ -2418,6 +2435,11 @@ server_client_get_flags(struct client *c)
|
||||
strlcat(s, "ignore-size,", sizeof s);
|
||||
if (c->flags & CLIENT_CONTROL_NOOUTPUT)
|
||||
strlcat(s, "no-output,", sizeof s);
|
||||
if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
|
||||
xsnprintf(tmp, sizeof tmp, "pause-after=%u,",
|
||||
c->pause_age / 1000);
|
||||
strlcat(s, tmp, sizeof s);
|
||||
}
|
||||
if (c->flags & CLIENT_READONLY)
|
||||
strlcat(s, "read-only,", sizeof s);
|
||||
if (c->flags & CLIENT_ACTIVEPANE)
|
||||
|
45
tmux.1
45
tmux.1
@ -977,14 +977,18 @@ detaching the client, typically causing it to exit.
|
||||
sets a comma-separated list of client flags.
|
||||
The flags are:
|
||||
.Bl -tag -width Ds
|
||||
.It read-only
|
||||
the client is read-only
|
||||
.It active-pane
|
||||
the client has an independent active pane
|
||||
.It ignore-size
|
||||
the client does not affect the size of other clients
|
||||
.It no-output
|
||||
the client does not receive pane output in control mode
|
||||
.It active-pane
|
||||
the client has an independent active pane
|
||||
.It pause-after=seconds
|
||||
output is paused once the pane is
|
||||
.Ar seconds
|
||||
behind in control mode
|
||||
.It read-only
|
||||
the client is read-only
|
||||
.El
|
||||
.Pp
|
||||
A leading
|
||||
@ -1295,22 +1299,27 @@ it.
|
||||
.Fl C
|
||||
sets the width and height of a control mode client.
|
||||
.Fl A
|
||||
informs
|
||||
.Nm
|
||||
of a control mode client's interest in a pane.
|
||||
allows a control mode client to trigger actions on a pane.
|
||||
The argument is a pane ID (with leading
|
||||
.Ql % ) ,
|
||||
a colon, then one of
|
||||
.Ql on
|
||||
.Ql on ,
|
||||
.Ql off
|
||||
or
|
||||
.Ql off .
|
||||
.Ql continue .
|
||||
If
|
||||
.Ql off ,
|
||||
.Nm
|
||||
will not send output from the pane to the client and if all clients have turned
|
||||
the pane off, will stop reading from the pane.
|
||||
If
|
||||
.Ql continue ,
|
||||
.Nm
|
||||
will return to sending output to a paused pane (see the
|
||||
.Ar pause-after
|
||||
flag).
|
||||
.Fl A
|
||||
may be given multiple times.
|
||||
may be given multiple times for different panes.
|
||||
.Pp
|
||||
.Fl f
|
||||
sets a comma-separated list of client flags, see
|
||||
@ -3345,6 +3354,10 @@ Allows setting the system clipboard.
|
||||
Allows setting the cursor colour.
|
||||
.It cstyle
|
||||
Allows setting the cursor style.
|
||||
.It extkeys
|
||||
Supports extended keys.
|
||||
.It focus
|
||||
Supports focus reporting.
|
||||
.It margins
|
||||
Supports DECSLRM margins.
|
||||
.It overline
|
||||
@ -3353,6 +3366,8 @@ Supports the overline SGR attribute.
|
||||
Supports the DECFRA rectangle fill escape sequence.
|
||||
.It RGB
|
||||
Supports RGB colour with the SGR escape sequences.
|
||||
.It strikethrough
|
||||
Supports the strikethrough SGR escape sequence.
|
||||
.It sync
|
||||
Supports synchronized updates.
|
||||
.It title
|
||||
@ -5881,6 +5896,12 @@ The client is now attached to the session with ID
|
||||
.Ar session-id ,
|
||||
which is named
|
||||
.Ar name .
|
||||
.It Ic %continue Ar pane-id
|
||||
The pane has been continued after being paused (if the
|
||||
.Ar pause-after
|
||||
flag is set, see
|
||||
.Ic refresh-client
|
||||
.Fl A ) .
|
||||
.It Ic %exit Op Ar reason
|
||||
The
|
||||
.Nm
|
||||
@ -5907,6 +5928,10 @@ escapes non-printable characters and backslash as octal \\xxx.
|
||||
The pane with ID
|
||||
.Ar pane-id
|
||||
has changed mode.
|
||||
.It Ic %pause Ar pane-id
|
||||
The pane has been paused (if the
|
||||
.Ar pause-after
|
||||
flag is set).
|
||||
.It Ic %session-changed Ar session-id Ar name
|
||||
The client is now attached to the session with ID
|
||||
.Ar session-id ,
|
||||
|
9
tmux.h
9
tmux.h
@ -1577,7 +1577,9 @@ struct client {
|
||||
struct cmdq_list *queue;
|
||||
|
||||
struct client_windows windows;
|
||||
|
||||
struct control_state *control_state;
|
||||
u_int pause_age;
|
||||
|
||||
pid_t pid;
|
||||
int fd;
|
||||
@ -1645,6 +1647,7 @@ struct client {
|
||||
#define CLIENT_REDRAWPANES 0x20000000
|
||||
#define CLIENT_NOFORK 0x40000000
|
||||
#define CLIENT_ACTIVEPANE 0x80000000ULL
|
||||
#define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL
|
||||
#define CLIENT_ALLREDRAWFLAGS \
|
||||
(CLIENT_REDRAWWINDOW| \
|
||||
CLIENT_REDRAWSTATUS| \
|
||||
@ -2451,8 +2454,9 @@ void status_prompt_save_history(void);
|
||||
void resize_window(struct window *, u_int, u_int, int, int);
|
||||
void default_window_size(struct client *, struct session *, struct window *,
|
||||
u_int *, u_int *, u_int *, u_int *, int);
|
||||
void recalculate_size(struct window *);
|
||||
void recalculate_size(struct window *, int);
|
||||
void recalculate_sizes(void);
|
||||
void recalculate_sizes_now(int);
|
||||
|
||||
/* input.c */
|
||||
struct input_ctx *input_init(struct window_pane *, struct bufferevent *);
|
||||
@ -2839,11 +2843,12 @@ char *default_window_name(struct window *);
|
||||
char *parse_window_name(const char *);
|
||||
|
||||
/* control.c */
|
||||
void control_flush(struct client *);
|
||||
void control_discard(struct client *);
|
||||
void control_start(struct client *);
|
||||
void control_stop(struct client *);
|
||||
void control_set_pane_on(struct client *, struct window_pane *);
|
||||
void control_set_pane_off(struct client *, struct window_pane *);
|
||||
void control_continue_pane(struct client *, struct window_pane *);
|
||||
struct window_pane_offset *control_pane_offset(struct client *,
|
||||
struct window_pane *, int *);
|
||||
void control_reset_offsets(struct client *);
|
||||
|
@ -266,7 +266,6 @@ struct window_copy_mode_data {
|
||||
u_int my;
|
||||
int showmark;
|
||||
|
||||
uint64_t searchtime;
|
||||
int searchtype;
|
||||
int searchregex;
|
||||
char *searchstr;
|
||||
@ -282,7 +281,6 @@ struct window_copy_mode_data {
|
||||
int timeout; /* search has timed out */
|
||||
#define WINDOW_COPY_SEARCH_TIMEOUT 10000
|
||||
#define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200
|
||||
#define WINDOW_COPY_SEARCH_REPEAT 50
|
||||
|
||||
int jumptype;
|
||||
char jumpchar;
|
||||
@ -1662,10 +1660,6 @@ window_copy_cmd_search_again(struct window_copy_cmd_state *cs)
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int np = wme->prefix;
|
||||
|
||||
if (data->searchtime != 0 &&
|
||||
get_timer() - data->searchtime < WINDOW_COPY_SEARCH_REPEAT)
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
|
||||
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
|
||||
for (; np != 0; np--)
|
||||
window_copy_search_up(wme, data->searchregex);
|
||||
@ -1673,7 +1667,6 @@ window_copy_cmd_search_again(struct window_copy_cmd_state *cs)
|
||||
for (; np != 0; np--)
|
||||
window_copy_search_down(wme, data->searchregex);
|
||||
}
|
||||
data->searchtime = get_timer();
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
}
|
||||
|
||||
@ -1684,10 +1677,6 @@ window_copy_cmd_search_reverse(struct window_copy_cmd_state *cs)
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
u_int np = wme->prefix;
|
||||
|
||||
if (data->searchtime != 0 &&
|
||||
get_timer() - data->searchtime < WINDOW_COPY_SEARCH_REPEAT)
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
|
||||
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
|
||||
for (; np != 0; np--)
|
||||
window_copy_search_down(wme, data->searchregex);
|
||||
@ -1695,7 +1684,6 @@ window_copy_cmd_search_reverse(struct window_copy_cmd_state *cs)
|
||||
for (; np != 0; np--)
|
||||
window_copy_search_up(wme, data->searchregex);
|
||||
}
|
||||
data->searchtime = get_timer();
|
||||
return (WINDOW_COPY_CMD_NOTHING);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user