Rewrite screen-redraw.c to make it tidier and more maintainable. A scene

is generated and cached in the client: it holds positions and sizes of
panes, borders and so on. The scene is invalidated when a pane is moved
or resized or relevant option is changed. This scene is then drawn to
the client as needed and text and colours are filled in. With Michael
Grant.
This commit is contained in:
nicm
2026-06-22 08:47:45 +00:00
parent e680420c89
commit 95afd7549c
16 changed files with 1836 additions and 1326 deletions

View File

@@ -125,6 +125,7 @@ SRCS= alerts.c \
tty.c \
utf8.c \
utf8-combined.c \
window-border.c \
window-buffer.c \
window-client.c \
window-clock.c \

View File

@@ -318,6 +318,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item)
grid_clear_history(wp->base.grid);
if (args_has(args, 'H'))
screen_reset_hyperlinks(wp->screen);
server_redraw_window(wp->window);
return (CMD_RETURN_NORMAL);
}

View File

@@ -48,6 +48,16 @@ struct cmd_display_panes_data {
struct args_command_state *state;
};
struct cmd_display_panes_ctx {
struct client *c;
int ox;
int oy;
u_int sx;
u_int sy;
u_int statuslines;
int statustop;
};
static enum args_parse_type
cmd_display_panes_args_parse(__unused struct args *args, __unused u_int idx,
__unused char **cause)
@@ -56,7 +66,7 @@ cmd_display_panes_args_parse(__unused struct args *args, __unused u_int idx,
}
static void
cmd_display_panes_put(struct screen_redraw_ctx *ctx,
cmd_display_panes_put(struct cmd_display_panes_ctx *ctx,
struct window_pane *wp, u_int cx, u_int cy, const char *buf, size_t len)
{
struct client *c = ctx->c;
@@ -76,7 +86,7 @@ cmd_display_panes_put(struct screen_redraw_ctx *ctx,
}
static void
cmd_display_panes_draw_format(struct screen_redraw_ctx *ctx,
cmd_display_panes_draw_format(struct cmd_display_panes_ctx *ctx,
struct window_pane *wp, u_int xoff, u_int yoff, u_int sx,
const struct grid_cell *gc)
{
@@ -112,7 +122,7 @@ cmd_display_panes_draw_format(struct screen_redraw_ctx *ctx,
}
static void
cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
cmd_display_panes_draw_pane(struct cmd_display_panes_ctx *ctx,
struct window_pane *wp)
{
struct client *c = ctx->c;
@@ -254,17 +264,30 @@ out:
}
static void
cmd_display_panes_draw(struct client *c, __unused void *data,
struct screen_redraw_ctx *ctx)
cmd_display_panes_draw(struct client *c, __unused void *data)
{
struct window *w = c->session->curw->window;
struct session *s = c->session;
struct window *w = s->curw->window;
struct window_pane *wp;
struct cmd_display_panes_ctx ctx;
u_int lines;
log_debug("%s: %s @%u", __func__, c->name, w->id);
memset(&ctx, 0, sizeof ctx);
ctx.c = c;
tty_window_offset(&c->tty, &ctx.ox, &ctx.oy, &ctx.sx, &ctx.sy);
if (options_get_number(s->options, "status-position") == 0) {
lines = status_line_size(c);
if (c->message_string != NULL || c->prompt_string != NULL)
lines = (lines == 0 ? 1 : lines);
ctx.statuslines = lines;
ctx.statustop = 1;
}
TAILQ_FOREACH(wp, &w->panes, entry) {
if (window_pane_is_visible(wp))
cmd_display_panes_draw_pane(ctx, wp);
cmd_display_panes_draw_pane(&ctx, wp);
}
}

View File

@@ -109,6 +109,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item)
window_set_active_pane(w, wp, 1);
cmd_find_from_winlink_pane(current, wl, wp, 0);
window_pop_zoom(w);
redraw_invalidate_scene(w);
server_redraw_window(w);
return (CMD_RETURN_NORMAL);

View File

@@ -149,9 +149,11 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
colour_palette_from_option(&src_wp->palette, src_wp->options);
colour_palette_from_option(&dst_wp->palette, dst_wp->options);
layout_fix_panes(src_w, NULL);
redraw_invalidate_scene(src_w);
server_redraw_window(src_w);
}
layout_fix_panes(dst_w, NULL);
redraw_invalidate_scene(dst_w);
server_redraw_window(dst_w);
notify_window("window-layout-changed", src_w);

View File

@@ -405,7 +405,8 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
struct window_pane *wp;
struct layout_cell *lc;
int status, scrollbars, sb_pos, sb_w, sb_pad;
u_int sx, sy;
int old_xoff, old_yoff, changed = 0;
u_int sx, sy, old_sx, old_sy;
status = window_get_pane_status(w);
scrollbars = options_get_number(w->options, "pane-scrollbars");
@@ -415,6 +416,11 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
if ((lc = wp->layout_cell) == NULL || wp == skip)
continue;
old_xoff = wp->xoff;
old_yoff = wp->yoff;
old_sx = wp->sx;
old_sy = wp->sy;
wp->xoff = lc->xoff;
wp->yoff = lc->yoff;
sx = lc->sx;
@@ -452,7 +458,15 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
}
window_pane_resize(wp, sx, sy);
if (wp->xoff != old_xoff ||
wp->yoff != old_yoff ||
wp->sx != old_sx ||
wp->sy != old_sy)
changed = 1;
}
if (changed)
redraw_invalidate_scene(w);
}
/* Count the number of available cells in a layout. */
@@ -818,11 +832,17 @@ layout_resize_floating_pane_to(struct window_pane *wp, enum layout_type type,
return;
}
if (type == LAYOUT_TOPBOTTOM)
if (type == LAYOUT_TOPBOTTOM) {
if (lc->sy == size)
return;
lc->sy = size;
else
} else {
if (lc->sx == size)
return;
lc->sx = size;
}
redraw_invalidate_scene(wp->window);
}
/* Resize a floating pane relative to its current size. */
void
@@ -836,6 +856,8 @@ layout_resize_floating_pane(struct window_pane *wp, enum layout_type type,
*cause = xstrdup("pane is not floating");
return;
}
if (change == 0)
return;
if (type == LAYOUT_TOPBOTTOM) {
size = lc->sy + change;
@@ -856,6 +878,7 @@ layout_resize_floating_pane(struct window_pane *wp, enum layout_type type,
if (opposite)
lc->xoff -= change;
}
redraw_invalidate_scene(wp->window);
}
/* Resize a layout cell. */

3
menu.c
View File

@@ -257,8 +257,7 @@ menu_reapply_styles(struct menu_data *md, struct client *c)
}
void
menu_draw_cb(struct client *c, void *data,
__unused struct screen_redraw_ctx *rctx)
menu_draw_cb(struct client *c, void *data)
{
struct menu_data *md = data;
struct tty *tty = &c->tty;

View File

@@ -1219,6 +1219,15 @@ options_push_changes(const char *name)
if (strcmp(name, "status") == 0 ||
strcmp(name, "status-interval") == 0)
status_timer_start_all();
if (strcmp(name, "status") == 0 ||
strcmp(name, "status-position") == 0 ||
strcmp(name, "pane-border-indicators") == 0 ||
strcmp(name, "pane-border-lines") == 0 ||
strcmp(name, "pane-border-status") == 0 ||
strcmp(name, "pane-scrollbars") == 0 ||
strcmp(name, "pane-scrollbars-position") == 0 ||
strcmp(name, "pane-scrollbars-style") == 0)
redraw_invalidate_all_scenes();
if (strcmp(name, "monitor-silence") == 0)
alerts_reset_all();
if (strcmp(name, "window-style") == 0 ||

View File

@@ -274,7 +274,7 @@ popup_check_cb(struct client* c, void *data, u_int px, u_int py, u_int nx)
}
static void
popup_draw_cb(struct client *c, void *data, struct screen_redraw_ctx *rctx)
popup_draw_cb(struct client *c, void *data)
{
struct popup_data *pd = data;
struct tty *tty = &c->tty;
@@ -329,7 +329,7 @@ popup_draw_cb(struct client *c, void *data, struct screen_redraw_ctx *rctx)
if (pd->md != NULL) {
c->overlay_check = NULL;
c->overlay_data = NULL;
menu_draw_cb(c, pd->md, rctx);
menu_draw_cb(c, pd->md);
}
c->overlay_check = popup_check_cb;
c->overlay_data = pd;

File diff suppressed because it is too large Load Diff

View File

@@ -729,19 +729,19 @@ screen_write_hline(struct screen_write_ctx *ctx, u_int nx, int left, int right,
gc.attr |= GRID_ATTR_CHARSET;
if (left)
screen_write_box_border_set(lines, CELL_LEFTJOIN, &gc);
screen_write_box_border_set(lines, CELL_URD, &gc);
else
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
screen_write_box_border_set(lines, CELL_LR, &gc);
screen_write_cell(ctx, &gc);
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
screen_write_box_border_set(lines, CELL_LR, &gc);
for (i = 1; i < nx - 1; i++)
screen_write_cell(ctx, &gc);
if (right)
screen_write_box_border_set(lines, CELL_RIGHTJOIN, &gc);
screen_write_box_border_set(lines, CELL_ULD, &gc);
else
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
screen_write_box_border_set(lines, CELL_LR, &gc);
screen_write_cell(ctx, &gc);
screen_write_set_cursor(ctx, cx, cy);
@@ -844,26 +844,26 @@ screen_write_box(struct screen_write_ctx *ctx, u_int nx, u_int ny,
gc.flags |= GRID_FLAG_NOPALETTE;
/* Draw top border */
screen_write_box_border_set(lines, CELL_TOPLEFT, &gc);
screen_write_box_border_set(lines, CELL_RD, &gc);
screen_write_cell(ctx, &gc);
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
screen_write_box_border_set(lines, CELL_LR, &gc);
for (i = 1; i < nx - 1; i++)
screen_write_cell(ctx, &gc);
screen_write_box_border_set(lines, CELL_TOPRIGHT, &gc);
screen_write_box_border_set(lines, CELL_LD, &gc);
screen_write_cell(ctx, &gc);
/* Draw bottom border */
screen_write_set_cursor(ctx, cx, cy + ny - 1);
screen_write_box_border_set(lines, CELL_BOTTOMLEFT, &gc);
screen_write_box_border_set(lines, CELL_RU, &gc);
screen_write_cell(ctx, &gc);
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
screen_write_box_border_set(lines, CELL_LR, &gc);
for (i = 1; i < nx - 1; i++)
screen_write_cell(ctx, &gc);
screen_write_box_border_set(lines, CELL_BOTTOMRIGHT, &gc);
screen_write_box_border_set(lines, CELL_LU, &gc);
screen_write_cell(ctx, &gc);
/* Draw sides */
screen_write_box_border_set(lines, CELL_TOPBOTTOM, &gc);
screen_write_box_border_set(lines, CELL_UD, &gc);
for (i = 1; i < ny - 1; i++) {
/* left side */
screen_write_set_cursor(ctx, cx, cy + i);

View File

@@ -534,6 +534,7 @@ server_client_free(__unused int fd, __unused short events, void *arg)
log_debug("free client %p (%d references)", c, c->references);
redraw_free_scene(c->redraw_scene);
cmdq_free(c->queue);
if (c->references == 0) {
@@ -2105,11 +2106,11 @@ server_client_check_redraw(struct client *c)
if (wp->flags & PANE_REDRAW) {
log_debug("%s: redraw pane %%%u", __func__,
wp->id);
screen_redraw_pane(c, wp, 0);
redraw_pane(c, wp);
} else if (wp->flags & PANE_REDRAWSCROLLBAR) {
log_debug("%s: redraw scrollbar %%%u", __func__,
wp->id);
screen_redraw_pane(c, wp, 1);
redraw_pane_scrollbar(c, wp);
}
}
}
@@ -2124,7 +2125,7 @@ server_client_check_redraw(struct client *c)
server_client_set_path(c);
}
server_client_set_progress_bar(c);
screen_redraw_screen(c);
redraw_screen(c);
}
/* Put the tty back how it was. */

84
tmux.h
View File

@@ -62,6 +62,8 @@ struct mouse_event;
struct options;
struct options_array_item;
struct options_entry;
struct redraw_scene;
struct redraw_span;
struct screen_write_citem;
struct screen_write_cline;
struct screen_write_ctx;
@@ -787,20 +789,23 @@ struct colour_palette {
#define GRID_STRING_USED_ONLY 0x8
#define GRID_STRING_EMPTY_CELLS 0x10
/* Cell positions. */
/*
* Cell border characters. Border cells are named for the directions they
* connect to: U for up, D for down, L for left and R for right.
*/
#define CELL_INSIDE 0
#define CELL_TOPBOTTOM 1
#define CELL_LEFTRIGHT 2
#define CELL_TOPLEFT 3
#define CELL_TOPRIGHT 4
#define CELL_BOTTOMLEFT 5
#define CELL_BOTTOMRIGHT 6
#define CELL_TOPJOIN 7
#define CELL_BOTTOMJOIN 8
#define CELL_LEFTJOIN 9
#define CELL_RIGHTJOIN 10
#define CELL_JOIN 11
#define CELL_OUTSIDE 12
#define CELL_UD 1
#define CELL_LR 2
#define CELL_RD 3
#define CELL_LD 4
#define CELL_RU 5
#define CELL_LU 6
#define CELL_LRD 7
#define CELL_LRU 8
#define CELL_URD 9
#define CELL_ULD 10
#define CELL_LRUD 11
#define CELL_NONE 12
#define CELL_SCROLLBAR 13
/* Cell borders. */
@@ -1079,27 +1084,6 @@ enum pane_lines {
#define WINDOW_PANE_COPY_MODE 1
#define WINDOW_PANE_VIEW_MODE 2
/* Screen redraw context. */
struct screen_redraw_ctx {
struct client *c;
u_int statuslines;
int statustop;
enum pane_lines pane_lines;
int pane_scrollbars;
int pane_scrollbars_pos;
struct grid_cell no_pane_gc;
int no_pane_gc_set;
u_int sx;
u_int sy;
int ox;
int oy;
};
/* Screen size. */
#define screen_size_x(s) ((s)->grid->sx)
#define screen_size_y(s) ((s)->grid->sy)
@@ -1250,7 +1234,7 @@ struct window_pane {
#define PANE_FOCUSED 0x4
#define PANE_VISITED 0x8
#define PANE_ZOOMED 0x10
/* 0x20 unused */
#define PANE_NEWSTATUS 0x20
#define PANE_INPUTOFF 0x40
#define PANE_CHANGED 0x80
#define PANE_EXITED 0x100
@@ -1306,7 +1290,6 @@ struct window_pane {
struct screen base;
struct screen status_screen;
size_t status_size;
TAILQ_HEAD(, window_mode_entry) modes;
@@ -1371,6 +1354,8 @@ struct window {
u_int new_xpixel;
u_int new_ypixel;
uint64_t redraw_scene_generation;
u_int last_new_pane_x;
u_int last_new_pane_y;
@@ -2012,8 +1997,7 @@ typedef struct visible_ranges *(*overlay_check_cb)(struct client*, void *,
u_int, u_int, u_int);
typedef struct screen *(*overlay_mode_cb)(struct client *, void *, u_int *,
u_int *);
typedef void (*overlay_draw_cb)(struct client *, void *,
struct screen_redraw_ctx *);
typedef void (*overlay_draw_cb)(struct client *, void *);
typedef int (*overlay_key_cb)(struct client *, void *, struct key_event *);
typedef void (*overlay_free_cb)(struct client *, void *);
typedef void (*overlay_resize_cb)(struct client *, void *);
@@ -2059,6 +2043,8 @@ struct client {
size_t discarded;
size_t redraw;
struct redraw_scene *redraw_scene;
struct event repeat_timer;
struct event click_timer;
@@ -3338,8 +3324,13 @@ void screen_write_alternateoff(struct screen_write_ctx *,
struct grid_cell *, int);
/* screen-redraw.c */
void screen_redraw_screen(struct client *);
void screen_redraw_pane(struct client *, struct window_pane *, int);
void redraw_screen(struct client *);
void redraw_pane(struct client *, struct window_pane *);
void redraw_pane_scrollbar(struct client *, struct window_pane *);
void redraw_free_scene(struct redraw_scene *);
void redraw_invalidate_scene(struct window *);
void redraw_invalidate_all_scenes(void);
int redraw_get_status_border_cell_type(struct redraw_span **, u_int);
/* screen.c */
void screen_init(struct screen *, u_int, u_int, u_int);
@@ -3487,6 +3478,16 @@ struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
u_int);
int window_pane_is_floating(struct window_pane *);
/* window-border.c */
void window_get_border_cell(struct window *, struct window_pane *,
enum pane_lines, int, struct grid_cell *);
void window_pane_get_border_cell(struct window_pane *, int,
struct grid_cell *);
void window_pane_get_border_style(struct window_pane *,
struct client *, struct grid_cell *);
int window_make_pane_status(struct window_pane *, struct client *,
u_int, struct redraw_span *);
/* window-visible.c */
int window_position_is_visible(struct visible_ranges *, u_int);
struct visible_ranges *window_visible_ranges(struct window_pane *, int, int,
@@ -3783,8 +3784,7 @@ int menu_display(struct menu *, int, int, struct cmdq_item *,
struct screen *menu_mode_cb(struct client *, void *, u_int *, u_int *);
struct visible_ranges *menu_check_cb(struct client *, void *, u_int, u_int,
u_int);
void menu_draw_cb(struct client *, void *,
struct screen_redraw_ctx *);
void menu_draw_cb(struct client *, void *);
void menu_free_cb(struct client *, void *);
int menu_key_cb(struct client *, void *, struct key_event *);

171
window-border.c Normal file
View File

@@ -0,0 +1,171 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/* Get border cell. */
void
window_get_border_cell(struct window *w, struct window_pane *wp,
enum pane_lines pane_lines, int cell_type, struct grid_cell *gc)
{
u_int idx;
if (cell_type == CELL_NONE && w->fill_character != NULL) {
utf8_copy(&gc->data, &w->fill_character[0]);
return;
}
switch (pane_lines) {
case PANE_LINES_NUMBER:
if (cell_type == CELL_NONE) {
gc->attr |= GRID_ATTR_CHARSET;
utf8_set(&gc->data, CELL_BORDERS[CELL_NONE]);
break;
}
gc->attr &= ~GRID_ATTR_CHARSET;
if (wp != NULL && window_pane_index(wp, &idx) == 0)
utf8_set(&gc->data, '0' + (idx % 10));
else
utf8_set(&gc->data, '*');
break;
case PANE_LINES_DOUBLE:
gc->attr &= ~GRID_ATTR_CHARSET;
utf8_copy(&gc->data, tty_acs_double_borders(cell_type));
break;
case PANE_LINES_HEAVY:
gc->attr &= ~GRID_ATTR_CHARSET;
utf8_copy(&gc->data, tty_acs_heavy_borders(cell_type));
break;
case PANE_LINES_SIMPLE:
gc->attr &= ~GRID_ATTR_CHARSET;
utf8_set(&gc->data, SIMPLE_BORDERS[cell_type]);
break;
case PANE_LINES_NONE:
case PANE_LINES_SPACES:
gc->attr &= ~GRID_ATTR_CHARSET;
utf8_set(&gc->data, ' ');
break;
default:
gc->attr |= GRID_ATTR_CHARSET;
utf8_set(&gc->data, CELL_BORDERS[cell_type]);
break;
}
}
/* Get pane border cell. */
void
window_pane_get_border_cell(struct window_pane *wp, int cell_type,
struct grid_cell *gc)
{
enum pane_lines pane_lines = window_pane_get_pane_lines(wp);
window_get_border_cell(wp->window, wp, pane_lines, cell_type, gc);
}
/* Get pane border style. */
void
window_pane_get_border_style(struct window_pane *wp, struct client *c,
struct grid_cell *gc)
{
struct session *s = c->session;
struct format_tree *ft;
const char *option;
struct grid_cell *saved;
int *flag;
if (wp == server_client_get_pane(c)) {
flag = &wp->active_border_gc_set;
saved = &wp->active_border_gc;
option = "pane-active-border-style";
} else {
flag = &wp->border_gc_set;
saved = &wp->border_gc;
option = "pane-border-style";
}
if (!*flag) {
ft = format_create_defaults(NULL, c, s, s->curw, wp);
style_apply(saved, wp->options, option, ft);
format_free(ft);
*flag = 1;
}
memcpy(gc, saved, sizeof *gc);
}
/* Build pane status line. */
int
window_make_pane_status(struct window_pane *wp, struct client *c, u_int width,
struct redraw_span *span)
{
struct grid_cell gc;
const char *fmt;
struct format_tree *ft;
struct style_line_entry *sle = &wp->border_status_line;
struct screen_write_ctx ctx;
struct screen old;
char *expanded;
u_int i;
enum pane_lines pane_lines;
int pane_status, cell_type;
pane_status = window_pane_get_pane_status(wp);
if (pane_status == PANE_STATUS_OFF || width == 0)
return (0);
ft = format_create(c, NULL, FORMAT_PANE|wp->id, FORMAT_STATUS);
format_defaults(ft, c, c->session, c->session->curw, wp);
fmt = options_get_string(wp->options, "pane-border-format");
expanded = format_expand_time(ft, fmt);
memcpy(&old, &wp->status_screen, sizeof old);
screen_init(&wp->status_screen, width, 1, 0);
wp->status_screen.mode = 0;
screen_write_start(&ctx, &wp->status_screen);
window_pane_get_border_style(wp, c, &gc);
pane_lines = window_pane_get_pane_lines(wp);
for (i = 0; i < width; i++) {
cell_type = redraw_get_status_border_cell_type(&span, i);
window_get_border_cell(wp->window, wp, pane_lines, cell_type, &gc);
screen_write_cell(&ctx, &gc);
}
gc.attr &= ~GRID_ATTR_CHARSET;
screen_write_cursormove(&ctx, 0, 0, 0);
style_ranges_free(&sle->ranges);
format_draw(&ctx, &gc, width, expanded, &sle->ranges, 0);
screen_write_stop(&ctx);
format_free(ft);
free(sle->expanded);
sle->expanded = expanded;
if (grid_compare(wp->status_screen.grid, old.grid) == 0) {
screen_free(&old);
return (0);
}
screen_free(&old);
return (1);
}

View File

@@ -800,7 +800,7 @@ window_copy_scroll1(struct window_mode_entry *wme, struct window_pane *wp,
return;
/*
* See screen_redraw_draw_pane_scrollbar - this is the inverse of the
* See redraw_draw_pane_scrollbar - this is the inverse of the
* formula used there.
*/
new_offset = new_slider_y * ((float)(size + sb_height) / sb_height);

View File

@@ -755,6 +755,7 @@ window_zoom(struct window_pane *wp)
w->flags |= WINDOW_ZOOMED;
notify_window("window-layout-changed", w);
redraw_invalidate_scene(w);
return (0);
}
@@ -781,6 +782,7 @@ window_unzoom(struct window *w, int notify)
if (notify)
notify_window("window-layout-changed", w);
redraw_invalidate_scene(w);
return (0);
}
@@ -837,6 +839,7 @@ window_add_pane(struct window *w, struct window_pane *other, u_int hlimit,
else {
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
}
redraw_invalidate_scene(w);
return (wp);
}
@@ -863,6 +866,7 @@ window_lost_pane(struct window *w, struct window_pane *wp)
window_update_focus(w);
}
}
redraw_invalidate_scene(w);
}
void
@@ -871,6 +875,7 @@ window_remove_pane(struct window *w, struct window_pane *wp)
window_lost_pane(w, wp);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_REMOVE(&w->z_index, wp, zentry);
redraw_invalidate_scene(w);
window_pane_destroy(wp);
}