mirror of
https://github.com/tmux/tmux.git
synced 2026-03-06 07:45:35 +00:00
Merge branch 'obsd-master'
This commit is contained in:
@@ -57,14 +57,12 @@ 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 = NULL;
|
||||||
char *bufname, *bufdata = NULL, *cause = NULL;
|
char *bufname = NULL, *bufdata = NULL, *cause = NULL;
|
||||||
const char *olddata;
|
const char *olddata;
|
||||||
size_t bufsize = 0, newsize;
|
size_t bufsize = 0, newsize;
|
||||||
|
|
||||||
if (args_get(args, 'b') == NULL)
|
if (args_get(args, 'b') != NULL) {
|
||||||
pb = NULL;
|
|
||||||
else {
|
|
||||||
bufname = xstrdup(args_get(args, 'b'));
|
bufname = xstrdup(args_get(args, 'b'));
|
||||||
pb = paste_get_name(bufname);
|
pb = paste_get_name(bufname);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,29 +51,24 @@ control_notify_window_layout_changed(struct window *w)
|
|||||||
template = "%layout-change #{window_id} #{window_layout} "
|
template = "%layout-change #{window_id} #{window_layout} "
|
||||||
"#{window_visible_layout} #{window_raw_flags}";
|
"#{window_visible_layout} #{window_raw_flags}";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the last pane in a window is closed it won't have a layout root
|
||||||
|
* and we don't need to inform the client about the layout change
|
||||||
|
* because the whole window will go away soon.
|
||||||
|
*/
|
||||||
|
wl = TAILQ_FIRST(&w->winlinks);
|
||||||
|
if (wl == NULL || w->layout_root == NULL)
|
||||||
|
return;
|
||||||
|
cp = format_single(NULL, template, NULL, NULL, wl, NULL);
|
||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
|
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
|
||||||
continue;
|
continue;
|
||||||
s = c->session;
|
s = c->session;
|
||||||
|
if (winlink_find_by_window_id(&s->windows, w->id) != NULL)
|
||||||
if (winlink_find_by_window_id(&s->windows, w->id) == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When the last pane in a window is closed it won't have a
|
|
||||||
* layout root and we don't need to inform the client about the
|
|
||||||
* layout change because the whole window will go away soon.
|
|
||||||
*/
|
|
||||||
if (w->layout_root == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wl = winlink_find_by_window(&s->windows, w);
|
|
||||||
if (wl != NULL) {
|
|
||||||
cp = format_single(NULL, template, c, NULL, wl, NULL);
|
|
||||||
control_write(c, "%s", cp);
|
control_write(c, "%s", cp);
|
||||||
|
}
|
||||||
free(cp);
|
free(cp);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
120
control.c
120
control.c
@@ -846,15 +846,13 @@ control_stop(struct client *c)
|
|||||||
|
|
||||||
/* Check session subscription. */
|
/* Check session subscription. */
|
||||||
static void
|
static void
|
||||||
control_check_subs_session(struct client *c, struct control_sub *csub)
|
control_check_subs_session(struct client *c, struct control_sub *csub,
|
||||||
|
struct format_tree *ft)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct format_tree *ft;
|
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
ft = format_create_defaults(NULL, c, s, NULL, NULL);
|
|
||||||
value = format_expand(ft, csub->format);
|
value = format_expand(ft, csub->format);
|
||||||
format_free(ft);
|
|
||||||
|
|
||||||
if (csub->last != NULL && strcmp(value, csub->last) == 0) {
|
if (csub->last != NULL && strcmp(value, csub->last) == 0) {
|
||||||
free(value);
|
free(value);
|
||||||
@@ -915,24 +913,17 @@ control_check_subs_pane(struct client *c, struct control_sub *csub)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check all panes subscription. */
|
/* Check all-panes subscription for a pane. */
|
||||||
static void
|
static void
|
||||||
control_check_subs_all_panes(struct client *c, struct control_sub *csub)
|
control_check_subs_all_panes_one(struct client *c, struct control_sub *csub,
|
||||||
|
struct format_tree *ft, struct winlink *wl, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window_pane *wp;
|
struct window *w = wl->window;
|
||||||
struct window *w;
|
|
||||||
struct winlink *wl;
|
|
||||||
struct format_tree *ft;
|
|
||||||
char *value;
|
char *value;
|
||||||
struct control_sub_pane *csp, find;
|
struct control_sub_pane *csp, find;
|
||||||
|
|
||||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
|
||||||
w = wl->window;
|
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
|
||||||
ft = format_create_defaults(NULL, c, s, wl, wp);
|
|
||||||
value = format_expand(ft, csub->format);
|
value = format_expand(ft, csub->format);
|
||||||
format_free(ft);
|
|
||||||
|
|
||||||
find.pane = wp->id;
|
find.pane = wp->id;
|
||||||
find.idx = wl->idx;
|
find.idx = wl->idx;
|
||||||
@@ -945,18 +936,15 @@ control_check_subs_all_panes(struct client *c, struct control_sub *csub)
|
|||||||
RB_INSERT(control_sub_panes, &csub->panes, csp);
|
RB_INSERT(control_sub_panes, &csub->panes, csp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (csp->last != NULL &&
|
if (csp->last != NULL && strcmp(value, csp->last) == 0) {
|
||||||
strcmp(value, csp->last) == 0) {
|
|
||||||
free(value);
|
free(value);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
control_write(c,
|
control_write(c,
|
||||||
"%%subscription-changed %s $%u @%u %u %%%u : %s",
|
"%%subscription-changed %s $%u @%u %u %%%u : %s",
|
||||||
csub->name, s->id, w->id, wl->idx, wp->id, value);
|
csub->name, s->id, w->id, wl->idx, wp->id, value);
|
||||||
free(csp->last);
|
free(csp->last);
|
||||||
csp->last = value;
|
csp->last = value;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check window subscription. */
|
/* Check window subscription. */
|
||||||
@@ -1005,23 +993,17 @@ control_check_subs_window(struct client *c, struct control_sub *csub)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check all windows subscription. */
|
/* Check all-windows subscription for a window. */
|
||||||
static void
|
static void
|
||||||
control_check_subs_all_windows(struct client *c, struct control_sub *csub)
|
control_check_subs_all_windows_one(struct client *c, struct control_sub *csub,
|
||||||
|
struct format_tree *ft, struct winlink *wl)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window *w;
|
struct window *w = wl->window;
|
||||||
struct winlink *wl;
|
|
||||||
struct format_tree *ft;
|
|
||||||
char *value;
|
char *value;
|
||||||
struct control_sub_window *csw, find;
|
struct control_sub_window *csw, find;
|
||||||
|
|
||||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
|
||||||
w = wl->window;
|
|
||||||
|
|
||||||
ft = format_create_defaults(NULL, c, s, wl, NULL);
|
|
||||||
value = format_expand(ft, csub->format);
|
value = format_expand(ft, csub->format);
|
||||||
format_free(ft);
|
|
||||||
|
|
||||||
find.window = w->id;
|
find.window = w->id;
|
||||||
find.idx = wl->idx;
|
find.idx = wl->idx;
|
||||||
@@ -1036,14 +1018,13 @@ control_check_subs_all_windows(struct client *c, struct control_sub *csub)
|
|||||||
|
|
||||||
if (csw->last != NULL && strcmp(value, csw->last) == 0) {
|
if (csw->last != NULL && strcmp(value, csw->last) == 0) {
|
||||||
free(value);
|
free(value);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
control_write(c,
|
control_write(c,
|
||||||
"%%subscription-changed %s $%u @%u %u - : %s",
|
"%%subscription-changed %s $%u @%u %u - : %s",
|
||||||
csub->name, s->id, w->id, wl->idx, value);
|
csub->name, s->id, w->id, wl->idx, value);
|
||||||
free(csw->last);
|
free(csw->last);
|
||||||
csw->last = value;
|
csw->last = value;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check subscriptions timer. */
|
/* Check subscriptions timer. */
|
||||||
@@ -1053,30 +1034,91 @@ control_check_subs_timer(__unused int fd, __unused short events, void *data)
|
|||||||
struct client *c = data;
|
struct client *c = data;
|
||||||
struct control_state *cs = c->control_state;
|
struct control_state *cs = c->control_state;
|
||||||
struct control_sub *csub, *csub1;
|
struct control_sub *csub, *csub1;
|
||||||
|
struct session *s = c->session;
|
||||||
|
struct format_tree *ft;
|
||||||
|
struct winlink *wl;
|
||||||
|
struct window_pane *wp;
|
||||||
struct timeval tv = { .tv_sec = 1 };
|
struct timeval tv = { .tv_sec = 1 };
|
||||||
|
int have_session = 0, have_all_panes = 0;
|
||||||
|
int have_all_windows = 0;
|
||||||
|
|
||||||
log_debug("%s: timer fired", __func__);
|
log_debug("%s: timer fired", __func__);
|
||||||
evtimer_add(&cs->subs_timer, &tv);
|
evtimer_add(&cs->subs_timer, &tv);
|
||||||
|
|
||||||
RB_FOREACH_SAFE(csub, control_subs, &cs->subs, csub1) {
|
/* Find which subscription types are present. */
|
||||||
|
RB_FOREACH(csub, control_subs, &cs->subs) {
|
||||||
switch (csub->type) {
|
switch (csub->type) {
|
||||||
case CONTROL_SUB_SESSION:
|
case CONTROL_SUB_SESSION:
|
||||||
control_check_subs_session(c, csub);
|
have_session = 1;
|
||||||
break;
|
|
||||||
case CONTROL_SUB_PANE:
|
|
||||||
control_check_subs_pane(c, csub);
|
|
||||||
break;
|
break;
|
||||||
case CONTROL_SUB_ALL_PANES:
|
case CONTROL_SUB_ALL_PANES:
|
||||||
control_check_subs_all_panes(c, csub);
|
have_all_panes = 1;
|
||||||
|
break;
|
||||||
|
case CONTROL_SUB_ALL_WINDOWS:
|
||||||
|
have_all_windows = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check session subscriptions. */
|
||||||
|
if (have_session) {
|
||||||
|
ft = format_create_defaults(NULL, c, s, NULL, NULL);
|
||||||
|
RB_FOREACH_SAFE(csub, control_subs, &cs->subs, csub1) {
|
||||||
|
if (csub->type == CONTROL_SUB_SESSION)
|
||||||
|
control_check_subs_session(c, csub, ft);
|
||||||
|
}
|
||||||
|
format_free(ft);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check pane and window subscriptions. */
|
||||||
|
RB_FOREACH_SAFE(csub, control_subs, &cs->subs, csub1) {
|
||||||
|
switch (csub->type) {
|
||||||
|
case CONTROL_SUB_PANE:
|
||||||
|
control_check_subs_pane(c, csub);
|
||||||
break;
|
break;
|
||||||
case CONTROL_SUB_WINDOW:
|
case CONTROL_SUB_WINDOW:
|
||||||
control_check_subs_window(c, csub);
|
control_check_subs_window(c, csub);
|
||||||
break;
|
break;
|
||||||
|
case CONTROL_SUB_SESSION:
|
||||||
|
case CONTROL_SUB_ALL_PANES:
|
||||||
case CONTROL_SUB_ALL_WINDOWS:
|
case CONTROL_SUB_ALL_WINDOWS:
|
||||||
control_check_subs_all_windows(c, csub);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check all-panes subscriptions. */
|
||||||
|
if (have_all_panes) {
|
||||||
|
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||||
|
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
|
||||||
|
ft = format_create_defaults(NULL, c, s, wl, wp);
|
||||||
|
RB_FOREACH_SAFE(csub, control_subs, &cs->subs,
|
||||||
|
csub1) {
|
||||||
|
if (csub->type != CONTROL_SUB_ALL_PANES)
|
||||||
|
continue;
|
||||||
|
control_check_subs_all_panes_one(c,
|
||||||
|
csub, ft, wl, wp);
|
||||||
|
}
|
||||||
|
format_free(ft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check all-windows subscriptions. */
|
||||||
|
if (have_all_windows) {
|
||||||
|
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||||
|
ft = format_create_defaults(NULL, c, s, wl, NULL);
|
||||||
|
RB_FOREACH_SAFE(csub, control_subs, &cs->subs,
|
||||||
|
csub1) {
|
||||||
|
if (csub->type != CONTROL_SUB_ALL_WINDOWS)
|
||||||
|
continue;
|
||||||
|
control_check_subs_all_windows_one(c, csub, ft,
|
||||||
|
wl);
|
||||||
|
}
|
||||||
|
format_free(ft);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a subscription. */
|
/* Add a subscription. */
|
||||||
|
|||||||
12
grid.c
12
grid.c
@@ -205,10 +205,16 @@ grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg)
|
|||||||
struct grid_line *gl = &gd->linedata[py];
|
struct grid_line *gl = &gd->linedata[py];
|
||||||
struct grid_cell_entry *gce = &gl->celldata[px];
|
struct grid_cell_entry *gce = &gl->celldata[px];
|
||||||
struct grid_extd_entry *gee;
|
struct grid_extd_entry *gee;
|
||||||
|
u_int old_offset = gce->offset;
|
||||||
|
int had_extd = (gce->flags & GRID_FLAG_EXTENDED);
|
||||||
|
|
||||||
memcpy(gce, &grid_cleared_entry, sizeof *gce);
|
memcpy(gce, &grid_cleared_entry, sizeof *gce);
|
||||||
if (bg != 8) {
|
if (bg != 8) {
|
||||||
if (bg & COLOUR_FLAG_RGB) {
|
if (bg & COLOUR_FLAG_RGB) {
|
||||||
|
if (had_extd && old_offset < gl->extdsize) {
|
||||||
|
gce->flags |= GRID_FLAG_EXTENDED;
|
||||||
|
gce->offset = old_offset;
|
||||||
|
} else
|
||||||
grid_get_extended_cell(gl, gce, gce->flags);
|
grid_get_extended_cell(gl, gce, gce->flags);
|
||||||
gee = grid_extended_cell(gl, gce, &grid_cleared_cell);
|
gee = grid_extended_cell(gl, gce, &grid_cleared_cell);
|
||||||
gee->bg = bg;
|
gee->bg = bg;
|
||||||
@@ -1089,12 +1095,16 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
|
|||||||
off = 0;
|
off = 0;
|
||||||
|
|
||||||
gl = grid_peek_line(gd, py);
|
gl = grid_peek_line(gd, py);
|
||||||
|
if (gl == NULL) {
|
||||||
|
buf[0] = '\0';
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
if (flags & GRID_STRING_EMPTY_CELLS)
|
if (flags & GRID_STRING_EMPTY_CELLS)
|
||||||
end = gl->cellsize;
|
end = gl->cellsize;
|
||||||
else
|
else
|
||||||
end = gl->cellused;
|
end = gl->cellused;
|
||||||
for (xx = px; xx < px + nx; xx++) {
|
for (xx = px; xx < px + nx; xx++) {
|
||||||
if (gl == NULL || xx >= end)
|
if (xx >= end)
|
||||||
break;
|
break;
|
||||||
grid_get_cell(gd, xx, py, &gc);
|
grid_get_cell(gd, xx, py, &gc);
|
||||||
if (gc.flags & GRID_FLAG_PADDING)
|
if (gc.flags & GRID_FLAG_PADDING)
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
|
|||||||
if (trim) {
|
if (trim) {
|
||||||
while (sy > screen_hsize(src)) {
|
while (sy > screen_hsize(src)) {
|
||||||
gl = grid_peek_line(src->grid, sy - 1);
|
gl = grid_peek_line(src->grid, sy - 1);
|
||||||
if (gl->cellused != 0)
|
if (gl == NULL || gl->cellused != 0)
|
||||||
break;
|
break;
|
||||||
sy--;
|
sy--;
|
||||||
}
|
}
|
||||||
@@ -3625,6 +3625,10 @@ window_copy_stringify(struct grid *gd, u_int py, u_int first, u_int last,
|
|||||||
buf = xrealloc(buf, bufsize);
|
buf = xrealloc(buf, bufsize);
|
||||||
|
|
||||||
gl = grid_peek_line(gd, py);
|
gl = grid_peek_line(gd, py);
|
||||||
|
if (gl == NULL) {
|
||||||
|
buf[*size - 1] = '\0';
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
bx = *size - 1;
|
bx = *size - 1;
|
||||||
for (ax = first; ax < last; ax++) {
|
for (ax = first; ax < last; ax++) {
|
||||||
d = window_copy_cellstring(gl, ax, &dlen, &allocated);
|
d = window_copy_cellstring(gl, ax, &dlen, &allocated);
|
||||||
@@ -3670,6 +3674,10 @@ window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy,
|
|||||||
px = *ppx;
|
px = *ppx;
|
||||||
pywrap = *ppy;
|
pywrap = *ppy;
|
||||||
gl = grid_peek_line(gd, pywrap);
|
gl = grid_peek_line(gd, pywrap);
|
||||||
|
if (gl == NULL) {
|
||||||
|
free(cells);
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (cell < ncells) {
|
while (cell < ncells) {
|
||||||
cells[cell].d = window_copy_cellstring(gl, px,
|
cells[cell].d = window_copy_cellstring(gl, px,
|
||||||
&cells[cell].dlen, &cells[cell].allocated);
|
&cells[cell].dlen, &cells[cell].allocated);
|
||||||
@@ -3679,6 +3687,8 @@ window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy,
|
|||||||
px = 0;
|
px = 0;
|
||||||
pywrap++;
|
pywrap++;
|
||||||
gl = grid_peek_line(gd, pywrap);
|
gl = grid_peek_line(gd, pywrap);
|
||||||
|
if (gl == NULL)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4080,7 +4090,7 @@ window_copy_visible_lines(struct window_copy_mode_data *data, u_int *start,
|
|||||||
|
|
||||||
for (*start = gd->hsize - data->oy; *start > 0; (*start)--) {
|
for (*start = gd->hsize - data->oy; *start > 0; (*start)--) {
|
||||||
gl = grid_peek_line(gd, (*start) - 1);
|
gl = grid_peek_line(gd, (*start) - 1);
|
||||||
if (~gl->flags & GRID_LINE_WRAPPED)
|
if (gl == NULL || ~gl->flags & GRID_LINE_WRAPPED)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*end = gd->hsize - data->oy + gd->sy;
|
*end = gd->hsize - data->oy + gd->sy;
|
||||||
|
|||||||
Reference in New Issue
Block a user