Merge branch 'master' into 3.2-rc

This commit is contained in:
Nicholas Marriott 2021-03-11 08:41:19 +00:00
commit 46cbbe3d45
22 changed files with 348 additions and 178 deletions

View File

@ -146,7 +146,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
TAILQ_INSERT_BEFORE(dst_wp, src_wp, entry);
else
TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
layout_assign_pane(lc, src_wp);
layout_assign_pane(lc, src_wp, 0);
recalculate_sizes();

View File

@ -52,7 +52,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item)
struct layout_cell *lc;
u_int sx, sy, xoff, yoff;
window_push_zoom(w, args_has(args, 'Z'));
window_push_zoom(w, 0, args_has(args, 'Z'));
if (args_has(args, 'D')) {
wp = TAILQ_LAST(&w->panes, window_panes);

View File

@ -117,7 +117,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
server_redraw_window_borders(lastwp->window);
server_status_window(lastwp->window);
} else {
if (window_push_zoom(w, args_has(args, 'Z')))
if (window_push_zoom(w, 0, args_has(args, 'Z')))
server_redraw_window(w);
window_redraw_active_switch(w, lastwp);
if (window_set_active_pane(w, lastwp, 1)) {
@ -171,19 +171,19 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
}
if (args_has(args, 'L')) {
window_push_zoom(w, 1);
window_push_zoom(w, 0, 1);
wp = window_pane_find_left(wp);
window_pop_zoom(w);
} else if (args_has(args, 'R')) {
window_push_zoom(w, 1);
window_push_zoom(w, 0, 1);
wp = window_pane_find_right(wp);
window_pop_zoom(w);
} else if (args_has(args, 'U')) {
window_push_zoom(w, 1);
window_push_zoom(w, 0, 1);
wp = window_pane_find_up(wp);
window_pop_zoom(w);
} else if (args_has(args, 'D')) {
window_push_zoom(w, 1);
window_push_zoom(w, 0, 1);
wp = window_pane_find_down(wp);
window_pop_zoom(w);
}
@ -220,7 +220,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
activewp = w->active;
if (wp == activewp)
return (CMD_RETURN_NORMAL);
if (window_push_zoom(w, args_has(args, 'Z')))
if (window_push_zoom(w, 0, args_has(args, 'Z')))
server_redraw_window(w);
window_redraw_active_switch(w, wp);
if (c != NULL && c->session != NULL && (c->flags & CLIENT_ACTIVEPANE))

View File

@ -39,8 +39,8 @@ const struct cmd_entry cmd_split_window_entry = {
.name = "split-window",
.alias = "splitw",
.args = { "bc:de:fF:hIl:p:Pt:v", 0, -1 },
.usage = "[-bdefhIPv] [-c start-directory] [-e environment] "
.args = { "bc:de:fF:hIl:p:Pt:vZ", 0, -1 },
.usage = "[-bdefhIPvZ] [-c start-directory] [-e environment] "
"[-F format] [-l size] " CMD_TARGET_PANE_USAGE " [command]",
.target = { 't', CMD_FIND_PANE, 0 },
@ -110,7 +110,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
} else
size = -1;
server_unzoom_window(wp->window);
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
input = (args_has(args, 'I') && args->argc == 0);
flags = 0;
@ -152,6 +152,8 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
sc.flags = flags;
if (args_has(args, 'd'))
sc.flags |= SPAWN_DETACHED;
if (args_has(args, 'Z'))
sc.flags |= SPAWN_ZOOM;
if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
cmdq_error(item, "create pane failed: %s", cause);
@ -168,6 +170,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
}
if (!args_has(args, 'd'))
cmd_find_from_winlink_pane(current, wl, new_wp, 0);
window_pop_zoom(wp->window);
server_redraw_window(wp->window);
server_status_session(s);

View File

@ -58,7 +58,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
src_w = source->wl->window;
src_wp = source->wp;
if (window_push_zoom(dst_w, args_has(args, 'Z')))
if (window_push_zoom(dst_w, 0, args_has(args, 'Z')))
server_redraw_window(dst_w);
if (args_has(args, 'D')) {
@ -73,7 +73,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
}
if (src_w != dst_w && window_push_zoom(src_w, args_has(args, 'Z')))
if (src_w != dst_w && window_push_zoom(src_w, 0, args_has(args, 'Z')))
server_redraw_window(src_w);
if (src_wp == dst_wp)

View File

@ -118,7 +118,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
if (wl != NULL && wp != NULL && wp != wl->window->active) {
w = wl->window;
if (window_push_zoom(w, args_has(args, 'Z')))
if (window_push_zoom(w, 0, args_has(args, 'Z')))
server_redraw_window(w);
window_redraw_active_switch(w, wp);
window_set_active_pane(w, wp, 1);

View File

@ -157,13 +157,14 @@ format_draw_put_list(struct screen_write_ctx *octx,
static void
format_draw_none(struct screen_write_ctx *octx, u_int available, u_int ocx,
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
struct format_ranges *frs)
struct screen *abs_centre, struct format_ranges *frs)
{
u_int width_left, width_centre, width_right;
u_int width_left, width_centre, width_right, width_abs_centre;
width_left = left->cx;
width_centre = centre->cx;
width_right = right->cx;
width_abs_centre = abs_centre->cx;
/*
* Try to keep as much of the left and right as possible at the expense
@ -199,23 +200,34 @@ format_draw_none(struct screen_write_ctx *octx, u_int available, u_int ocx,
- width_centre / 2,
centre->cx / 2 - width_centre / 2,
width_centre);
/*
* Write abs_centre in the perfect centre of all horizontal space.
*/
if (width_abs_centre > available)
width_abs_centre = available;
format_draw_put(octx, ocx, ocy, abs_centre, frs,
(available - width_abs_centre) / 2,
0,
width_abs_centre);
}
/* Draw format with list on the left. */
static void
format_draw_left(struct screen_write_ctx *octx, u_int available, u_int ocx,
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
struct screen *list, struct screen *list_left, struct screen *list_right,
struct screen *after, int focus_start, int focus_end,
struct format_ranges *frs)
struct screen *abs_centre, struct screen *list, struct screen *list_left,
struct screen *list_right, struct screen *after, int focus_start,
int focus_end, struct format_ranges *frs)
{
u_int width_left, width_centre, width_right;
u_int width_list, width_after;
u_int width_list, width_after, width_abs_centre;
struct screen_write_ctx ctx;
width_left = left->cx;
width_centre = centre->cx;
width_right = right->cx;
width_abs_centre = abs_centre->cx;
width_list = list->cx;
width_after = after->cx;
@ -247,7 +259,7 @@ format_draw_left(struct screen_write_ctx *octx, u_int available, u_int ocx,
screen_write_stop(&ctx);
format_draw_none(octx, available, ocx, ocy, left, centre,
right, frs);
right, abs_centre, frs);
return;
}
@ -291,23 +303,34 @@ format_draw_left(struct screen_write_ctx *octx, u_int available, u_int ocx,
focus_start = focus_end = 0;
format_draw_put_list(octx, ocx, ocy, width_left, width_list, list,
list_left, list_right, focus_start, focus_end, frs);
/*
* Write abs_centre in the perfect centre of all horizontal space.
*/
if (width_abs_centre > available)
width_abs_centre = available;
format_draw_put(octx, ocx, ocy, abs_centre, frs,
(available - width_abs_centre) / 2,
0,
width_abs_centre);
}
/* Draw format with list in the centre. */
static void
format_draw_centre(struct screen_write_ctx *octx, u_int available, u_int ocx,
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
struct screen *list, struct screen *list_left, struct screen *list_right,
struct screen *after, int focus_start, int focus_end,
struct format_ranges *frs)
struct screen *abs_centre, struct screen *list, struct screen *list_left,
struct screen *list_right, struct screen *after, int focus_start,
int focus_end, struct format_ranges *frs)
{
u_int width_left, width_centre, width_right;
u_int width_list, width_after, middle;
u_int width_left, width_centre, width_right, middle;
u_int width_list, width_after, width_abs_centre;
struct screen_write_ctx ctx;
width_left = left->cx;
width_centre = centre->cx;
width_right = right->cx;
width_abs_centre = abs_centre->cx;
width_list = list->cx;
width_after = after->cx;
@ -339,7 +362,7 @@ format_draw_centre(struct screen_write_ctx *octx, u_int available, u_int ocx,
screen_write_stop(&ctx);
format_draw_none(octx, available, ocx, ocy, left, centre,
right, frs);
right, abs_centre, frs);
return;
}
@ -388,23 +411,34 @@ format_draw_centre(struct screen_write_ctx *octx, u_int available, u_int ocx,
format_draw_put_list(octx, ocx, ocy, middle - width_list / 2,
width_list, list, list_left, list_right, focus_start, focus_end,
frs);
/*
* Write abs_centre in the perfect centre of all horizontal space.
*/
if (width_abs_centre > available)
width_abs_centre = available;
format_draw_put(octx, ocx, ocy, abs_centre, frs,
(available - width_abs_centre) / 2,
0,
width_abs_centre);
}
/* Draw format with list on the right. */
static void
format_draw_right(struct screen_write_ctx *octx, u_int available, u_int ocx,
u_int ocy, struct screen *left, struct screen *centre, struct screen *right,
struct screen *list, struct screen *list_left, struct screen *list_right,
struct screen *after, int focus_start, int focus_end,
struct format_ranges *frs)
struct screen *abs_centre, struct screen *list,
struct screen *list_left, struct screen *list_right, struct screen *after,
int focus_start, int focus_end, struct format_ranges *frs)
{
u_int width_left, width_centre, width_right;
u_int width_list, width_after;
u_int width_list, width_after, width_abs_centre;
struct screen_write_ctx ctx;
width_left = left->cx;
width_centre = centre->cx;
width_right = right->cx;
width_abs_centre = abs_centre->cx;
width_list = list->cx;
width_after = after->cx;
@ -436,7 +470,7 @@ format_draw_right(struct screen_write_ctx *octx, u_int available, u_int ocx,
screen_write_stop(&ctx);
format_draw_none(octx, available, ocx, ocy, left, centre,
right, frs);
right, abs_centre, frs);
return;
}
@ -484,6 +518,118 @@ format_draw_right(struct screen_write_ctx *octx, u_int available, u_int ocx,
format_draw_put_list(octx, ocx, ocy, available - width_list -
width_after, width_list, list, list_left, list_right, focus_start,
focus_end, frs);
/*
* Write abs_centre in the perfect centre of all horizontal space.
*/
if (width_abs_centre > available)
width_abs_centre = available;
format_draw_put(octx, ocx, ocy, abs_centre, frs,
(available - width_abs_centre) / 2,
0,
width_abs_centre);
}
static void
format_draw_absolute_centre(struct screen_write_ctx *octx, u_int available,
u_int ocx, u_int ocy, struct screen *left, struct screen *centre,
struct screen *right, struct screen *abs_centre, struct screen *list,
struct screen *list_left, struct screen *list_right, struct screen *after,
int focus_start, int focus_end, struct format_ranges *frs)
{
u_int width_left, width_centre, width_right, width_abs_centre;
u_int width_list, width_after, middle, abs_centre_offset;
width_left = left->cx;
width_centre = centre->cx;
width_right = right->cx;
width_abs_centre = abs_centre->cx;
width_list = list->cx;
width_after = after->cx;
/*
* Trim first centre, then the right, then the left.
*/
while (width_left +
width_centre +
width_right > available) {
if (width_centre > 0)
width_centre--;
else if (width_right > 0)
width_right--;
else
width_left--;
}
/*
* We trim list after and abs_centre independently, as we are drawing
* them over the rest. Trim first the list, then after the list, then
* abs_centre.
*/
while (width_list + width_after + width_abs_centre > available) {
if (width_list > 0)
width_list--;
else if (width_after > 0)
width_after--;
else
width_abs_centre--;
}
/* Write left at 0. */
format_draw_put(octx, ocx, ocy, left, frs, 0, 0, width_left);
/* Write right at available - width_right. */
format_draw_put(octx, ocx, ocy, right, frs,
available - width_right,
right->cx - width_right,
width_right);
/*
* Keep writing centre at the relative centre. Only the list is written
* in the absolute centre of the horizontal space.
*/
middle = (width_left + ((available - width_right) - width_left) / 2);
/*
* Write centre at
* middle - width_centre.
*/
format_draw_put(octx, ocx, ocy, centre, frs,
middle - width_centre,
0,
width_centre);
/*
* If there is no focus given, keep the centre in focus.
*/
if (focus_start == -1 || focus_end == -1)
focus_start = focus_end = list->cx / 2;
/*
* We centre abs_centre and the list together, so their shared centre is
* in the perfect centre of horizontal space.
*/
abs_centre_offset = (available - width_list - width_abs_centre) / 2;
/*
* Write abs_centre before the list.
*/
format_draw_put(octx, ocx, ocy, abs_centre, frs, abs_centre_offset,
0, width_abs_centre);
abs_centre_offset += width_abs_centre;
/*
* Draw the list in the absolute centre
*/
format_draw_put_list(octx, ocx, ocy, abs_centre_offset, width_list,
list, list_left, list_right, focus_start, focus_end, frs);
abs_centre_offset += width_list;
/*
* Write after at the end of the centre
*/
format_draw_put(octx, ocx, ocy, after, frs, abs_centre_offset, 0,
width_after);
}
/* Draw multiple characters. */
@ -506,6 +652,7 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
enum { LEFT,
CENTRE,
RIGHT,
ABSOLUTE_CENTRE,
LIST,
LIST_LEFT,
LIST_RIGHT,
@ -514,6 +661,7 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
const char *names[] = { "LEFT",
"CENTRE",
"RIGHT",
"ABSOLUTE_CENTRE",
"LIST",
"LIST_LEFT",
"LIST_RIGHT",
@ -522,7 +670,11 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
struct screen *os = octx->s, s[TOTAL];
struct screen_write_ctx ctx[TOTAL];
u_int ocx = os->cx, ocy = os->cy, n, i, width[TOTAL];
u_int map[] = { LEFT, LEFT, CENTRE, RIGHT };
u_int map[] = { LEFT,
LEFT,
CENTRE,
RIGHT,
ABSOLUTE_CENTRE };
int focus_start = -1, focus_end = -1;
int list_state = -1, fill = -1, even;
enum style_align list_align = STYLE_ALIGN_DEFAULT;
@ -789,25 +941,35 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base,
case STYLE_ALIGN_DEFAULT:
/* No list. */
format_draw_none(octx, available, ocx, ocy, &s[LEFT],
&s[CENTRE], &s[RIGHT], &frs);
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &frs);
break;
case STYLE_ALIGN_LEFT:
/* List is part of the left. */
format_draw_left(octx, available, ocx, ocy, &s[LEFT],
&s[CENTRE], &s[RIGHT], &s[LIST], &s[LIST_LEFT],
&s[LIST_RIGHT], &s[AFTER], focus_start, focus_end, &frs);
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
focus_start, focus_end, &frs);
break;
case STYLE_ALIGN_CENTRE:
/* List is part of the centre. */
format_draw_centre(octx, available, ocx, ocy, &s[LEFT],
&s[CENTRE], &s[RIGHT], &s[LIST], &s[LIST_LEFT],
&s[LIST_RIGHT], &s[AFTER], focus_start, focus_end, &frs);
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
focus_start, focus_end, &frs);
break;
case STYLE_ALIGN_RIGHT:
/* List is part of the right. */
format_draw_right(octx, available, ocx, ocy, &s[LEFT],
&s[CENTRE], &s[RIGHT], &s[LIST], &s[LIST_LEFT],
&s[LIST_RIGHT], &s[AFTER], focus_start, focus_end, &frs);
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
focus_start, focus_end, &frs);
break;
case STYLE_ALIGN_ABSOLUTE_CENTRE:
/* List is in the centre of the entire horizontal space. */
format_draw_absolute_centre(octx, available, ocx, ocy, &s[LEFT],
&s[CENTRE], &s[RIGHT], &s[ABSOLUTE_CENTRE], &s[LIST],
&s[LIST_LEFT], &s[LIST_RIGHT], &s[AFTER],
focus_start, focus_end, &frs);
break;
}

View File

@ -41,7 +41,6 @@
struct format_expand_state;
static char *format_job_get(struct format_expand_state *, const char *);
static void format_job_timer(int, short, void *);
static char *format_expand1(struct format_expand_state *, const char *);
static int format_replace(struct format_expand_state *, const char *,
size_t, char **, size_t *, size_t *);
@ -69,7 +68,6 @@ struct format_job {
};
/* Format job tree. */
static struct event format_job_event;
static int format_job_cmp(struct format_job *, struct format_job *);
static RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER();
RB_GENERATE_STATIC(format_job_tree, format_job, entry, format_job_cmp);
@ -437,6 +435,19 @@ format_job_tidy(struct format_job_tree *jobs, int force)
}
}
/* Tidy old jobs for all clients. */
void
format_tidy_jobs(void)
{
struct client *c;
format_job_tidy(&format_jobs, 0);
TAILQ_FOREACH(c, &clients, entry) {
if (c->jobs != NULL)
format_job_tidy(c->jobs, 0);
}
}
/* Remove old jobs for client. */
void
format_lost_client(struct client *c)
@ -446,23 +457,6 @@ format_lost_client(struct client *c)
free(c->jobs);
}
/* Remove old jobs periodically. */
static void
format_job_timer(__unused int fd, __unused short events, __unused void *arg)
{
struct client *c;
struct timeval tv = { .tv_sec = 60 };
format_job_tidy(&format_jobs, 0);
TAILQ_FOREACH(c, &clients, entry) {
if (c->jobs != NULL)
format_job_tidy(c->jobs, 0);
}
evtimer_del(&format_job_event);
evtimer_add(&format_job_event, &tv);
}
/* Wrapper for asprintf. */
static char * printflike(1, 2)
format_printf(const char *fmt, ...)
@ -3048,11 +3042,6 @@ format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
{
struct format_tree *ft;
if (!event_initialized(&format_job_event)) {
evtimer_set(&format_job_event, format_job_timer, NULL);
format_job_timer(-1, 0, NULL);
}
ft = xcalloc(1, sizeof *ft);
RB_INIT(&ft->tree);

View File

@ -172,7 +172,7 @@ grid_reader_cursor_next_word(struct grid_reader *gr, const char *separators)
/* Do not break up wrapped words. */
if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
xx = grid_reader_line_length(gr) - 1;
xx = gr->gd->sx - 1;
else
xx = grid_reader_line_length(gr);
yy = gr->gd->hsize + gr->gd->sy - 1;
@ -197,7 +197,7 @@ grid_reader_cursor_next_word(struct grid_reader *gr, const char *separators)
if (grid_get_line(gr->gd, gr->cy)->flags &
GRID_LINE_WRAPPED)
xx = grid_reader_line_length(gr) - 1;
xx = gr->gd->sx - 1;
else
xx = grid_reader_line_length(gr);
} else
@ -216,7 +216,7 @@ grid_reader_cursor_next_word_end(struct grid_reader *gr, const char *separators)
/* Do not break up wrapped words. */
if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
xx = grid_reader_line_length(gr) - 1;
xx = gr->gd->sx - 1;
else
xx = grid_reader_line_length(gr);
yy = gr->gd->hsize + gr->gd->sy - 1;
@ -241,7 +241,7 @@ grid_reader_cursor_next_word_end(struct grid_reader *gr, const char *separators)
if (grid_get_line(gr->gd, gr->cy)->flags &
GRID_LINE_WRAPPED)
xx = grid_reader_line_length(gr) - 1;
xx = gr->gd->sx - 1;
else
xx = grid_reader_line_length(gr);
} else
@ -294,7 +294,7 @@ grid_reader_cursor_previous_word(struct grid_reader *gr, const char *separators,
GRID_LINE_WRAPPED)
break;
grid_reader_cursor_up(gr);
grid_reader_cursor_end_of_line(gr, 0, 0);
grid_reader_cursor_end_of_line(gr, 0, 1);
}
if (gr->cx > 0)
gr->cx--;

3
grid.c
View File

@ -265,9 +265,6 @@ grid_free_lines(struct grid *gd, u_int py, u_int ny)
for (yy = py; yy < py + ny; yy++)
grid_free_line(gd, yy);
#ifdef HAVE_MALLOC_TRIM
malloc_trim(0);
#endif
}
/* Create a new grid. */

View File

@ -233,7 +233,7 @@ layout_parse(struct window *w, const char *layout)
/* Update pane offsets and sizes. */
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
recalculate_sizes();
layout_print_cell(lc, __func__, 0);

View File

@ -160,7 +160,7 @@ layout_set_even(struct window *w, enum layout_type type)
/* Fix cell offsets. */
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
layout_print_cell(w->layout_root, __func__, 1);
@ -270,7 +270,7 @@ layout_set_main_h(struct window *w)
/* Fix cell offsets. */
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
layout_print_cell(w->layout_root, __func__, 1);
@ -368,7 +368,7 @@ layout_set_main_v(struct window *w)
/* Fix cell offsets. */
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
layout_print_cell(w->layout_root, __func__, 1);
@ -477,7 +477,7 @@ layout_set_tiled(struct window *w)
/* Fix cell offsets. */
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
layout_print_cell(w->layout_root, __func__, 1);

View File

@ -286,7 +286,7 @@ layout_add_border(struct window *w, struct layout_cell *lc, int status)
/* Update pane offsets and sizes based on their cells. */
void
layout_fix_panes(struct window *w)
layout_fix_panes(struct window *w, struct window_pane *skip)
{
struct window_pane *wp;
struct layout_cell *lc;
@ -294,7 +294,7 @@ layout_fix_panes(struct window *w)
status = options_get_number(w->options, "pane-border-status");
TAILQ_FOREACH(wp, &w->panes, entry) {
if ((lc = wp->layout_cell) == NULL)
if ((lc = wp->layout_cell) == NULL || wp == skip)
continue;
wp->xoff = lc->xoff;
@ -482,7 +482,7 @@ layout_init(struct window *w, struct window_pane *wp)
lc = w->layout_root = layout_create_cell(NULL);
layout_set_size(lc, w->sx, w->sy, 0, 0);
layout_make_leaf(lc, wp);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
}
void
@ -540,7 +540,7 @@ layout_resize(struct window *w, u_int sx, u_int sy)
/* Fix cell offsets. */
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
}
/* Resize a pane to an absolute size. */
@ -600,7 +600,7 @@ layout_resize_layout(struct window *w, struct layout_cell *lc,
/* Fix cell offsets. */
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
notify_window("window-layout-changed", w);
}
@ -704,10 +704,14 @@ layout_resize_pane_shrink(struct window *w, struct layout_cell *lc,
/* Assign window pane to newly split cell. */
void
layout_assign_pane(struct layout_cell *lc, struct window_pane *wp)
layout_assign_pane(struct layout_cell *lc, struct window_pane *wp,
int do_not_resize)
{
layout_make_leaf(lc, wp);
layout_fix_panes(wp->window);
if (do_not_resize)
layout_fix_panes(wp->window, wp);
else
layout_fix_panes(wp->window, NULL);
}
/* Calculate the new pane size for resized parent. */
@ -1040,7 +1044,7 @@ layout_close_pane(struct window_pane *wp)
/* Fix pane offsets and sizes. */
if (w->layout_root != NULL) {
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
}
notify_window("window-layout-changed", w);
}
@ -1109,7 +1113,7 @@ layout_spread_out(struct window_pane *wp)
do {
if (layout_spread_cell(w, parent)) {
layout_fix_offsets(w);
layout_fix_panes(w);
layout_fix_panes(w, NULL);
break;
}
} while ((parent = parent->parent) != NULL);

View File

@ -45,7 +45,7 @@ static const char *options_table_status_keys_list[] = {
"emacs", "vi", NULL
};
static const char *options_table_status_justify_list[] = {
"left", "centre", "right", NULL
"left", "centre", "right", "absolute-centre", NULL
};
static const char *options_table_status_position_list[] = {
"top", "bottom", NULL

View File

@ -1115,7 +1115,7 @@ options_push_changes(const char *name)
}
if (strcmp(name, "pane-border-status") == 0) {
RB_FOREACH(w, windows, &windows)
layout_fix_panes(w);
layout_fix_panes(w, NULL);
}
RB_FOREACH(s, sessions, &sessions)
status_update_cache(s);

View File

@ -46,6 +46,7 @@ static int server_fd = -1;
static uint64_t server_client_flags;
static int server_exit;
static struct event server_ev_accept;
static struct event server_ev_tidy;
struct cmd_find_state marked_pane;
@ -149,15 +150,33 @@ fail:
return (-1);
}
/* Tidy up every hour. */
static void
server_tidy_event(__unused int fd, __unused short events, __unused void *data)
{
struct timeval tv = { .tv_sec = 3600 };
uint64_t t = get_timer();
format_tidy_jobs();
#ifdef HAVE_MALLOC_TRIM
malloc_trim(0);
#endif
log_debug("%s: took %llu milliseconds", __func__, get_timer() - t);
evtimer_add(&server_ev_tidy, &tv);
}
/* Fork new server. */
int
server_start(struct tmuxproc *client, int flags, struct event_base *base,
int lockfd, char *lockfile)
{
int fd;
sigset_t set, oldset;
struct client *c = NULL;
char *cause = NULL;
int fd;
sigset_t set, oldset;
struct client *c = NULL;
char *cause = NULL;
struct timeval tv = { .tv_sec = 3600 };
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, &oldset);
@ -216,6 +235,9 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base,
free(cause);
}
evtimer_set(&server_ev_tidy, server_tidy_event, NULL);
evtimer_add(&server_ev_tidy, &tv);
server_add_accept(0);
proc_loop(server_proc, server_loop);

View File

@ -259,7 +259,10 @@ spawn_pane(struct spawn_context *sc, char **cause)
layout_init(w, new_wp);
} else {
new_wp = window_add_pane(w, sc->wp0, hlimit, sc->flags);
layout_assign_pane(sc->lc, new_wp);
if (sc->flags & SPAWN_ZOOM)
layout_assign_pane(sc->lc, new_wp, 1);
else
layout_assign_pane(sc->lc, new_wp, 0);
}
/*

View File

@ -139,6 +139,8 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in)
sy->align = STYLE_ALIGN_CENTRE;
else if (strcasecmp(tmp + 6, "right") == 0)
sy->align = STYLE_ALIGN_RIGHT;
else if (strcasecmp(tmp + 6, "absolute-centre") == 0)
sy->align = STYLE_ALIGN_ABSOLUTE_CENTRE;
else
goto error;
} else if (end > 5 && strncasecmp(tmp, "fill=", 5) == 0) {
@ -227,6 +229,8 @@ style_tostring(struct style *sy)
tmp = "centre";
else if (sy->align == STYLE_ALIGN_RIGHT)
tmp = "right";
else if (sy->align == STYLE_ALIGN_ABSOLUTE_CENTRE)
tmp = "absolute-centre";
off += xsnprintf(s + off, sizeof s - off, "%salign=%s", comma,
tmp);
comma = ",";

11
tmux.1
View File

@ -2804,7 +2804,7 @@ is given and the selected window is already the current window,
the command behaves like
.Ic last-window .
.It Xo Ic split-window
.Op Fl bdfhIvP
.Op Fl bdfhIvPZ
.Op Fl c Ar start-directory
.Op Fl e Ar environment
.Op Fl l Ar size
@ -2840,6 +2840,8 @@ option creates a new pane spanning the full window height (with
or full window width (with
.Fl v ) ,
instead of splitting the active pane.
.Fl Z
zooms if the window is not zoomed, or keeps it zoomed if already zoomed.
.Pp
An empty
.Ar shell-command
@ -3813,10 +3815,11 @@ seconds.
By default, updates will occur every 15 seconds.
A setting of zero disables redrawing at interval.
.It Xo Ic status-justify
.Op Ic left | centre | right
.Op Ic left | centre | right | absolute-centre
.Xc
Set the position of the window list component of the status line: left, centre
or right justified.
Set the position of the window list in the status line: left, centre or right.
centre puts the window list in the relative centre of the available free space;
absolute-centre uses the centre of the entire horizontal space.
.It Xo Ic status-keys
.Op Ic vi | emacs
.Xc

12
tmux.h
View File

@ -741,7 +741,8 @@ enum style_align {
STYLE_ALIGN_DEFAULT,
STYLE_ALIGN_LEFT,
STYLE_ALIGN_CENTRE,
STYLE_ALIGN_RIGHT
STYLE_ALIGN_RIGHT,
STYLE_ALIGN_ABSOLUTE_CENTRE
};
/* Style list. */
@ -1863,6 +1864,7 @@ struct spawn_context {
#define SPAWN_NONOTIFY 0x10
#define SPAWN_FULLSIZE 0x20
#define SPAWN_EMPTY 0x40
#define SPAWN_ZOOM 0x80
};
/* Mode tree sort order. */
@ -1946,6 +1948,7 @@ char *paste_make_sample(struct paste_buffer *);
struct format_tree;
struct format_modifier;
typedef void *(*format_cb)(struct format_tree *);
void format_tidy_jobs(void);
const char *format_skip(const char *, const char *);
int format_true(const char *);
struct format_tree *format_create(struct client *, struct cmdq_item *, int,
@ -2753,7 +2756,7 @@ void window_resize(struct window *, u_int, u_int, int, int);
void window_pane_send_resize(struct window_pane *, int);
int window_zoom(struct window_pane *);
int window_unzoom(struct window *);
int window_push_zoom(struct window *, int);
int window_push_zoom(struct window *, int, int);
int window_pop_zoom(struct window *);
void window_lost_pane(struct window *, struct window_pane *);
void window_remove_pane(struct window *, struct window_pane *);
@ -2816,7 +2819,7 @@ void layout_set_size(struct layout_cell *, u_int, u_int, u_int,
void layout_make_leaf(struct layout_cell *, struct window_pane *);
void layout_make_node(struct layout_cell *, enum layout_type);
void layout_fix_offsets(struct window *);
void layout_fix_panes(struct window *);
void layout_fix_panes(struct window *, struct window_pane *);
void layout_resize_adjust(struct window *, struct layout_cell *,
enum layout_type, int);
void layout_init(struct window *, struct window_pane *);
@ -2826,7 +2829,8 @@ void layout_resize_pane(struct window_pane *, enum layout_type,
int, int);
void layout_resize_pane_to(struct window_pane *, enum layout_type,
u_int);
void layout_assign_pane(struct layout_cell *, struct window_pane *);
void layout_assign_pane(struct layout_cell *, struct window_pane *,
int);
struct layout_cell *layout_split_pane(struct window_pane *, enum layout_type,
int, int);
void layout_close_pane(struct window_pane *);

View File

@ -1759,12 +1759,15 @@ window_copy_cmd_select_line(struct window_copy_cmd_state *cs)
window_copy_cursor_start_of_line(wme);
data->selrx = data->cx;
data->selry = screen_hsize(data->backing) + data->cy - data->oy;
data->endselrx = window_copy_find_length(wme, data->selry);
data->endselry = data->selry;
window_copy_start_selection(wme);
for (; np > 1; np--)
window_copy_cursor_down(wme, 0);
window_copy_cursor_end_of_line(wme);
data->endselry = screen_hsize(data->backing) + data->cy - data->oy;
data->endselrx = window_copy_find_length(wme, data->endselry);
for (; np > 1; np--) {
window_copy_cursor_down(wme, 0);
window_copy_cursor_end_of_line(wme);
}
return (WINDOW_COPY_CMD_REDRAW);
}
@ -1775,7 +1778,7 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
struct window_mode_entry *wme = cs->wme;
struct session *s = cs->s;
struct window_copy_mode_data *data = wme->data;
u_int px, py;
u_int px, py, nextx, nexty;
data->lineflag = LINE_SEL_LEFT_RIGHT;
data->rectflag = 0;
@ -1791,8 +1794,16 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
data->selry = py;
window_copy_start_selection(wme);
/* Handle single character words. */
nextx = px + 1;
nexty = py;
if (grid_get_line(data->backing->grid, nexty)->flags &
GRID_LINE_WRAPPED && nextx > screen_size_x(data->backing) - 1) {
nextx = 0;
nexty++;
}
if (px >= window_copy_find_length(wme, py) ||
!window_copy_in_set(wme, px + 1, py, data->ws))
!window_copy_in_set(wme, nextx, nexty, data->ws))
window_copy_cursor_next_word_end(wme, data->ws, 1);
else {
window_copy_update_cursor(wme, px, data->cy);
@ -1801,7 +1812,10 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs)
}
data->endselrx = data->cx;
data->endselry = screen_hsize(data->backing) + data->cy - data->oy;
if (data->dx > data->endselrx)
if (data->dy > data->endselry) {
data->dy = data->endselry;
data->dx = data->endselrx;
} else if (data->dx > data->endselrx)
data->dx = data->endselrx;
return (WINDOW_COPY_CMD_REDRAW);
@ -3352,8 +3366,11 @@ window_copy_match_at_cursor(struct window_copy_mode_data *data)
cy = screen_hsize(data->backing) - data->oy + data->cy;
if (window_copy_search_mark_at(data, data->cx, cy, &at) != 0)
return (NULL);
if (data->searchmark[at] == 0)
return (NULL);
if (data->searchmark[at] == 0) {
/* Allow one position after the match. */
if (at == 0 || data->searchmark[--at] == 0)
return (NULL);
}
window_copy_match_start_end(data, at, &start, &end);
/*
@ -3635,6 +3652,8 @@ window_copy_synchronize_cursor_end(struct window_mode_entry *wme, int begin,
data->endsely = data->endselry;
} else {
/* Left to right selection. */
if (yy < data->endselry)
yy = data->endselry;
xx = window_copy_find_length(wme, yy);
/* Reset the start. */
@ -3929,8 +3948,12 @@ window_copy_get_selection(struct window_mode_entry *wme, size_t *len)
*len = 0;
return (NULL);
}
if (keys == MODEKEY_EMACS || lastex <= ey_last)
off -= 1; /* remove final \n (unless at end in vi mode) */
/* Remove final \n (unless at end in vi mode). */
if (keys == MODEKEY_EMACS || lastex <= ey_last) {
if (~grid_get_line(data->backing->grid, ey)->flags &
GRID_LINE_WRAPPED || lastex != ey_last)
off -= 1;
}
*len = off;
return (buf);
}
@ -4531,6 +4554,7 @@ window_copy_cursor_next_word(struct window_mode_entry *wme,
data->oy, oldy, px, py, 0);
}
/* Compute the next place where a word ends. */
static void
window_copy_cursor_next_word_end_pos(struct window_mode_entry *wme,
const char *separators, u_int *ppx, u_int *ppy)
@ -4539,47 +4563,27 @@ window_copy_cursor_next_word_end_pos(struct window_mode_entry *wme,
struct window_copy_mode_data *data = wme->data;
struct options *oo = wp->window->options;
struct screen *back_s = data->backing;
u_int px, py, xx, yy;
int keys, expected = 1;
struct grid_reader gr;
u_int px, py, hsize;
int keys;
px = data->cx;
py = screen_hsize(back_s) + data->cy - data->oy;
xx = window_copy_find_length(wme, py);
yy = screen_hsize(back_s) + screen_size_y(back_s) - 1;
hsize = screen_hsize(back_s);
py = hsize + data->cy - data->oy;
grid_reader_start(&gr, back_s->grid, px, py);
keys = options_get_number(oo, "mode-keys");
if (keys == MODEKEY_VI && !window_copy_in_set(wme, px, py, separators))
px++;
/*
* First skip past any word characters, then any non-word characters.
*
* expected is initially set to 1 for the former and then 0 for the
* latter.
*/
do {
while (px > xx ||
window_copy_in_set(wme, px, py, separators) == expected) {
/* Move down if we're past the end of the line. */
if (px > xx) {
if (py == yy)
return;
py++;
px = 0;
xx = window_copy_find_length(wme, py);
} else
px++;
}
expected = !expected;
} while (expected == 0);
if (keys == MODEKEY_VI && px != 0)
px--;
if (keys == MODEKEY_VI && !grid_reader_in_set(&gr, separators))
grid_reader_cursor_right(&gr, 0, 0);
grid_reader_cursor_next_word_end(&gr, separators);
if (keys == MODEKEY_VI)
grid_reader_cursor_left(&gr);
grid_reader_get_cursor(&gr, &px, &py);
*ppx = px;
*ppy = py;
}
/* Move to the next place where a word ends. */
static void
window_copy_cursor_next_word_end(struct window_mode_entry *wme,
const char *separators, int no_reset)
@ -4615,42 +4619,17 @@ window_copy_cursor_previous_word_pos(struct window_mode_entry *wme,
const char *separators, int already, u_int *ppx, u_int *ppy)
{
struct window_copy_mode_data *data = wme->data;
struct screen *back_s = data->backing;
struct grid_reader gr;
u_int px, py, hsize;
hsize = screen_hsize(data->backing);
px = data->cx;
hsize = screen_hsize(back_s);
py = hsize + data->cy - data->oy;
/* Move back to the previous word character. */
if (already || window_copy_in_set(wme, px, py, separators)) {
for (;;) {
if (px > 0) {
px--;
if (!window_copy_in_set(wme, px, py,
separators))
break;
} else {
if (py == 0 ||
(data->cy == 0 &&
(hsize == 0 || data->oy > hsize - 1)))
goto out;
py--;
px = window_copy_find_length(wme, py);
/* Stop if separator at EOL. */
if (px > 0 && window_copy_in_set(wme, px - 1,
py, separators))
break;
}
}
}
/* Move back to the beginning of this word. */
while (px > 0 && !window_copy_in_set(wme, px - 1, py, separators))
px--;
out:
grid_reader_start(&gr, back_s->grid, px, py);
grid_reader_cursor_previous_word(&gr, separators, already);
grid_reader_get_cursor(&gr, &px, &py);
*ppx = px;
*ppy = py;
}

View File

@ -629,18 +629,18 @@ window_unzoom(struct window *w)
wp->layout_cell = wp->saved_layout_cell;
wp->saved_layout_cell = NULL;
}
layout_fix_panes(w);
layout_fix_panes(w, NULL);
notify_window("window-layout-changed", w);
return (0);
}
int
window_push_zoom(struct window *w, int flag)
window_push_zoom(struct window *w, int always, int flag)
{
log_debug("%s: @%u %d", __func__, w->id,
flag && (w->flags & WINDOW_ZOOMED));
if (flag && (w->flags & WINDOW_ZOOMED))
if (flag && (always || (w->flags & WINDOW_ZOOMED)))
w->flags |= WINDOW_WASZOOMED;
else
w->flags &= ~WINDOW_WASZOOMED;