summaryrefslogtreecommitdiffstats
path: root/cmd-display-panes.c
diff options
context:
space:
mode:
authornicm <nicm>2019-05-07 20:01:41 +0000
committernicm <nicm>2019-05-07 20:01:41 +0000
commit89db309e106cfdd901ab62243bc07f0b76ef41da (patch)
treecac6d1b5756f000a362e815544d798e0278705e2 /cmd-display-panes.c
parentd53d3bce59daa26720682dfcb6bcad182851c9a0 (diff)
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.c254
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);
}