summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-display-panes.c254
-rw-r--r--screen-redraw.c183
-rw-r--r--server-client.c81
-rw-r--r--tmux.h35
4 files changed, 286 insertions, 267 deletions
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 1330ffac..45f59a6b 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -20,6 +20,7 @@
#include <ctype.h>
#include <stdlib.h>
+#include <string.h>
#include "tmux.h"
@@ -30,9 +31,6 @@
static enum cmd_retval cmd_display_panes_exec(struct cmd *,
struct cmdq_item *);
-static void cmd_display_panes_callback(struct client *,
- struct window_pane *);
-
const struct cmd_entry cmd_display_panes_entry = {
.name = "display-panes",
.alias = "displayp",
@@ -44,46 +42,145 @@ const struct cmd_entry cmd_display_panes_entry = {
.exec = cmd_display_panes_exec
};
-static enum cmd_retval
-cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item)
+struct cmd_display_panes_data {
+ struct cmdq_item *item;
+ char *command;
+};
+
+static void
+cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
+ struct window_pane *wp)
{
- struct args *args = self->args;
- struct client *c;
- struct session *s;
- u_int delay;
- char *cause;
+ struct client *c = ctx->c;
+ struct tty *tty = &c->tty;
+ struct session *s = c->session;
+ struct options *oo = s->options;
+ struct window *w = wp->window;
+ struct grid_cell gc;
+ u_int idx, px, py, i, j, xoff, yoff, sx, sy;
+ int colour, active_colour;
+ char buf[16], *ptr;
+ size_t len;
- if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL)
- return (CMD_RETURN_ERROR);
- s = c->session;
+ if (wp->xoff + wp->sx <= ctx->ox ||
+ wp->xoff >= ctx->ox + ctx->sx ||
+ wp->yoff + wp->sy <= ctx->oy ||
+ wp->yoff >= ctx->oy + ctx->sy)
+ return;
- if (c->identify_callback != NULL)
- return (CMD_RETURN_NORMAL);
+ if (wp->xoff >= ctx->ox && wp->xoff + wp->sx <= ctx->ox + ctx->sx) {
+ /* All visible. */
+ xoff = wp->xoff - ctx->ox;
+ sx = wp->sx;
+ } else if (wp->xoff < ctx->ox &&
+ wp->xoff + wp->sx > ctx->ox + ctx->sx) {
+ /* Both left and right not visible. */
+ xoff = 0;
+ sx = ctx->sx;
+ } else if (wp->xoff < ctx->ox) {
+ /* Left not visible. */
+ xoff = 0;
+ sx = wp->sx - (ctx->ox - wp->xoff);
+ } else {
+ /* Right not visible. */
+ xoff = wp->xoff - ctx->ox;
+ sx = wp->sx - xoff;
+ }
+ if (wp->yoff >= ctx->oy && wp->yoff + wp->sy <= ctx->oy + ctx->sy) {
+ /* All visible. */
+ yoff = wp->yoff - ctx->oy;
+ sy = wp->sy;
+ } else if (wp->yoff < ctx->oy &&
+ wp->yoff + wp->sy > ctx->oy + ctx->sy) {
+ /* Both top and bottom not visible. */
+ yoff = 0;
+ sy = ctx->sy;
+ } else if (wp->yoff < ctx->oy) {
+ /* Top not visible. */
+ yoff = 0;
+ sy = wp->sy - (ctx->oy - wp->yoff);
+ } else {
+ /* Bottom not visible. */
+ yoff = wp->yoff - ctx->oy;
+ sy = wp->sy - yoff;
+ }
- c->identify_callback = cmd_display_panes_callback;
- if (args->argc != 0)
- c->identify_callback_data = xstrdup(args->argv[0]);
- else
- c->identify_callback_data = xstrdup("select-pane -t '%%'");
- if (args_has(args, 'b'))
- c->identify_callback_item = NULL;
+ if (ctx->statustop)
+ yoff += ctx->statuslines;
+ px = sx / 2;
+ py = sy / 2;
+
+ if (window_pane_index(wp, &idx) != 0)
+ fatalx("index not found");
+ len = xsnprintf(buf, sizeof buf, "%u", idx);
+
+ if (sx < len)
+ return;
+ colour = options_get_number(oo, "display-panes-colour");
+ active_colour = options_get_number(oo, "display-panes-active-colour");
+
+ if (sx < len * 6 || sy < 5) {
+ tty_cursor(tty, xoff + px - len / 2, yoff + py);
+ goto draw_text;
+ }
+
+ px -= len * 3;
+ py -= 2;
+
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ if (w->active == wp)
+ gc.bg = active_colour;
else
- c->identify_callback_item = item;
+ gc.bg = colour;
+ gc.flags |= GRID_FLAG_NOPALETTE;
- if (args_has(args, 'd')) {
- delay = args_strtonum(args, 'd', 0, UINT_MAX, &cause);
- if (cause != NULL) {
- cmdq_error(item, "delay %s", cause);
- free(cause);
- return (CMD_RETURN_ERROR);
+ tty_attributes(tty, &gc, wp);
+ for (ptr = buf; *ptr != '\0'; ptr++) {
+ if (*ptr < '0' || *ptr > '9')
+ continue;
+ idx = *ptr - '0';
+
+ for (j = 0; j < 5; j++) {
+ for (i = px; i < px + 5; i++) {
+ tty_cursor(tty, xoff + i, yoff + py + j);
+ if (window_clock_table[idx][j][i - px])
+ tty_putc(tty, ' ');
+ }
}
- } else
- delay = options_get_number(s->options, "display-panes-time");
- server_client_set_identify(c, delay);
+ px += 6;
+ }
- if (args_has(args, 'b'))
- return (CMD_RETURN_NORMAL);
- return (CMD_RETURN_WAIT);
+ len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy);
+ if (sx < len || sy < 6)
+ return;
+ tty_cursor(tty, xoff + sx - len, yoff);
+
+draw_text:
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ if (w->active == wp)
+ gc.fg = active_colour;
+ else
+ gc.fg = colour;
+ gc.flags |= GRID_FLAG_NOPALETTE;
+
+ tty_attributes(tty, &gc, wp);
+ tty_puts(tty, buf);
+
+ tty_cursor(tty, 0, 0);
+}
+
+static void
+cmd_display_panes_draw(struct client *c, struct screen_redraw_ctx *ctx)
+{
+ struct window *w = c->session->curw->window;
+ struct window_pane *wp;
+
+ log_debug("%s: %s @%u", __func__, c->name, w->id);
+
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (window_pane_visible(wp))
+ cmd_display_panes_draw_pane(ctx, wp);
+ }
}
static enum cmd_retval
@@ -98,17 +195,36 @@ cmd_display_panes_error(struct cmdq_item *item, void *data)
}
static void
-cmd_display_panes_callback(struct client *c, struct window_pane *wp)
+cmd_display_panes_free(struct client *c)
{
- struct cmd_list *cmdlist;
- struct cmdq_item *new_item;
- char *cmd, *expanded, *cause;
+ struct cmd_display_panes_data *cdata = c->overlay_data;
+
+ if (cdata->item != NULL)
+ cdata->item->flags &= ~CMDQ_WAITING;
+ free(cdata->command);
+ free(cdata);
+}
+
+static int
+cmd_display_panes_key(struct client *c, struct key_event *event)
+{
+ struct cmd_display_panes_data *cdata = c->overlay_data;
+ struct cmd_list *cmdlist;
+ struct cmdq_item *new_item;
+ char *cmd, *expanded, *cause;
+ struct window *w = c->session->curw->window;
+ struct window_pane *wp;
+
+ if (event->key < '0' || event->key > '9')
+ return (1);
+ wp = window_pane_at_index(w, event->key - '0');
if (wp == NULL)
- goto out;
+ return (1);
+ window_unzoom(w);
xasprintf(&expanded, "%%%u", wp->id);
- cmd = cmd_template_replace(c->identify_callback_data, expanded, 1);
+ cmd = cmd_template_replace(cdata->command, expanded, 1);
cmdlist = cmd_string_parse(cmd, NULL, 0, &cause);
if (cmdlist == NULL && cause != NULL)
@@ -119,25 +235,59 @@ cmd_display_panes_callback(struct client *c, struct window_pane *wp)
new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
cmd_list_free(cmdlist);
}
-
if (new_item != NULL) {
- if (c->identify_callback_item != NULL)
- cmdq_insert_after(c->identify_callback_item, new_item);
+ if (cdata->item != NULL)
+ cmdq_insert_after(cdata->item, new_item);
else
cmdq_append(c, new_item);
}
free(cmd);
free(expanded);
+ return (1);
+}
-out:
- if (c->identify_callback_item != NULL) {
- c->identify_callback_item->flags &= ~CMDQ_WAITING;
- c->identify_callback_item = NULL;
- }
+static enum cmd_retval
+cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item)
+{
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ u_int delay;
+ char *cause;
+ struct cmd_display_panes_data *cdata;
+
+ if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+ s = c->session;
- free(c->identify_callback_data);
- c->identify_callback_data = NULL;
+ if (c->overlay_draw != NULL)
+ return (CMD_RETURN_NORMAL);
+
+ if (args_has(args, 'd')) {
+ delay = args_strtonum(args, 'd', 0, UINT_MAX, &cause);
+ if (cause != NULL) {
+ cmdq_error(item, "delay %s", cause);
+ free(cause);
+ return (CMD_RETURN_ERROR);
+ }
+ } else
+ delay = options_get_number(s->options, "display-panes-time");
+
+ cdata = xmalloc(sizeof *cdata);
+ if (args->argc != 0)
+ cdata->command = xstrdup(args->argv[0]);
+ else
+ cdata->command = xstrdup("select-pane -t '%%'");
+ if (args_has(args, 'b'))
+ cdata->item = NULL;
+ else
+ cdata->item = item;
+
+ server_client_set_overlay(c, delay, cmd_display_panes_draw,
+ cmd_display_panes_key, cmd_display_panes_free, cdata);
- c->identify_callback = NULL;
+ if (args_has(args, 'b'))
+ return (CMD_RETURN_NORMAL);
+ return (CMD_RETURN_WAIT);
}
diff --git a/screen-redraw.c b/screen-redraw.c
index 0ce3374d..5278e776 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -23,27 +23,11 @@
#include "tmux.h"
-struct screen_redraw_ctx {
- struct client *c;
-
- u_int lines;
- int top;
-
- int pane_status;
-
- u_int sx;
- u_int sy;
- u_int ox;
- u_int oy;
-};
-
static void screen_redraw_draw_borders(struct screen_redraw_ctx *);
static void screen_redraw_draw_panes(struct screen_redraw_ctx *);
static void screen_redraw_draw_status(struct screen_redraw_ctx *);
static void screen_redraw_draw_pane(struct screen_redraw_ctx *,
struct window_pane *);
-static void screen_redraw_draw_number(struct screen_redraw_ctx *,
- struct window_pane *);
#define CELL_INSIDE 0
#define CELL_LEFTRIGHT 1
@@ -374,8 +358,8 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
width = size - x;
}
- if (ctx->top)
- yoff += ctx->lines;
+ if (ctx->statustop)
+ yoff += ctx->statuslines;
tty_draw_line(tty, NULL, s, i, 0, width, x, yoff - ctx->oy);
}
tty_cursor(tty, 0, 0);
@@ -419,21 +403,25 @@ screen_redraw_set_context(struct client *c, struct screen_redraw_ctx *ctx)
struct options *oo = s->options;
struct window *w = s->curw->window;
struct options *wo = w->options;
+ u_int lines;
memset(ctx, 0, sizeof *ctx);
ctx->c = c;
- ctx->lines = status_line_size(c);
+ lines = status_line_size(c);
if (c->message_string != NULL || c->prompt_string != NULL)
- ctx->lines = (ctx->lines == 0) ? 1 : ctx->lines;
- if (ctx->lines != 0 && options_get_number(oo, "status-position") == 0)
- ctx->top = 1;
+ lines = (lines == 0) ? 1 : lines;
+ if (lines != 0 && options_get_number(oo, "status-position") == 0)
+ ctx->statustop = 1;
+ ctx->statuslines = lines;
+
ctx->pane_status = options_get_number(wo, "pane-border-status");
tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy);
log_debug("%s: %s @%u ox=%u oy=%u sx=%u sy=%u %u/%d", __func__, c->name,
- w->id, ctx->ox, ctx->oy, ctx->sx, ctx->sy, ctx->lines, ctx->top);
+ w->id, ctx->ox, ctx->oy, ctx->sx, ctx->sy, ctx->statuslines,
+ ctx->statustop);
}
/* Redraw entire screen. */
@@ -456,9 +444,11 @@ screen_redraw_screen(struct client *c)
}
if (flags & CLIENT_REDRAWWINDOW)
screen_redraw_draw_panes(&ctx);
- if (ctx.lines != 0 &&
+ if (ctx.statuslines != 0 &&
(flags & (CLIENT_REDRAWSTATUS|CLIENT_REDRAWSTATUSALWAYS)))
screen_redraw_draw_status(&ctx);
+ if (c->overlay_draw != NULL)
+ c->overlay_draw(c, &ctx);
tty_reset(&c->tty);
}
@@ -508,8 +498,8 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j,
tty_attributes(tty, active_gc, NULL);
else
tty_attributes(tty, other_gc, NULL);
- if (ctx->top)
- tty_cursor(tty, i, ctx->lines + j);
+ if (ctx->statustop)
+ tty_cursor(tty, i, ctx->statuslines + j);
else
tty_cursor(tty, i, j);
tty_putc(tty, CELL_BORDERS[type]);
@@ -538,7 +528,7 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx)
memcpy(&m_active_gc, &active_gc, sizeof m_active_gc);
m_active_gc.attr ^= GRID_ATTR_REVERSE;
- for (j = 0; j < tty->sy - ctx->lines; j++) {
+ for (j = 0; j < tty->sy - ctx->statuslines; j++) {
for (i = 0; i < tty->sx; i++) {
screen_redraw_draw_borders_cell(ctx, i, j,
&m_active_gc, &active_gc, &m_other_gc, &other_gc);
@@ -557,11 +547,8 @@ screen_redraw_draw_panes(struct screen_redraw_ctx *ctx)
log_debug("%s: %s @%u", __func__, c->name, w->id);
TAILQ_FOREACH(wp, &w->panes, entry) {
- if (!window_pane_visible(wp))
- continue;
- screen_redraw_draw_pane(ctx, wp);
- if (c->flags & CLIENT_IDENTIFY)
- screen_redraw_draw_number(ctx, wp);
+ if (window_pane_visible(wp))
+ screen_redraw_draw_pane(ctx, wp);
}
}
@@ -577,11 +564,11 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx)
log_debug("%s: %s @%u", __func__, c->name, w->id);
- if (ctx->top)
+ if (ctx->statustop)
y = 0;
else
- y = c->tty.sy - ctx->lines;
- for (i = 0; i < ctx->lines; i++)
+ y = c->tty.sy - ctx->statuslines;
+ for (i = 0; i < ctx->statuslines; i++)
tty_draw_line(tty, NULL, s, 0, i, UINT_MAX, 0, y + i);
}
@@ -599,8 +586,8 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx)
return;
- if (ctx->top)
- top = ctx->lines;
+ if (ctx->statustop)
+ top = ctx->statuslines;
else
top = 0;
@@ -639,125 +626,3 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
tty_draw_line(tty, wp, s, i, j, width, x, y);
}
}
-
-/* Draw number on a pane. */
-static void
-screen_redraw_draw_number(struct screen_redraw_ctx *ctx, struct window_pane *wp)
-{
- struct client *c = ctx->c;
- struct tty *tty = &c->tty;
- struct session *s = c->session;
- struct options *oo = s->options;
- struct window *w = wp->window;
- struct grid_cell gc;
- u_int idx, px, py, i, j, xoff, yoff, sx, sy;
- int colour, active_colour;
- char buf[16], *ptr;
- size_t len;
-
- if (wp->xoff + wp->sx <= ctx->ox ||
- wp->xoff >= ctx->ox + ctx->sx ||
- wp->yoff + wp->sy <= ctx->oy ||
- wp->yoff >= ctx->oy + ctx->sy)
- return;
-
- if (wp->xoff >= ctx->ox && wp->xoff + wp->sx <= ctx->ox + ctx->sx) {
- /* All visible. */
- xoff = wp->xoff - ctx->ox;
- sx = wp->sx;
- } else if (wp->xoff < ctx->ox &&
- wp->xoff + wp->sx > ctx->ox + ctx->sx) {
- /* Both left and right not visible. */
- xoff = 0;
- sx = ctx->sx;
- } else if (wp->xoff < ctx->ox) {
- /* Left not visible. */
- xoff = 0;
- sx = wp->sx - (ctx->ox - wp->xoff);
- } else {
- /* Right not visible. */
- xoff = wp->xoff - ctx->ox;
- sx = wp->sx - xoff;
- }
- if (wp->yoff >= ctx->oy && wp->yoff + wp->sy <= ctx->oy + ctx->sy) {
- /* All visible. */
- yoff = wp->yoff - ctx->oy;
- sy = wp->sy;
- } else if (wp->yoff < ctx->oy &&
- wp->yoff + wp->sy > ctx->oy + ctx->sy) {
- /* Both top and bottom not visible. */
- yoff = 0;
- sy = ctx->sy;
- } else if (wp->yoff < ctx->oy) {
- /* Top not visible. */
- yoff = 0;
- sy = wp->sy - (ctx->oy - wp->yoff);
- } else {
- /* Bottom not visible. */
- yoff = wp->yoff - ctx->oy;
- sy = wp->sy - yoff;
- }
-
- if (ctx->top)
- yoff += ctx->lines;
- px = sx / 2;
- py = sy / 2;
-
- if (window_pane_index(wp, &idx) != 0)
- fatalx("index not found");
- len = xsnprintf(buf, sizeof buf, "%u", idx);
-
- if (sx < len)
- return;
- colour = options_get_number(oo, "display-panes-colour");
- active_colour = options_get_number(oo, "display-panes-active-colour");
-
- if (sx < len * 6 || sy < 5) {
- tty_cursor(tty, xoff + px - len / 2, yoff + py);
- goto draw_text;
- }
-
- px -= len * 3;
- py -= 2;
-
- memcpy(&gc, &grid_default_cell, sizeof gc);
- if (w->active == wp)
- gc.bg = active_colour;
- else
- gc.bg = colour;
- gc.flags |= GRID_FLAG_NOPALETTE;
-
- tty_attributes(tty, &gc, wp);
- for (ptr = buf; *ptr != '\0'; ptr++) {
- if (*ptr < '0' || *ptr > '9')
- continue;
- idx = *ptr - '0';
-
- for (j = 0; j < 5; j++) {
- for (i = px; i < px + 5; i++) {
- tty_cursor(tty, xoff + i, yoff + py + j);
- if (window_clock_table[idx][j][i - px])
- tty_putc(tty, ' ');
- }
- }
- px += 6;
- }
-
- len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy);
- if (sx < len || sy < 6)
- return;
- tty_cursor(tty, xoff + sx - len, yoff);
-
-draw_text:
- memcpy(&gc, &grid_default_cell, sizeof gc);
- if (w->active == wp)
- gc.fg = active_colour;
- else
- gc.fg = colour;
- gc.flags |= GRID_FLAG_NOPALETTE;
-
- tty_attributes(tty, &gc, wp);
- tty_puts(tty, buf);
-
- tty_cursor(tty, 0, 0);
-}
diff --git a/server-client.c b/server-client.c
index 2840ba60..9e986d4d 100644
--- a/server-client.c
+++ b/server-client.c
@@ -43,8 +43,7 @@ static void server_client_check_redraw(struct client *);
static void server_client_set_title(struct client *);
static void server_client_reset_state(struct client *);
static int server_client_assume_paste(struct session *);
-static void server_client_clear_identify(struct client *,
- struct window_pane *);
+static void server_client_clear_overlay(struct client *);
static void server_client_dispatch(struct imsg *, void *);
static void server_client_dispatch_command(struct client *, struct imsg *);
@@ -66,44 +65,53 @@ server_client_how_many(void)
return (n);
}
-/* Identify mode callback. */
+/* Overlay timer callback. */
static void
-server_client_callback_identify(__unused int fd, __unused short events,
- void *data)
+server_client_overlay_timer(__unused int fd, __unused short events, void *data)
{
- server_client_clear_identify(data, NULL);
+ server_client_clear_overlay(data);
}
-/* Set identify mode on client. */
+/* Set an overlay on client. */
void
-server_client_set_identify(struct client *c, u_int delay)
+server_client_set_overlay(struct client *c, u_int delay, overlay_draw_cb drawcb,
+ overlay_key_cb keycb, overlay_free_cb freecb, void *data)
{
struct timeval tv;
tv.tv_sec = delay / 1000;
tv.tv_usec = (delay % 1000) * 1000L;
- if (event_initialized(&c->identify_timer))
- evtimer_del(&c->identify_timer);
- evtimer_set(&c->identify_timer, server_client_callback_identify, c);
+ if (event_initialized(&c->overlay_timer))
+ evtimer_del(&c->overlay_timer);
+ evtimer_set(&c->overlay_timer, server_client_overlay_timer, c);
if (delay != 0)
- evtimer_add(&c->identify_timer, &tv);
+ evtimer_add(&c->overlay_timer, &tv);
+
+ c->overlay_draw = drawcb;
+ c->overlay_key = keycb;
+ c->overlay_free = freecb;
+ c->overlay_data = data;
- c->flags |= CLIENT_IDENTIFY;
c->tty.flags |= (TTY_FREEZE|TTY_NOCURSOR);
server_redraw_client(c);
}
-/* Clear identify mode on client. */
+/* Clear overlay mode on client. */
static void
-server_client_clear_identify(struct client *c, struct window_pane *wp)
+server_client_clear_overlay(struct client *c)
{
- if (~c->flags & CLIENT_IDENTIFY)
+ if (c->overlay_draw == NULL)
return;
- c->flags &= ~CLIENT_IDENTIFY;
- if (c->identify_callback != NULL)
- c->identify_callback(c, wp);
+ if (event_initialized(&c->overlay_timer))
+ evtimer_del(&c->overlay_timer);
+
+ if (c->overlay_free != NULL)
+ c->overlay_free(c);
+
+ c->overlay_draw = NULL;
+ c->overlay_key = NULL;
c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR);
server_redraw_client(c);
@@ -257,7 +265,7 @@ server_client_lost(struct client *c)
c->flags |= CLIENT_DEAD;
- server_client_clear_identify(c, NULL);
+ server_client_clear_overlay(c);
status_prompt_clear(c);
status_message_clear(c);
@@ -291,9 +299,6 @@ server_client_lost(struct client *c)
key_bindings_unref_table(c->keytable);
- if (event_initialized(&c->identify_timer))
- evtimer_del(&c->identify_timer);
-
free(c->message_string);
if (event_initialized(&c->message_timer))
evtimer_del(&c->message_timer);
@@ -1016,21 +1021,9 @@ server_client_key_callback(struct cmdq_item *item, void *data)
fatal("gettimeofday failed");
session_update_activity(s, &c->activity_time);
- /* Number keys jump to pane in identify mode. */
- if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') {
- if (c->flags & CLIENT_READONLY)
- goto out;
- window_unzoom(w);
- wp = window_pane_at_index(w, key - '0');
- server_client_clear_identify(c, wp);
- goto out;
- }
-
/* Handle status line. */
- if (!(c->flags & CLIENT_READONLY)) {
+ if (~c->flags & CLIENT_READONLY)
status_message_clear(c);
- server_client_clear_identify(c, NULL);
- }
if (c->prompt_string != NULL) {
if (c->flags & CLIENT_READONLY)
goto out;
@@ -1211,27 +1204,19 @@ int
server_client_handle_key(struct client *c, struct key_event *event)
{
struct session *s = c->session;
- struct window *w;
- struct window_pane *wp = NULL;
struct cmdq_item *item;
/* Check the client is good to accept input. */
if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
return (0);
- w = s->curw->window;
/*
- * Key presses in identify mode are a special case. The queue might be
+ * Key presses in overlay mode are a special case. The queue might be
* blocked so they need to be processed immediately rather than queued.
*/
- if (c->flags & CLIENT_IDENTIFY) {
- if (c->flags & CLIENT_READONLY)
- return (0);
- if (event->key >= '0' && event->key <= '9') {
- window_unzoom(w);
- wp = window_pane_at_index(w, event->key - '0');
- }
- server_client_clear_identify(c, wp);
+ if ((~c->flags & CLIENT_READONLY) && c->overlay_key != NULL) {
+ if (c->overlay_key(c, event) != 0)
+ server_client_clear_overlay(c);
return (0);
}
diff --git a/tmux.h b/tmux.h
index 55c24531..fb1da4a4 100644
--- a/tmux.h
+++ b/tmux.h
@@ -727,6 +727,21 @@ struct screen_write_ctx {
u_int skipped;
};
+/* Screen redraw context. */
+struct screen_redraw_ctx {
+ struct client *c;
+
+ u_int statuslines;
+ int statustop;
+
+ int pane_status;
+
+ u_int sx;
+ u_int sy;
+ u_int ox;
+ u_int oy;
+};
+
/* Screen size. */
#define screen_size_x(s) ((s)->grid->sx)
#define screen_size_y(s) ((s)->grid->sy)
@@ -1374,6 +1389,9 @@ struct status_line {
/* Client connection. */
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
typedef void (*prompt_free_cb)(void *);
+typedef void (*overlay_draw_cb)(struct client *, struct screen_redraw_ctx *);
+typedef int (*overlay_key_cb)(struct client *, struct key_event *);
+typedef void (*overlay_free_cb)(struct client *);
struct client {
const char *name;
struct tmuxpeer *peer;
@@ -1423,7 +1441,7 @@ struct client {
#define CLIENT_REPEAT 0x20
#define CLIENT_SUSPENDED 0x40
#define CLIENT_ATTACHED 0x80
-#define CLIENT_IDENTIFY 0x100
+/* 0x100 unused */
#define CLIENT_DEAD 0x200
#define CLIENT_REDRAWBORDERS 0x400
#define CLIENT_READONLY 0x800
@@ -1452,12 +1470,6 @@ struct client {
int flags;
struct key_table *keytable;
- struct event identify_timer;
- void (*identify_callback)(struct client *,
- struct window_pane *);
- void *identify_callback_data;
- struct cmdq_item *identify_callback_item;
-
char *message_string;
struct event message_timer;
u_int message_next;
@@ -1488,6 +1500,12 @@ struct client {
u_int pan_ox;
u_int pan_oy;
+ overlay_draw_cb overlay_draw;
+ overlay_key_cb overlay_key;
+ overlay_free_cb overlay_free;
+ void *overlay_data;
+ struct event overlay_timer;
+
TAILQ_ENTRY(client) entry;
};
TAILQ_HEAD(clients, client);
@@ -2008,7 +2026,8 @@ void server_add_accept(int);
/* server-client.c */
u_int server_client_how_many(void);
-void server_client_set_identify(struct client *, u_int);
+void server_client_set_overlay(struct client *, u_int, overlay_draw_cb,
+ overlay_key_cb, overlay_free_cb, void *);
void server_client_set_key_table(struct client *, const char *);
const char *server_client_get_key_table(struct client *);
int server_client_check_nested(struct client *);