mirror of
https://github.com/tmux/tmux.git
synced 2025-09-03 06:17:04 +00:00
Move alternate screen into the screen rather than the pane.
This commit is contained in:
@ -118,7 +118,7 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
|
|||||||
|
|
||||||
sx = screen_size_x(&wp->base);
|
sx = screen_size_x(&wp->base);
|
||||||
if (args_has(args, 'a')) {
|
if (args_has(args, 'a')) {
|
||||||
gd = wp->saved_grid;
|
gd = wp->base.saved_grid;
|
||||||
if (gd == NULL) {
|
if (gd == NULL) {
|
||||||
if (!args_has(args, 'q')) {
|
if (!args_has(args, 'q')) {
|
||||||
cmdq_error(item, "no alternate screen");
|
cmdq_error(item, "no alternate screen");
|
||||||
|
8
format.c
8
format.c
@ -2729,9 +2729,11 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
|
|||||||
format_add(ft, "scroll_region_upper", "%u", wp->base.rupper);
|
format_add(ft, "scroll_region_upper", "%u", wp->base.rupper);
|
||||||
format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
|
format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
|
||||||
|
|
||||||
format_add(ft, "alternate_on", "%d", wp->saved_grid ? 1 : 0);
|
format_add(ft, "alternate_on", "%d", wp->base.saved_grid != NULL);
|
||||||
format_add(ft, "alternate_saved_x", "%u", wp->saved_cx);
|
if (wp->base.saved_cx != UINT_MAX)
|
||||||
format_add(ft, "alternate_saved_y", "%u", wp->saved_cy);
|
format_add(ft, "alternate_saved_x", "%u", wp->base.saved_cx);
|
||||||
|
if (wp->base.saved_cy != UINT_MAX)
|
||||||
|
format_add(ft, "alternate_saved_y", "%u", wp->base.saved_cy);
|
||||||
|
|
||||||
format_add(ft, "cursor_flag", "%d",
|
format_add(ft, "cursor_flag", "%d",
|
||||||
!!(wp->base.mode & MODE_CURSOR));
|
!!(wp->base.mode & MODE_CURSOR));
|
||||||
|
34
input.c
34
input.c
@ -75,6 +75,7 @@ struct input_param {
|
|||||||
/* Input parser context. */
|
/* Input parser context. */
|
||||||
struct input_ctx {
|
struct input_ctx {
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
struct bufferevent *event;
|
||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
|
|
||||||
struct input_cell cell;
|
struct input_cell cell;
|
||||||
@ -788,12 +789,13 @@ input_restore_state(struct input_ctx *ictx)
|
|||||||
|
|
||||||
/* Initialise input parser. */
|
/* Initialise input parser. */
|
||||||
struct input_ctx *
|
struct input_ctx *
|
||||||
input_init(struct window_pane *wp)
|
input_init(struct window_pane *wp, struct bufferevent *bev)
|
||||||
{
|
{
|
||||||
struct input_ctx *ictx;
|
struct input_ctx *ictx;
|
||||||
|
|
||||||
ictx = xcalloc(1, sizeof *ictx);
|
ictx = xcalloc(1, sizeof *ictx);
|
||||||
ictx->wp = wp;
|
ictx->wp = wp;
|
||||||
|
ictx->event = bev;
|
||||||
|
|
||||||
ictx->input_space = INPUT_BUF_START;
|
ictx->input_space = INPUT_BUF_START;
|
||||||
ictx->input_buf = xmalloc(INPUT_BUF_START);
|
ictx->input_buf = xmalloc(INPUT_BUF_START);
|
||||||
@ -1058,18 +1060,15 @@ input_get(struct input_ctx *ictx, u_int validx, int minval, int defval)
|
|||||||
static void
|
static void
|
||||||
input_reply(struct input_ctx *ictx, const char *fmt, ...)
|
input_reply(struct input_ctx *ictx, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
struct window_pane *wp = ictx->wp;
|
struct bufferevent *bev = ictx->event;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *reply;
|
char *reply;
|
||||||
|
|
||||||
if (wp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
xvasprintf(&reply, fmt, ap);
|
xvasprintf(&reply, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
bufferevent_write(wp->event, reply, strlen(reply));
|
bufferevent_write(bev, reply, strlen(reply));
|
||||||
free(reply);
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1680,10 +1679,14 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
|
|||||||
case 1047:
|
case 1047:
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
window_pane_alternate_off(wp, gc, 0);
|
window_pane_alternate_off(wp, gc, 0);
|
||||||
|
else
|
||||||
|
screen_alternate_off(sctx->s, gc, 0);
|
||||||
break;
|
break;
|
||||||
case 1049:
|
case 1049:
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
window_pane_alternate_off(wp, gc, 1);
|
window_pane_alternate_off(wp, gc, 1);
|
||||||
|
else
|
||||||
|
screen_alternate_off(sctx->s, gc, 1);
|
||||||
break;
|
break;
|
||||||
case 2004:
|
case 2004:
|
||||||
screen_write_mode_clear(sctx, MODE_BRACKETPASTE);
|
screen_write_mode_clear(sctx, MODE_BRACKETPASTE);
|
||||||
@ -1781,10 +1784,14 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
|||||||
case 1047:
|
case 1047:
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
window_pane_alternate_on(wp, gc, 0);
|
window_pane_alternate_on(wp, gc, 0);
|
||||||
|
else
|
||||||
|
screen_alternate_on(sctx->s, gc, 0);
|
||||||
break;
|
break;
|
||||||
case 1049:
|
case 1049:
|
||||||
if (wp != NULL)
|
if (wp != NULL)
|
||||||
window_pane_alternate_on(wp, gc, 1);
|
window_pane_alternate_on(wp, gc, 1);
|
||||||
|
else
|
||||||
|
screen_alternate_on(sctx->s, gc, 1);
|
||||||
break;
|
break;
|
||||||
case 2004:
|
case 2004:
|
||||||
screen_write_mode_set(sctx, MODE_BRACKETPASTE);
|
screen_write_mode_set(sctx, MODE_BRACKETPASTE);
|
||||||
@ -1801,7 +1808,9 @@ static void
|
|||||||
input_csi_dispatch_winops(struct input_ctx *ictx)
|
input_csi_dispatch_winops(struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||||
|
struct screen *s = sctx->s;
|
||||||
struct window_pane *wp = ictx->wp;
|
struct window_pane *wp = ictx->wp;
|
||||||
|
u_int x = screen_size_x(s), y = screen_size_y(s);
|
||||||
int n, m;
|
int n, m;
|
||||||
|
|
||||||
m = 0;
|
m = 0;
|
||||||
@ -1858,10 +1867,7 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 18:
|
case 18:
|
||||||
if (wp != NULL) {
|
input_reply(ictx, "\033[8;%u;%ut", x, y);
|
||||||
input_reply(ictx, "\033[8;%u;%ut", wp->sy,
|
|
||||||
wp->sx);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
||||||
@ -2565,13 +2571,13 @@ input_osc_52(struct input_ctx *ictx, const char *p)
|
|||||||
outlen = 0;
|
outlen = 0;
|
||||||
out = NULL;
|
out = NULL;
|
||||||
}
|
}
|
||||||
bufferevent_write(wp->event, "\033]52;;", 6);
|
bufferevent_write(ictx->event, "\033]52;;", 6);
|
||||||
if (outlen != 0)
|
if (outlen != 0)
|
||||||
bufferevent_write(wp->event, out, outlen);
|
bufferevent_write(ictx->event, out, outlen);
|
||||||
if (ictx->input_end == INPUT_END_BEL)
|
if (ictx->input_end == INPUT_END_BEL)
|
||||||
bufferevent_write(wp->event, "\007", 1);
|
bufferevent_write(ictx->event, "\007", 1);
|
||||||
else
|
else
|
||||||
bufferevent_write(wp->event, "\033\\", 2);
|
bufferevent_write(ictx->event, "\033\\", 2);
|
||||||
free(out);
|
free(out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
84
screen.c
84
screen.c
@ -76,6 +76,8 @@ void
|
|||||||
screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
|
screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
|
||||||
{
|
{
|
||||||
s->grid = grid_create(sx, sy, hlimit);
|
s->grid = grid_create(sx, sy, hlimit);
|
||||||
|
s->saved_grid = NULL;
|
||||||
|
|
||||||
s->title = xstrdup("");
|
s->title = xstrdup("");
|
||||||
s->titles = NULL;
|
s->titles = NULL;
|
||||||
|
|
||||||
@ -99,6 +101,11 @@ screen_reinit(struct screen *s)
|
|||||||
|
|
||||||
s->mode = MODE_CURSOR | MODE_WRAP;
|
s->mode = MODE_CURSOR | MODE_WRAP;
|
||||||
|
|
||||||
|
if (s->saved_grid != NULL)
|
||||||
|
screen_alternate_off(s, NULL, 0);
|
||||||
|
s->saved_cx = UINT_MAX;
|
||||||
|
s->saved_cy = UINT_MAX;
|
||||||
|
|
||||||
screen_reset_tabs(s);
|
screen_reset_tabs(s);
|
||||||
|
|
||||||
grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy, 8);
|
grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy, 8);
|
||||||
@ -116,6 +123,8 @@ screen_free(struct screen *s)
|
|||||||
free(s->title);
|
free(s->title);
|
||||||
free(s->ccolour);
|
free(s->ccolour);
|
||||||
|
|
||||||
|
if (s->saved_grid != NULL)
|
||||||
|
grid_destroy(s->saved_grid);
|
||||||
grid_destroy(s->grid);
|
grid_destroy(s->grid);
|
||||||
|
|
||||||
screen_free_titles(s);
|
screen_free_titles(s);
|
||||||
@ -502,3 +511,78 @@ screen_reflow(struct screen *s, u_int new_x)
|
|||||||
log_debug("%s: reflow took %llu.%06u seconds", __func__,
|
log_debug("%s: reflow took %llu.%06u seconds", __func__,
|
||||||
(unsigned long long)tv.tv_sec, (u_int)tv.tv_usec);
|
(unsigned long long)tv.tv_sec, (u_int)tv.tv_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enter alternative screen mode. A copy of the visible screen is saved and the
|
||||||
|
* history is not updated.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
|
||||||
|
{
|
||||||
|
u_int sx, sy;
|
||||||
|
|
||||||
|
if (s->saved_grid != NULL)
|
||||||
|
return;
|
||||||
|
sx = screen_size_x(s);
|
||||||
|
sy = screen_size_y(s);
|
||||||
|
|
||||||
|
s->saved_grid = grid_create(sx, sy, 0);
|
||||||
|
grid_duplicate_lines(s->saved_grid, 0, s->grid, screen_hsize(s), sy);
|
||||||
|
if (cursor) {
|
||||||
|
s->saved_cx = s->cx;
|
||||||
|
s->saved_cy = s->cy;
|
||||||
|
}
|
||||||
|
memcpy(&s->saved_cell, gc, sizeof s->saved_cell);
|
||||||
|
|
||||||
|
grid_view_clear(s->grid, 0, 0, sx, sy, 8);
|
||||||
|
|
||||||
|
s->grid->flags &= ~GRID_HISTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exit alternate screen mode and restore the copied grid. */
|
||||||
|
void
|
||||||
|
screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
|
||||||
|
{
|
||||||
|
u_int sx, sy;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore the cursor position and cell. This happens even if not
|
||||||
|
* currently in the alternate screen.
|
||||||
|
*/
|
||||||
|
if (cursor && s->saved_cx != UINT_MAX && s->saved_cy != UINT_MAX) {
|
||||||
|
s->cx = s->saved_cx;
|
||||||
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
|
s->cx = screen_size_x(s) - 1;
|
||||||
|
s->cy = s->saved_cy;
|
||||||
|
if (s->cy > screen_size_y(s) - 1)
|
||||||
|
s->cy = screen_size_y(s) - 1;
|
||||||
|
if (gc != NULL)
|
||||||
|
memcpy(gc, &s->saved_cell, sizeof *gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->saved_grid == NULL)
|
||||||
|
return;
|
||||||
|
sx = screen_size_x(s);
|
||||||
|
sy = screen_size_y(s);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the current size is bigger, temporarily resize to the old size
|
||||||
|
* before copying back.
|
||||||
|
*/
|
||||||
|
if (sy > s->saved_grid->sy)
|
||||||
|
screen_resize(s, sx, s->saved_grid->sy, 1);
|
||||||
|
|
||||||
|
/* Restore the saved grid. */
|
||||||
|
grid_duplicate_lines(s->grid, screen_hsize(s), s->saved_grid, 0, sy);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Turn history back on (so resize can use it) and then resize back to
|
||||||
|
* the current size.
|
||||||
|
*/
|
||||||
|
s->grid->flags |= GRID_HISTORY;
|
||||||
|
if (sy > s->saved_grid->sy || sx != s->saved_grid->sx)
|
||||||
|
screen_resize(s, sx, sy, 1);
|
||||||
|
|
||||||
|
grid_destroy(s->saved_grid);
|
||||||
|
s->saved_grid = NULL;
|
||||||
|
}
|
||||||
|
@ -1400,7 +1400,7 @@ server_client_resize_event(__unused int fd, __unused short events, void *data)
|
|||||||
log_debug("%s: %%%u timer fired (was%s resized)", __func__, wp->id,
|
log_debug("%s: %%%u timer fired (was%s resized)", __func__, wp->id,
|
||||||
(wp->flags & PANE_RESIZED) ? "" : " not");
|
(wp->flags & PANE_RESIZED) ? "" : " not");
|
||||||
|
|
||||||
if (wp->saved_grid == NULL && (wp->flags & PANE_RESIZED)) {
|
if (wp->base.saved_grid == NULL && (wp->flags & PANE_RESIZED)) {
|
||||||
log_debug("%s: %%%u deferring timer", __func__, wp->id);
|
log_debug("%s: %%%u deferring timer", __func__, wp->id);
|
||||||
server_client_start_resize_timer(wp);
|
server_client_start_resize_timer(wp);
|
||||||
} else if (!server_client_resize_force(wp)) {
|
} else if (!server_client_resize_force(wp)) {
|
||||||
|
18
tmux.h
18
tmux.h
@ -754,8 +754,12 @@ struct screen {
|
|||||||
|
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
bitstr_t *tabs;
|
u_int saved_cx;
|
||||||
|
u_int saved_cy;
|
||||||
|
struct grid *saved_grid;
|
||||||
|
struct grid_cell saved_cell;
|
||||||
|
|
||||||
|
bitstr_t *tabs;
|
||||||
struct screen_sel *sel;
|
struct screen_sel *sel;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -917,12 +921,6 @@ struct window_pane {
|
|||||||
struct screen status_screen;
|
struct screen status_screen;
|
||||||
size_t status_size;
|
size_t status_size;
|
||||||
|
|
||||||
/* Saved in alternative screen mode. */
|
|
||||||
u_int saved_cx;
|
|
||||||
u_int saved_cy;
|
|
||||||
struct grid *saved_grid;
|
|
||||||
struct grid_cell saved_cell;
|
|
||||||
|
|
||||||
TAILQ_HEAD (, window_mode_entry) modes;
|
TAILQ_HEAD (, window_mode_entry) modes;
|
||||||
struct event modetimer;
|
struct event modetimer;
|
||||||
time_t modelast;
|
time_t modelast;
|
||||||
@ -2296,7 +2294,7 @@ void recalculate_size(struct window *);
|
|||||||
void recalculate_sizes(void);
|
void recalculate_sizes(void);
|
||||||
|
|
||||||
/* input.c */
|
/* input.c */
|
||||||
struct input_ctx *input_init(struct window_pane *);
|
struct input_ctx *input_init(struct window_pane *, struct bufferevent *);
|
||||||
void input_free(struct input_ctx *);
|
void input_free(struct input_ctx *);
|
||||||
void input_reset(struct input_ctx *, int);
|
void input_reset(struct input_ctx *, int);
|
||||||
struct evbuffer *input_pending(struct input_ctx *);
|
struct evbuffer *input_pending(struct input_ctx *);
|
||||||
@ -2334,6 +2332,7 @@ struct grid *grid_create(u_int, u_int, u_int);
|
|||||||
void grid_destroy(struct grid *);
|
void grid_destroy(struct grid *);
|
||||||
int grid_compare(struct grid *, struct grid *);
|
int grid_compare(struct grid *, struct grid *);
|
||||||
void grid_collect_history(struct grid *);
|
void grid_collect_history(struct grid *);
|
||||||
|
void grid_remove_history(struct grid *, u_int );
|
||||||
void grid_scroll_history(struct grid *, u_int);
|
void grid_scroll_history(struct grid *, u_int);
|
||||||
void grid_scroll_history_region(struct grid *, u_int, u_int, u_int);
|
void grid_scroll_history_region(struct grid *, u_int, u_int, u_int);
|
||||||
void grid_clear_history(struct grid *);
|
void grid_clear_history(struct grid *);
|
||||||
@ -2458,6 +2457,9 @@ void screen_hide_selection(struct screen *);
|
|||||||
int screen_check_selection(struct screen *, u_int, u_int);
|
int screen_check_selection(struct screen *, u_int, u_int);
|
||||||
void screen_select_cell(struct screen *, struct grid_cell *,
|
void screen_select_cell(struct screen *, struct grid_cell *,
|
||||||
const struct grid_cell *);
|
const struct grid_cell *);
|
||||||
|
void screen_alternate_on(struct screen *, struct grid_cell *, int);
|
||||||
|
void screen_alternate_off(struct screen *, struct grid_cell *, int);
|
||||||
|
|
||||||
|
|
||||||
/* window.c */
|
/* window.c */
|
||||||
extern struct windows windows;
|
extern struct windows windows;
|
||||||
|
86
window.c
86
window.c
@ -879,10 +879,6 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
|||||||
wp->pipe_off = 0;
|
wp->pipe_off = 0;
|
||||||
wp->pipe_event = NULL;
|
wp->pipe_event = NULL;
|
||||||
|
|
||||||
wp->saved_grid = NULL;
|
|
||||||
wp->saved_cx = UINT_MAX;
|
|
||||||
wp->saved_cy = UINT_MAX;
|
|
||||||
|
|
||||||
screen_init(&wp->base, sx, sy, hlimit);
|
screen_init(&wp->base, sx, sy, hlimit);
|
||||||
wp->screen = &wp->base;
|
wp->screen = &wp->base;
|
||||||
|
|
||||||
@ -891,8 +887,6 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
|||||||
if (gethostname(host, sizeof host) == 0)
|
if (gethostname(host, sizeof host) == 0)
|
||||||
screen_set_title(&wp->base, host);
|
screen_set_title(&wp->base, host);
|
||||||
|
|
||||||
wp->ictx = input_init(wp);
|
|
||||||
|
|
||||||
return (wp);
|
return (wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,14 +900,12 @@ window_pane_destroy(struct window_pane *wp)
|
|||||||
bufferevent_free(wp->event);
|
bufferevent_free(wp->event);
|
||||||
close(wp->fd);
|
close(wp->fd);
|
||||||
}
|
}
|
||||||
|
if (wp->ictx != NULL)
|
||||||
input_free(wp->ictx);
|
input_free(wp->ictx);
|
||||||
|
|
||||||
screen_free(&wp->status_screen);
|
screen_free(&wp->status_screen);
|
||||||
|
|
||||||
screen_free(&wp->base);
|
screen_free(&wp->base);
|
||||||
if (wp->saved_grid != NULL)
|
|
||||||
grid_destroy(wp->saved_grid);
|
|
||||||
|
|
||||||
if (wp->pipe_fd != -1) {
|
if (wp->pipe_fd != -1) {
|
||||||
bufferevent_free(wp->pipe_event);
|
bufferevent_free(wp->pipe_event);
|
||||||
@ -974,6 +966,7 @@ window_pane_set_event(struct window_pane *wp)
|
|||||||
|
|
||||||
wp->event = bufferevent_new(wp->fd, window_pane_read_callback,
|
wp->event = bufferevent_new(wp->fd, window_pane_read_callback,
|
||||||
NULL, window_pane_error_callback, wp);
|
NULL, window_pane_error_callback, wp);
|
||||||
|
wp->ictx = input_init(wp, wp->event);
|
||||||
|
|
||||||
bufferevent_setwatermark(wp->event, EV_READ, 0, READ_SIZE);
|
bufferevent_setwatermark(wp->event, EV_READ, 0, READ_SIZE);
|
||||||
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
|
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
|
||||||
@ -990,7 +983,7 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
|||||||
wp->sy = sy;
|
wp->sy = sy;
|
||||||
|
|
||||||
log_debug("%s: %%%u resize %ux%u", __func__, wp->id, sx, sy);
|
log_debug("%s: %%%u resize %ux%u", __func__, wp->id, sx, sy);
|
||||||
screen_resize(&wp->base, sx, sy, wp->saved_grid == NULL);
|
screen_resize(&wp->base, sx, sy, wp->base.saved_grid == NULL);
|
||||||
|
|
||||||
wme = TAILQ_FIRST(&wp->modes);
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wme != NULL && wme->mode->resize != NULL)
|
if (wme != NULL && wme->mode->resize != NULL)
|
||||||
@ -999,90 +992,23 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
|||||||
wp->flags |= (PANE_RESIZE|PANE_RESIZED);
|
wp->flags |= (PANE_RESIZE|PANE_RESIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Enter alternative screen mode. A copy of the visible screen is saved and the
|
|
||||||
* history is not updated
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc,
|
window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc,
|
||||||
int cursor)
|
int cursor)
|
||||||
{
|
{
|
||||||
struct screen *s = &wp->base;
|
|
||||||
u_int sx, sy;
|
|
||||||
|
|
||||||
if (wp->saved_grid != NULL)
|
|
||||||
return;
|
|
||||||
if (!options_get_number(wp->options, "alternate-screen"))
|
if (!options_get_number(wp->options, "alternate-screen"))
|
||||||
return;
|
return;
|
||||||
sx = screen_size_x(s);
|
screen_alternate_on(&wp->base, gc, cursor);
|
||||||
sy = screen_size_y(s);
|
|
||||||
|
|
||||||
wp->saved_grid = grid_create(sx, sy, 0);
|
|
||||||
grid_duplicate_lines(wp->saved_grid, 0, s->grid, screen_hsize(s), sy);
|
|
||||||
if (cursor) {
|
|
||||||
wp->saved_cx = s->cx;
|
|
||||||
wp->saved_cy = s->cy;
|
|
||||||
}
|
|
||||||
memcpy(&wp->saved_cell, gc, sizeof wp->saved_cell);
|
|
||||||
|
|
||||||
grid_view_clear(s->grid, 0, 0, sx, sy, 8);
|
|
||||||
|
|
||||||
wp->base.grid->flags &= ~GRID_HISTORY;
|
|
||||||
|
|
||||||
wp->flags |= PANE_REDRAW;
|
wp->flags |= PANE_REDRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exit alternate screen mode and restore the copied grid. */
|
|
||||||
void
|
void
|
||||||
window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc,
|
window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc,
|
||||||
int cursor)
|
int cursor)
|
||||||
{
|
{
|
||||||
struct screen *s = &wp->base;
|
|
||||||
u_int sx, sy;
|
|
||||||
|
|
||||||
if (!options_get_number(wp->options, "alternate-screen"))
|
if (!options_get_number(wp->options, "alternate-screen"))
|
||||||
return;
|
return;
|
||||||
|
screen_alternate_off(&wp->base, gc, cursor);
|
||||||
/*
|
|
||||||
* Restore the cursor position and cell. This happens even if not
|
|
||||||
* currently in the alternate screen.
|
|
||||||
*/
|
|
||||||
if (cursor && wp->saved_cx != UINT_MAX && wp->saved_cy != UINT_MAX) {
|
|
||||||
s->cx = wp->saved_cx;
|
|
||||||
if (s->cx > screen_size_x(s) - 1)
|
|
||||||
s->cx = screen_size_x(s) - 1;
|
|
||||||
s->cy = wp->saved_cy;
|
|
||||||
if (s->cy > screen_size_y(s) - 1)
|
|
||||||
s->cy = screen_size_y(s) - 1;
|
|
||||||
memcpy(gc, &wp->saved_cell, sizeof *gc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wp->saved_grid == NULL)
|
|
||||||
return;
|
|
||||||
sx = screen_size_x(s);
|
|
||||||
sy = screen_size_y(s);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the current size is bigger, temporarily resize to the old size
|
|
||||||
* before copying back.
|
|
||||||
*/
|
|
||||||
if (sy > wp->saved_grid->sy)
|
|
||||||
screen_resize(s, sx, wp->saved_grid->sy, 1);
|
|
||||||
|
|
||||||
/* Restore the saved grid. */
|
|
||||||
grid_duplicate_lines(s->grid, screen_hsize(s), wp->saved_grid, 0, sy);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Turn history back on (so resize can use it) and then resize back to
|
|
||||||
* the current size.
|
|
||||||
*/
|
|
||||||
wp->base.grid->flags |= GRID_HISTORY;
|
|
||||||
if (sy > wp->saved_grid->sy || sx != wp->saved_grid->sx)
|
|
||||||
screen_resize(s, sx, sy, 1);
|
|
||||||
|
|
||||||
grid_destroy(wp->saved_grid);
|
|
||||||
wp->saved_grid = NULL;
|
|
||||||
|
|
||||||
wp->flags |= PANE_REDRAW;
|
wp->flags |= PANE_REDRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user