mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
Store and restore cursor position when copy mode is resized, from Anindya
Mukherjee.
This commit is contained in:
parent
1f6c00f8ef
commit
e810f15272
2
grid.c
2
grid.c
@ -1285,7 +1285,7 @@ grid_reflow(struct grid *gd, u_int sx)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If the line is exactly right or the first character is wider
|
* If the line is exactly right or the first character is wider
|
||||||
* than the targe width, just move it across unchanged.
|
* than the target width, just move it across unchanged.
|
||||||
*/
|
*/
|
||||||
if (width == sx || first > sx) {
|
if (width == sx || first > sx) {
|
||||||
grid_reflow_move(target, gl);
|
grid_reflow_move(target, gl);
|
||||||
|
52
screen.c
52
screen.c
@ -48,7 +48,7 @@ struct screen_title_entry {
|
|||||||
TAILQ_HEAD(screen_titles, screen_title_entry);
|
TAILQ_HEAD(screen_titles, screen_title_entry);
|
||||||
|
|
||||||
static void screen_resize_y(struct screen *, u_int, int, u_int *);
|
static void screen_resize_y(struct screen *, u_int, int, u_int *);
|
||||||
static void screen_reflow(struct screen *, u_int, u_int *, u_int *);
|
static void screen_reflow(struct screen *, u_int, u_int *, u_int *, int);
|
||||||
|
|
||||||
/* Free titles stack. */
|
/* Free titles stack. */
|
||||||
static void
|
static void
|
||||||
@ -219,27 +219,19 @@ screen_pop_title(struct screen *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize screen and return cursor position. */
|
/* Resize screen with options. */
|
||||||
void
|
void
|
||||||
screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
|
screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
|
||||||
int eat_empty, u_int *cx, u_int *cy)
|
int eat_empty, int cursor)
|
||||||
{
|
{
|
||||||
u_int tcx, tcy;
|
u_int cx = s->cx, cy = s->grid->hsize + s->cy;
|
||||||
|
|
||||||
if (s->write_list != NULL)
|
if (s->write_list != NULL)
|
||||||
screen_write_free_list(s);
|
screen_write_free_list(s);
|
||||||
|
|
||||||
if (cx == NULL)
|
|
||||||
cx = &tcx;
|
|
||||||
*cx = s->cx;
|
|
||||||
|
|
||||||
if (cy == NULL)
|
|
||||||
cy = т
|
|
||||||
*cy = s->grid->hsize + s->cy;
|
|
||||||
|
|
||||||
log_debug("%s: new size %ux%u, now %ux%u (cursor %u,%u = %u,%u)",
|
log_debug("%s: new size %ux%u, now %ux%u (cursor %u,%u = %u,%u)",
|
||||||
__func__, sx, sy, screen_size_x(s), screen_size_y(s), s->cx, s->cy,
|
__func__, sx, sy, screen_size_x(s), screen_size_y(s), s->cx, s->cy,
|
||||||
*cx, *cy);
|
cx, cy);
|
||||||
|
|
||||||
if (sx < 1)
|
if (sx < 1)
|
||||||
sx = 1;
|
sx = 1;
|
||||||
@ -253,20 +245,21 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
|
|||||||
reflow = 0;
|
reflow = 0;
|
||||||
|
|
||||||
if (sy != screen_size_y(s))
|
if (sy != screen_size_y(s))
|
||||||
screen_resize_y(s, sy, eat_empty, cy);
|
screen_resize_y(s, sy, eat_empty, &cy);
|
||||||
|
|
||||||
if (reflow)
|
if (reflow)
|
||||||
screen_reflow(s, sx, cx, cy);
|
screen_reflow(s, sx, &cx, &cy, cursor);
|
||||||
|
|
||||||
if (*cy >= s->grid->hsize) {
|
if (cy >= s->grid->hsize) {
|
||||||
s->cx = *cx;
|
s->cx = cx;
|
||||||
s->cy = (*cy) - s->grid->hsize;
|
s->cy = cy - s->grid->hsize;
|
||||||
} else {
|
} else {
|
||||||
s->cx = 0;
|
s->cx = 0;
|
||||||
s->cy = 0;
|
s->cy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("%s: cursor finished at %u,%u = %u,%u", __func__, s->cx,
|
log_debug("%s: cursor finished at %u,%u = %u,%u", __func__, s->cx,
|
||||||
s->cy, *cx, *cy);
|
s->cy, cx, cy);
|
||||||
|
|
||||||
if (s->write_list != NULL)
|
if (s->write_list != NULL)
|
||||||
screen_write_make_list(s);
|
screen_write_make_list(s);
|
||||||
@ -276,7 +269,7 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
|
|||||||
void
|
void
|
||||||
screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
|
screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
|
||||||
{
|
{
|
||||||
screen_resize_cursor(s, sx, sy, reflow, 1, NULL, NULL);
|
screen_resize_cursor(s, sx, sy, reflow, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -524,17 +517,26 @@ screen_select_cell(struct screen *s, struct grid_cell *dst,
|
|||||||
|
|
||||||
/* Reflow wrapped lines. */
|
/* Reflow wrapped lines. */
|
||||||
static void
|
static void
|
||||||
screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy)
|
screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy, int cursor)
|
||||||
{
|
{
|
||||||
u_int wx, wy;
|
u_int wx, wy;
|
||||||
|
|
||||||
grid_wrap_position(s->grid, *cx, *cy, &wx, &wy);
|
if (cursor) {
|
||||||
log_debug("%s: cursor %u,%u is %u,%u", __func__, *cx, *cy, wx, wy);
|
grid_wrap_position(s->grid, *cx, *cy, &wx, &wy);
|
||||||
|
log_debug("%s: cursor %u,%u is %u,%u", __func__, *cx, *cy, wx,
|
||||||
|
wy);
|
||||||
|
}
|
||||||
|
|
||||||
grid_reflow(s->grid, new_x);
|
grid_reflow(s->grid, new_x);
|
||||||
|
|
||||||
grid_unwrap_position(s->grid, cx, cy, wx, wy);
|
if (cursor) {
|
||||||
log_debug("%s: new cursor is %u,%u", __func__, *cx,* cy);
|
grid_unwrap_position(s->grid, cx, cy, wx, wy);
|
||||||
|
log_debug("%s: new cursor is %u,%u", __func__, *cx, *cy);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*cx = 0;
|
||||||
|
*cy = s->grid->hsize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
3
tmux.h
3
tmux.h
@ -2527,8 +2527,7 @@ void screen_set_path(struct screen *, const char *);
|
|||||||
void screen_push_title(struct screen *);
|
void screen_push_title(struct screen *);
|
||||||
void screen_pop_title(struct screen *);
|
void screen_pop_title(struct screen *);
|
||||||
void screen_resize(struct screen *, u_int, u_int, int);
|
void screen_resize(struct screen *, u_int, u_int, int);
|
||||||
void screen_resize_cursor(struct screen *, u_int, u_int, int, int, u_int *,
|
void screen_resize_cursor(struct screen *, u_int, u_int, int, int, int);
|
||||||
u_int *);
|
|
||||||
void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
|
void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int,
|
||||||
u_int, int, struct grid_cell *);
|
u_int, int, struct grid_cell *);
|
||||||
void screen_clear_selection(struct screen *);
|
void screen_clear_selection(struct screen *);
|
||||||
|
@ -306,8 +306,9 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
|
|||||||
u_int *cy, int trim)
|
u_int *cy, int trim)
|
||||||
{
|
{
|
||||||
struct screen *dst;
|
struct screen *dst;
|
||||||
u_int sy;
|
|
||||||
const struct grid_line *gl;
|
const struct grid_line *gl;
|
||||||
|
u_int sy, wx, wy;
|
||||||
|
int reflow;
|
||||||
|
|
||||||
dst = xcalloc(1, sizeof *dst);
|
dst = xcalloc(1, sizeof *dst);
|
||||||
|
|
||||||
@ -324,6 +325,12 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
|
|||||||
screen_size_x(src), sy, screen_size_x(hint),
|
screen_size_x(src), sy, screen_size_x(hint),
|
||||||
screen_hsize(src) + screen_size_y(src));
|
screen_hsize(src) + screen_size_y(src));
|
||||||
screen_init(dst, screen_size_x(src), sy, screen_hlimit(src));
|
screen_init(dst, screen_size_x(src), sy, screen_hlimit(src));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure history is on for the backing grid so lines are not deleted
|
||||||
|
* during resizing.
|
||||||
|
*/
|
||||||
|
dst->grid->flags |= GRID_HISTORY;
|
||||||
grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy);
|
grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy);
|
||||||
|
|
||||||
dst->grid->sy = sy - screen_hsize(src);
|
dst->grid->sy = sy - screen_hsize(src);
|
||||||
@ -337,8 +344,19 @@ window_copy_clone_screen(struct screen *src, struct screen *hint, u_int *cx,
|
|||||||
dst->cy = src->cy;
|
dst->cy = src->cy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cx != NULL && cy != NULL) {
|
||||||
|
*cx = dst->cx;
|
||||||
|
*cy = screen_hsize(dst) + dst->cy;
|
||||||
|
reflow = (screen_size_x(hint) != screen_size_x(dst));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
reflow = 0;
|
||||||
|
if (reflow)
|
||||||
|
grid_wrap_position(dst->grid, *cx, *cy, &wx, &wy);
|
||||||
screen_resize_cursor(dst, screen_size_x(hint), screen_size_y(hint), 1,
|
screen_resize_cursor(dst, screen_size_x(hint), screen_size_y(hint), 1,
|
||||||
0, cx, cy);
|
0, 0);
|
||||||
|
if (reflow)
|
||||||
|
grid_unwrap_position(dst->grid, cx, cy, wx, wy);
|
||||||
|
|
||||||
return (dst);
|
return (dst);
|
||||||
}
|
}
|
||||||
@ -392,13 +410,12 @@ window_copy_init(struct window_mode_entry *wme,
|
|||||||
data->backing = window_copy_clone_screen(base, &data->screen, &cx, &cy,
|
data->backing = window_copy_clone_screen(base, &data->screen, &cx, &cy,
|
||||||
wme->swp != wme->wp);
|
wme->swp != wme->wp);
|
||||||
|
|
||||||
|
data->cx = cx;
|
||||||
if (cy < screen_hsize(data->backing)) {
|
if (cy < screen_hsize(data->backing)) {
|
||||||
data->cx = cx;
|
|
||||||
data->cy = 0;
|
data->cy = 0;
|
||||||
data->oy = screen_hsize(data->backing) - cy;
|
data->oy = screen_hsize(data->backing) - cy;
|
||||||
} else {
|
} else {
|
||||||
data->cx = data->backing->cx;
|
data->cy = cy - screen_hsize(data->backing);
|
||||||
data->cy = data->backing->cy;
|
|
||||||
data->oy = 0;
|
data->oy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,16 +748,28 @@ window_copy_resize(struct window_mode_entry *wme, u_int sx, u_int sy)
|
|||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
struct screen *s = &data->screen;
|
struct screen *s = &data->screen;
|
||||||
|
struct grid *gd = data->backing->grid;
|
||||||
|
u_int cx, cy, wx, wy;
|
||||||
|
int reflow;
|
||||||
|
|
||||||
screen_resize(s, sx, sy, 0);
|
screen_resize(s, sx, sy, 0);
|
||||||
screen_resize_cursor(data->backing, sx, sy, 1, 0, NULL, NULL);
|
cx = data->cx;
|
||||||
|
cy = gd->hsize + data->cy - data->oy;
|
||||||
|
reflow = (gd->sx != sx);
|
||||||
|
if (reflow)
|
||||||
|
grid_wrap_position(gd, cx, cy, &wx, &wy);
|
||||||
|
screen_resize_cursor(data->backing, sx, sy, 1, 0, 0);
|
||||||
|
if (reflow)
|
||||||
|
grid_unwrap_position(gd, &cx, &cy, wx, wy);
|
||||||
|
|
||||||
if (data->cy > sy - 1)
|
data->cx = cx;
|
||||||
data->cy = sy - 1;
|
if (cy < gd->hsize) {
|
||||||
if (data->cx > sx)
|
data->cy = 0;
|
||||||
data->cx = sx;
|
data->oy = gd->hsize - cy;
|
||||||
if (data->oy > screen_hsize(data->backing))
|
} else {
|
||||||
data->oy = screen_hsize(data->backing);
|
data->cy = cy - gd->hsize;
|
||||||
|
data->oy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
window_copy_size_changed(wme);
|
window_copy_size_changed(wme);
|
||||||
window_copy_redraw_screen(wme);
|
window_copy_redraw_screen(wme);
|
||||||
|
Loading…
Reference in New Issue
Block a user