mirror of
https://github.com/tmux/tmux.git
synced 2026-02-25 12:25:04 +00:00
Merge branch 'master' into feature-floating-window-panes
This commit is contained in:
15
cmd-find.c
15
cmd-find.c
@@ -924,6 +924,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
|
||||
const char *target, enum cmd_find_type type, int flags)
|
||||
{
|
||||
struct mouse_event *m;
|
||||
struct client *c;
|
||||
struct cmd_find_state current;
|
||||
char *colon, *period, *copy = NULL, tmp[256];
|
||||
const char *session, *window, *pane, *s;
|
||||
@@ -995,6 +996,20 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
|
||||
if (target == NULL || *target == '\0')
|
||||
goto current;
|
||||
|
||||
if (strcmp(target, "@") == 0 ||
|
||||
strcmp(target, "{active}") == 0 ||
|
||||
strcmp(target, "{current}") == 0) {
|
||||
c = cmdq_get_client(item);
|
||||
if (c == NULL) {
|
||||
cmdq_error(item, "no current client");
|
||||
goto error;
|
||||
}
|
||||
fs->wl = c->session->curw;
|
||||
fs->wp = c->session->curw->window->active;
|
||||
fs->w = c->session->curw->window;
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* Mouse target is a plain = or {mouse}. */
|
||||
if (strcmp(target, "=") == 0 || strcmp(target, "{mouse}") == 0) {
|
||||
m = &cmdq_get_event(item)->m;
|
||||
|
||||
@@ -109,7 +109,8 @@ cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args,
|
||||
key = key_string_lookup_key(bd->key, 0);
|
||||
|
||||
if (bd->note == NULL || *bd->note == '\0')
|
||||
note = cmd_list_print(bd->cmdlist, 1);
|
||||
note = cmd_list_print(bd->cmdlist,
|
||||
CMD_LIST_PRINT_ESCAPED|CMD_LIST_PRINT_NO_GROUPS);
|
||||
else
|
||||
note = xstrdup(bd->note);
|
||||
tmp = utf8_padcstr(key, keywidth + 1);
|
||||
@@ -288,7 +289,8 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
|
||||
tmpused = strlcat(tmp, " ", tmpsize);
|
||||
free(cp);
|
||||
|
||||
cp = cmd_list_print(bd->cmdlist, 1);
|
||||
cp = cmd_list_print(bd->cmdlist,
|
||||
CMD_LIST_PRINT_ESCAPED|CMD_LIST_PRINT_NO_GROUPS);
|
||||
cplen = strlen(cp);
|
||||
while (tmpused + cplen + 1 >= tmpsize) {
|
||||
tmpsize *= 2;
|
||||
|
||||
23
cmd.c
23
cmd.c
@@ -682,11 +682,16 @@ cmd_list_copy(const struct cmd_list *cmdlist, int argc, char **argv)
|
||||
|
||||
/* Get a command list as a string. */
|
||||
char *
|
||||
cmd_list_print(const struct cmd_list *cmdlist, int escaped)
|
||||
cmd_list_print(const struct cmd_list *cmdlist, int flags)
|
||||
{
|
||||
struct cmd *cmd, *next;
|
||||
char *buf, *this;
|
||||
size_t len;
|
||||
const char *separator;
|
||||
int escaped = flags & CMD_LIST_PRINT_ESCAPED;
|
||||
int no_groups = flags & CMD_LIST_PRINT_NO_GROUPS;
|
||||
const char *single_separator = escaped ? " \\; " : " ; ";
|
||||
const char *double_separator = escaped ? " \\;\\; " : " ;; ";
|
||||
|
||||
len = 1;
|
||||
buf = xcalloc(1, len);
|
||||
@@ -701,17 +706,11 @@ cmd_list_print(const struct cmd_list *cmdlist, int escaped)
|
||||
|
||||
next = TAILQ_NEXT(cmd, qentry);
|
||||
if (next != NULL) {
|
||||
if (cmd->group != next->group) {
|
||||
if (escaped)
|
||||
strlcat(buf, " \\;\\; ", len);
|
||||
else
|
||||
strlcat(buf, " ;; ", len);
|
||||
} else {
|
||||
if (escaped)
|
||||
strlcat(buf, " \\; ", len);
|
||||
else
|
||||
strlcat(buf, " ; ", len);
|
||||
}
|
||||
if (!no_groups && cmd->group != next->group)
|
||||
separator = double_separator;
|
||||
else
|
||||
separator = single_separator;
|
||||
strlcat(buf, separator, len);
|
||||
}
|
||||
|
||||
free(this);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: imsg-buffer.c,v 1.35 2025/06/04 09:06:56 claudio Exp $ */
|
||||
/* $OpenBSD: imsg-buffer.c,v 1.36 2025/08/25 08:29:49 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
|
||||
@@ -699,8 +699,6 @@ msgbuf_queuelen(struct msgbuf *msgbuf)
|
||||
void
|
||||
msgbuf_clear(struct msgbuf *msgbuf)
|
||||
{
|
||||
struct ibuf *buf;
|
||||
|
||||
/* write side */
|
||||
ibufq_flush(&msgbuf->bufs);
|
||||
|
||||
|
||||
4
format.c
4
format.c
@@ -4464,7 +4464,9 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt)
|
||||
for (i = 0; i < n; i++) {
|
||||
s = l[i];
|
||||
format_log(es, "session loop: $%u", s->id);
|
||||
if (active != NULL && s->id == ft->c->session->id)
|
||||
if (active != NULL &&
|
||||
ft->c != NULL &&
|
||||
s->id == ft->c->session->id)
|
||||
use = active;
|
||||
else
|
||||
use = all;
|
||||
|
||||
6
grid.c
6
grid.c
@@ -361,9 +361,13 @@ grid_compare(struct grid *ga, struct grid *gb)
|
||||
static void
|
||||
grid_trim_history(struct grid *gd, u_int ny)
|
||||
{
|
||||
u_int remaining;
|
||||
|
||||
grid_free_lines(gd, 0, ny);
|
||||
remaining = gd->hsize + gd->sy - ny;
|
||||
memmove(&gd->linedata[0], &gd->linedata[ny],
|
||||
(gd->hsize + gd->sy - ny) * (sizeof *gd->linedata));
|
||||
remaining * (sizeof *gd->linedata));
|
||||
memset(&gd->linedata[remaining], 0, ny * (sizeof *gd->linedata));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -313,12 +313,6 @@ static struct input_key_entry input_key_defaults[] = {
|
||||
{ .key = KEYC_DC|KEYC_BUILD_MODIFIERS,
|
||||
.data = "\033[3;_~"
|
||||
},
|
||||
{ .key = KEYC_REPORT_DARK_THEME,
|
||||
.data = "\033[?997;1n"
|
||||
},
|
||||
{ .key = KEYC_REPORT_LIGHT_THEME,
|
||||
.data = "\033[?997;2n"
|
||||
},
|
||||
};
|
||||
static const key_code input_key_modifiers[] = {
|
||||
0,
|
||||
|
||||
34
input.c
34
input.c
@@ -63,7 +63,7 @@ struct input_request {
|
||||
struct input_ctx *ictx;
|
||||
|
||||
enum input_request_type type;
|
||||
time_t t;
|
||||
uint64_t t;
|
||||
enum input_end_type end;
|
||||
|
||||
int idx;
|
||||
@@ -72,7 +72,7 @@ struct input_request {
|
||||
TAILQ_ENTRY(input_request) entry;
|
||||
TAILQ_ENTRY(input_request) centry;
|
||||
};
|
||||
#define INPUT_REQUEST_TIMEOUT 2
|
||||
#define INPUT_REQUEST_TIMEOUT 500
|
||||
|
||||
/* Input parser cell. */
|
||||
struct input_cell {
|
||||
@@ -1902,6 +1902,8 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
|
||||
break;
|
||||
case 2031:
|
||||
screen_write_mode_clear(sctx, MODE_THEME_UPDATES);
|
||||
if (ictx->wp != NULL)
|
||||
ictx->wp->flags &= ~PANE_THEMECHANGED;
|
||||
break;
|
||||
case 2026: /* synchronized output */
|
||||
screen_write_stop_sync(ictx->wp);
|
||||
@@ -2005,6 +2007,10 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
||||
break;
|
||||
case 2031:
|
||||
screen_write_mode_set(sctx, MODE_THEME_UPDATES);
|
||||
if (ictx->wp != NULL) {
|
||||
ictx->wp->last_theme = window_pane_get_theme(ictx->wp);
|
||||
ictx->wp->flags &= ~PANE_THEMECHANGED;
|
||||
}
|
||||
break;
|
||||
case 2026: /* synchronized output */
|
||||
screen_write_start_sync(ictx->wp);
|
||||
@@ -3237,7 +3243,7 @@ input_request_timer_callback(__unused int fd, __unused short events, void *arg)
|
||||
{
|
||||
struct input_ctx *ictx = arg;
|
||||
struct input_request *ir, *ir1;
|
||||
time_t t = time(NULL);
|
||||
uint64_t t = get_timer();
|
||||
|
||||
TAILQ_FOREACH_SAFE(ir, &ictx->requests, entry, ir1) {
|
||||
if (ir->t >= t - INPUT_REQUEST_TIMEOUT)
|
||||
@@ -3254,7 +3260,7 @@ input_request_timer_callback(__unused int fd, __unused short events, void *arg)
|
||||
static void
|
||||
input_start_request_timer(struct input_ctx *ictx)
|
||||
{
|
||||
struct timeval tv = { .tv_sec = 0, .tv_usec = 500000 };
|
||||
struct timeval tv = { .tv_sec = 0, .tv_usec = 100000 };
|
||||
|
||||
event_del(&ictx->request_timer);
|
||||
event_add(&ictx->request_timer, &tv);
|
||||
@@ -3269,7 +3275,7 @@ input_make_request(struct input_ctx *ictx, enum input_request_type type)
|
||||
ir = xcalloc (1, sizeof *ir);
|
||||
ir->type = type;
|
||||
ir->ictx = ictx;
|
||||
ir->t = time(NULL);
|
||||
ir->t = get_timer();
|
||||
|
||||
if (++ictx->request_count == 1)
|
||||
input_start_request_timer(ictx);
|
||||
@@ -3390,7 +3396,11 @@ input_request_reply(struct client *c, enum input_request_type type, void *data)
|
||||
input_free_request(ir);
|
||||
continue;
|
||||
}
|
||||
if (type == INPUT_REQUEST_PALETTE && pd->idx == ir->idx) {
|
||||
if (type == INPUT_REQUEST_PALETTE) {
|
||||
if (pd->idx != ir->idx) {
|
||||
input_free_request(ir);
|
||||
continue;
|
||||
}
|
||||
found = ir;
|
||||
break;
|
||||
}
|
||||
@@ -3432,14 +3442,24 @@ input_cancel_requests(struct client *c)
|
||||
static void
|
||||
input_report_current_theme(struct input_ctx *ictx)
|
||||
{
|
||||
switch (window_pane_get_theme(ictx->wp)) {
|
||||
struct window_pane *wp = ictx->wp;
|
||||
|
||||
if (wp != NULL) {
|
||||
wp->last_theme = window_pane_get_theme(wp);
|
||||
wp->flags &= ~PANE_THEMECHANGED;
|
||||
|
||||
switch (wp->last_theme) {
|
||||
case THEME_DARK:
|
||||
log_debug("%s: %%%u dark theme", __func__, wp->id);
|
||||
input_reply(ictx, 0, "\033[?997;1n");
|
||||
break;
|
||||
case THEME_LIGHT:
|
||||
log_debug("%s: %%%u light theme", __func__, wp->id);
|
||||
input_reply(ictx, 0, "\033[?997;2n");
|
||||
break;
|
||||
case THEME_UNKNOWN:
|
||||
log_debug("%s: %%%u unknown theme", __func__, wp->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,6 +444,7 @@ key_bindings_init(void)
|
||||
|
||||
/* Mouse button 1 down on pane. */
|
||||
"bind -n MouseDown1Pane { select-pane -t=; send -M }",
|
||||
"bind -n C-MouseDown1Pane { swap-pane -s@ }",
|
||||
|
||||
/* Mouse button 1 drag on pane. */
|
||||
"bind -n MouseDrag1Pane { if -F '#{||:#{pane_in_mode},#{mouse_any_flag}}' { send -M } { copy-mode -M } }",
|
||||
@@ -468,6 +469,7 @@ key_bindings_init(void)
|
||||
|
||||
/* Mouse button 1 down on status line. */
|
||||
"bind -n MouseDown1Status { switch-client -t= }",
|
||||
"bind -n C-MouseDown1Status { swap-window -t@ }",
|
||||
|
||||
/* Mouse wheel down on status line. */
|
||||
"bind -n WheelDownStatus { next-window }",
|
||||
|
||||
@@ -382,6 +382,14 @@ key_string_lookup_key(key_code key, int with_flags)
|
||||
s = "PasteEnd";
|
||||
goto append;
|
||||
}
|
||||
if (key == KEYC_REPORT_DARK_THEME) {
|
||||
s = "ReportDarkTheme";
|
||||
goto append;
|
||||
}
|
||||
if (key == KEYC_REPORT_LIGHT_THEME) {
|
||||
s = "ReportLightTheme";
|
||||
goto append;
|
||||
}
|
||||
if (key == KEYC_MOUSE) {
|
||||
s = "Mouse";
|
||||
goto append;
|
||||
|
||||
@@ -664,6 +664,13 @@ const struct options_table_entry options_table[] = {
|
||||
.text = "Time for which status line messages should appear."
|
||||
},
|
||||
|
||||
{ .name = "focus-follows-mouse",
|
||||
.type = OPTIONS_TABLE_FLAG,
|
||||
.scope = OPTIONS_TABLE_SESSION,
|
||||
.default_num = 0,
|
||||
.text = "Whether moving the mouse into a pane selects it."
|
||||
},
|
||||
|
||||
{ .name = "history-limit",
|
||||
.type = OPTIONS_TABLE_NUMBER,
|
||||
.scope = OPTIONS_TABLE_SESSION,
|
||||
@@ -970,6 +977,15 @@ const struct options_table_entry options_table[] = {
|
||||
.text = "Style of the cursor when in the command prompt."
|
||||
},
|
||||
|
||||
{ .name = "prompt-command-cursor-style",
|
||||
.type = OPTIONS_TABLE_CHOICE,
|
||||
.scope = OPTIONS_TABLE_SESSION,
|
||||
.choices = options_table_cursor_style_list,
|
||||
.default_num = 0,
|
||||
.text = "Style of the cursor in the command prompt when in command "
|
||||
"mode, if 'status-keys' is set to 'vi'."
|
||||
},
|
||||
|
||||
{ .name = "session-status-current-style",
|
||||
.type = OPTIONS_TABLE_STRING,
|
||||
.scope = OPTIONS_TABLE_WINDOW,
|
||||
|
||||
@@ -749,7 +749,7 @@ options_get_number(struct options *oo, const char *name)
|
||||
return (o->value.number);
|
||||
}
|
||||
|
||||
const struct cmd_list *
|
||||
struct cmd_list *
|
||||
options_get_command(struct options *oo, const char *name)
|
||||
{
|
||||
struct options_entry *o;
|
||||
|
||||
@@ -61,9 +61,9 @@ screen_write_get_citem(void)
|
||||
|
||||
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);
|
||||
TAILQ_REMOVE(&screen_write_citem_freelist, ci, entry);
|
||||
memset(ci, 0, sizeof *ci);
|
||||
return (ci);
|
||||
}
|
||||
return (xcalloc(1, sizeof *ci));
|
||||
}
|
||||
@@ -71,7 +71,7 @@ screen_write_get_citem(void)
|
||||
static void
|
||||
screen_write_free_citem(struct screen_write_citem *ci)
|
||||
{
|
||||
TAILQ_INSERT_TAIL(&screen_write_citem_freelist, ci, entry);
|
||||
TAILQ_INSERT_TAIL(&screen_write_citem_freelist, ci, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1833,8 +1833,16 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
|
||||
struct visible_ranges *vr;
|
||||
struct window_pane *wp = ctx->wp;
|
||||
|
||||
if (s->mode & MODE_SYNC)
|
||||
if (s->mode & MODE_SYNC) {
|
||||
for (y = 0; y < screen_size_y(s); y++) {
|
||||
cl = &ctx->s->write_list[y];
|
||||
TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
|
||||
TAILQ_REMOVE(&cl->items, ci, entry);
|
||||
screen_write_free_citem(ci);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->scrolled != 0) {
|
||||
log_debug("%s: scrolled %u (region %u-%u)", __func__,
|
||||
@@ -1945,7 +1953,7 @@ void
|
||||
screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
struct screen_write_citem *ci = ctx->item, *before;
|
||||
struct screen_write_citem *ci = ctx->item, *nci, *before;
|
||||
struct screen_write_cline *cl = &s->write_list[s->cy];
|
||||
struct grid_cell gc;
|
||||
u_int xx;
|
||||
@@ -1974,6 +1982,8 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
break;
|
||||
grid_view_set_cell(s->grid, xx, s->cy,
|
||||
&grid_default_cell);
|
||||
log_debug("%s: padding erased (before) at %u",
|
||||
__func__, xx);
|
||||
}
|
||||
if (xx != s->cx) {
|
||||
if (xx == 0)
|
||||
@@ -1981,8 +1991,19 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
if (gc.data.width > 1) {
|
||||
grid_view_set_cell(s->grid, xx, s->cy,
|
||||
&grid_default_cell);
|
||||
log_debug("%s: padding erased (before) at %u",
|
||||
__func__, xx);
|
||||
}
|
||||
}
|
||||
if (xx != s->cx) {
|
||||
nci = ctx->item;
|
||||
nci->type = CLEAR;
|
||||
nci->x = xx;
|
||||
nci->bg = 8;
|
||||
nci->used = s->cx - xx;
|
||||
TAILQ_INSERT_BEFORE(ci, nci, entry);
|
||||
ctx->item = screen_write_get_citem();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SIXEL
|
||||
@@ -1999,6 +2020,16 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
if (~gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
grid_view_set_cell(s->grid, xx, s->cy, &grid_default_cell);
|
||||
log_debug("%s: padding erased (after) at %u", __func__, xx);
|
||||
}
|
||||
if (xx != s->cx) {
|
||||
nci = ctx->item;
|
||||
nci->type = CLEAR;
|
||||
nci->x = s->cx;
|
||||
nci->bg = 8;
|
||||
nci->used = xx - s->cx;
|
||||
TAILQ_INSERT_AFTER(&cl->items, ci, nci, entry);
|
||||
ctx->item = screen_write_get_citem();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2069,7 +2100,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
struct tty_ctx ttyctx;
|
||||
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
||||
u_int width = ud->width, xx, not_wrap;
|
||||
int selected, skip = 1;
|
||||
int selected, skip = 1, redraw = 0;
|
||||
|
||||
/* Ignore padding cells. */
|
||||
if (gc->flags & GRID_FLAG_PADDING)
|
||||
@@ -2111,8 +2142,10 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
|
||||
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))
|
||||
if (screen_write_overwrite(ctx, &now_gc, width)) {
|
||||
redraw = 1;
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2189,6 +2222,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
ttyctx.cell = &tmp_gc;
|
||||
} else
|
||||
ttyctx.cell = gc;
|
||||
ttyctx.num = redraw ? 2 : 0;
|
||||
tty_write(tty_cmd_cell, &ttyctx);
|
||||
}
|
||||
}
|
||||
@@ -2483,8 +2517,10 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
screen_write_collect_flush(ctx, 0, __func__);
|
||||
screen_alternate_on(ctx->s, gc, cursor);
|
||||
|
||||
if (wp != NULL)
|
||||
if (wp != NULL) {
|
||||
layout_fix_panes(wp->window, NULL);
|
||||
server_redraw_window_borders(wp->window);
|
||||
}
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
@@ -2505,8 +2541,10 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
screen_write_collect_flush(ctx, 0, __func__);
|
||||
screen_alternate_off(ctx->s, gc, cursor);
|
||||
|
||||
if (wp != NULL)
|
||||
if (wp != NULL) {
|
||||
layout_fix_panes(wp->window, NULL);
|
||||
server_redraw_window_borders(wp->window);
|
||||
}
|
||||
|
||||
screen_write_initctx(ctx, &ttyctx, 1);
|
||||
if (ttyctx.redraw_cb != NULL)
|
||||
|
||||
2
screen.c
2
screen.c
@@ -765,6 +765,8 @@ screen_mode_to_string(int mode)
|
||||
strlcat(tmp, "KEYS_EXTENDED,", sizeof tmp);
|
||||
if (mode & MODE_KEYS_EXTENDED_2)
|
||||
strlcat(tmp, "KEYS_EXTENDED_2,", sizeof tmp);
|
||||
if (mode & MODE_THEME_UPDATES)
|
||||
strlcat(tmp, "THEME_UPDATES,", sizeof tmp);
|
||||
tmp[strlen(tmp) - 1] = '\0';
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
@@ -1092,8 +1092,16 @@ have_event:
|
||||
case NOTYPE:
|
||||
break;
|
||||
case MOVE:
|
||||
if (where == PANE)
|
||||
if (where == PANE) {
|
||||
key = KEYC_MOUSEMOVE_PANE;
|
||||
if (wp != NULL &&
|
||||
wp != w->active &&
|
||||
options_get_number(s->options, "focus-follows-mouse")) {
|
||||
window_set_active_pane(w, wp, 1);
|
||||
server_redraw_window_borders(w);
|
||||
server_status_window(w);
|
||||
}
|
||||
}
|
||||
if (where == STATUS)
|
||||
key = KEYC_MOUSEMOVE_STATUS;
|
||||
if (where == STATUS_LEFT)
|
||||
@@ -3012,7 +3020,8 @@ server_client_reset_state(struct client *c)
|
||||
|
||||
/*
|
||||
* Set mouse mode if requested. To support dragging, always use button
|
||||
* mode.
|
||||
* mode. For focus-follows-mouse, we need all-motion mode to receive
|
||||
* movement events.
|
||||
*/
|
||||
if (options_get_number(oo, "mouse")) {
|
||||
if (c->overlay_draw == NULL) {
|
||||
@@ -3022,7 +3031,9 @@ server_client_reset_state(struct client *c)
|
||||
mode |= MODE_MOUSE_ALL;
|
||||
}
|
||||
}
|
||||
if (~mode & MODE_MOUSE_ALL)
|
||||
if (options_get_number(oo, "focus-follows-mouse"))
|
||||
mode |= MODE_MOUSE_ALL;
|
||||
else if (~mode & MODE_MOUSE_ALL)
|
||||
mode |= MODE_MOUSE_BUTTON;
|
||||
}
|
||||
|
||||
@@ -3475,6 +3486,24 @@ server_client_read_only(struct cmdq_item *item, __unused void *data)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
/* Callback for default command. */
|
||||
static enum cmd_retval
|
||||
server_client_default_command(struct cmdq_item *item, __unused void *data)
|
||||
{
|
||||
struct client *c = cmdq_get_client(item);
|
||||
struct cmd_list *cmdlist;
|
||||
struct cmdq_item *new_item;
|
||||
|
||||
cmdlist = options_get_command(global_options, "default-client-command");
|
||||
if ((c->flags & CLIENT_READONLY) &&
|
||||
!cmd_list_all_have(cmdlist, CMD_READONLY))
|
||||
new_item = cmdq_get_callback(server_client_read_only, NULL);
|
||||
else
|
||||
new_item = cmdq_get_command(cmdlist, NULL);
|
||||
cmdq_insert_after(item, new_item);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
/* Callback when command is done. */
|
||||
static enum cmd_retval
|
||||
server_client_command_done(struct cmdq_item *item, __unused void *data)
|
||||
@@ -3503,7 +3532,6 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
|
||||
struct cmd_parse_result *pr;
|
||||
struct args_value *values;
|
||||
struct cmdq_item *new_item;
|
||||
struct cmd_list *cmdlist;
|
||||
|
||||
if (c->flags & CLIENT_EXIT)
|
||||
return (0);
|
||||
@@ -3524,8 +3552,8 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
|
||||
|
||||
argc = data.argc;
|
||||
if (argc == 0) {
|
||||
cmdlist = cmd_list_copy(options_get_command(global_options,
|
||||
"default-client-command"), 0, NULL);
|
||||
new_item = cmdq_get_callback(server_client_default_command,
|
||||
NULL);
|
||||
} else {
|
||||
values = args_from_vector(argc, argv);
|
||||
pr = cmd_parse_from_arguments(values, argc, NULL);
|
||||
@@ -3539,18 +3567,17 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
|
||||
args_free_values(values, argc);
|
||||
free(values);
|
||||
cmd_free_argv(argc, argv);
|
||||
cmdlist = pr->cmdlist;
|
||||
if ((c->flags & CLIENT_READONLY) &&
|
||||
!cmd_list_all_have(pr->cmdlist, CMD_READONLY)) {
|
||||
new_item = cmdq_get_callback(server_client_read_only,
|
||||
NULL);
|
||||
} else
|
||||
new_item = cmdq_get_command(pr->cmdlist, NULL);
|
||||
cmd_list_free(pr->cmdlist);
|
||||
}
|
||||
|
||||
if ((c->flags & CLIENT_READONLY) &&
|
||||
!cmd_list_all_have(cmdlist, CMD_READONLY))
|
||||
new_item = cmdq_get_callback(server_client_read_only, NULL);
|
||||
else
|
||||
new_item = cmdq_get_command(cmdlist, NULL);
|
||||
cmdq_append(c, new_item);
|
||||
cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL));
|
||||
|
||||
cmd_list_free(cmdlist);
|
||||
return (0);
|
||||
|
||||
error:
|
||||
|
||||
10
status.c
10
status.c
@@ -804,7 +804,10 @@ status_prompt_redraw(struct client *c)
|
||||
|
||||
n = options_get_number(s->options, "prompt-cursor-colour");
|
||||
sl->active->default_ccolour = n;
|
||||
n = options_get_number(s->options, "prompt-cursor-style");
|
||||
if (c->prompt_mode == PROMPT_COMMAND)
|
||||
n = options_get_number(s->options, "prompt-command-cursor-style");
|
||||
else
|
||||
n = options_get_number(s->options, "prompt-cursor-style");
|
||||
screen_set_cursor_style(n, &sl->active->default_cstyle,
|
||||
&sl->active->default_mode);
|
||||
|
||||
@@ -936,6 +939,8 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
return (1);
|
||||
case '\033': /* Escape */
|
||||
c->prompt_mode = PROMPT_COMMAND;
|
||||
if (c->prompt_index != 0)
|
||||
c->prompt_index--;
|
||||
c->flags |= CLIENT_REDRAWSTATUS;
|
||||
return (0);
|
||||
}
|
||||
@@ -961,10 +966,11 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
||||
*new_key = 'u'|KEYC_CTRL;
|
||||
return (1);
|
||||
case 'i':
|
||||
case '\033': /* Escape */
|
||||
c->prompt_mode = PROMPT_ENTRY;
|
||||
c->flags |= CLIENT_REDRAWSTATUS;
|
||||
return (0);
|
||||
case '\033': /* Escape */
|
||||
return (0);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
|
||||
15
tmux.1
15
tmux.1
@@ -841,6 +841,7 @@ Each has a single-character alternative form.
|
||||
.It Li "{last}" Ta "!" Ta "The last (previously current) window"
|
||||
.It Li "{next}" Ta "+" Ta "The next window by number"
|
||||
.It Li "{previous}" Ta "-" Ta "The previous window by number"
|
||||
.It Li "{current}" Ta "@" Ta "The current window"
|
||||
.El
|
||||
.Pp
|
||||
.Ar target-pane
|
||||
@@ -873,6 +874,7 @@ The following special tokens are available for the pane index:
|
||||
.It Li "{down-of}" Ta "" Ta "The pane below the active pane"
|
||||
.It Li "{left-of}" Ta "" Ta "The pane to the left of the active pane"
|
||||
.It Li "{right-of}" Ta "" Ta "The pane to the right of the active pane"
|
||||
.It Li "{active}" Ta "@" Ta "The active pane"
|
||||
.El
|
||||
.Pp
|
||||
The tokens
|
||||
@@ -4242,6 +4244,12 @@ passed through to applications running in
|
||||
.Nm .
|
||||
Attached clients should be detached and attached again after changing this
|
||||
option.
|
||||
.It Xo Ic focus-follows-mouse
|
||||
.Op Ic on | off
|
||||
.Xc
|
||||
When enabled and
|
||||
.Ic mouse
|
||||
is on, moving the mouse into a pane selects it.
|
||||
.It Xo Ic get-clipboard
|
||||
.Op Ic both | request | buffer | off
|
||||
.Xc
|
||||
@@ -4696,6 +4704,12 @@ Set the style of the cursor in the command prompt.
|
||||
See the
|
||||
.Ic cursor-style
|
||||
options for available styles.
|
||||
.It Ic prompt-command-cursor-style Ar style
|
||||
Set the style of the cursor in the command prompt when vi keys are enabled and
|
||||
the prompt is in command mode.
|
||||
See the
|
||||
.Ic cursor-style
|
||||
options for available styles.
|
||||
.It Xo Ic renumber-windows
|
||||
.Op Ic on | off
|
||||
.Xc
|
||||
@@ -6232,6 +6246,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "selection_active" Ta "" Ta "1 if selection started and changes with the cursor in copy mode"
|
||||
.It Li "selection_end_x" Ta "" Ta "X position of the end of the selection"
|
||||
.It Li "selection_end_y" Ta "" Ta "Y position of the end of the selection"
|
||||
.It Li "selection_mode" Ta "" Ta "Selection mode"
|
||||
.It Li "selection_present" Ta "" Ta "1 if selection started in copy mode"
|
||||
.It Li "selection_start_x" Ta "" Ta "X position of the start of the selection"
|
||||
.It Li "selection_start_y" Ta "" Ta "Y position of the start of the selection"
|
||||
|
||||
25
tmux.h
25
tmux.h
@@ -1167,6 +1167,16 @@ struct window_pane_resize {
|
||||
};
|
||||
TAILQ_HEAD(window_pane_resizes, window_pane_resize);
|
||||
|
||||
/*
|
||||
* Client theme, this is worked out from the background colour if not reported
|
||||
* by terminal.
|
||||
*/
|
||||
enum client_theme {
|
||||
THEME_UNKNOWN,
|
||||
THEME_LIGHT,
|
||||
THEME_DARK
|
||||
};
|
||||
|
||||
/* Child window structure. */
|
||||
struct window_pane {
|
||||
u_int id;
|
||||
@@ -1233,6 +1243,7 @@ struct window_pane {
|
||||
struct grid_cell cached_gc;
|
||||
struct grid_cell cached_active_gc;
|
||||
struct colour_palette palette;
|
||||
enum client_theme last_theme;
|
||||
|
||||
int pipe_fd;
|
||||
struct bufferevent *pipe_event;
|
||||
@@ -1918,16 +1929,6 @@ struct overlay_ranges {
|
||||
u_int nx[OVERLAY_MAX_RANGES];
|
||||
};
|
||||
|
||||
/*
|
||||
* Client theme, this is worked out from the background colour if not reported
|
||||
* by terminal.
|
||||
*/
|
||||
enum client_theme {
|
||||
THEME_UNKNOWN,
|
||||
THEME_LIGHT,
|
||||
THEME_DARK
|
||||
};
|
||||
|
||||
/* Client connection. */
|
||||
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
|
||||
typedef void (*prompt_free_cb)(void *);
|
||||
@@ -2453,7 +2454,7 @@ struct options_entry *options_match_get(struct options *, const char *, int *,
|
||||
int, int *);
|
||||
const char *options_get_string(struct options *, const char *);
|
||||
long long options_get_number(struct options *, const char *);
|
||||
const struct cmd_list *options_get_command(struct options *, const char *);
|
||||
struct cmd_list *options_get_command(struct options *, const char *);
|
||||
struct options_entry * printflike(4, 5) options_set_string(struct options *,
|
||||
const char *, int, const char *, ...);
|
||||
struct options_entry *options_set_number(struct options *, const char *,
|
||||
@@ -2750,6 +2751,8 @@ void cmd_list_append(struct cmd_list *, struct cmd *);
|
||||
void cmd_list_append_all(struct cmd_list *, struct cmd_list *);
|
||||
void cmd_list_move(struct cmd_list *, struct cmd_list *);
|
||||
void cmd_list_free(struct cmd_list *);
|
||||
#define CMD_LIST_PRINT_ESCAPED 0x1
|
||||
#define CMD_LIST_PRINT_NO_GROUPS 0x2
|
||||
char *cmd_list_print(const struct cmd_list *, int);
|
||||
struct cmd *cmd_list_first(struct cmd_list *);
|
||||
struct cmd *cmd_list_next(struct cmd *);
|
||||
|
||||
@@ -956,7 +956,8 @@ partial_key:
|
||||
if (delay == 0)
|
||||
delay = 1;
|
||||
if ((tty->flags & (TTY_WAITFG|TTY_WAITBG) ||
|
||||
(tty->flags & TTY_ALL_REQUEST_FLAGS) != TTY_ALL_REQUEST_FLAGS)) {
|
||||
(tty->flags & TTY_ALL_REQUEST_FLAGS) != TTY_ALL_REQUEST_FLAGS) ||
|
||||
!TAILQ_EMPTY(&c->input_requests)) {
|
||||
log_debug("%s: increasing delay for active query", c->name);
|
||||
if (delay < 500)
|
||||
delay = 500;
|
||||
@@ -1750,7 +1751,9 @@ tty_keys_palette(struct tty *tty, const char *buf, size_t len, size_t *size)
|
||||
|
||||
/* Copy the rest up to \033\ or \007. */
|
||||
start = (endptr - buf) + 1;
|
||||
for (i = start; i < len && i - start < sizeof tmp; i++) {
|
||||
for (i = start; i - start < sizeof tmp; i++) {
|
||||
if (i == len)
|
||||
return (1);
|
||||
if (buf[i - 1] == '\033' && buf[i] == '\\')
|
||||
break;
|
||||
if (buf[i] == '\007')
|
||||
|
||||
9
tty.c
9
tty.c
@@ -2288,6 +2288,13 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||
|
||||
vr = screen_redraw_get_visible_ranges(wp, px, py,
|
||||
gcp->data.width);
|
||||
|
||||
if (ctx->num == 2) {
|
||||
/* xxxx need to check visible range */
|
||||
tty_draw_line(tty, s, 0, s->cy, screen_size_x(s),
|
||||
ctx->xoff - ctx->wox, py, &ctx->defaults, ctx->palette);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Handle partially obstructed wide characters. */
|
||||
if (gcp->data.width > 1) {
|
||||
@@ -2297,7 +2304,7 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||
for (i = 0; i < OVERLAY_MAX_RANGES; i++)
|
||||
vis += r.nx[i];
|
||||
if (vis < gcp->data.width ||
|
||||
vis2 < gcp->data.width) { /* xxxx check visible range */
|
||||
vis2 < gcp->data.width) { /* xxxx need to check visible range */
|
||||
tty_draw_line(tty, s, s->cx, s->cy, gcp->data.width,
|
||||
px, py, &ctx->defaults, ctx->palette);
|
||||
return;
|
||||
|
||||
@@ -956,6 +956,18 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
|
||||
format_add(ft, "selection_present", "0");
|
||||
}
|
||||
|
||||
switch (data->selflag) {
|
||||
case SEL_CHAR:
|
||||
format_add(ft, "selection_mode", "char");
|
||||
break;
|
||||
case SEL_WORD:
|
||||
format_add(ft, "selection_mode", "word");
|
||||
break;
|
||||
case SEL_LINE:
|
||||
format_add(ft, "selection_mode", "line");
|
||||
break;
|
||||
}
|
||||
|
||||
format_add(ft, "search_present", "%d", data->searchmark != NULL);
|
||||
format_add(ft, "search_timed_out", "%d", data->timeout);
|
||||
if (data->searchcount != -1) {
|
||||
|
||||
21
window.c
21
window.c
@@ -1036,7 +1036,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
||||
wp = xcalloc(1, sizeof *wp);
|
||||
wp->window = w;
|
||||
wp->options = options_create(w->options);
|
||||
wp->flags = (PANE_STYLECHANGED|PANE_THEMECHANGED);
|
||||
wp->flags = PANE_STYLECHANGED;
|
||||
|
||||
wp->id = next_window_pane_id++;
|
||||
RB_INSERT(window_pane_tree, &all_window_panes, wp);
|
||||
@@ -2051,6 +2051,8 @@ window_pane_get_theme(struct window_pane *wp)
|
||||
void
|
||||
window_pane_send_theme_update(struct window_pane *wp)
|
||||
{
|
||||
enum client_theme theme;
|
||||
|
||||
if (wp == NULL || window_pane_exited(wp))
|
||||
return;
|
||||
if (~wp->flags & PANE_THEMECHANGED)
|
||||
@@ -2058,16 +2060,23 @@ window_pane_send_theme_update(struct window_pane *wp)
|
||||
if (~wp->screen->mode & MODE_THEME_UPDATES)
|
||||
return;
|
||||
|
||||
switch (window_pane_get_theme(wp)) {
|
||||
theme = window_pane_get_theme(wp);
|
||||
if (theme == wp->last_theme)
|
||||
return;
|
||||
wp->last_theme = theme;
|
||||
wp->flags &= ~PANE_THEMECHANGED;
|
||||
|
||||
switch (theme) {
|
||||
case THEME_LIGHT:
|
||||
input_key_pane(wp, KEYC_REPORT_LIGHT_THEME, NULL);
|
||||
log_debug("%s: %%%u light theme", __func__, wp->id);
|
||||
bufferevent_write(wp->event, "\033[?997;2n", 9);
|
||||
break;
|
||||
case THEME_DARK:
|
||||
input_key_pane(wp, KEYC_REPORT_DARK_THEME, NULL);
|
||||
log_debug("%s: %%%u dark theme", __func__, wp->id);
|
||||
bufferevent_write(wp->event, "\033[?997;1n", 9);
|
||||
break;
|
||||
case THEME_UNKNOWN:
|
||||
log_debug("%s: %%%u unknown theme", __func__, wp->id);
|
||||
break;
|
||||
}
|
||||
|
||||
wp->flags &= ~PANE_THEMECHANGED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user