mirror of
https://github.com/tmux/tmux.git
synced 2026-07-22 08:51:17 +00:00
Prevent display-panes from shifting the active pane scroll position by
copying the screen from before zoom, also do not let resize consume blank lines.
This commit is contained in:
3
tmux.h
3
tmux.h
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1408 2026/07/17 12:42:51 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1409 2026/07/17 16:03:15 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1277,6 +1277,7 @@ struct window_pane {
|
||||
#define PANE_DESTROYED 0x10000
|
||||
#define PANE_CMDRUNNING 0x20000
|
||||
#define PANE_ACTIVITY 0x40000
|
||||
#define PANE_NORESIZETRIM 0x80000
|
||||
|
||||
bitstr_t *sync_dirty;
|
||||
u_int sync_dirty_size;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: window-panes.c,v 1.1 2026/07/14 17:17:18 nicm Exp $ */
|
||||
/* $OpenBSD: window-panes.c,v 1.2 2026/07/17 16:03:15 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -57,6 +57,7 @@ struct window_panes_modedata {
|
||||
u_int source_session;
|
||||
u_int source_window;
|
||||
struct screen screen;
|
||||
struct screen *preview;
|
||||
|
||||
struct event timer;
|
||||
|
||||
@@ -103,6 +104,24 @@ window_panes_get_source(struct window_panes_modedata *data, struct session **sp,
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
window_panes_set_preview(struct window_panes_modedata *data)
|
||||
{
|
||||
struct window_pane *wp = data->wp;
|
||||
struct screen *src = &wp->base, *dst;
|
||||
struct screen_write_ctx ctx;
|
||||
u_int sx = screen_size_x(src), sy = screen_size_y(src);
|
||||
|
||||
data->preview = dst = xmalloc(sizeof *data->preview);
|
||||
screen_init(dst, sx, sy, 0);
|
||||
screen_write_start(&ctx, dst);
|
||||
screen_write_fast_copy(&ctx, src, 0, src->grid->hsize, sx, sy);
|
||||
screen_write_stop(&ctx);
|
||||
dst->mode = src->mode;
|
||||
dst->cx = src->cx;
|
||||
dst->cy = src->cy;
|
||||
}
|
||||
|
||||
static void
|
||||
window_panes_free_areas(struct window_panes_modedata *data)
|
||||
{
|
||||
@@ -379,7 +398,7 @@ window_panes_mark_pane_status_borders(u_char *map, struct window *w,
|
||||
}
|
||||
|
||||
static int
|
||||
window_panes_get_floating_frame(struct window_pane *wp, u_int osx, u_int osy,
|
||||
window_panes_get_floating_borders(struct window_pane *wp, u_int osx, u_int osy,
|
||||
u_int dsx, u_int dsy, int *xp, int *yp, int *x2p, int *y2p)
|
||||
{
|
||||
struct layout_cell *lc;
|
||||
@@ -404,12 +423,12 @@ window_panes_get_floating_frame(struct window_pane *wp, u_int osx, u_int osy,
|
||||
}
|
||||
|
||||
static int
|
||||
window_panes_clip_floating_body(struct window_pane *wp, u_int osx, u_int osy,
|
||||
window_panes_clip_floating_pane(struct window_pane *wp, u_int osx, u_int osy,
|
||||
u_int dsx, u_int dsy, u_int *xp, u_int *yp, u_int *sxp, u_int *syp)
|
||||
{
|
||||
int x, y, x2, y2, bx, by, bx2, by2;
|
||||
|
||||
if (!window_panes_get_floating_frame(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
if (!window_panes_get_floating_borders(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
&x2, &y2))
|
||||
return (1);
|
||||
|
||||
@@ -601,7 +620,7 @@ window_panes_draw_floating_border(struct screen_write_ctx *ctx,
|
||||
|
||||
if (dsx == 0 || dsy == 0)
|
||||
return;
|
||||
if (!window_panes_get_floating_frame(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
if (!window_panes_get_floating_borders(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
&x2, &y2))
|
||||
return;
|
||||
|
||||
@@ -634,7 +653,7 @@ window_panes_clear_floating_area(struct screen_write_ctx *ctx,
|
||||
struct grid_cell gc;
|
||||
int x, y, x2, y2, xx, yy;
|
||||
|
||||
if (!window_panes_get_floating_frame(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
if (!window_panes_get_floating_borders(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
&x2, &y2))
|
||||
return;
|
||||
|
||||
@@ -778,6 +797,7 @@ window_panes_draw_pane(struct window_panes_modedata *data,
|
||||
struct screen_write_ctx *ctx, struct window_pane *wp,
|
||||
struct layout_cell *root, u_int osx, u_int osy, u_int dsx, u_int dsy)
|
||||
{
|
||||
struct screen *s = &wp->base;
|
||||
u_int pane, x, y, sx, sy;
|
||||
|
||||
if (!window_panes_pane_visible(wp))
|
||||
@@ -785,7 +805,7 @@ window_panes_draw_pane(struct window_panes_modedata *data,
|
||||
if (!window_panes_get_geometry(wp, root, osx, osy, dsx, dsy, &x, &y,
|
||||
&sx, &sy))
|
||||
return;
|
||||
if (!window_panes_clip_floating_body(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
if (!window_panes_clip_floating_pane(wp, osx, osy, dsx, dsy, &x, &y,
|
||||
&sx, &sy))
|
||||
return;
|
||||
if (window_pane_index(wp, &pane) != 0)
|
||||
@@ -793,11 +813,15 @@ window_panes_draw_pane(struct window_panes_modedata *data,
|
||||
window_panes_add_area(data, wp, x, y, sx, sy);
|
||||
|
||||
screen_write_cursormove(ctx, x, y, 0);
|
||||
if (data->preview != NULL &&
|
||||
wp == data->wp &&
|
||||
sx <= screen_size_x(data->preview) &&
|
||||
sy <= screen_size_y(data->preview))
|
||||
s = data->preview;
|
||||
if (osx <= dsx && osy <= dsy)
|
||||
screen_write_fast_copy(ctx, &wp->base, 0, wp->base.grid->hsize,
|
||||
sx, sy);
|
||||
screen_write_fast_copy(ctx, s, 0, s->grid->hsize, sx, sy);
|
||||
else
|
||||
screen_write_preview(ctx, &wp->base, sx, sy);
|
||||
screen_write_preview(ctx, s, sx, sy);
|
||||
window_panes_draw_number(data, ctx, wp, pane, x, y, sx, sy);
|
||||
}
|
||||
|
||||
@@ -917,6 +941,8 @@ window_panes_init(struct window_mode_entry *wme, struct cmdq_item *item,
|
||||
data->zoomed = -1;
|
||||
else {
|
||||
data->zoomed = (w->flags & WINDOW_ZOOMED);
|
||||
if (!data->zoomed)
|
||||
window_panes_set_preview(data);
|
||||
if (!data->zoomed && window_zoom(wp) == 0)
|
||||
server_redraw_window(w);
|
||||
}
|
||||
@@ -940,8 +966,10 @@ window_panes_free(struct window_mode_entry *wme)
|
||||
|
||||
evtimer_del(&data->timer);
|
||||
|
||||
if (data->zoomed == 0)
|
||||
if (data->zoomed == 0) {
|
||||
wme->wp->flags |= PANE_NORESIZETRIM;
|
||||
server_unzoom_window(w);
|
||||
}
|
||||
server_redraw_window(w);
|
||||
server_redraw_window_borders(w);
|
||||
server_status_window(w);
|
||||
@@ -949,6 +977,10 @@ window_panes_free(struct window_mode_entry *wme)
|
||||
if (data->state != NULL)
|
||||
args_make_commands_free(data->state);
|
||||
window_panes_free_areas(data);
|
||||
if (data->preview != NULL) {
|
||||
screen_free(data->preview);
|
||||
free(data->preview);
|
||||
}
|
||||
screen_free(&data->screen);
|
||||
free(data);
|
||||
}
|
||||
@@ -1060,8 +1092,11 @@ window_panes_key(struct window_mode_entry *wme, struct client *c,
|
||||
return;
|
||||
}
|
||||
|
||||
if (wp->window->flags & WINDOW_ZOOMED)
|
||||
if (wp->window->flags & WINDOW_ZOOMED) {
|
||||
if (data->zoomed == 0)
|
||||
wp->flags |= PANE_NORESIZETRIM;
|
||||
window_unzoom(wp->window, 1);
|
||||
}
|
||||
window_panes_run_command(data, c, target);
|
||||
window_pane_reset_mode(wp);
|
||||
}
|
||||
|
||||
13
window.c
13
window.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: window.c,v 1.364 2026/07/15 13:02:33 nicm Exp $ */
|
||||
/* $OpenBSD: window.c,v 1.365 2026/07/17 16:03:15 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1556,6 +1556,12 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
||||
struct window_pane_resize *r;
|
||||
struct event_payload *ep;
|
||||
struct cmd_find_state fs;
|
||||
int trim = 1;
|
||||
|
||||
if (wp->flags & PANE_NORESIZETRIM) {
|
||||
wp->flags &= ~PANE_NORESIZETRIM;
|
||||
trim = 0;
|
||||
}
|
||||
|
||||
if (sx == wp->sx && sy == wp->sy)
|
||||
return;
|
||||
@@ -1573,7 +1579,10 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
||||
wp->sy = sy;
|
||||
|
||||
log_debug("%s: %%%u resize %ux%u", __func__, wp->id, sx, sy);
|
||||
screen_resize(&wp->base, sx, sy, wp->base.saved_grid == NULL);
|
||||
if (wp->base.saved_grid == NULL)
|
||||
screen_resize_cursor(&wp->base, sx, sy, 1, trim, 1);
|
||||
else
|
||||
screen_resize_cursor(&wp->base, sx, sy, 0, trim, 1);
|
||||
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme != NULL && wme->mode->resize != NULL)
|
||||
|
||||
Reference in New Issue
Block a user