aboutsummaryrefslogtreecommitdiff
path: root/server-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'server-client.c')
-rw-r--r--server-client.c89
1 files changed, 62 insertions, 27 deletions
diff --git a/server-client.c b/server-client.c
index afc390c7..410b8c02 100644
--- a/server-client.c
+++ b/server-client.c
@@ -23,8 +23,6 @@
#include <errno.h>
#include <event.h>
#include <fcntl.h>
-#include <imsg.h>
-#include <paths.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -194,6 +192,7 @@ server_client_create(int fd)
c->session = NULL;
c->last_session = NULL;
+
c->tty.sx = 80;
c->tty.sy = 24;
@@ -412,7 +411,7 @@ 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;
@@ -422,8 +421,8 @@ server_client_check_mouse(struct client *c)
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 != ' ' &&
@@ -442,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)) {
@@ -518,20 +517,33 @@ have_event:
/* 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;
+ 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 == x &&
- wp->yoff <= 1 + y &&
- wp->yoff + wp->sy >= y) ||
- (wp->yoff + wp->sy == y &&
- wp->xoff <= 1 + x &&
- wp->xoff + wp->sx >= x))
+ 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)
@@ -540,7 +552,7 @@ have_event:
/* Otherwise try inside the pane. */
if (where == NOWHERE) {
- wp = window_get_active_at(s->curw->window, x, y);
+ wp = window_get_active_at(s->curw->window, px, py);
if (wp != NULL)
where = PANE;
}
@@ -928,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;
}
@@ -1171,6 +1181,9 @@ server_client_resize_force(struct window_pane *wp)
ws.ws_col = wp->sx;
ws.ws_row = wp->sy - 1;
if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
+#ifdef __sun
+ if (errno != EINVAL && errno != ENXIO)
+#endif
fatal("ioctl failed");
log_debug("%s: %%%u forcing resize", __func__, wp->id);
@@ -1197,6 +1210,15 @@ server_client_resize_event(__unused int fd, __unused short events, void *data)
ws.ws_col = wp->sx;
ws.ws_row = wp->sy;
if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
+#ifdef __sun
+ /*
+ * Some versions of Solaris apparently can return an error when
+ * resizing; don't know why this happens, can't reproduce on
+ * other platforms and ignoring it doesn't seem to cause any
+ * issues.
+ */
+ if (errno != EINVAL && errno != ENXIO)
+#endif
fatal("ioctl failed");
log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy);
@@ -1304,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) {
@@ -1774,6 +1805,10 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
c->name = name;
log_debug("client %p name is %s", c, c->name);
+#ifdef __CYGWIN__
+ c->fd = open(c->ttyname, O_RDWR|O_NOCTTY);
+#endif
+
if (c->flags & CLIENT_CONTROL) {
c->stdin_callback = control_callback;