2009-06-01 22:58:49 +00:00
|
|
|
/* $OpenBSD$ */
|
|
|
|
|
|
|
|
/*
|
2016-01-19 15:59:12 +00:00
|
|
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
2009-06-01 22:58:49 +00:00
|
|
|
*
|
|
|
|
* 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>
|
|
|
|
|
2012-07-10 11:53:01 +00:00
|
|
|
#include <stdlib.h>
|
2009-06-01 22:58:49 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "tmux.h"
|
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
static struct screen_write_citem *screen_write_collect_trim(
|
|
|
|
struct screen_write_ctx *, u_int, u_int, u_int, int *);
|
2017-02-08 16:45:18 +00:00
|
|
|
static void screen_write_collect_clear(struct screen_write_ctx *, u_int,
|
|
|
|
u_int);
|
2021-01-29 09:48:43 +00:00
|
|
|
static void screen_write_collect_scroll(struct screen_write_ctx *, u_int);
|
2020-04-16 17:24:28 +00:00
|
|
|
static void screen_write_collect_flush(struct screen_write_ctx *, int,
|
|
|
|
const char *);
|
2016-05-30 09:32:24 +00:00
|
|
|
static int screen_write_overwrite(struct screen_write_ctx *,
|
|
|
|
struct grid_cell *, u_int);
|
2023-09-15 15:49:05 +00:00
|
|
|
static int screen_write_combine(struct screen_write_ctx *,
|
|
|
|
const struct grid_cell *);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen_write_citem {
|
|
|
|
u_int x;
|
|
|
|
int wrapped;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
enum { TEXT, CLEAR } type;
|
|
|
|
u_int used;
|
|
|
|
u_int bg;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
struct grid_cell gc;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
TAILQ_ENTRY(screen_write_citem) entry;
|
2017-02-08 16:45:18 +00:00
|
|
|
};
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen_write_cline {
|
|
|
|
char *data;
|
|
|
|
TAILQ_HEAD(, screen_write_citem) items;
|
2017-02-08 16:45:18 +00:00
|
|
|
};
|
2021-01-29 09:48:43 +00:00
|
|
|
TAILQ_HEAD(, screen_write_citem) screen_write_citem_freelist =
|
|
|
|
TAILQ_HEAD_INITIALIZER(screen_write_citem_freelist);
|
|
|
|
|
|
|
|
static struct screen_write_citem *
|
|
|
|
screen_write_get_citem(void)
|
|
|
|
{
|
|
|
|
struct screen_write_citem *ci;
|
|
|
|
|
|
|
|
ci = TAILQ_FIRST(&screen_write_citem_freelist);
|
|
|
|
if (ci != NULL) {
|
|
|
|
TAILQ_REMOVE(&screen_write_citem_freelist, ci, entry);
|
|
|
|
memset(ci, 0, sizeof *ci);
|
|
|
|
return (ci);
|
|
|
|
}
|
|
|
|
return (xcalloc(1, sizeof *ci));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
screen_write_free_citem(struct screen_write_citem *ci)
|
|
|
|
{
|
|
|
|
TAILQ_INSERT_TAIL(&screen_write_citem_freelist, ci, entry);
|
|
|
|
}
|
2016-07-15 00:49:08 +00:00
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
static void
|
|
|
|
screen_write_offset_timer(__unused int fd, __unused short events, void *data)
|
|
|
|
{
|
|
|
|
struct window *w = data;
|
|
|
|
|
|
|
|
tty_update_window_offset(w);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set cursor position. */
|
|
|
|
static void
|
|
|
|
screen_write_set_cursor(struct screen_write_ctx *ctx, int cx, int cy)
|
|
|
|
{
|
|
|
|
struct window_pane *wp = ctx->wp;
|
|
|
|
struct window *w;
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct timeval tv = { .tv_usec = 10000 };
|
|
|
|
|
|
|
|
if (cx != -1 && (u_int)cx == s->cx && cy != -1 && (u_int)cy == s->cy)
|
|
|
|
return;
|
|
|
|
|
2019-03-12 07:39:27 +00:00
|
|
|
if (cx != -1) {
|
2019-03-12 13:14:14 +00:00
|
|
|
if ((u_int)cx > screen_size_x(s)) /* allow last column */
|
2019-03-12 07:39:27 +00:00
|
|
|
cx = screen_size_x(s) - 1;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
s->cx = cx;
|
2019-03-12 07:39:27 +00:00
|
|
|
}
|
|
|
|
if (cy != -1) {
|
|
|
|
if ((u_int)cy > screen_size_y(s) - 1)
|
|
|
|
cy = screen_size_y(s) - 1;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
s->cy = cy;
|
2019-03-12 07:39:27 +00:00
|
|
|
}
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
|
|
|
|
if (wp == NULL)
|
|
|
|
return;
|
|
|
|
w = wp->window;
|
|
|
|
|
|
|
|
if (!event_initialized(&w->offset_timer))
|
|
|
|
evtimer_set(&w->offset_timer, screen_write_offset_timer, w);
|
|
|
|
if (!evtimer_pending(&w->offset_timer, NULL))
|
|
|
|
evtimer_add(&w->offset_timer, &tv);
|
|
|
|
}
|
|
|
|
|
2020-05-16 15:34:08 +00:00
|
|
|
/* Do a full redraw. */
|
|
|
|
static void
|
|
|
|
screen_write_redraw_cb(const struct tty_ctx *ttyctx)
|
|
|
|
{
|
|
|
|
struct window_pane *wp = ttyctx->arg;
|
|
|
|
|
2020-06-18 08:41:56 +00:00
|
|
|
if (wp != NULL)
|
|
|
|
wp->flags |= PANE_REDRAW;
|
2020-05-16 15:34:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Update context for client. */
|
|
|
|
static int
|
|
|
|
screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
|
|
|
{
|
|
|
|
struct window_pane *wp = ttyctx->arg;
|
|
|
|
|
2023-03-27 08:31:32 +00:00
|
|
|
if (ttyctx->allow_invisible_panes) {
|
|
|
|
if (session_has(c->session, wp->window))
|
|
|
|
return (1);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2020-05-16 15:34:08 +00:00
|
|
|
if (c->session->curw->window != wp->window)
|
|
|
|
return (0);
|
|
|
|
if (wp->layout_cell == NULL)
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
if (wp->flags & (PANE_REDRAW|PANE_DROP))
|
|
|
|
return (-1);
|
|
|
|
if (c->flags & CLIENT_REDRAWPANES) {
|
|
|
|
/*
|
|
|
|
* Redraw is already deferred to redraw another pane - redraw
|
|
|
|
* this one also when that happens.
|
|
|
|
*/
|
2021-01-29 09:48:43 +00:00
|
|
|
log_debug("%s: adding %%%u to deferred redraw", __func__,
|
|
|
|
wp->id);
|
2020-05-16 15:34:08 +00:00
|
|
|
wp->flags |= PANE_REDRAW;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
ttyctx->bigger = tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy,
|
|
|
|
&ttyctx->wsx, &ttyctx->wsy);
|
|
|
|
|
|
|
|
ttyctx->xoff = ttyctx->rxoff = wp->xoff;
|
|
|
|
ttyctx->yoff = ttyctx->ryoff = wp->yoff;
|
|
|
|
|
|
|
|
if (status_at_line(c) == 0)
|
|
|
|
ttyctx->yoff += status_line_size(c);
|
|
|
|
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
/* Set up context for TTY command. */
|
|
|
|
static void
|
|
|
|
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
|
|
|
|
int sync)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
|
|
|
|
memset(ttyctx, 0, sizeof *ttyctx);
|
|
|
|
|
2020-05-16 15:34:08 +00:00
|
|
|
ttyctx->s = s;
|
2020-05-16 15:27:08 +00:00
|
|
|
ttyctx->sx = screen_size_x(s);
|
|
|
|
ttyctx->sy = screen_size_y(s);
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
ttyctx->ocx = s->cx;
|
|
|
|
ttyctx->ocy = s->cy;
|
|
|
|
ttyctx->orlower = s->rlower;
|
|
|
|
ttyctx->orupper = s->rupper;
|
|
|
|
|
2021-08-11 20:49:55 +00:00
|
|
|
memcpy(&ttyctx->defaults, &grid_default_cell, sizeof ttyctx->defaults);
|
|
|
|
if (ctx->init_ctx_cb != NULL) {
|
2020-05-16 15:34:08 +00:00
|
|
|
ctx->init_ctx_cb(ctx, ttyctx);
|
2021-08-11 20:49:55 +00:00
|
|
|
if (ttyctx->palette != NULL) {
|
2021-10-25 09:38:36 +00:00
|
|
|
if (ttyctx->defaults.fg == 8)
|
2021-10-25 09:22:17 +00:00
|
|
|
ttyctx->defaults.fg = ttyctx->palette->fg;
|
2021-10-25 09:38:36 +00:00
|
|
|
if (ttyctx->defaults.bg == 8)
|
2021-10-25 09:22:17 +00:00
|
|
|
ttyctx->defaults.bg = ttyctx->palette->bg;
|
2021-08-11 20:49:55 +00:00
|
|
|
}
|
|
|
|
} else {
|
2020-05-16 15:34:08 +00:00
|
|
|
ttyctx->redraw_cb = screen_write_redraw_cb;
|
2021-08-11 20:49:55 +00:00
|
|
|
if (ctx->wp != NULL) {
|
|
|
|
tty_default_colours(&ttyctx->defaults, ctx->wp);
|
|
|
|
ttyctx->palette = &ctx->wp->palette;
|
2020-05-16 15:34:08 +00:00
|
|
|
ttyctx->set_client_cb = screen_write_set_client_cb;
|
2021-08-11 20:49:55 +00:00
|
|
|
ttyctx->arg = ctx->wp;
|
|
|
|
}
|
2020-05-16 15:34:08 +00:00
|
|
|
}
|
|
|
|
|
2021-08-17 08:44:52 +00:00
|
|
|
if (~ctx->flags & SCREEN_WRITE_SYNC) {
|
|
|
|
/*
|
|
|
|
* For the active pane or for an overlay (no pane), we want to
|
|
|
|
* only use synchronized updates if requested (commands that
|
|
|
|
* move the cursor); for other panes, always use it, since the
|
|
|
|
* cursor will have to move.
|
|
|
|
*/
|
|
|
|
if (ctx->wp != NULL) {
|
|
|
|
if (ctx->wp != ctx->wp->window->active)
|
|
|
|
ttyctx->num = 1;
|
|
|
|
else
|
|
|
|
ttyctx->num = sync;
|
|
|
|
} else
|
|
|
|
ttyctx->num = 0x10|sync;
|
2020-04-16 16:13:56 +00:00
|
|
|
tty_write(tty_cmd_syncstart, ttyctx);
|
2020-05-16 16:22:01 +00:00
|
|
|
ctx->flags |= SCREEN_WRITE_SYNC;
|
2020-04-16 16:13:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-18 15:12:28 +00:00
|
|
|
/* Make write list. */
|
|
|
|
void
|
|
|
|
screen_write_make_list(struct screen *s)
|
|
|
|
{
|
|
|
|
u_int y;
|
|
|
|
|
|
|
|
s->write_list = xcalloc(screen_size_y(s), sizeof *s->write_list);
|
|
|
|
for (y = 0; y < screen_size_y(s); y++)
|
|
|
|
TAILQ_INIT(&s->write_list[y].items);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free write list. */
|
|
|
|
void
|
|
|
|
screen_write_free_list(struct screen *s)
|
|
|
|
{
|
|
|
|
u_int y;
|
|
|
|
|
|
|
|
for (y = 0; y < screen_size_y(s); y++)
|
|
|
|
free(s->write_list[y].data);
|
|
|
|
free(s->write_list);
|
|
|
|
}
|
|
|
|
|
2020-05-16 15:34:08 +00:00
|
|
|
/* Set up for writing. */
|
|
|
|
static void
|
|
|
|
screen_write_init(struct screen_write_ctx *ctx, struct screen *s)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
2017-02-08 16:45:18 +00:00
|
|
|
memset(ctx, 0, sizeof *ctx);
|
2016-07-15 00:49:08 +00:00
|
|
|
|
2020-05-16 15:34:08 +00:00
|
|
|
ctx->s = s;
|
2016-07-15 00:49:08 +00:00
|
|
|
|
2020-04-18 15:12:28 +00:00
|
|
|
if (ctx->s->write_list == NULL)
|
|
|
|
screen_write_make_list(ctx->s);
|
2021-01-29 09:48:43 +00:00
|
|
|
ctx->item = screen_write_get_citem();
|
2016-07-15 00:49:08 +00:00
|
|
|
|
2017-05-12 13:00:56 +00:00
|
|
|
ctx->scrolled = 0;
|
|
|
|
ctx->bg = 8;
|
2020-05-16 15:34:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize writing with a pane. */
|
|
|
|
void
|
|
|
|
screen_write_start_pane(struct screen_write_ctx *ctx, struct window_pane *wp,
|
|
|
|
struct screen *s)
|
|
|
|
{
|
|
|
|
if (s == NULL)
|
|
|
|
s = wp->screen;
|
|
|
|
screen_write_init(ctx, s);
|
|
|
|
ctx->wp = wp;
|
2017-05-12 13:00:56 +00:00
|
|
|
|
2019-09-24 15:52:14 +00:00
|
|
|
if (log_get_level() != 0) {
|
2020-05-16 15:34:08 +00:00
|
|
|
log_debug("%s: size %ux%u, pane %%%u (at %u,%u)",
|
|
|
|
__func__, screen_size_x(ctx->s), screen_size_y(ctx->s),
|
|
|
|
wp->id, wp->xoff, wp->yoff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize writing with a callback. */
|
|
|
|
void
|
|
|
|
screen_write_start_callback(struct screen_write_ctx *ctx, struct screen *s,
|
|
|
|
screen_write_init_ctx_cb cb, void *arg)
|
|
|
|
{
|
|
|
|
screen_write_init(ctx, s);
|
|
|
|
|
|
|
|
ctx->init_ctx_cb = cb;
|
|
|
|
ctx->arg = arg;
|
|
|
|
|
|
|
|
if (log_get_level() != 0) {
|
|
|
|
log_debug("%s: size %ux%u, with callback", __func__,
|
|
|
|
screen_size_x(ctx->s), screen_size_y(ctx->s));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize writing. */
|
|
|
|
void
|
|
|
|
screen_write_start(struct screen_write_ctx *ctx, struct screen *s)
|
|
|
|
{
|
|
|
|
screen_write_init(ctx, s);
|
|
|
|
|
|
|
|
if (log_get_level() != 0) {
|
|
|
|
log_debug("%s: size %ux%u, no pane", __func__,
|
|
|
|
screen_size_x(ctx->s), screen_size_y(ctx->s));
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Finish writing. */
|
|
|
|
void
|
2016-07-15 00:49:08 +00:00
|
|
|
screen_write_stop(struct screen_write_ctx *ctx)
|
|
|
|
{
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_collect_end(ctx);
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2016-07-15 00:49:08 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
screen_write_free_citem(ctx->item);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2012-01-21 08:10:21 +00:00
|
|
|
/* Reset screen state. */
|
|
|
|
void
|
|
|
|
screen_write_reset(struct screen_write_ctx *ctx)
|
|
|
|
{
|
2013-03-21 18:47:56 +00:00
|
|
|
struct screen *s = ctx->s;
|
2012-01-21 08:10:21 +00:00
|
|
|
|
2013-03-21 18:47:56 +00:00
|
|
|
screen_reset_tabs(s);
|
|
|
|
screen_write_scrollregion(ctx, 0, screen_size_y(s) - 1);
|
2013-03-22 10:33:50 +00:00
|
|
|
|
2023-07-14 19:32:59 +00:00
|
|
|
s->mode = MODE_CURSOR|MODE_WRAP;
|
|
|
|
if (options_get_number(global_options, "extended-keys") == 2)
|
|
|
|
s->mode |= MODE_KEXTENDED;
|
2012-01-21 08:10:21 +00:00
|
|
|
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_clearscreen(ctx, 8);
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, 0, 0);
|
2012-01-21 08:10:21 +00:00
|
|
|
}
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Write character. */
|
|
|
|
void
|
2016-04-29 13:21:33 +00:00
|
|
|
screen_write_putc(struct screen_write_ctx *ctx, const struct grid_cell *gcp,
|
2014-04-17 14:45:49 +00:00
|
|
|
u_char ch)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
2016-04-29 13:21:33 +00:00
|
|
|
struct grid_cell gc;
|
|
|
|
|
|
|
|
memcpy(&gc, gcp, sizeof gc);
|
|
|
|
|
|
|
|
utf8_set(&gc.data, ch);
|
|
|
|
screen_write_cell(ctx, &gc);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2009-06-03 16:05:46 +00:00
|
|
|
/* Calculate string length. */
|
2014-10-20 23:57:13 +00:00
|
|
|
size_t
|
2015-11-12 11:09:11 +00:00
|
|
|
screen_write_strlen(const char *fmt, ...)
|
2009-06-03 16:05:46 +00:00
|
|
|
{
|
2009-10-20 19:18:28 +00:00
|
|
|
va_list ap;
|
|
|
|
char *msg;
|
2015-11-12 22:04:37 +00:00
|
|
|
struct utf8_data ud;
|
2009-10-20 19:18:28 +00:00
|
|
|
u_char *ptr;
|
|
|
|
size_t left, size = 0;
|
2015-11-14 11:45:43 +00:00
|
|
|
enum utf8_state more;
|
2009-06-03 16:05:46 +00:00
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
xvasprintf(&msg, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
ptr = msg;
|
|
|
|
while (*ptr != '\0') {
|
2015-11-14 11:45:43 +00:00
|
|
|
if (*ptr > 0x7f && utf8_open(&ud, *ptr) == UTF8_MORE) {
|
2009-10-20 19:18:28 +00:00
|
|
|
ptr++;
|
2009-06-03 16:05:46 +00:00
|
|
|
|
|
|
|
left = strlen(ptr);
|
2015-11-13 08:09:28 +00:00
|
|
|
if (left < (size_t)ud.size - 1)
|
2009-10-20 19:18:28 +00:00
|
|
|
break;
|
2015-11-14 11:45:43 +00:00
|
|
|
while ((more = utf8_append(&ud, *ptr)) == UTF8_MORE)
|
2009-06-03 16:05:46 +00:00
|
|
|
ptr++;
|
2009-10-20 19:18:28 +00:00
|
|
|
ptr++;
|
|
|
|
|
2015-11-14 11:45:43 +00:00
|
|
|
if (more == UTF8_DONE)
|
2015-11-14 10:56:31 +00:00
|
|
|
size += ud.width;
|
2009-06-03 16:05:46 +00:00
|
|
|
} else {
|
2015-11-12 11:09:11 +00:00
|
|
|
if (*ptr > 0x1f && *ptr < 0x7f)
|
|
|
|
size++;
|
2009-06-03 16:05:46 +00:00
|
|
|
ptr++;
|
|
|
|
}
|
2009-06-05 03:13:16 +00:00
|
|
|
}
|
2009-06-03 16:05:46 +00:00
|
|
|
|
2012-07-10 11:53:01 +00:00
|
|
|
free(msg);
|
2009-06-03 16:05:46 +00:00
|
|
|
return (size);
|
|
|
|
}
|
|
|
|
|
2020-05-16 16:02:24 +00:00
|
|
|
/* Write string wrapped over lines. */
|
|
|
|
int
|
|
|
|
screen_write_text(struct screen_write_ctx *ctx, u_int cx, u_int width,
|
|
|
|
u_int lines, int more, const struct grid_cell *gcp, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
va_list ap;
|
|
|
|
char *tmp;
|
|
|
|
u_int cy = s->cy, i, end, next, idx = 0, at, left;
|
|
|
|
struct utf8_data *text;
|
|
|
|
struct grid_cell gc;
|
|
|
|
|
|
|
|
memcpy(&gc, gcp, sizeof gc);
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
xvasprintf(&tmp, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
text = utf8_fromcstr(tmp);
|
|
|
|
free(tmp);
|
|
|
|
|
|
|
|
left = (cx + width) - s->cx;
|
|
|
|
for (;;) {
|
|
|
|
/* Find the end of what can fit on the line. */
|
|
|
|
at = 0;
|
|
|
|
for (end = idx; text[end].size != 0; end++) {
|
|
|
|
if (text[end].size == 1 && text[end].data[0] == '\n')
|
|
|
|
break;
|
|
|
|
if (at + text[end].width > left)
|
|
|
|
break;
|
|
|
|
at += text[end].width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we're on a space, that's the end. If not, walk back to
|
|
|
|
* try and find one.
|
|
|
|
*/
|
|
|
|
if (text[end].size == 0)
|
|
|
|
next = end;
|
|
|
|
else if (text[end].size == 1 && text[end].data[0] == '\n')
|
|
|
|
next = end + 1;
|
|
|
|
else if (text[end].size == 1 && text[end].data[0] == ' ')
|
|
|
|
next = end + 1;
|
|
|
|
else {
|
|
|
|
for (i = end; i > idx; i--) {
|
|
|
|
if (text[i].size == 1 && text[i].data[0] == ' ')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i != idx) {
|
|
|
|
next = i + 1;
|
|
|
|
end = i;
|
|
|
|
} else
|
|
|
|
next = end;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print the line. */
|
|
|
|
for (i = idx; i < end; i++) {
|
|
|
|
utf8_copy(&gc.data, &text[i]);
|
|
|
|
screen_write_cell(ctx, &gc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If at the bottom, stop. */
|
|
|
|
idx = next;
|
|
|
|
if (s->cy == cy + lines - 1 || text[idx].size == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
screen_write_cursormove(ctx, cx, s->cy + 1, 0);
|
|
|
|
left = width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fail if on the last line and there is more to come or at the end, or
|
|
|
|
* if the text was not entirely consumed.
|
|
|
|
*/
|
|
|
|
if ((s->cy == cy + lines - 1 && (!more || s->cx == cx + width)) ||
|
|
|
|
text[idx].size != 0) {
|
|
|
|
free(text);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
free(text);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If no more to come, move to the next line. Otherwise, leave on
|
|
|
|
* the same line (except if at the end).
|
|
|
|
*/
|
|
|
|
if (!more || s->cx == cx + width)
|
|
|
|
screen_write_cursormove(ctx, cx, s->cy + 1, 0);
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write simple string (no maximum length). */
|
2014-10-20 23:57:13 +00:00
|
|
|
void
|
2016-04-29 13:21:33 +00:00
|
|
|
screen_write_puts(struct screen_write_ctx *ctx, const struct grid_cell *gcp,
|
2014-10-20 23:57:13 +00:00
|
|
|
const char *fmt, ...)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
2016-04-29 13:21:33 +00:00
|
|
|
screen_write_vnputs(ctx, -1, gcp, fmt, ap);
|
2009-06-01 22:58:49 +00:00
|
|
|
va_end(ap);
|
2009-06-03 16:05:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Write string with length limit (-1 for unlimited). */
|
2014-10-20 23:57:13 +00:00
|
|
|
void
|
|
|
|
screen_write_nputs(struct screen_write_ctx *ctx, ssize_t maxlen,
|
2016-04-29 13:21:33 +00:00
|
|
|
const struct grid_cell *gcp, const char *fmt, ...)
|
2009-06-03 16:05:46 +00:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
2016-04-29 13:21:33 +00:00
|
|
|
screen_write_vnputs(ctx, maxlen, gcp, fmt, ap);
|
2009-06-03 16:05:46 +00:00
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-06-03 16:54:26 +00:00
|
|
|
screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
|
2016-04-29 13:21:33 +00:00
|
|
|
const struct grid_cell *gcp, const char *fmt, va_list ap)
|
2009-06-03 16:05:46 +00:00
|
|
|
{
|
2016-04-29 13:21:33 +00:00
|
|
|
struct grid_cell gc;
|
|
|
|
struct utf8_data *ud = &gc.data;
|
2009-10-20 19:18:28 +00:00
|
|
|
char *msg;
|
|
|
|
u_char *ptr;
|
|
|
|
size_t left, size = 0;
|
2015-11-14 11:45:43 +00:00
|
|
|
enum utf8_state more;
|
2009-06-03 16:05:46 +00:00
|
|
|
|
2016-04-29 13:21:33 +00:00
|
|
|
memcpy(&gc, gcp, sizeof gc);
|
2009-06-03 16:05:46 +00:00
|
|
|
xvasprintf(&msg, fmt, ap);
|
|
|
|
|
|
|
|
ptr = msg;
|
|
|
|
while (*ptr != '\0') {
|
2016-04-29 13:21:33 +00:00
|
|
|
if (*ptr > 0x7f && utf8_open(ud, *ptr) == UTF8_MORE) {
|
2009-10-20 19:18:28 +00:00
|
|
|
ptr++;
|
2009-06-03 16:05:46 +00:00
|
|
|
|
|
|
|
left = strlen(ptr);
|
2016-04-29 13:21:33 +00:00
|
|
|
if (left < (size_t)ud->size - 1)
|
2009-10-20 19:18:28 +00:00
|
|
|
break;
|
2016-04-29 13:21:33 +00:00
|
|
|
while ((more = utf8_append(ud, *ptr)) == UTF8_MORE)
|
2009-06-03 16:05:46 +00:00
|
|
|
ptr++;
|
2009-10-20 19:18:28 +00:00
|
|
|
ptr++;
|
2009-06-05 03:13:16 +00:00
|
|
|
|
2016-04-29 13:21:33 +00:00
|
|
|
if (more != UTF8_DONE)
|
|
|
|
continue;
|
|
|
|
if (maxlen > 0 && size + ud->width > (size_t)maxlen) {
|
|
|
|
while (size < (size_t)maxlen) {
|
|
|
|
screen_write_putc(ctx, &gc, ' ');
|
|
|
|
size++;
|
2009-06-03 16:05:46 +00:00
|
|
|
}
|
2016-04-29 13:21:33 +00:00
|
|
|
break;
|
2015-11-14 10:56:31 +00:00
|
|
|
}
|
2016-04-29 13:21:33 +00:00
|
|
|
size += ud->width;
|
|
|
|
screen_write_cell(ctx, &gc);
|
2009-06-03 16:05:46 +00:00
|
|
|
} else {
|
2016-04-29 13:21:33 +00:00
|
|
|
if (maxlen > 0 && size + 1 > (size_t)maxlen)
|
2009-06-03 16:05:46 +00:00
|
|
|
break;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2012-09-24 12:53:55 +00:00
|
|
|
if (*ptr == '\001')
|
2016-04-29 13:21:33 +00:00
|
|
|
gc.attr ^= GRID_ATTR_CHARSET;
|
2020-07-21 05:24:33 +00:00
|
|
|
else if (*ptr == '\n') {
|
|
|
|
screen_write_linefeed(ctx, 0, 8);
|
|
|
|
screen_write_carriagereturn(ctx);
|
|
|
|
} else if (*ptr > 0x1f && *ptr < 0x7f) {
|
2012-09-24 12:53:55 +00:00
|
|
|
size++;
|
2016-04-29 13:21:33 +00:00
|
|
|
screen_write_putc(ctx, &gc, *ptr);
|
2012-09-24 12:53:55 +00:00
|
|
|
}
|
2009-06-03 16:05:46 +00:00
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2012-07-10 11:53:01 +00:00
|
|
|
free(msg);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2017-11-02 21:29:17 +00:00
|
|
|
/*
|
2020-05-16 15:11:52 +00:00
|
|
|
* Copy from another screen but without the selection stuff. Assumes the target
|
|
|
|
* region is already big enough.
|
2017-11-02 21:29:17 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
|
|
|
u_int px, u_int py, u_int nx, u_int ny)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid *gd = src->grid;
|
|
|
|
struct grid_cell gc;
|
|
|
|
u_int xx, yy, cx, cy;
|
|
|
|
|
|
|
|
if (nx == 0 || ny == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
cy = s->cy;
|
|
|
|
for (yy = py; yy < py + ny; yy++) {
|
2017-11-03 17:02:33 +00:00
|
|
|
if (yy >= gd->hsize + gd->sy)
|
|
|
|
break;
|
2017-11-02 21:29:17 +00:00
|
|
|
cx = s->cx;
|
|
|
|
for (xx = px; xx < px + nx; xx++) {
|
2018-07-04 09:44:07 +00:00
|
|
|
if (xx >= grid_get_line(gd, yy)->cellsize)
|
2017-11-02 21:29:17 +00:00
|
|
|
break;
|
|
|
|
grid_get_cell(gd, xx, yy, &gc);
|
2017-11-15 19:21:24 +00:00
|
|
|
if (xx + gc.data.width > px + nx)
|
|
|
|
break;
|
2019-04-03 06:43:04 +00:00
|
|
|
grid_view_set_cell(ctx->s->grid, cx, cy, &gc);
|
2017-11-02 21:29:17 +00:00
|
|
|
cx++;
|
|
|
|
}
|
|
|
|
cy++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-08 07:41:04 +00:00
|
|
|
/* Select character set for drawing border lines. */
|
|
|
|
static void
|
|
|
|
screen_write_box_border_set(enum box_lines lines, int cell_type,
|
|
|
|
struct grid_cell *gc)
|
|
|
|
{
|
|
|
|
switch (lines) {
|
|
|
|
case BOX_LINES_NONE:
|
|
|
|
break;
|
|
|
|
case BOX_LINES_DOUBLE:
|
|
|
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
|
|
|
utf8_copy(&gc->data, tty_acs_double_borders(cell_type));
|
|
|
|
break;
|
|
|
|
case BOX_LINES_HEAVY:
|
|
|
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
|
|
|
utf8_copy(&gc->data, tty_acs_heavy_borders(cell_type));
|
|
|
|
break;
|
|
|
|
case BOX_LINES_ROUNDED:
|
|
|
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
|
|
|
utf8_copy(&gc->data, tty_acs_rounded_borders(cell_type));
|
|
|
|
break;
|
|
|
|
case BOX_LINES_SIMPLE:
|
|
|
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
|
|
|
utf8_set(&gc->data, SIMPLE_BORDERS[cell_type]);
|
|
|
|
break;
|
|
|
|
case BOX_LINES_PADDED:
|
|
|
|
gc->attr &= ~GRID_ATTR_CHARSET;
|
|
|
|
utf8_set(&gc->data, PADDED_BORDERS[cell_type]);
|
|
|
|
break;
|
|
|
|
case BOX_LINES_SINGLE:
|
|
|
|
case BOX_LINES_DEFAULT:
|
|
|
|
gc->attr |= GRID_ATTR_CHARSET;
|
|
|
|
utf8_set(&gc->data, CELL_BORDERS[cell_type]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 22:24:08 +00:00
|
|
|
/* Draw a horizontal line on screen. */
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
void
|
2023-08-08 07:41:04 +00:00
|
|
|
screen_write_hline(struct screen_write_ctx *ctx, u_int nx, int left, int right,
|
|
|
|
enum box_lines lines, const struct grid_cell *border_gc)
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid_cell gc;
|
|
|
|
u_int cx, cy, i;
|
|
|
|
|
|
|
|
cx = s->cx;
|
|
|
|
cy = s->cy;
|
|
|
|
|
2023-08-08 07:41:04 +00:00
|
|
|
if (border_gc != NULL)
|
|
|
|
memcpy(&gc, border_gc, sizeof gc);
|
|
|
|
else
|
|
|
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
gc.attr |= GRID_ATTR_CHARSET;
|
|
|
|
|
2023-08-08 07:41:04 +00:00
|
|
|
if (left)
|
|
|
|
screen_write_box_border_set(lines, CELL_LEFTJOIN, &gc);
|
|
|
|
else
|
|
|
|
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
|
|
|
|
screen_write_cell(ctx, &gc);
|
|
|
|
|
|
|
|
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
for (i = 1; i < nx - 1; i++)
|
2023-08-08 07:41:04 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
|
|
|
|
|
|
|
if (right)
|
|
|
|
screen_write_box_border_set(lines, CELL_RIGHTJOIN, &gc);
|
|
|
|
else
|
|
|
|
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
|
|
|
|
screen_write_cell(ctx, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
}
|
|
|
|
|
2021-08-06 07:32:21 +00:00
|
|
|
/* Draw a vertical line on screen. */
|
2017-06-30 22:24:08 +00:00
|
|
|
void
|
2017-08-09 11:43:45 +00:00
|
|
|
screen_write_vline(struct screen_write_ctx *ctx, u_int ny, int top, int bottom)
|
2017-06-30 22:24:08 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid_cell gc;
|
|
|
|
u_int cx, cy, i;
|
|
|
|
|
|
|
|
cx = s->cx;
|
|
|
|
cy = s->cy;
|
|
|
|
|
|
|
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
|
|
|
gc.attr |= GRID_ATTR_CHARSET;
|
|
|
|
|
|
|
|
screen_write_putc(ctx, &gc, top ? 'w' : 'x');
|
|
|
|
for (i = 1; i < ny - 1; i++) {
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx, cy + i);
|
2017-06-30 22:24:08 +00:00
|
|
|
screen_write_putc(ctx, &gc, 'x');
|
|
|
|
}
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx, cy + ny - 1);
|
2017-06-30 22:24:08 +00:00
|
|
|
screen_write_putc(ctx, &gc, bottom ? 'v' : 'x');
|
|
|
|
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
2017-06-30 22:24:08 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 14:12:47 +00:00
|
|
|
/* Draw a menu on screen. */
|
|
|
|
void
|
2023-08-08 07:41:04 +00:00
|
|
|
screen_write_menu(struct screen_write_ctx *ctx, struct menu *menu, int choice,
|
|
|
|
enum box_lines lines, const struct grid_cell *menu_gc,
|
|
|
|
const struct grid_cell *border_gc, const struct grid_cell *choice_gc)
|
2019-05-10 14:12:47 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2020-04-15 16:11:23 +00:00
|
|
|
struct grid_cell default_gc;
|
|
|
|
const struct grid_cell *gc = &default_gc;
|
2023-08-08 07:41:04 +00:00
|
|
|
u_int cx, cy, i, j, width = menu->width;
|
2019-05-28 09:50:54 +00:00
|
|
|
const char *name;
|
2019-05-10 14:12:47 +00:00
|
|
|
|
|
|
|
cx = s->cx;
|
|
|
|
cy = s->cy;
|
|
|
|
|
2023-08-08 07:41:04 +00:00
|
|
|
memcpy(&default_gc, menu_gc, sizeof default_gc);
|
2019-05-10 14:12:47 +00:00
|
|
|
|
2023-08-08 07:41:04 +00:00
|
|
|
screen_write_box(ctx, menu->width + 4, menu->count + 2, lines,
|
|
|
|
border_gc, menu->title);
|
2019-05-10 14:12:47 +00:00
|
|
|
|
|
|
|
for (i = 0; i < menu->count; i++) {
|
2019-05-28 09:50:54 +00:00
|
|
|
name = menu->items[i].name;
|
|
|
|
if (name == NULL) {
|
2019-05-10 14:12:47 +00:00
|
|
|
screen_write_cursormove(ctx, cx, cy + 1 + i, 0);
|
2023-08-08 08:08:47 +00:00
|
|
|
screen_write_hline(ctx, width + 4, 1, 1, lines,
|
|
|
|
border_gc);
|
2023-08-08 07:41:04 +00:00
|
|
|
continue;
|
2019-05-10 14:12:47 +00:00
|
|
|
}
|
|
|
|
|
2023-08-08 07:41:04 +00:00
|
|
|
if (choice >= 0 && i == (u_int)choice && *name != '-')
|
|
|
|
gc = choice_gc;
|
2019-05-10 14:12:47 +00:00
|
|
|
|
2023-08-08 08:08:47 +00:00
|
|
|
screen_write_cursormove(ctx, cx + 1, cy + 1 + i, 0);
|
|
|
|
for (j = 0; j < width + 2; j++)
|
2023-08-08 07:41:04 +00:00
|
|
|
screen_write_putc(ctx, gc, ' ');
|
|
|
|
|
|
|
|
screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0);
|
|
|
|
if (*name == '-') {
|
|
|
|
default_gc.attr |= GRID_ATTR_DIM;
|
|
|
|
format_draw(ctx, gc, width, name + 1, NULL, 0);
|
|
|
|
default_gc.attr &= ~GRID_ATTR_DIM;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-08-15 07:01:47 +00:00
|
|
|
format_draw(ctx, gc, width, name, NULL, 0);
|
2023-08-08 07:41:04 +00:00
|
|
|
gc = &default_gc;
|
2021-10-14 13:19:01 +00:00
|
|
|
}
|
2023-08-08 07:41:04 +00:00
|
|
|
|
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
2021-10-14 13:19:01 +00:00
|
|
|
}
|
|
|
|
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
/* Draw a box on screen. */
|
|
|
|
void
|
2021-10-13 09:28:36 +00:00
|
|
|
screen_write_box(struct screen_write_ctx *ctx, u_int nx, u_int ny,
|
2021-10-20 09:50:40 +00:00
|
|
|
enum box_lines lines, const struct grid_cell *gcp, const char *title)
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2021-10-13 09:28:36 +00:00
|
|
|
struct grid_cell gc;
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
u_int cx, cy, i;
|
|
|
|
|
|
|
|
cx = s->cx;
|
|
|
|
cy = s->cy;
|
|
|
|
|
2021-10-13 09:28:36 +00:00
|
|
|
if (gcp != NULL)
|
|
|
|
memcpy(&gc, gcp, sizeof gc);
|
|
|
|
else
|
|
|
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
2021-10-20 09:50:40 +00:00
|
|
|
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
gc.attr |= GRID_ATTR_CHARSET;
|
2021-08-11 20:49:55 +00:00
|
|
|
gc.flags |= GRID_FLAG_NOPALETTE;
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
|
2021-10-14 13:19:01 +00:00
|
|
|
/* Draw top border */
|
2021-10-20 09:50:40 +00:00
|
|
|
screen_write_box_border_set(lines, CELL_TOPLEFT, &gc);
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
2021-10-20 09:50:40 +00:00
|
|
|
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
for (i = 1; i < nx - 1; i++)
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
2021-10-20 09:50:40 +00:00
|
|
|
screen_write_box_border_set(lines, CELL_TOPRIGHT, &gc);
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
|
2021-10-14 13:19:01 +00:00
|
|
|
/* Draw bottom border */
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx, cy + ny - 1);
|
2021-10-20 09:50:40 +00:00
|
|
|
screen_write_box_border_set(lines, CELL_BOTTOMLEFT, &gc);
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
2021-10-20 09:50:40 +00:00
|
|
|
screen_write_box_border_set(lines, CELL_LEFTRIGHT, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
for (i = 1; i < nx - 1; i++)
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
2021-10-20 09:50:40 +00:00
|
|
|
screen_write_box_border_set(lines, CELL_BOTTOMRIGHT, &gc);
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
|
2021-10-14 13:19:01 +00:00
|
|
|
/* Draw sides */
|
2021-10-20 09:50:40 +00:00
|
|
|
screen_write_box_border_set(lines, CELL_TOPBOTTOM, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
for (i = 1; i < ny - 1; i++) {
|
2021-10-14 13:19:01 +00:00
|
|
|
/* left side */
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx, cy + i);
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
|
|
|
/* right side */
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx + nx - 1, cy + i);
|
2021-10-14 13:19:01 +00:00
|
|
|
screen_write_cell(ctx, &gc);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
}
|
|
|
|
|
2021-10-20 09:50:40 +00:00
|
|
|
if (title != NULL) {
|
|
|
|
gc.attr &= ~GRID_ATTR_CHARSET;
|
|
|
|
screen_write_cursormove(ctx, cx + 2, cy, 0);
|
2021-10-26 12:22:23 +00:00
|
|
|
format_draw(ctx, &gc, nx - 4, title, NULL, 0);
|
2021-10-20 09:50:40 +00:00
|
|
|
}
|
|
|
|
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
}
|
|
|
|
|
2017-11-02 21:29:17 +00:00
|
|
|
/*
|
|
|
|
* Write a preview version of a window. Assumes target area is big enough and
|
|
|
|
* already cleared.
|
|
|
|
*/
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
void
|
|
|
|
screen_write_preview(struct screen_write_ctx *ctx, struct screen *src, u_int nx,
|
|
|
|
u_int ny)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid_cell gc;
|
|
|
|
u_int cx, cy, px, py;
|
|
|
|
|
|
|
|
cx = s->cx;
|
|
|
|
cy = s->cy;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the cursor is on, pick the area around the cursor, otherwise use
|
|
|
|
* the top left.
|
|
|
|
*/
|
|
|
|
if (src->mode & MODE_CURSOR) {
|
|
|
|
px = src->cx;
|
|
|
|
if (px < nx / 3)
|
|
|
|
px = 0;
|
|
|
|
else
|
|
|
|
px = px - nx / 3;
|
|
|
|
if (px + nx > screen_size_x(src)) {
|
|
|
|
if (nx > screen_size_x(src))
|
|
|
|
px = 0;
|
|
|
|
else
|
|
|
|
px = screen_size_x(src) - nx;
|
|
|
|
}
|
|
|
|
py = src->cy;
|
|
|
|
if (py < ny / 3)
|
|
|
|
py = 0;
|
|
|
|
else
|
|
|
|
py = py - ny / 3;
|
|
|
|
if (py + ny > screen_size_y(src)) {
|
|
|
|
if (ny > screen_size_y(src))
|
|
|
|
py = 0;
|
|
|
|
else
|
|
|
|
py = screen_size_y(src) - ny;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
px = 0;
|
|
|
|
py = 0;
|
|
|
|
}
|
|
|
|
|
2017-11-02 21:29:17 +00:00
|
|
|
screen_write_fast_copy(ctx, src, px, src->grid->hsize + py, nx, ny);
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
|
|
|
|
if (src->mode & MODE_CURSOR) {
|
|
|
|
grid_view_get_cell(src->grid, src->cx, src->cy, &gc);
|
|
|
|
gc.attr |= GRID_ATTR_REVERSE;
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, cx + (src->cx - px),
|
Rewrite of choose mode, both to simplify and tidy the code and to add
some modern features.
Now the common code is in mode-tree.c, which provides an API used by the
three modes now separated into window-{buffer,client,tree}.c. Buffer
mode shows buffers, client mode clients and tree mode a tree of
sessions, windows and panes.
Each mode has a common set of key bindings plus a few that are specific
to the mode. Other changes are:
- each mode has a preview pane: for buffers this is the buffer content
(very useful), for others it is a preview of the pane;
- items may be sorted in different ways ('O' key);
- multiple items may be tagged and an operation applied to all of them
(for example, to delete multiple buffers at once);
- in tree mode a command may be run on the selected item (session,
window, pane) or on tagged items (key ':');
- displayed items may be filtered in tree mode by using a format (this
is used to implement find-window) (key 'f');
- the custom format (-F) for the display is no longer available;
- shortcut keys change from 0-9, a-z, A-Z which was always a bit weird
with keys used for other uses to 0-9, M-a to M-z.
Now that the code is simpler, other improvements will come later.
Primary key bindings for each mode are documented under the commands in
the man page (choose-buffer, choose-client, choose-tree).
Parts written by Thomas Adam.
2017-05-30 21:44:59 +00:00
|
|
|
cy + (src->cy - py));
|
|
|
|
screen_write_cell(ctx, &gc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-21 18:47:56 +00:00
|
|
|
/* Set a mode. */
|
|
|
|
void
|
|
|
|
screen_write_mode_set(struct screen_write_ctx *ctx, int mode)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
|
|
|
|
s->mode |= mode;
|
2021-06-10 07:43:44 +00:00
|
|
|
|
|
|
|
if (log_get_level() != 0)
|
|
|
|
log_debug("%s: %s", __func__, screen_mode_to_string(mode));
|
2013-03-21 18:47:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear a mode. */
|
|
|
|
void
|
|
|
|
screen_write_mode_clear(struct screen_write_ctx *ctx, int mode)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
|
|
|
|
s->mode &= ~mode;
|
2021-06-10 07:43:44 +00:00
|
|
|
|
|
|
|
if (log_get_level() != 0)
|
|
|
|
log_debug("%s: %s", __func__, screen_mode_to_string(mode));
|
2013-03-21 18:47:56 +00:00
|
|
|
}
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Cursor up by ny. */
|
|
|
|
void
|
|
|
|
screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
u_int cx = s->cx, cy = s->cy;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (ny == 0)
|
|
|
|
ny = 1;
|
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (cy < s->rupper) {
|
2009-07-09 17:57:11 +00:00
|
|
|
/* Above region. */
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (ny > cy)
|
|
|
|
ny = cy;
|
2009-07-09 17:57:11 +00:00
|
|
|
} else {
|
|
|
|
/* Below region. */
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (ny > cy - s->rupper)
|
|
|
|
ny = cy - s->rupper;
|
2009-07-09 17:57:11 +00:00
|
|
|
}
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (cx == screen_size_x(s))
|
|
|
|
cx--;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
cy -= ny;
|
|
|
|
|
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Cursor down by ny. */
|
|
|
|
void
|
|
|
|
screen_write_cursordown(struct screen_write_ctx *ctx, u_int ny)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
u_int cx = s->cx, cy = s->cy;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (ny == 0)
|
|
|
|
ny = 1;
|
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (cy > s->rlower) {
|
2009-07-09 17:57:11 +00:00
|
|
|
/* Below region. */
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (ny > screen_size_y(s) - 1 - cy)
|
|
|
|
ny = screen_size_y(s) - 1 - cy;
|
2009-07-09 17:57:11 +00:00
|
|
|
} else {
|
|
|
|
/* Above region. */
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (ny > s->rlower - cy)
|
|
|
|
ny = s->rlower - cy;
|
2009-07-09 17:57:11 +00:00
|
|
|
}
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (cx == screen_size_x(s))
|
|
|
|
cx--;
|
|
|
|
else if (ny == 0)
|
2009-06-01 22:58:49 +00:00
|
|
|
return;
|
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
cy += ny;
|
|
|
|
|
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2016-12-09 21:39:27 +00:00
|
|
|
/* Cursor right by nx. */
|
2009-06-01 22:58:49 +00:00
|
|
|
void
|
|
|
|
screen_write_cursorright(struct screen_write_ctx *ctx, u_int nx)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
u_int cx = s->cx, cy = s->cy;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (nx == 0)
|
|
|
|
nx = 1;
|
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (nx > screen_size_x(s) - 1 - cx)
|
|
|
|
nx = screen_size_x(s) - 1 - cx;
|
2009-06-01 22:58:49 +00:00
|
|
|
if (nx == 0)
|
|
|
|
return;
|
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
cx += nx;
|
|
|
|
|
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Cursor left by nx. */
|
|
|
|
void
|
|
|
|
screen_write_cursorleft(struct screen_write_ctx *ctx, u_int nx)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
u_int cx = s->cx, cy = s->cy;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (nx == 0)
|
|
|
|
nx = 1;
|
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (nx > cx)
|
|
|
|
nx = cx;
|
2009-06-01 22:58:49 +00:00
|
|
|
if (nx == 0)
|
|
|
|
return;
|
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
cx -= nx;
|
|
|
|
|
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2009-10-12 16:59:55 +00:00
|
|
|
/* Backspace; cursor left unless at start of wrapped line when can move up. */
|
|
|
|
void
|
|
|
|
screen_write_backspace(struct screen_write_ctx *ctx)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid_line *gl;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
u_int cx = s->cx, cy = s->cy;
|
2009-10-12 16:59:55 +00:00
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (cx == 0) {
|
|
|
|
if (cy == 0)
|
2009-10-12 16:59:55 +00:00
|
|
|
return;
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
gl = grid_get_line(s->grid, s->grid->hsize + cy - 1);
|
2009-10-12 16:59:55 +00:00
|
|
|
if (gl->flags & GRID_LINE_WRAPPED) {
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
cy--;
|
|
|
|
cx = screen_size_x(s) - 1;
|
2009-10-12 16:59:55 +00:00
|
|
|
}
|
|
|
|
} else
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
cx--;
|
|
|
|
|
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
2009-10-12 16:59:55 +00:00
|
|
|
}
|
|
|
|
|
2009-06-03 23:30:40 +00:00
|
|
|
/* VT100 alignment test. */
|
|
|
|
void
|
|
|
|
screen_write_alignmenttest(struct screen_write_ctx *ctx)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2009-06-03 23:30:40 +00:00
|
|
|
struct grid_cell gc;
|
|
|
|
u_int xx, yy;
|
|
|
|
|
|
|
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
2015-11-13 08:09:28 +00:00
|
|
|
utf8_set(&gc.data, 'E');
|
2009-06-05 03:13:16 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_free_all(s) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2009-06-03 23:30:40 +00:00
|
|
|
for (yy = 0; yy < screen_size_y(s); yy++) {
|
|
|
|
for (xx = 0; xx < screen_size_x(s); xx++)
|
|
|
|
grid_view_set_cell(s->grid, xx, yy, &gc);
|
|
|
|
}
|
2009-06-05 03:13:16 +00:00
|
|
|
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, 0, 0);
|
2009-06-03 23:30:40 +00:00
|
|
|
|
|
|
|
s->rupper = 0;
|
|
|
|
s->rlower = screen_size_y(s) - 1;
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2018-11-13 11:36:37 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1);
|
2009-07-22 20:53:38 +00:00
|
|
|
tty_write(tty_cmd_alignmenttest, &ttyctx);
|
2009-06-03 23:30:40 +00:00
|
|
|
}
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Insert nx characters. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (nx == 0)
|
|
|
|
nx = 1;
|
|
|
|
|
2009-06-29 21:30:50 +00:00
|
|
|
if (nx > screen_size_x(s) - s->cx)
|
|
|
|
nx = screen_size_x(s) - s->cx;
|
2009-06-01 22:58:49 +00:00
|
|
|
if (nx == 0)
|
|
|
|
return;
|
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
if (s->cx > screen_size_x(s) - 1)
|
|
|
|
return;
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
2017-02-08 15:49:29 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
ttyctx.num = nx;
|
|
|
|
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete nx characters. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (nx == 0)
|
|
|
|
nx = 1;
|
|
|
|
|
2009-06-29 21:30:50 +00:00
|
|
|
if (nx > screen_size_x(s) - s->cx)
|
|
|
|
nx = screen_size_x(s) - s->cx;
|
2009-06-01 22:58:49 +00:00
|
|
|
if (nx == 0)
|
|
|
|
return;
|
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
if (s->cx > screen_size_x(s) - 1)
|
|
|
|
return;
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
2017-02-08 15:49:29 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
ttyctx.num = nx;
|
|
|
|
tty_write(tty_cmd_deletecharacter, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2013-01-15 23:18:55 +00:00
|
|
|
/* Clear nx characters. */
|
|
|
|
void
|
2017-05-12 10:50:11 +00:00
|
|
|
screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
2013-01-15 23:18:55 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
|
|
|
|
if (nx == 0)
|
|
|
|
nx = 1;
|
|
|
|
|
|
|
|
if (nx > screen_size_x(s) - s->cx)
|
|
|
|
nx = screen_size_x(s) - s->cx;
|
|
|
|
if (nx == 0)
|
|
|
|
return;
|
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
if (s->cx > screen_size_x(s) - 1)
|
|
|
|
return;
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
2017-05-12 10:50:11 +00:00
|
|
|
ttyctx.bg = bg;
|
2013-01-15 23:18:55 +00:00
|
|
|
|
2017-05-12 14:56:56 +00:00
|
|
|
grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg);
|
2013-01-15 23:18:55 +00:00
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2013-01-15 23:18:55 +00:00
|
|
|
ttyctx.num = nx;
|
|
|
|
tty_write(tty_cmd_clearcharacter, &ttyctx);
|
|
|
|
}
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Insert ny lines. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2017-02-08 15:49:29 +00:00
|
|
|
struct grid *gd = s->grid;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
u_int sy = screen_size_y(s);
|
|
|
|
#endif
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
if (ny == 0)
|
|
|
|
ny = 1;
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2009-07-09 07:58:14 +00:00
|
|
|
if (s->cy < s->rupper || s->cy > s->rlower) {
|
|
|
|
if (ny > screen_size_y(s) - s->cy)
|
|
|
|
ny = screen_size_y(s) - s->cy;
|
|
|
|
if (ny == 0)
|
|
|
|
return;
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2017-02-08 15:49:29 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-07-09 07:58:14 +00:00
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_insert_lines(gd, s->cy, ny, bg);
|
2009-07-09 07:58:14 +00:00
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
ttyctx.num = ny;
|
|
|
|
tty_write(tty_cmd_insertline, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
return;
|
2009-07-09 07:58:14 +00:00
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2009-07-09 07:58:14 +00:00
|
|
|
if (ny > s->rlower + 1 - s->cy)
|
|
|
|
ny = s->rlower + 1 - s->cy;
|
|
|
|
if (ny == 0)
|
|
|
|
return;
|
2009-12-03 22:50:09 +00:00
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2017-02-08 15:49:29 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (s->cy < s->rupper || s->cy > s->rlower)
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_insert_lines(gd, s->cy, ny, bg);
|
|
|
|
else
|
|
|
|
grid_view_insert_lines_region(gd, s->rlower, s->cy, ny, bg);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
|
|
|
|
2009-07-22 20:53:38 +00:00
|
|
|
ttyctx.num = ny;
|
|
|
|
tty_write(tty_cmd_insertline, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete ny lines. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2017-02-08 15:49:29 +00:00
|
|
|
struct grid *gd = s->grid;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2023-08-22 07:43:35 +00:00
|
|
|
u_int sy = screen_size_y(s);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (ny == 0)
|
|
|
|
ny = 1;
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2009-07-09 07:58:14 +00:00
|
|
|
if (s->cy < s->rupper || s->cy > s->rlower) {
|
2023-08-22 07:43:35 +00:00
|
|
|
if (ny > sy - s->cy)
|
|
|
|
ny = sy - s->cy;
|
2009-07-09 07:58:14 +00:00
|
|
|
if (ny == 0)
|
|
|
|
return;
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2017-02-08 15:49:29 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-07-09 07:58:14 +00:00
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_delete_lines(gd, s->cy, ny, bg);
|
2009-07-09 07:58:14 +00:00
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
ttyctx.num = ny;
|
|
|
|
tty_write(tty_cmd_deleteline, &ttyctx);
|
2009-07-09 07:58:14 +00:00
|
|
|
return;
|
|
|
|
}
|
2009-12-03 22:50:09 +00:00
|
|
|
|
2009-07-09 07:58:14 +00:00
|
|
|
if (ny > s->rlower + 1 - s->cy)
|
|
|
|
ny = s->rlower + 1 - s->cy;
|
2009-06-01 22:58:49 +00:00
|
|
|
if (ny == 0)
|
|
|
|
return;
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2017-02-08 15:49:29 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
if (s->cy < s->rupper || s->cy > s->rlower)
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_delete_lines(gd, s->cy, ny, bg);
|
|
|
|
else
|
|
|
|
grid_view_delete_lines_region(gd, s->rlower, s->cy, ny, bg);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
ttyctx.num = ny;
|
|
|
|
tty_write(tty_cmd_deleteline, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear line at cursor. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid_line *gl;
|
|
|
|
u_int sx = screen_size_x(s);
|
|
|
|
struct screen_write_citem *ci = ctx->item;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2018-07-04 09:44:07 +00:00
|
|
|
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
|
2018-10-25 15:13:38 +00:00
|
|
|
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))
|
2016-07-15 00:49:08 +00:00
|
|
|
return;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2016-10-13 20:27:27 +00:00
|
|
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_collect_clear(ctx, s->cy, 1);
|
2021-01-29 09:48:43 +00:00
|
|
|
ci->x = 0;
|
|
|
|
ci->used = sx;
|
|
|
|
ci->type = CLEAR;
|
|
|
|
ci->bg = bg;
|
|
|
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
|
|
|
ctx->item = screen_write_get_citem();
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear to end of line from cursor. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid_line *gl;
|
|
|
|
u_int sx = screen_size_x(s);
|
|
|
|
struct screen_write_citem *ci = ctx->item, *before;
|
2020-04-16 20:32:51 +00:00
|
|
|
|
|
|
|
if (s->cx == 0) {
|
|
|
|
screen_write_clearline(ctx, bg);
|
|
|
|
return;
|
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2018-07-04 09:44:07 +00:00
|
|
|
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
|
2018-10-25 15:13:38 +00:00
|
|
|
if (s->cx > sx - 1 || (s->cx >= gl->cellsize && COLOUR_DEFAULT(bg)))
|
2016-07-15 00:49:08 +00:00
|
|
|
return;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2016-10-13 20:27:27 +00:00
|
|
|
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);
|
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
before = screen_write_collect_trim(ctx, s->cy, s->cx, sx - s->cx, NULL);
|
2020-07-06 10:07:02 +00:00
|
|
|
ci->x = s->cx;
|
2021-01-29 09:48:43 +00:00
|
|
|
ci->used = sx - s->cx;
|
|
|
|
ci->type = CLEAR;
|
2020-07-06 10:07:02 +00:00
|
|
|
ci->bg = bg;
|
2021-01-29 09:48:43 +00:00
|
|
|
if (before == NULL)
|
|
|
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
|
|
|
else
|
|
|
|
TAILQ_INSERT_BEFORE(before, ci, entry);
|
|
|
|
ctx->item = screen_write_get_citem();
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear to start of line from cursor. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
2020-04-16 20:32:51 +00:00
|
|
|
struct screen *s = ctx->s;
|
2021-01-29 09:48:43 +00:00
|
|
|
u_int sx = screen_size_x(s);
|
|
|
|
struct screen_write_citem *ci = ctx->item, *before;
|
2020-04-16 20:32:51 +00:00
|
|
|
|
|
|
|
if (s->cx >= sx - 1) {
|
|
|
|
screen_write_clearline(ctx, bg);
|
|
|
|
return;
|
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
if (s->cx > sx - 1)
|
2016-10-13 20:27:27 +00:00
|
|
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
2017-02-08 16:45:18 +00:00
|
|
|
else
|
2016-10-13 20:27:27 +00:00
|
|
|
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
before = screen_write_collect_trim(ctx, s->cy, 0, s->cx + 1, NULL);
|
|
|
|
ci->x = 0;
|
|
|
|
ci->used = s->cx + 1;
|
|
|
|
ci->type = CLEAR;
|
2020-07-06 10:07:02 +00:00
|
|
|
ci->bg = bg;
|
2021-01-29 09:48:43 +00:00
|
|
|
if (before == NULL)
|
|
|
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
|
|
|
|
else
|
|
|
|
TAILQ_INSERT_BEFORE(before, ci, entry);
|
|
|
|
ctx->item = screen_write_get_citem();
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2016-12-09 21:39:27 +00:00
|
|
|
/* Move cursor to px,py. */
|
2009-06-01 22:58:49 +00:00
|
|
|
void
|
2019-03-12 20:02:47 +00:00
|
|
|
screen_write_cursormove(struct screen_write_ctx *ctx, int px, int py,
|
|
|
|
int origin)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
|
2019-03-12 20:02:47 +00:00
|
|
|
if (origin && py != -1 && (s->mode & MODE_ORIGIN)) {
|
2019-03-12 18:30:08 +00:00
|
|
|
if ((u_int)py > s->rlower - s->rupper)
|
2019-03-12 07:39:27 +00:00
|
|
|
py = s->rlower;
|
|
|
|
else
|
|
|
|
py += s->rupper;
|
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2019-03-12 18:30:08 +00:00
|
|
|
if (px != -1 && (u_int)px > screen_size_x(s) - 1)
|
2019-03-12 13:14:14 +00:00
|
|
|
px = screen_size_x(s) - 1;
|
2019-03-12 18:30:08 +00:00
|
|
|
if (py != -1 && (u_int)py > screen_size_y(s) - 1)
|
2019-03-12 13:14:14 +00:00
|
|
|
py = screen_size_y(s) - 1;
|
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
log_debug("%s: from %u,%u to %u,%u", __func__, s->cx, s->cy, px, py);
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, px, py);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2016-12-09 21:39:27 +00:00
|
|
|
/* Reverse index (up with scroll). */
|
2009-06-01 22:58:49 +00:00
|
|
|
void
|
2017-05-12 13:00:56 +00:00
|
|
|
screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-09-07 21:02:11 +00:00
|
|
|
if (s->cy == s->rupper) {
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
2023-09-07 21:02:11 +00:00
|
|
|
if (image_free_all(s) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
2023-08-22 07:43:35 +00:00
|
|
|
#endif
|
|
|
|
|
2017-05-12 13:00:56 +00:00
|
|
|
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg);
|
2020-04-16 20:32:51 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
|
|
|
|
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
|
|
|
ttyctx.bg = bg;
|
|
|
|
|
|
|
|
tty_write(tty_cmd_reverseindex, &ttyctx);
|
|
|
|
} else if (s->cy > 0)
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, -1, s->cy - 1);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set scroll region. */
|
|
|
|
void
|
2015-12-11 16:37:21 +00:00
|
|
|
screen_write_scrollregion(struct screen_write_ctx *ctx, u_int rupper,
|
|
|
|
u_int rlower)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
|
|
|
|
if (rupper > screen_size_y(s) - 1)
|
|
|
|
rupper = screen_size_y(s) - 1;
|
|
|
|
if (rlower > screen_size_y(s) - 1)
|
|
|
|
rlower = screen_size_y(s) - 1;
|
2009-07-14 14:47:32 +00:00
|
|
|
if (rupper >= rlower) /* cannot be one line */
|
2009-06-01 22:58:49 +00:00
|
|
|
return;
|
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2017-02-08 17:31:09 +00:00
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Cursor moves to top-left. */
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, 0, 0);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
s->rupper = rupper;
|
|
|
|
s->rlower = rlower;
|
|
|
|
}
|
|
|
|
|
2009-10-20 16:32:23 +00:00
|
|
|
/* Line feed. */
|
2009-06-01 22:58:49 +00:00
|
|
|
void
|
2017-05-12 13:00:56 +00:00
|
|
|
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
2009-08-08 15:57:49 +00:00
|
|
|
struct screen *s = ctx->s;
|
2017-02-08 16:45:18 +00:00
|
|
|
struct grid *gd = s->grid;
|
2009-08-08 15:57:49 +00:00
|
|
|
struct grid_line *gl;
|
2023-09-15 11:33:33 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
2023-08-22 07:43:35 +00:00
|
|
|
int redraw = 0;
|
2023-09-15 11:33:33 +00:00
|
|
|
#endif
|
2023-08-22 07:43:35 +00:00
|
|
|
u_int rupper = s->rupper, rlower = s->rlower;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2018-07-04 09:44:07 +00:00
|
|
|
gl = grid_get_line(gd, gd->hsize + s->cy);
|
2009-08-08 15:57:49 +00:00
|
|
|
if (wrapped)
|
|
|
|
gl->flags |= GRID_LINE_WRAPPED;
|
|
|
|
|
2017-02-21 10:30:15 +00:00
|
|
|
log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy,
|
2023-08-22 07:43:35 +00:00
|
|
|
rupper, rlower);
|
2017-02-21 10:30:15 +00:00
|
|
|
|
2017-05-12 13:00:56 +00:00
|
|
|
if (bg != ctx->bg) {
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 1, __func__);
|
2017-05-12 13:00:56 +00:00
|
|
|
ctx->bg = bg;
|
|
|
|
}
|
|
|
|
|
2016-07-15 00:49:08 +00:00
|
|
|
if (s->cy == s->rlower) {
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (rlower == screen_size_y(s) - 1)
|
|
|
|
redraw = image_scroll_up(s, 1);
|
|
|
|
else
|
|
|
|
redraw = image_check_line(s, rupper, rlower - rupper);
|
|
|
|
if (redraw && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
2017-05-12 13:00:56 +00:00
|
|
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
2021-01-29 09:48:43 +00:00
|
|
|
screen_write_collect_scroll(ctx, bg);
|
2017-02-08 17:31:09 +00:00
|
|
|
ctx->scrolled++;
|
2017-02-08 16:45:18 +00:00
|
|
|
} else if (s->cy < screen_size_y(s) - 1)
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, -1, s->cy + 1);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2017-02-08 17:31:09 +00:00
|
|
|
/* Scroll up. */
|
|
|
|
void
|
2017-05-12 13:00:56 +00:00
|
|
|
screen_write_scrollup(struct screen_write_ctx *ctx, u_int lines, u_int bg)
|
2017-02-08 17:31:09 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid *gd = s->grid;
|
|
|
|
u_int i;
|
|
|
|
|
|
|
|
if (lines == 0)
|
|
|
|
lines = 1;
|
|
|
|
else if (lines > s->rlower - s->rupper + 1)
|
|
|
|
lines = s->rlower - s->rupper + 1;
|
|
|
|
|
2017-05-12 13:00:56 +00:00
|
|
|
if (bg != ctx->bg) {
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 1, __func__);
|
2017-05-12 13:00:56 +00:00
|
|
|
ctx->bg = bg;
|
|
|
|
}
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_scroll_up(s, lines) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2017-02-08 17:31:09 +00:00
|
|
|
for (i = 0; i < lines; i++) {
|
2017-05-12 13:00:56 +00:00
|
|
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
2021-01-29 09:48:43 +00:00
|
|
|
screen_write_collect_scroll(ctx, bg);
|
2017-02-08 17:31:09 +00:00
|
|
|
}
|
|
|
|
ctx->scrolled += lines;
|
|
|
|
}
|
|
|
|
|
2019-08-05 06:42:02 +00:00
|
|
|
/* Scroll down. */
|
|
|
|
void
|
|
|
|
screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid *gd = s->grid;
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
u_int i;
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2019-08-05 06:42:02 +00:00
|
|
|
ttyctx.bg = bg;
|
|
|
|
|
|
|
|
if (lines == 0)
|
|
|
|
lines = 1;
|
|
|
|
else if (lines > s->rlower - s->rupper + 1)
|
|
|
|
lines = s->rlower - s->rupper + 1;
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_free_all(s) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2019-08-05 06:42:02 +00:00
|
|
|
for (i = 0; i < lines; i++)
|
|
|
|
grid_view_scroll_region_down(gd, s->rupper, s->rlower, bg);
|
|
|
|
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2019-08-05 06:42:02 +00:00
|
|
|
ttyctx.num = lines;
|
|
|
|
tty_write(tty_cmd_scrolldown, &ttyctx);
|
|
|
|
}
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Carriage return (cursor to start of line). */
|
|
|
|
void
|
|
|
|
screen_write_carriagereturn(struct screen_write_ctx *ctx)
|
|
|
|
{
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, 0, -1);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear to end of screen from cursor. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2017-02-08 15:49:29 +00:00
|
|
|
struct grid *gd = s->grid;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2016-07-15 00:49:08 +00:00
|
|
|
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2016-10-13 20:27:27 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2011-01-25 23:40:26 +00:00
|
|
|
/* Scroll into history if it is enabled and clearing entire screen. */
|
2022-03-17 11:35:37 +00:00
|
|
|
if (s->cx == 0 &&
|
|
|
|
s->cy == 0 &&
|
|
|
|
(gd->flags & GRID_HISTORY) &&
|
|
|
|
ctx->wp != NULL &&
|
|
|
|
options_get_number(ctx->wp->options, "scroll-on-clear"))
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_clear_history(gd, bg);
|
2017-02-08 16:45:18 +00:00
|
|
|
else {
|
|
|
|
if (s->cx <= sx - 1)
|
2017-02-08 15:49:29 +00:00
|
|
|
grid_view_clear(gd, s->cx, s->cy, sx - s->cx, 1, bg);
|
|
|
|
grid_view_clear(gd, 0, s->cy + 1, sx, sy - (s->cy + 1), bg);
|
2011-01-25 23:40:26 +00:00
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1));
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
tty_write(tty_cmd_clearendofscreen, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear to start of screen. */
|
|
|
|
void
|
2017-02-06 19:26:49 +00:00
|
|
|
screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2016-07-15 00:49:08 +00:00
|
|
|
u_int sx = screen_size_x(s);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_line(s, 0, s->cy - 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2017-02-06 19:26:49 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
if (s->cy > 0)
|
2017-02-06 19:26:49 +00:00
|
|
|
grid_view_clear(s->grid, 0, 0, sx, s->cy, bg);
|
2017-02-08 16:45:18 +00:00
|
|
|
if (s->cx > sx - 1)
|
2017-05-11 11:39:30 +00:00
|
|
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
2017-02-08 16:45:18 +00:00
|
|
|
else
|
2017-05-11 11:39:30 +00:00
|
|
|
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_collect_clear(ctx, 0, s->cy);
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
tty_write(tty_cmd_clearstartofscreen, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear entire screen. */
|
|
|
|
void
|
2016-10-13 20:27:27 +00:00
|
|
|
screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
2009-07-22 20:53:38 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2016-07-15 00:49:08 +00:00
|
|
|
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_free_all(s) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2016-10-13 20:27:27 +00:00
|
|
|
ttyctx.bg = bg;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2011-01-25 23:40:26 +00:00
|
|
|
/* Scroll into history if it is enabled. */
|
2022-03-17 13:39:13 +00:00
|
|
|
if ((s->grid->flags & GRID_HISTORY) &&
|
|
|
|
ctx->wp != NULL &&
|
|
|
|
options_get_number(ctx->wp->options, "scroll-on-clear"))
|
2016-10-13 20:27:27 +00:00
|
|
|
grid_view_clear_history(s->grid, bg);
|
2015-12-11 16:37:21 +00:00
|
|
|
else
|
2016-10-13 20:27:27 +00:00
|
|
|
grid_view_clear(s->grid, 0, 0, sx, sy, bg);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_collect_clear(ctx, 0, sy);
|
2009-07-22 20:53:38 +00:00
|
|
|
tty_write(tty_cmd_clearscreen, &ttyctx);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2011-10-23 10:16:14 +00:00
|
|
|
/* Clear entire history. */
|
|
|
|
void
|
|
|
|
screen_write_clearhistory(struct screen_write_ctx *ctx)
|
|
|
|
{
|
2019-07-08 11:38:14 +00:00
|
|
|
grid_clear_history(ctx->s->grid);
|
2011-10-23 10:16:14 +00:00
|
|
|
}
|
|
|
|
|
2021-08-11 20:49:55 +00:00
|
|
|
/* Force a full redraw. */
|
|
|
|
void
|
|
|
|
screen_write_fullredraw(struct screen_write_ctx *ctx)
|
|
|
|
{
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
|
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
|
|
|
|
2022-10-25 17:53:31 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
|
|
|
if (ttyctx.redraw_cb != NULL)
|
2022-10-25 09:04:49 +00:00
|
|
|
ttyctx.redraw_cb(&ttyctx);
|
2021-08-11 20:49:55 +00:00
|
|
|
}
|
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
/* Trim collected items. */
|
|
|
|
static struct screen_write_citem *
|
|
|
|
screen_write_collect_trim(struct screen_write_ctx *ctx, u_int y, u_int x,
|
|
|
|
u_int used, int *wrapped)
|
2020-04-16 20:32:51 +00:00
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen_write_cline *cl = &ctx->s->write_list[y];
|
|
|
|
struct screen_write_citem *ci, *ci2, *tmp, *before = NULL;
|
|
|
|
u_int sx = x, ex = x + used - 1;
|
|
|
|
u_int csx, cex;
|
|
|
|
|
|
|
|
if (TAILQ_EMPTY(&cl->items))
|
|
|
|
return (NULL);
|
|
|
|
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
|
|
|
csx = ci->x;
|
|
|
|
cex = ci->x + ci->used - 1;
|
|
|
|
|
|
|
|
/* Item is entirely before. */
|
|
|
|
if (cex < sx) {
|
|
|
|
log_debug("%s: %p %u-%u before %u-%u", __func__, ci,
|
|
|
|
csx, cex, sx, ex);
|
2020-04-16 20:32:51 +00:00
|
|
|
continue;
|
2021-01-29 09:48:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Item is entirely after. */
|
|
|
|
if (csx > ex) {
|
|
|
|
log_debug("%s: %p %u-%u after %u-%u", __func__, ci,
|
|
|
|
csx, cex, sx, ex);
|
|
|
|
before = ci;
|
2020-04-16 20:32:51 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
/* Item is entirely inside. */
|
|
|
|
if (csx >= sx && cex <= ex) {
|
|
|
|
log_debug("%s: %p %u-%u inside %u-%u", __func__, ci,
|
|
|
|
csx, cex, sx, ex);
|
|
|
|
TAILQ_REMOVE(&cl->items, ci, entry);
|
|
|
|
screen_write_free_citem(ci);
|
|
|
|
if (csx == 0 && ci->wrapped && wrapped != NULL)
|
|
|
|
*wrapped = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2020-04-16 20:32:51 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
/* Item under the start. */
|
|
|
|
if (csx < sx && cex >= sx && cex <= ex) {
|
|
|
|
log_debug("%s: %p %u-%u start %u-%u", __func__, ci,
|
|
|
|
csx, cex, sx, ex);
|
|
|
|
ci->used = sx - csx;
|
|
|
|
log_debug("%s: %p now %u-%u", __func__, ci, ci->x,
|
|
|
|
ci->x + ci->used + 1);
|
2020-04-16 20:32:51 +00:00
|
|
|
continue;
|
2021-01-29 09:48:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Item covers the end. */
|
|
|
|
if (cex > ex && csx >= sx && csx <= ex) {
|
|
|
|
log_debug("%s: %p %u-%u end %u-%u", __func__, ci,
|
|
|
|
csx, cex, sx, ex);
|
|
|
|
ci->x = ex + 1;
|
|
|
|
ci->used = cex - ex;
|
|
|
|
log_debug("%s: %p now %u-%u", __func__, ci, ci->x,
|
|
|
|
ci->x + ci->used + 1);
|
|
|
|
before = ci;
|
2020-04-16 20:32:51 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-01-29 09:48:43 +00:00
|
|
|
|
|
|
|
/* Item must cover both sides. */
|
|
|
|
log_debug("%s: %p %u-%u under %u-%u", __func__, ci,
|
|
|
|
csx, cex, sx, ex);
|
|
|
|
ci2 = screen_write_get_citem();
|
|
|
|
ci2->type = ci->type;
|
|
|
|
ci2->bg = ci->bg;
|
|
|
|
memcpy(&ci2->gc, &ci->gc, sizeof ci2->gc);
|
|
|
|
TAILQ_INSERT_AFTER(&cl->items, ci, ci2, entry);
|
|
|
|
|
|
|
|
ci->used = sx - csx;
|
|
|
|
ci2->x = ex + 1;
|
|
|
|
ci2->used = cex - ex;
|
|
|
|
|
|
|
|
log_debug("%s: %p now %u-%u (%p) and %u-%u (%p)", __func__, ci,
|
|
|
|
ci->x, ci->x + ci->used - 1, ci, ci2->x,
|
|
|
|
ci2->x + ci2->used - 1, ci2);
|
|
|
|
before = ci2;
|
|
|
|
break;
|
2020-04-16 20:32:51 +00:00
|
|
|
}
|
2021-01-29 09:48:43 +00:00
|
|
|
return (before);
|
2020-04-16 20:32:51 +00:00
|
|
|
}
|
|
|
|
|
2020-04-18 15:12:28 +00:00
|
|
|
/* Clear collected lines. */
|
2017-02-08 16:45:18 +00:00
|
|
|
static void
|
|
|
|
screen_write_collect_clear(struct screen_write_ctx *ctx, u_int y, u_int n)
|
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen_write_cline *cl;
|
|
|
|
u_int i;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2019-04-18 11:07:28 +00:00
|
|
|
for (i = y; i < y + n; i++) {
|
2020-04-18 17:20:25 +00:00
|
|
|
cl = &ctx->s->write_list[i];
|
2021-01-29 09:48:43 +00:00
|
|
|
TAILQ_CONCAT(&screen_write_citem_freelist, &cl->items, entry);
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scroll collected lines up. */
|
|
|
|
static void
|
2021-01-29 09:48:43 +00:00
|
|
|
screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg)
|
2017-02-08 16:45:18 +00:00
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct screen_write_cline *cl;
|
|
|
|
u_int y;
|
|
|
|
char *saved;
|
|
|
|
struct screen_write_citem *ci;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2017-02-21 10:30:15 +00:00
|
|
|
log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy,
|
|
|
|
s->rupper, s->rlower);
|
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_collect_clear(ctx, s->rupper, 1);
|
2020-04-18 17:20:25 +00:00
|
|
|
saved = ctx->s->write_list[s->rupper].data;
|
2017-02-08 16:45:18 +00:00
|
|
|
for (y = s->rupper; y < s->rlower; y++) {
|
2020-04-18 17:20:25 +00:00
|
|
|
cl = &ctx->s->write_list[y + 1];
|
|
|
|
TAILQ_CONCAT(&ctx->s->write_list[y].items, &cl->items, entry);
|
|
|
|
ctx->s->write_list[y].data = cl->data;
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
2020-04-21 13:48:56 +00:00
|
|
|
ctx->s->write_list[s->rlower].data = saved;
|
2021-01-29 09:48:43 +00:00
|
|
|
|
|
|
|
ci = screen_write_get_citem();
|
|
|
|
ci->x = 0;
|
|
|
|
ci->used = screen_size_x(s);
|
|
|
|
ci->type = CLEAR;
|
|
|
|
ci->bg = bg;
|
|
|
|
TAILQ_INSERT_TAIL(&ctx->s->write_list[s->rlower].items, ci, entry);
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Flush collected lines. */
|
|
|
|
static void
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
|
|
|
const char *from)
|
2017-02-08 16:45:18 +00:00
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct screen_write_citem *ci, *tmp;
|
|
|
|
struct screen_write_cline *cl;
|
|
|
|
u_int y, cx, cy, last, items = 0;
|
|
|
|
struct tty_ctx ttyctx;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2017-02-08 17:31:09 +00:00
|
|
|
if (ctx->scrolled != 0) {
|
|
|
|
log_debug("%s: scrolled %u (region %u-%u)", __func__,
|
|
|
|
ctx->scrolled, s->rupper, s->rlower);
|
|
|
|
if (ctx->scrolled > s->rlower - s->rupper + 1)
|
|
|
|
ctx->scrolled = s->rlower - s->rupper + 1;
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2017-02-08 17:31:09 +00:00
|
|
|
ttyctx.num = ctx->scrolled;
|
2017-05-12 13:00:56 +00:00
|
|
|
ttyctx.bg = ctx->bg;
|
2017-02-08 17:31:09 +00:00
|
|
|
tty_write(tty_cmd_scrollup, &ttyctx);
|
|
|
|
}
|
|
|
|
ctx->scrolled = 0;
|
2017-05-12 13:00:56 +00:00
|
|
|
ctx->bg = 8;
|
|
|
|
|
2017-02-09 09:33:15 +00:00
|
|
|
if (scroll_only)
|
|
|
|
return;
|
2017-02-08 17:31:09 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
cx = s->cx; cy = s->cy;
|
|
|
|
for (y = 0; y < screen_size_y(s); y++) {
|
2020-04-18 17:20:25 +00:00
|
|
|
cl = &ctx->s->write_list[y];
|
2021-01-29 09:48:43 +00:00
|
|
|
last = UINT_MAX;
|
2020-04-18 17:20:25 +00:00
|
|
|
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
2021-01-29 09:48:43 +00:00
|
|
|
if (last != UINT_MAX && ci->x <= last) {
|
|
|
|
fatalx("collect list not in order: %u <= %u",
|
|
|
|
ci->x, last);
|
|
|
|
}
|
2019-03-12 07:39:27 +00:00
|
|
|
screen_write_set_cursor(ctx, ci->x, y);
|
2021-01-29 09:48:43 +00:00
|
|
|
if (ci->type == CLEAR) {
|
2020-04-16 21:46:43 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
2020-04-16 20:32:51 +00:00
|
|
|
ttyctx.bg = ci->bg;
|
2021-01-29 09:48:43 +00:00
|
|
|
ttyctx.num = ci->used;
|
|
|
|
tty_write(tty_cmd_clearcharacter, &ttyctx);
|
2020-04-16 20:32:51 +00:00
|
|
|
} else {
|
2020-04-16 21:46:43 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
2020-04-16 20:32:51 +00:00
|
|
|
ttyctx.cell = &ci->gc;
|
|
|
|
ttyctx.wrapped = ci->wrapped;
|
2020-04-18 17:20:25 +00:00
|
|
|
ttyctx.ptr = cl->data + ci->x;
|
2020-04-16 20:32:51 +00:00
|
|
|
ttyctx.num = ci->used;
|
|
|
|
tty_write(tty_cmd_cells, &ttyctx);
|
|
|
|
}
|
2017-03-07 13:48:28 +00:00
|
|
|
items++;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2020-04-18 17:20:25 +00:00
|
|
|
TAILQ_REMOVE(&cl->items, ci, entry);
|
2021-01-29 09:48:43 +00:00
|
|
|
screen_write_free_citem(ci);
|
|
|
|
last = ci->x;
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
s->cx = cx; s->cy = cy;
|
2017-03-07 13:48:28 +00:00
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
log_debug("%s: flushed %u items (%s)", __func__, items, from);
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Finish and store collected cells. */
|
|
|
|
void
|
|
|
|
screen_write_collect_end(struct screen_write_ctx *ctx)
|
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct screen_write_citem *ci = ctx->item, *before;
|
|
|
|
struct screen_write_cline *cl = &s->write_list[s->cy];
|
|
|
|
struct grid_cell gc;
|
|
|
|
u_int xx;
|
|
|
|
int wrapped = ci->wrapped;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
|
|
|
if (ci->used == 0)
|
|
|
|
return;
|
|
|
|
|
2021-01-29 09:48:43 +00:00
|
|
|
before = screen_write_collect_trim(ctx, s->cy, s->cx, ci->used,
|
|
|
|
&wrapped);
|
2017-02-08 16:45:18 +00:00
|
|
|
ci->x = s->cx;
|
2021-01-29 09:48:43 +00:00
|
|
|
ci->wrapped = wrapped;
|
|
|
|
if (before == NULL)
|
|
|
|
TAILQ_INSERT_TAIL(&cl->items, ci, entry);
|
|
|
|
else
|
|
|
|
TAILQ_INSERT_BEFORE(before, ci, entry);
|
|
|
|
ctx->item = screen_write_get_citem();
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2020-04-18 15:12:28 +00:00
|
|
|
log_debug("%s: %u %.*s (at %u,%u)", __func__, ci->used,
|
2020-04-18 17:20:25 +00:00
|
|
|
(int)ci->used, cl->data + ci->x, s->cx, s->cy);
|
2017-02-08 16:45:18 +00:00
|
|
|
|
2017-10-05 08:12:24 +00:00
|
|
|
if (s->cx != 0) {
|
|
|
|
for (xx = s->cx; xx > 0; xx--) {
|
|
|
|
grid_view_get_cell(s->grid, xx, s->cy, &gc);
|
|
|
|
if (~gc.flags & GRID_FLAG_PADDING)
|
|
|
|
break;
|
2018-01-12 16:43:47 +00:00
|
|
|
grid_view_set_cell(s->grid, xx, s->cy,
|
|
|
|
&grid_default_cell);
|
2017-10-05 08:12:24 +00:00
|
|
|
}
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
if (gc.data.width > 1) {
|
2018-01-12 16:43:47 +00:00
|
|
|
grid_view_set_cell(s->grid, xx, s->cy,
|
|
|
|
&grid_default_cell);
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
}
|
2017-10-05 08:12:24 +00:00
|
|
|
}
|
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
if (image_check_area(s, s->cx, s->cy, ci->used, 1) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
#endif
|
|
|
|
|
2020-04-18 17:20:25 +00:00
|
|
|
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, cl->data + ci->x,
|
|
|
|
ci->used);
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, s->cx + ci->used, -1);
|
2017-10-05 08:12:24 +00:00
|
|
|
|
|
|
|
for (xx = s->cx; xx < screen_size_x(s); xx++) {
|
|
|
|
grid_view_get_cell(s->grid, xx, s->cy, &gc);
|
|
|
|
if (~gc.flags & GRID_FLAG_PADDING)
|
|
|
|
break;
|
|
|
|
grid_view_set_cell(s->grid, xx, s->cy, &grid_default_cell);
|
|
|
|
}
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Write cell data, collecting if necessary. */
|
|
|
|
void
|
|
|
|
screen_write_collect_add(struct screen_write_ctx *ctx,
|
|
|
|
const struct grid_cell *gc)
|
|
|
|
{
|
2021-01-29 09:48:43 +00:00
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct screen_write_citem *ci;
|
|
|
|
u_int sx = screen_size_x(s);
|
|
|
|
int collect;
|
2017-02-08 16:45:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't need to check that the attributes and whatnot are still the
|
2017-03-07 13:48:28 +00:00
|
|
|
* same - input_parse will end the collection when anything that isn't
|
2019-09-24 20:44:58 +00:00
|
|
|
* a plain character is encountered.
|
2017-02-08 16:45:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
collect = 1;
|
2018-01-12 16:43:47 +00:00
|
|
|
if (gc->data.width != 1 || gc->data.size != 1 || *gc->data.data >= 0x7f)
|
2017-02-08 16:45:18 +00:00
|
|
|
collect = 0;
|
|
|
|
else if (gc->attr & GRID_ATTR_CHARSET)
|
|
|
|
collect = 0;
|
|
|
|
else if (~s->mode & MODE_WRAP)
|
|
|
|
collect = 0;
|
|
|
|
else if (s->mode & MODE_INSERT)
|
|
|
|
collect = 0;
|
2018-07-31 11:49:26 +00:00
|
|
|
else if (s->sel != NULL)
|
2017-02-08 16:45:18 +00:00
|
|
|
collect = 0;
|
|
|
|
if (!collect) {
|
|
|
|
screen_write_collect_end(ctx);
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2017-02-08 16:45:18 +00:00
|
|
|
screen_write_cell(ctx, gc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s->cx > sx - 1 || ctx->item->used > sx - 1 - s->cx)
|
|
|
|
screen_write_collect_end(ctx);
|
2017-04-25 18:30:29 +00:00
|
|
|
ci = ctx->item; /* may have changed */
|
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
if (s->cx > sx - 1) {
|
2017-02-21 10:30:15 +00:00
|
|
|
log_debug("%s: wrapped at %u,%u", __func__, s->cx, s->cy);
|
2017-04-25 18:30:29 +00:00
|
|
|
ci->wrapped = 1;
|
2017-05-12 13:00:56 +00:00
|
|
|
screen_write_linefeed(ctx, 1, 8);
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, 0, -1);
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ci->used == 0)
|
|
|
|
memcpy(&ci->gc, gc, sizeof ci->gc);
|
2020-04-18 17:20:25 +00:00
|
|
|
if (ctx->s->write_list[s->cy].data == NULL)
|
|
|
|
ctx->s->write_list[s->cy].data = xmalloc(screen_size_x(ctx->s));
|
|
|
|
ctx->s->write_list[s->cy].data[s->cx + ci->used++] = gc->data.data[0];
|
2017-02-08 16:45:18 +00:00
|
|
|
}
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Write cell data. */
|
|
|
|
void
|
2013-01-18 02:16:21 +00:00
|
|
|
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid *gd = s->grid;
|
2023-09-15 15:49:05 +00:00
|
|
|
const struct utf8_data *ud = &gc->data;
|
2016-07-15 00:49:08 +00:00
|
|
|
struct grid_line *gl;
|
|
|
|
struct grid_cell_entry *gce;
|
2017-02-08 16:45:18 +00:00
|
|
|
struct grid_cell tmp_gc, now_gc;
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
2023-09-15 15:49:05 +00:00
|
|
|
u_int width = ud->width, xx, not_wrap;
|
2017-02-08 16:45:18 +00:00
|
|
|
int selected, skip = 1;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
/* Ignore padding cells. */
|
2009-06-01 22:58:49 +00:00
|
|
|
if (gc->flags & GRID_FLAG_PADDING)
|
|
|
|
return;
|
2009-10-17 08:32:18 +00:00
|
|
|
|
2023-09-15 15:49:05 +00:00
|
|
|
/* Get the previous cell to check for combining. */
|
|
|
|
if (screen_write_combine(ctx, gc) != 0)
|
2021-08-06 09:34:09 +00:00
|
|
|
return;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-02-09 10:09:14 +00:00
|
|
|
/* Flush any existing scrolling. */
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 1, __func__);
|
2017-02-09 10:09:14 +00:00
|
|
|
|
2017-02-08 16:45:18 +00:00
|
|
|
/* If this character doesn't fit, ignore it. */
|
|
|
|
if ((~s->mode & MODE_WRAP) &&
|
|
|
|
width > 1 &&
|
|
|
|
(width > sx || (s->cx != sx && s->cx > sx - width)))
|
|
|
|
return;
|
|
|
|
|
2009-06-03 23:37:30 +00:00
|
|
|
/* If in insert mode, make space for the cells. */
|
2016-10-12 15:43:51 +00:00
|
|
|
if (s->mode & MODE_INSERT) {
|
2017-02-08 16:45:18 +00:00
|
|
|
grid_view_insert_cells(s->grid, s->cx, s->cy, width, 8);
|
|
|
|
skip = 0;
|
|
|
|
}
|
2009-06-03 23:37:30 +00:00
|
|
|
|
2009-08-08 15:57:49 +00:00
|
|
|
/* Check this will fit on the current line and wrap if not. */
|
2016-07-15 00:49:08 +00:00
|
|
|
if ((s->mode & MODE_WRAP) && s->cx > sx - width) {
|
2017-06-12 10:57:35 +00:00
|
|
|
log_debug("%s: wrapped at %u,%u", __func__, s->cx, s->cy);
|
2017-05-12 13:00:56 +00:00
|
|
|
screen_write_linefeed(ctx, 1, 8);
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, 0, -1);
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 1, __func__);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2013-03-22 10:36:53 +00:00
|
|
|
/* Sanity check cursor position. */
|
2016-07-15 00:49:08 +00:00
|
|
|
if (s->cx > sx - width || s->cy > sy - 1)
|
2009-06-01 22:58:49 +00:00
|
|
|
return;
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
2017-02-08 08:50:10 +00:00
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/* Handle overwriting of UTF-8 characters. */
|
2018-07-04 09:44:07 +00:00
|
|
|
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
|
2016-07-15 00:49:08 +00:00
|
|
|
if (gl->flags & GRID_LINE_EXTENDED) {
|
|
|
|
grid_view_get_cell(gd, s->cx, s->cy, &now_gc);
|
|
|
|
if (screen_write_overwrite(ctx, &now_gc, width))
|
|
|
|
skip = 0;
|
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the new character is UTF-8 wide, fill in padding cells. Have
|
|
|
|
* already ensured there is enough room.
|
|
|
|
*/
|
2016-05-30 09:32:24 +00:00
|
|
|
for (xx = s->cx + 1; xx < s->cx + width; xx++) {
|
2017-10-05 08:12:24 +00:00
|
|
|
log_debug("%s: new padding at %u,%u", __func__, xx, s->cy);
|
2020-06-02 20:51:46 +00:00
|
|
|
grid_view_set_padding(gd, xx, s->cy);
|
2016-05-30 09:32:24 +00:00
|
|
|
skip = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If no change, do not draw. */
|
2016-07-15 00:49:08 +00:00
|
|
|
if (skip) {
|
|
|
|
if (s->cx >= gl->cellsize)
|
|
|
|
skip = grid_cells_equal(gc, &grid_default_cell);
|
|
|
|
else {
|
|
|
|
gce = &gl->celldata[s->cx];
|
|
|
|
if (gce->flags & GRID_FLAG_EXTENDED)
|
|
|
|
skip = 0;
|
2016-10-05 12:36:36 +00:00
|
|
|
else if (gc->flags != gce->flags)
|
2016-07-15 00:49:08 +00:00
|
|
|
skip = 0;
|
|
|
|
else if (gc->attr != gce->data.attr)
|
|
|
|
skip = 0;
|
|
|
|
else if (gc->fg != gce->data.fg)
|
|
|
|
skip = 0;
|
|
|
|
else if (gc->bg != gce->data.bg)
|
|
|
|
skip = 0;
|
2016-10-05 12:36:36 +00:00
|
|
|
else if (gc->data.width != 1)
|
|
|
|
skip = 0;
|
2017-02-08 16:45:18 +00:00
|
|
|
else if (gc->data.size != 1)
|
|
|
|
skip = 0;
|
2016-10-05 12:36:36 +00:00
|
|
|
else if (gce->data.data != gc->data.data[0])
|
2016-07-15 00:49:08 +00:00
|
|
|
skip = 0;
|
|
|
|
}
|
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2017-06-04 08:02:20 +00:00
|
|
|
/* Update the selected flag and set the cell. */
|
2016-06-06 07:28:52 +00:00
|
|
|
selected = screen_check_selection(s, s->cx, s->cy);
|
2017-02-08 16:45:18 +00:00
|
|
|
if (selected && (~gc->flags & GRID_FLAG_SELECTED)) {
|
2016-06-06 07:28:52 +00:00
|
|
|
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
|
|
|
tmp_gc.flags |= GRID_FLAG_SELECTED;
|
|
|
|
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
|
2017-02-08 16:45:18 +00:00
|
|
|
} else if (!selected && (gc->flags & GRID_FLAG_SELECTED)) {
|
2016-06-06 07:28:52 +00:00
|
|
|
memcpy(&tmp_gc, gc, sizeof tmp_gc);
|
|
|
|
tmp_gc.flags &= ~GRID_FLAG_SELECTED;
|
|
|
|
grid_view_set_cell(gd, s->cx, s->cy, &tmp_gc);
|
|
|
|
} else if (!skip)
|
2016-05-30 09:32:24 +00:00
|
|
|
grid_view_set_cell(gd, s->cx, s->cy, gc);
|
2017-02-08 16:45:18 +00:00
|
|
|
if (selected)
|
|
|
|
skip = 0;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2013-03-22 10:36:53 +00:00
|
|
|
/*
|
|
|
|
* Move the cursor. If not wrapping, stick at the last character and
|
|
|
|
* replace it.
|
|
|
|
*/
|
2023-09-15 15:49:05 +00:00
|
|
|
not_wrap = !(s->mode & MODE_WRAP);
|
|
|
|
if (s->cx <= sx - not_wrap - width)
|
Support for windows larger than visible on the attached client. This has
been a limitation for a long time.
There are two new options, window-size and default-size, and a new
command, resize-window. The force-width and force-height options and the
session_width and session_height formats have been removed.
The new window-size option tells tmux how to work out the size of
windows: largest means it picks the size of the largest session,
smallest the smallest session (similar to the old behaviour) and manual
means that it does not automatically resize windows. The default is
currently largest but this may change. aggressive-resize modifies the
choice of session for largest and smallest as it did before.
If a window is in a session attached to a client that is too small, only
part of the window is shown. tmux attempts to keep the cursor visible,
so the part of the window displayed is changed as the cursor moves (with
a small delay, to try and avoid excess redrawing when applications
redraw status lines or similar that are not currently visible). The
offset of the visible portion of the window is shown in status-right.
Drawing windows which are larger than the client is not as efficient as
those which fit, particularly when the cursor moves, so it is
recommended to avoid using this on slow machines or networks (set
window-size to smallest or manual).
The resize-window command can be used to resize a window manually. If it
is used, the window-size option is automatically set to manual for the
window (undo this with "setw -u window-size"). resize-window works in a
similar way to resize-pane (-U -D -L -R -x -y flags) but also has -a and
-A flags. -a sets the window to the size of the smallest client (what it
would be if window-size was smallest) and -A the largest.
For the same behaviour as force-width or force-height, use resize-window
-x or -y, and "setw -u window-size" to revert to automatic sizing..
If the global window-size option is set to manual, the default-size
option is used for new windows. If -x or -y is used with new-session,
that sets the default-size option for the new session.
The maximum size of a window is 10000x10000. But expect applications to
complain and much higher memory use if making a window excessively
big. The minimum size is the size required for the current layout
including borders.
The refresh-client command can be used to pan around a window, -U -D -L
-R moves up, down, left or right and -c returns to automatic cursor
tracking. The position is reset when the current window is changed.
2018-10-18 08:38:01 +00:00
|
|
|
screen_write_set_cursor(ctx, s->cx + width, -1);
|
2013-03-22 10:36:53 +00:00
|
|
|
else
|
2023-09-15 15:49:05 +00:00
|
|
|
screen_write_set_cursor(ctx, sx - not_wrap, -1);
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2016-05-30 09:32:24 +00:00
|
|
|
/* Create space for character in insert mode. */
|
2017-02-08 16:45:18 +00:00
|
|
|
if (s->mode & MODE_INSERT) {
|
2020-04-16 17:24:28 +00:00
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2009-07-22 20:53:38 +00:00
|
|
|
ttyctx.num = width;
|
|
|
|
tty_write(tty_cmd_insertcharacter, &ttyctx);
|
|
|
|
}
|
2016-05-30 09:32:24 +00:00
|
|
|
|
|
|
|
/* Write to the screen. */
|
2017-02-08 16:45:18 +00:00
|
|
|
if (!skip) {
|
|
|
|
if (selected) {
|
|
|
|
screen_select_cell(s, &tmp_gc, gc);
|
|
|
|
ttyctx.cell = &tmp_gc;
|
|
|
|
} else
|
|
|
|
ttyctx.cell = gc;
|
2009-07-22 18:02:23 +00:00
|
|
|
tty_write(tty_cmd_cell, &ttyctx);
|
2021-01-29 09:48:43 +00:00
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
|
|
|
|
2023-09-15 15:49:05 +00:00
|
|
|
/* Combine a UTF-8 zero-width character onto the previous if necessary. */
|
|
|
|
static int
|
|
|
|
screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
2009-10-20 17:33:33 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid *gd = s->grid;
|
2023-09-15 15:49:05 +00:00
|
|
|
const struct utf8_data *ud = &gc->data;
|
|
|
|
u_int n, cx = s->cx, cy = s->cy;
|
|
|
|
struct grid_cell last;
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
int force_wide = 0, zero_width = 0;
|
2009-10-20 17:33:33 +00:00
|
|
|
|
2023-09-15 15:49:05 +00:00
|
|
|
/*
|
|
|
|
* Is this character which makes no sense without being combined? If
|
|
|
|
* this is true then flag it here and discard the character (return 1)
|
|
|
|
* if we cannot combine it.
|
|
|
|
*/
|
|
|
|
if (utf8_is_zwj(ud))
|
|
|
|
zero_width = 1;
|
|
|
|
else if (utf8_is_vs(ud))
|
|
|
|
zero_width = force_wide = 1;
|
|
|
|
else if (ud->width == 0)
|
|
|
|
zero_width = 1;
|
|
|
|
|
|
|
|
/* Cannot combine empty character or at left. */
|
|
|
|
if (ud->size < 2 || cx == 0)
|
|
|
|
return (zero_width);
|
|
|
|
log_debug("%s: character %.*s at %u,%u (width %u)", __func__,
|
|
|
|
(int)ud->size, ud->data, cx, cy, ud->width);
|
|
|
|
|
|
|
|
/* Find the cell to combine with. */
|
|
|
|
n = 1;
|
|
|
|
grid_view_get_cell(gd, cx - n, cy, &last);
|
|
|
|
if (cx != 1 && (last.flags & GRID_FLAG_PADDING)) {
|
|
|
|
n = 2;
|
|
|
|
grid_view_get_cell(gd, cx - n, cy, &last);
|
2023-02-10 14:01:43 +00:00
|
|
|
}
|
2023-09-15 15:49:05 +00:00
|
|
|
if (n != last.data.width || (last.flags & GRID_FLAG_PADDING))
|
|
|
|
return (zero_width);
|
2009-11-11 18:53:21 +00:00
|
|
|
|
2023-09-15 15:49:05 +00:00
|
|
|
/*
|
|
|
|
* Check if we need to combine characters. This could be zero width
|
2023-10-23 08:12:00 +00:00
|
|
|
* (set above), a modifier character (with an existing Unicode
|
2023-09-15 15:49:05 +00:00
|
|
|
* character) or a previous ZWJ.
|
|
|
|
*/
|
|
|
|
if (!zero_width) {
|
|
|
|
if (utf8_is_modifier(ud)) {
|
|
|
|
if (last.data.size < 2)
|
|
|
|
return (0);
|
|
|
|
force_wide = 1;
|
|
|
|
} else if (!utf8_has_zwj(&last.data))
|
|
|
|
return (0);
|
2017-02-06 13:23:00 +00:00
|
|
|
}
|
2009-10-20 17:33:33 +00:00
|
|
|
|
2023-10-30 16:05:30 +00:00
|
|
|
/* Check if this combined character would be too long. */
|
|
|
|
if (last.data.size + ud->size > sizeof last.data.data)
|
|
|
|
return (0);
|
|
|
|
|
2023-09-15 15:49:05 +00:00
|
|
|
/* Combining; flush any pending output. */
|
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2017-02-06 13:23:00 +00:00
|
|
|
|
2023-09-15 15:49:05 +00:00
|
|
|
log_debug("%s: %.*s -> %.*s at %u,%u (offset %u, width %u)", __func__,
|
|
|
|
(int)ud->size, ud->data, (int)last.data.size, last.data.data,
|
|
|
|
cx - n, cy, n, last.data.width);
|
2009-10-20 17:33:33 +00:00
|
|
|
|
2015-11-13 08:09:28 +00:00
|
|
|
/* Append the data. */
|
2023-09-15 15:49:05 +00:00
|
|
|
memcpy(last.data.data + last.data.size, ud->data, ud->size);
|
|
|
|
last.data.size += ud->size;
|
|
|
|
|
|
|
|
/* Force the width to 2 for modifiers and variation selector. */
|
|
|
|
if (last.data.width == 1 && force_wide) {
|
|
|
|
last.data.width = 2;
|
|
|
|
n = 2;
|
|
|
|
cx++;
|
|
|
|
} else
|
|
|
|
force_wide = 0;
|
2022-12-16 08:19:58 +00:00
|
|
|
|
2015-11-13 08:09:28 +00:00
|
|
|
/* Set the new cell. */
|
2023-09-15 15:49:05 +00:00
|
|
|
grid_view_set_cell(gd, cx - n, cy, &last);
|
|
|
|
if (force_wide)
|
2024-03-21 12:10:57 +00:00
|
|
|
grid_view_set_padding(gd, cx - 1, cy);
|
2009-10-20 17:33:33 +00:00
|
|
|
|
2023-09-15 15:49:05 +00:00
|
|
|
/*
|
|
|
|
* Redraw the combined cell. If forcing the cell to width 2, reset the
|
|
|
|
* cached cursor position in the tty, since we don't really know
|
|
|
|
* whether the terminal thought the character was width 1 or width 2
|
|
|
|
* and what it is going to do now.
|
|
|
|
*/
|
|
|
|
screen_write_set_cursor(ctx, cx - n, cy);
|
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
|
|
|
ttyctx.cell = &last;
|
|
|
|
ttyctx.num = force_wide; /* reset cached cursor position */
|
|
|
|
tty_write(tty_cmd_cell, &ttyctx);
|
|
|
|
screen_write_set_cursor(ctx, cx, cy);
|
|
|
|
|
|
|
|
return (1);
|
2009-10-20 17:33:33 +00:00
|
|
|
}
|
|
|
|
|
2009-06-01 22:58:49 +00:00
|
|
|
/*
|
|
|
|
* UTF-8 wide characters are a bit of an annoyance. They take up more than one
|
|
|
|
* cell on the screen, so following cells must not be drawn by marking them as
|
|
|
|
* padding.
|
|
|
|
*
|
|
|
|
* So far, so good. The problem is, when overwriting a padding cell, or a UTF-8
|
|
|
|
* character, it is necessary to also overwrite any other cells which covered
|
|
|
|
* by the same character.
|
|
|
|
*/
|
2016-05-30 09:32:24 +00:00
|
|
|
static int
|
|
|
|
screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
|
|
|
u_int width)
|
2009-06-01 22:58:49 +00:00
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid *gd = s->grid;
|
2016-05-30 09:32:24 +00:00
|
|
|
struct grid_cell tmp_gc;
|
2009-06-01 22:58:49 +00:00
|
|
|
u_int xx;
|
2016-05-30 09:32:24 +00:00
|
|
|
int done = 0;
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2016-05-30 09:32:24 +00:00
|
|
|
if (gc->flags & GRID_FLAG_PADDING) {
|
2009-06-01 22:58:49 +00:00
|
|
|
/*
|
|
|
|
* A padding cell, so clear any following and leading padding
|
|
|
|
* cells back to the character. Don't overwrite the current
|
|
|
|
* cell as that happens later anyway.
|
|
|
|
*/
|
|
|
|
xx = s->cx + 1;
|
|
|
|
while (--xx > 0) {
|
2016-05-30 09:32:24 +00:00
|
|
|
grid_view_get_cell(gd, xx, s->cy, &tmp_gc);
|
|
|
|
if (~tmp_gc.flags & GRID_FLAG_PADDING)
|
2009-06-01 22:58:49 +00:00
|
|
|
break;
|
2017-10-05 08:12:24 +00:00
|
|
|
log_debug("%s: padding at %u,%u", __func__, xx, s->cy);
|
2009-06-01 22:58:49 +00:00
|
|
|
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Overwrite the character at the start of this padding. */
|
2017-10-05 08:12:24 +00:00
|
|
|
log_debug("%s: character at %u,%u", __func__, xx, s->cy);
|
2009-06-01 22:58:49 +00:00
|
|
|
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
|
2016-05-30 09:32:24 +00:00
|
|
|
done = 1;
|
2010-06-21 00:11:12 +00:00
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
|
2010-06-21 00:11:12 +00:00
|
|
|
/*
|
2016-10-05 12:36:36 +00:00
|
|
|
* Overwrite any padding cells that belong to any UTF-8 characters
|
|
|
|
* we'll be overwriting with the current character.
|
2010-06-21 00:11:12 +00:00
|
|
|
*/
|
2016-10-05 12:36:36 +00:00
|
|
|
if (width != 1 ||
|
|
|
|
gc->data.width != 1 ||
|
|
|
|
gc->flags & GRID_FLAG_PADDING) {
|
2016-05-30 09:32:24 +00:00
|
|
|
xx = s->cx + width - 1;
|
|
|
|
while (++xx < screen_size_x(s)) {
|
|
|
|
grid_view_get_cell(gd, xx, s->cy, &tmp_gc);
|
|
|
|
if (~tmp_gc.flags & GRID_FLAG_PADDING)
|
|
|
|
break;
|
2019-11-28 10:17:22 +00:00
|
|
|
log_debug("%s: overwrite at %u,%u", __func__, xx,
|
|
|
|
s->cy);
|
2016-05-30 09:32:24 +00:00
|
|
|
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
|
|
|
|
done = 1;
|
|
|
|
}
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
2016-05-30 09:32:24 +00:00
|
|
|
|
|
|
|
return (done);
|
2009-06-01 22:58:49 +00:00
|
|
|
}
|
2011-03-07 23:46:27 +00:00
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
/* Set external clipboard. */
|
2011-05-18 20:24:29 +00:00
|
|
|
void
|
2022-06-09 09:12:55 +00:00
|
|
|
screen_write_setselection(struct screen_write_ctx *ctx, const char *flags,
|
|
|
|
u_char *str, u_int len)
|
2011-05-18 20:24:29 +00:00
|
|
|
{
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
2011-05-18 20:24:29 +00:00
|
|
|
ttyctx.ptr = str;
|
2022-06-09 09:12:55 +00:00
|
|
|
ttyctx.ptr2 = (void *)flags;
|
2011-05-18 20:24:29 +00:00
|
|
|
ttyctx.num = len;
|
|
|
|
|
|
|
|
tty_write(tty_cmd_setselection, &ttyctx);
|
|
|
|
}
|
|
|
|
|
2017-02-08 15:49:29 +00:00
|
|
|
/* Write unmodified string. */
|
2011-03-07 23:46:27 +00:00
|
|
|
void
|
2022-08-02 11:09:26 +00:00
|
|
|
screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len,
|
|
|
|
int allow_invisible_panes)
|
2011-03-07 23:46:27 +00:00
|
|
|
{
|
2016-05-27 23:02:17 +00:00
|
|
|
struct tty_ctx ttyctx;
|
2011-03-07 23:46:27 +00:00
|
|
|
|
2020-04-16 16:13:56 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
2011-03-07 23:46:27 +00:00
|
|
|
ttyctx.ptr = str;
|
|
|
|
ttyctx.num = len;
|
2022-08-02 11:09:26 +00:00
|
|
|
ttyctx.allow_invisible_panes = allow_invisible_panes;
|
2011-03-07 23:46:27 +00:00
|
|
|
|
|
|
|
tty_write(tty_cmd_rawstring, &ttyctx);
|
|
|
|
}
|
2020-05-16 15:34:08 +00:00
|
|
|
|
2023-08-22 07:43:35 +00:00
|
|
|
#ifdef ENABLE_SIXEL
|
|
|
|
/* Write a SIXEL image. */
|
|
|
|
void
|
|
|
|
screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si,
|
|
|
|
u_int bg)
|
|
|
|
{
|
|
|
|
struct screen *s = ctx->s;
|
|
|
|
struct grid *gd = s->grid;
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
u_int x, y, sx, sy, cx = s->cx, cy = s->cy, i, lines;
|
|
|
|
struct sixel_image *new;
|
|
|
|
|
|
|
|
sixel_size_in_cells(si, &x, &y);
|
|
|
|
if (x > screen_size_x(s) || y > screen_size_y(s)) {
|
|
|
|
if (x > screen_size_x(s) - cx)
|
|
|
|
sx = screen_size_x(s) - cx;
|
|
|
|
else
|
|
|
|
sx = x;
|
|
|
|
if (y > screen_size_y(s) - 1)
|
|
|
|
sy = screen_size_y(s) - 1;
|
|
|
|
else
|
|
|
|
sy = y;
|
|
|
|
new = sixel_scale(si, 0, 0, 0, y - sy, sx, sy, 1);
|
|
|
|
sixel_free(si);
|
|
|
|
si = new;
|
2024-03-21 11:37:09 +00:00
|
|
|
|
|
|
|
/* Bail out if the image cannot be scaled. */
|
|
|
|
if (si == NULL)
|
|
|
|
return;
|
2023-08-22 07:43:35 +00:00
|
|
|
sixel_size_in_cells(si, &x, &y);
|
|
|
|
}
|
|
|
|
|
|
|
|
sy = screen_size_y(s) - cy;
|
|
|
|
if (sy < y) {
|
|
|
|
lines = y - sy + 1;
|
|
|
|
if (image_scroll_up(s, lines) && ctx->wp != NULL)
|
|
|
|
ctx->wp->flags |= PANE_REDRAW;
|
|
|
|
for (i = 0; i < lines; i++) {
|
|
|
|
grid_view_scroll_region_up(gd, 0, screen_size_y(s) - 1,
|
|
|
|
bg);
|
|
|
|
screen_write_collect_scroll(ctx, bg);
|
|
|
|
}
|
|
|
|
ctx->scrolled += lines;
|
|
|
|
if (lines > cy)
|
|
|
|
screen_write_cursormove(ctx, -1, 0, 0);
|
|
|
|
else
|
|
|
|
screen_write_cursormove(ctx, -1, cy - lines, 0);
|
|
|
|
}
|
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
|
|
|
|
|
|
|
screen_write_initctx(ctx, &ttyctx, 0);
|
|
|
|
ttyctx.ptr = image_store(s, si);
|
|
|
|
|
|
|
|
tty_write(tty_cmd_sixelimage, &ttyctx);
|
|
|
|
|
|
|
|
screen_write_cursormove(ctx, 0, cy + y, 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-05-16 15:34:08 +00:00
|
|
|
/* Turn alternate screen on. */
|
|
|
|
void
|
|
|
|
screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
|
|
|
int cursor)
|
|
|
|
{
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
struct window_pane *wp = ctx->wp;
|
|
|
|
|
|
|
|
if (wp != NULL && !options_get_number(wp->options, "alternate-screen"))
|
|
|
|
return;
|
2021-01-27 10:42:52 +00:00
|
|
|
|
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2020-05-16 15:34:08 +00:00
|
|
|
screen_alternate_on(ctx->s, gc, cursor);
|
|
|
|
|
2022-10-25 17:53:31 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
|
|
|
if (ttyctx.redraw_cb != NULL)
|
2022-10-25 09:04:49 +00:00
|
|
|
ttyctx.redraw_cb(&ttyctx);
|
2020-05-16 15:34:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Turn alternate screen off. */
|
|
|
|
void
|
|
|
|
screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
|
|
|
int cursor)
|
|
|
|
{
|
|
|
|
struct tty_ctx ttyctx;
|
|
|
|
struct window_pane *wp = ctx->wp;
|
|
|
|
|
|
|
|
if (wp != NULL && !options_get_number(wp->options, "alternate-screen"))
|
|
|
|
return;
|
2021-01-27 10:42:52 +00:00
|
|
|
|
|
|
|
screen_write_collect_flush(ctx, 0, __func__);
|
2020-05-16 15:34:08 +00:00
|
|
|
screen_alternate_off(ctx->s, gc, cursor);
|
|
|
|
|
2022-10-25 17:53:31 +00:00
|
|
|
screen_write_initctx(ctx, &ttyctx, 1);
|
|
|
|
if (ttyctx.redraw_cb != NULL)
|
2022-10-25 09:04:49 +00:00
|
|
|
ttyctx.redraw_cb(&ttyctx);
|
2020-05-16 15:34:08 +00:00
|
|
|
}
|