aboutsummaryrefslogtreecommitdiff
path: root/server-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'server-client.c')
-rw-r--r--server-client.c246
1 files changed, 176 insertions, 70 deletions
diff --git a/server-client.c b/server-client.c
index 84b93272..410b8c02 100644
--- a/server-client.c
+++ b/server-client.c
@@ -192,6 +192,7 @@ server_client_create(int fd)
c->session = NULL;
c->last_session = NULL;
+
c->tty.sx = 80;
c->tty.sy = 24;
@@ -300,6 +301,7 @@ server_client_lost(struct client *c)
free(msg);
}
+ free(c->prompt_saved);
free(c->prompt_string);
free(c->prompt_buffer);
@@ -409,18 +411,18 @@ server_client_check_mouse(struct client *c)
struct mouse_event *m = &c->tty.mouse;
struct window *w;
struct window_pane *wp;
- u_int x, y, b;
+ u_int x, y, b, sx, sy, px, py;
int flag;
key_code key;
struct timeval tv;
enum { NOTYPE, MOVE, DOWN, UP, DRAG, WHEEL, DOUBLE, TRIPLE } type;
- enum { NOWHERE, PANE, STATUS, BORDER } where;
+ enum { NOWHERE, PANE, STATUS, STATUS_LEFT, STATUS_RIGHT, BORDER } where;
type = NOTYPE;
where = NOWHERE;
- log_debug("mouse %02x at %u,%u (last %u,%u) (%d)", m->b, m->x, m->y,
- m->lx, m->ly, c->tty.mouse_drag_flag);
+ log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b,
+ m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag);
/* What type of event is this? */
if ((m->sgr_type != ' ' &&
@@ -439,7 +441,7 @@ server_client_check_mouse(struct client *c)
x = m->x, y = m->y, b = m->b;
log_debug("drag update at %u,%u", x, y);
} else {
- x = m->lx, y = m->ly, b = m->lb;
+ x = m->lx - m->ox, y = m->ly - m->oy, b = m->lb;
log_debug("drag start at %u,%u", x, y);
}
} else if (MOUSE_WHEEL(m->b)) {
@@ -493,48 +495,74 @@ have_event:
if (type == NOTYPE)
return (KEYC_UNKNOWN);
- /* Always save the session. */
+ /* Save the session. */
m->s = s->id;
+ m->w = -1;
/* Is this on the status line? */
m->statusat = status_at_line(c);
if (m->statusat != -1 && y == (u_int)m->statusat) {
- w = status_get_window_at(c, x);
- if (w == NULL)
- return (KEYC_UNKNOWN);
- m->w = w->id;
- where = STATUS;
- } else
- m->w = -1;
+ if (x < c->status.left_size)
+ where = STATUS_LEFT;
+ else if (x > c->tty.sx - c->status.right_size)
+ where = STATUS_RIGHT;
+ else {
+ w = status_get_window_at(c, x);
+ if (w == NULL)
+ return (KEYC_UNKNOWN);
+ m->w = w->id;
+ where = STATUS;
+ }
+ }
/* Not on status line. Adjust position and check for border or pane. */
if (where == NOWHERE) {
+ px = x;
if (m->statusat == 0 && y > 0)
- y--;
+ py = y - 1;
else if (m->statusat > 0 && y >= (u_int)m->statusat)
- y = m->statusat - 1;
-
- TAILQ_FOREACH(wp, &s->curw->window->panes, entry) {
- if ((wp->xoff + wp->sx == x &&
- wp->yoff <= 1 + y &&
- wp->yoff + wp->sy >= y) ||
- (wp->yoff + wp->sy == y &&
- wp->xoff <= 1 + x &&
- wp->xoff + wp->sx >= x))
- break;
+ py = m->statusat - 1;
+ else
+ py = y;
+
+ tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy);
+ log_debug("mouse window @%u at %u,%u (%ux%u)",
+ s->curw->window->id, m->ox, m->oy, sx, sy);
+ if (px > sx || py > sy)
+ return (KEYC_UNKNOWN);
+ px = px + m->ox;
+ py = py + m->oy;
+ m->x = x + m->ox;
+ m->y = y + m->oy;
+
+ /* Try the pane borders if not zoomed. */
+ if (~s->curw->window->flags & WINDOW_ZOOMED) {
+ TAILQ_FOREACH(wp, &s->curw->window->panes, entry) {
+ if ((wp->xoff + wp->sx == px &&
+ wp->yoff <= 1 + py &&
+ wp->yoff + wp->sy >= py) ||
+ (wp->yoff + wp->sy == py &&
+ wp->xoff <= 1 + px &&
+ wp->xoff + wp->sx >= px))
+ break;
+ }
+ if (wp != NULL)
+ where = BORDER;
}
- if (wp != NULL)
- where = BORDER;
- else {
- wp = window_get_active_at(s->curw->window, x, y);
- if (wp != NULL) {
+
+ /* Otherwise try inside the pane. */
+ if (where == NOWHERE) {
+ wp = window_get_active_at(s->curw->window, px, py);
+ if (wp != NULL)
where = PANE;
- log_debug("mouse at %u,%u is on pane %%%u",
- x, y, wp->id);
- }
}
+
if (where == NOWHERE)
return (KEYC_UNKNOWN);
+ if (where == PANE)
+ log_debug("mouse %u,%u on pane %%%u", x, y, wp->id);
+ else if (where == BORDER)
+ log_debug("mouse on pane %%%u border", wp->id);
m->wp = wp->id;
m->w = wp->window->id;
} else
@@ -558,6 +586,10 @@ have_event:
key = KEYC_MOUSEDRAGEND1_PANE;
if (where == STATUS)
key = KEYC_MOUSEDRAGEND1_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDRAGEND1_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDRAGEND1_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND1_BORDER;
break;
@@ -566,6 +598,10 @@ have_event:
key = KEYC_MOUSEDRAGEND2_PANE;
if (where == STATUS)
key = KEYC_MOUSEDRAGEND2_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDRAGEND2_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDRAGEND2_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND2_BORDER;
break;
@@ -574,6 +610,10 @@ have_event:
key = KEYC_MOUSEDRAGEND3_PANE;
if (where == STATUS)
key = KEYC_MOUSEDRAGEND3_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDRAGEND3_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDRAGEND3_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDRAGEND3_BORDER;
break;
@@ -609,6 +649,10 @@ have_event:
key = KEYC_MOUSEDRAG1_PANE;
if (where == STATUS)
key = KEYC_MOUSEDRAG1_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDRAG1_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDRAG1_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDRAG1_BORDER;
break;
@@ -617,6 +661,10 @@ have_event:
key = KEYC_MOUSEDRAG2_PANE;
if (where == STATUS)
key = KEYC_MOUSEDRAG2_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDRAG2_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDRAG2_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDRAG2_BORDER;
break;
@@ -625,6 +673,10 @@ have_event:
key = KEYC_MOUSEDRAG3_PANE;
if (where == STATUS)
key = KEYC_MOUSEDRAG3_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDRAG3_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDRAG3_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDRAG3_BORDER;
break;
@@ -643,6 +695,10 @@ have_event:
key = KEYC_WHEELUP_PANE;
if (where == STATUS)
key = KEYC_WHEELUP_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_WHEELUP_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_WHEELUP_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_WHEELUP_BORDER;
} else {
@@ -661,6 +717,10 @@ have_event:
key = KEYC_MOUSEUP1_PANE;
if (where == STATUS)
key = KEYC_MOUSEUP1_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEUP1_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEUP1_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEUP1_BORDER;
break;
@@ -669,6 +729,10 @@ have_event:
key = KEYC_MOUSEUP2_PANE;
if (where == STATUS)
key = KEYC_MOUSEUP2_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEUP2_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEUP2_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEUP2_BORDER;
break;
@@ -677,6 +741,10 @@ have_event:
key = KEYC_MOUSEUP3_PANE;
if (where == STATUS)
key = KEYC_MOUSEUP3_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEUP3_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEUP3_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEUP3_BORDER;
break;
@@ -689,6 +757,10 @@ have_event:
key = KEYC_MOUSEDOWN1_PANE;
if (where == STATUS)
key = KEYC_MOUSEDOWN1_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDOWN1_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDOWN1_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDOWN1_BORDER;
break;
@@ -697,6 +769,10 @@ have_event:
key = KEYC_MOUSEDOWN2_PANE;
if (where == STATUS)
key = KEYC_MOUSEDOWN2_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDOWN2_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDOWN2_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDOWN2_BORDER;
break;
@@ -705,6 +781,10 @@ have_event:
key = KEYC_MOUSEDOWN3_PANE;
if (where == STATUS)
key = KEYC_MOUSEDOWN3_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_MOUSEDOWN3_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_MOUSEDOWN3_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_MOUSEDOWN3_BORDER;
break;
@@ -717,6 +797,10 @@ have_event:
key = KEYC_DOUBLECLICK1_PANE;
if (where == STATUS)
key = KEYC_DOUBLECLICK1_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_DOUBLECLICK1_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_DOUBLECLICK1_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_DOUBLECLICK1_BORDER;
break;
@@ -725,6 +809,10 @@ have_event:
key = KEYC_DOUBLECLICK2_PANE;
if (where == STATUS)
key = KEYC_DOUBLECLICK2_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_DOUBLECLICK2_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_DOUBLECLICK2_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_DOUBLECLICK2_BORDER;
break;
@@ -733,6 +821,10 @@ have_event:
key = KEYC_DOUBLECLICK3_PANE;
if (where == STATUS)
key = KEYC_DOUBLECLICK3_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_DOUBLECLICK3_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_DOUBLECLICK3_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_DOUBLECLICK3_BORDER;
break;
@@ -745,6 +837,10 @@ have_event:
key = KEYC_TRIPLECLICK1_PANE;
if (where == STATUS)
key = KEYC_TRIPLECLICK1_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_TRIPLECLICK1_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_TRIPLECLICK1_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_TRIPLECLICK1_BORDER;
break;
@@ -753,6 +849,10 @@ have_event:
key = KEYC_TRIPLECLICK2_PANE;
if (where == STATUS)
key = KEYC_TRIPLECLICK2_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_TRIPLECLICK2_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_TRIPLECLICK2_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_TRIPLECLICK2_BORDER;
break;
@@ -761,6 +861,10 @@ have_event:
key = KEYC_TRIPLECLICK3_PANE;
if (where == STATUS)
key = KEYC_TRIPLECLICK3_STATUS;
+ if (where == STATUS_LEFT)
+ key = KEYC_TRIPLECLICK3_STATUS_LEFT;
+ if (where == STATUS_RIGHT)
+ key = KEYC_TRIPLECLICK3_STATUS_RIGHT;
if (where == BORDER)
key = KEYC_TRIPLECLICK3_BORDER;
break;
@@ -836,8 +940,6 @@ server_client_handle_key(struct client *c, key_code key)
return;
window_unzoom(w);
wp = window_pane_at_index(w, key - '0');
- if (wp != NULL && !window_pane_visible(wp))
- wp = NULL;
server_client_clear_identify(c, wp);
return;
}
@@ -1183,7 +1285,7 @@ server_client_check_focus(struct window_pane *wp)
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == NULL || !(c->flags & CLIENT_FOCUSED))
continue;
- if (c->session->flags & SESSION_UNATTACHED)
+ if (c->session->attached == 0)
continue;
if (c->session->curw->window == wp->window)
@@ -1224,28 +1326,37 @@ server_client_reset_state(struct client *c)
struct window_pane *wp = w->active, *loop;
struct screen *s = wp->screen;
struct options *oo = c->session->options;
- int lines, mode;
+ int mode, cursor = 0;
+ u_int cx = 0, cy = 0, ox, oy, sx, sy;
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
return;
+ mode = s->mode;
tty_region_off(&c->tty);
tty_margin_off(&c->tty);
- if (status_at_line(c) != 0)
- lines = 0;
- else
- lines = status_line_size(c->session);
- if (!window_pane_visible(wp) || wp->yoff + s->cy >= c->tty.sy - lines)
- tty_cursor(&c->tty, 0, 0);
- else
- tty_cursor(&c->tty, wp->xoff + s->cx, lines + wp->yoff + s->cy);
+ /* Move cursor to pane cursor and offset. */
+ cursor = 0;
+ tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
+ if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx &&
+ wp->yoff + s->cy >= oy && wp->yoff + s->cy <= oy + sy) {
+ cursor = 1;
+
+ cx = wp->xoff + s->cx - ox;
+ cy = wp->yoff + s->cy - oy;
+
+ if (status_at_line(c) == 0)
+ cy += status_line_size(c);
+ }
+ if (!cursor)
+ mode &= ~MODE_CURSOR;
+ tty_cursor(&c->tty, cx, cy);
/*
* Set mouse mode if requested. To support dragging, always use button
* mode.
*/
- mode = s->mode;
if (options_get_number(oo, "mouse")) {
mode &= ~ALL_MOUSE_MODES;
TAILQ_FOREACH(loop, &w->panes, entry) {
@@ -1322,13 +1433,19 @@ server_client_check_redraw(struct client *c)
struct session *s = c->session;
struct tty *tty = &c->tty;
struct window_pane *wp;
- int needed, flags, masked;
+ int needed, flags;
struct timeval tv = { .tv_usec = 1000 };
static struct event ev;
size_t left;
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
return;
+ if (c->flags & CLIENT_ALLREDRAWFLAGS) {
+ log_debug("%s: redraw%s%s%s", c->name,
+ (c->flags & CLIENT_REDRAWWINDOW) ? " window" : "",
+ (c->flags & CLIENT_REDRAWSTATUS) ? " status" : "",
+ (c->flags & CLIENT_REDRAWBORDERS) ? " borders" : "");
+ }
/*
* If there is outstanding data, defer the redraw until it has been
@@ -1336,7 +1453,7 @@ server_client_check_redraw(struct client *c)
* end up back here.
*/
needed = 0;
- if (c->flags & CLIENT_REDRAW)
+ if (c->flags & CLIENT_ALLREDRAWFLAGS)
needed = 1;
else {
TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) {
@@ -1359,25 +1476,19 @@ server_client_check_redraw(struct client *c)
* We may have got here for a single pane redraw, but force a
* full redraw next time in case other panes have been updated.
*/
- c->flags |= CLIENT_REDRAW;
+ c->flags |= CLIENT_ALLREDRAWFLAGS;
return;
} else if (needed)
log_debug("%s: redraw needed", c->name);
- if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
- if (options_get_number(s->options, "set-titles"))
- server_client_set_title(c);
- screen_redraw_update(c); /* will adjust flags */
- }
-
flags = tty->flags & (TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR);
tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE)) | TTY_NOCURSOR;
- if (c->flags & CLIENT_REDRAW) {
- tty_update_mode(tty, tty->mode, NULL);
- screen_redraw_screen(c, 1, 1, 1);
- c->flags &= ~(CLIENT_STATUS|CLIENT_BORDERS);
- } else {
+ if (~c->flags & CLIENT_REDRAWWINDOW) {
+ /*
+ * If not redrawing the entire window, check whether each pane
+ * needs to be redrawn.
+ */
TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) {
if (wp->flags & PANE_REDRAW) {
tty_update_mode(tty, tty->mode, NULL);
@@ -1386,21 +1497,16 @@ server_client_check_redraw(struct client *c)
}
}
- masked = c->flags & (CLIENT_BORDERS|CLIENT_STATUS);
- if (masked != 0)
- tty_update_mode(tty, tty->mode, NULL);
- if (masked == CLIENT_BORDERS)
- screen_redraw_screen(c, 0, 0, 1);
- else if (masked == CLIENT_STATUS)
- screen_redraw_screen(c, 0, 1, 0);
- else if (masked != 0)
- screen_redraw_screen(c, 0, 1, 1);
+ if (c->flags & CLIENT_ALLREDRAWFLAGS) {
+ if (options_get_number(s->options, "set-titles"))
+ server_client_set_title(c);
+ screen_redraw_screen(c);
+ }
tty->flags = (tty->flags & ~(TTY_FREEZE|TTY_NOCURSOR)) | flags;
tty_update_mode(tty, tty->mode, NULL);
- c->flags &= ~(CLIENT_REDRAW|CLIENT_BORDERS|CLIENT_STATUS|
- CLIENT_STATUSFORCE);
+ c->flags &= ~(CLIENT_ALLREDRAWFLAGS|CLIENT_STATUSFORCE);
if (needed) {
/*