summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2021-03-11 08:41:19 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2021-03-11 08:41:19 +0000
commit46cbbe3d4566885b8ad4235598389936f63c2c01 (patch)
tree08d62878ba077a0027ece4ae562d77b160a2d9c1
parent7bef887fd1051e2bbeb268888b51588ccaac306e (diff)
parentef9700816fd2bd521bab837ccd85e0a596aa3aa8 (diff)
Merge branch 'master' into 3.2-rc
-rw-r--r--cmd-join-pane.c2
-rw-r--r--cmd-rotate-window.c2
-rw-r--r--cmd-select-pane.c12
-rw-r--r--cmd-split-window.c9
-rw-r--r--cmd-swap-pane.c4
-rw-r--r--cmd-switch-client.c2
-rw-r--r--format-draw.c214
-rw-r--r--format.c31
-rw-r--r--grid-reader.c10
-rw-r--r--grid.c3
-rw-r--r--layout-custom.c2
-rw-r--r--layout-set.c8
-rw-r--r--layout.c22
-rw-r--r--options-table.c2
-rw-r--r--options.c2
-rw-r--r--server.c30
-rw-r--r--spawn.c5
-rw-r--r--style.c4
-rw-r--r--tmux.111
-rw-r--r--tmux.h12
-rw-r--r--window-copy.c127
-rw-r--r--window.c6
22 files changed, 345 insertions, 175 deletions
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index 36805c46..d860eeb1 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -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();
diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c
index 55c1dde2..450ffc17 100644
--- a/cmd-rotate-window.c
+++ b/cmd-rotate-window.c
@@ -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);
diff --git a/cmd-select-pane.c b/cmd-select-pane.c
index fa388548..7871fe05 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -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))
diff --git a/cmd-split-window.c b/cmd-split-window.c
index e5b3ac49..77b1eac7 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -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);
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
index dd981b9a..12bc20b4 100644
--- a/cmd-swap-pane.c
+++ b/cmd-swap-pane.c
@@ -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)
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index fc7f9d75..b10496e3 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -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);
diff --git a/format-draw.c b/format-draw.c
index 67b961d9..cf0bdf5f 100644
--- a/format-draw.c
+++ b/format-draw.c
@@ -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;
}
diff --git a/format.c b/format.c
index d3c7508a..0e8ea8f3 100644
--- a/format.c
+++ b/format.c
@@ -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,30 +435,26 @@ format_job_tidy(struct format_job_tree *jobs, int force)
}
}
-/* Remove old jobs for client. */
+/* Tidy old jobs for all clients. */
void
-format_lost_client(struct client *c)
-{
- if (c->jobs != NULL)
- format_job_tidy(c->jobs, 1);
- free(c->jobs);
-}
-
-/* Remove old jobs periodically. */
-static void
-format_job_timer(__unused int fd, __unused short events, __unused void *arg)
+format_tidy_jobs(void)
{
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);
+/* Remove old jobs for client. */
+void
+format_lost_client(struct client *c)
+{
+ if (c->jobs != NULL)
+ format_job_tidy(c->jobs, 1);
+ free(c->jobs);
}
/* Wrapper for asprintf. */
@@ -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);
diff --git a/grid-reader.c b/grid-reader.c
index c011ea1d..ae2f4d2b 100644
--- a/grid-reader.c
+++ b/grid-reader.c
@@ -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--;
diff --git a/grid.c b/grid.c
index 1822f2b5..7744587a 100644
--- a/grid.c
+++ b/grid.c
@@ -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. */
diff --git a/layout-custom.c b/layout-custom.c
index 097dabe6..e7fb4253 100644
--- a/layout-custom.c
+++ b/layout-custom.c
@@ -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);
diff --git a/layout-set.c b/layout-set.c
index 9ef28416..c702817d 100644
--- a/layout-set.c
+++ b/layout-set.c
@@ -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);
diff --git a/layout.c b/layout.c
index 37214d02..04a13b0c 100644
--- a/layout.c
+++ b/layout.c
@@ -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);
diff --git a/options-table.c b/options-table.c
index a6f07cf9..b185969c 100644
--- a/options-table.c
+++ b/options-table.c
@@ -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
diff --git a/options.c b/options.c
index 9bc89db3..52f4f67e 100644
--- a/options.c
+++ b/options.c
@@ -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);
diff --git a/server.c b/server.c
index 0260898c..0b878d9e 100644
--- a/server.c
+++ b/server.c
@@ -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);
diff --git a/spawn.c b/spawn.c
index c47b11f4..565b7da5 100644
--- a/spawn.c
+++ b/spawn.c
@@ -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);
}
/*
diff --git a/style.c b/style.c
index 08614f9c..24b09882 100644
--- a/style.c
+++ b/style.c
@@ -139,6 +139,8 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in)
sy->align = STYLE_ALIGN_CENTRE;