diff options
author | nicm <nicm> | 2019-05-07 20:01:41 +0000 |
---|---|---|
committer | nicm <nicm> | 2019-05-07 20:01:41 +0000 |
commit | 89db309e106cfdd901ab62243bc07f0b76ef41da (patch) | |
tree | cac6d1b5756f000a362e815544d798e0278705e2 /cmd-display-panes.c | |
parent | d53d3bce59daa26720682dfcb6bcad182851c9a0 (diff) | |
download | rtmux-89db309e106cfdd901ab62243bc07f0b76ef41da.tar.gz rtmux-89db309e106cfdd901ab62243bc07f0b76ef41da.tar.bz2 rtmux-89db309e106cfdd901ab62243bc07f0b76ef41da.zip |
Move around the display-panes identify code to make it a bit more
generic and hide the display-panes specific bits into
cmd-display-panes.c.
Diffstat (limited to 'cmd-display-panes.c')
-rw-r--r-- | cmd-display-panes.c | 254 |
1 files changed, 202 insertions, 52 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); } |