mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-07 16:54:01 +01:00
Make mouse event structure clearer by defining events (up, click, drag)
and simplifying how buttons and wheels are represented, from Ailin Nemui. Should be no functional changes.
This commit is contained in:
parent
2a609b332f
commit
d210d99cce
12
input-keys.c
12
input-keys.c
@ -200,7 +200,7 @@ input_key(struct window_pane *wp, int key)
|
||||
|
||||
/* Translate mouse and output. */
|
||||
void
|
||||
input_mouse(struct window_pane *wp, struct mouse_event *m)
|
||||
input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m)
|
||||
{
|
||||
char buf[10];
|
||||
size_t len;
|
||||
@ -208,14 +208,14 @@ input_mouse(struct window_pane *wp, struct mouse_event *m)
|
||||
if (wp->screen->mode & ALL_MOUSE_MODES) {
|
||||
if (wp->screen->mode & MODE_MOUSE_UTF8) {
|
||||
len = xsnprintf(buf, sizeof buf, "\033[M");
|
||||
len += utf8_split2(m->b + 32, &buf[len]);
|
||||
len += utf8_split2(m->xb + 32, &buf[len]);
|
||||
len += utf8_split2(m->x + 33, &buf[len]);
|
||||
len += utf8_split2(m->y + 33, &buf[len]);
|
||||
} else {
|
||||
if (m->b > 223 || m->x >= 222 || m->y > 222)
|
||||
if (m->xb > 223 || m->x >= 222 || m->y > 222)
|
||||
return;
|
||||
len = xsnprintf(buf, sizeof buf, "\033[M");
|
||||
buf[len++] = m->b + 32;
|
||||
buf[len++] = m->xb + 32;
|
||||
buf[len++] = m->x + 33;
|
||||
buf[len++] = m->y + 33;
|
||||
}
|
||||
@ -223,12 +223,12 @@ input_mouse(struct window_pane *wp, struct mouse_event *m)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m->b & 3) != 1 &&
|
||||
if ((m->xb & 3) != 1 &&
|
||||
options_get_number(&wp->window->options, "mode-mouse") == 1) {
|
||||
if (window_pane_set_mode(wp, &window_copy_mode) == 0) {
|
||||
window_copy_init_from_pane(wp);
|
||||
if (wp->mode->mouse != NULL)
|
||||
wp->mode->mouse(wp, NULL, m);
|
||||
wp->mode->mouse(wp, s, m);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
41
layout.c
41
layout.c
@ -488,50 +488,51 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change)
|
||||
}
|
||||
|
||||
void
|
||||
layout_resize_pane_mouse(struct client *c, struct mouse_event *mouse)
|
||||
layout_resize_pane_mouse(struct client *c)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
struct mouse_event *m = &c->tty.mouse;
|
||||
int pane_border;
|
||||
|
||||
w = c->session->curw->window;
|
||||
|
||||
pane_border = 0;
|
||||
if ((c->last_mouse.b & MOUSE_BUTTON) != MOUSE_UP &&
|
||||
(c->last_mouse.b & MOUSE_RESIZE_PANE)) {
|
||||
if (m->event & MOUSE_EVENT_DRAG && m->flags & MOUSE_RESIZE_PANE) {
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->xoff + wp->sx == c->last_mouse.x &&
|
||||
wp->yoff <= 1 + c->last_mouse.y &&
|
||||
wp->yoff + wp->sy >= c->last_mouse.y) {
|
||||
if (wp->xoff + wp->sx == m->lx &&
|
||||
wp->yoff <= 1 + m->ly &&
|
||||
wp->yoff + wp->sy >= m->ly) {
|
||||
layout_resize_pane(wp, LAYOUT_LEFTRIGHT,
|
||||
mouse->x - c->last_mouse.x);
|
||||
m->x - m->lx);
|
||||
pane_border = 1;
|
||||
}
|
||||
if (wp->yoff + wp->sy == c->last_mouse.y &&
|
||||
wp->xoff <= 1 + c->last_mouse.x &&
|
||||
wp->xoff + wp->sx >= c->last_mouse.x) {
|
||||
if (wp->yoff + wp->sy == m->ly &&
|
||||
wp->xoff <= 1 + m->lx &&
|
||||
wp->xoff + wp->sx >= m->lx) {
|
||||
layout_resize_pane(wp, LAYOUT_TOPBOTTOM,
|
||||
mouse->y - c->last_mouse.y);
|
||||
m->y - m->ly);
|
||||
pane_border = 1;
|
||||
}
|
||||
}
|
||||
if (pane_border)
|
||||
server_redraw_window(w);
|
||||
} else if (mouse->b != MOUSE_UP &&
|
||||
mouse->b == (mouse->b & MOUSE_BUTTON)) {
|
||||
} else if (~m->event & MOUSE_EVENT_UP) {
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if ((wp->xoff + wp->sx == mouse->x &&
|
||||
wp->yoff <= 1 + mouse->y &&
|
||||
wp->yoff + wp->sy >= mouse->y) ||
|
||||
(wp->yoff + wp->sy == mouse->y &&
|
||||
wp->xoff <= 1 + mouse->x &&
|
||||
wp->xoff + wp->sx >= mouse->x)) {
|
||||
if ((wp->xoff + wp->sx == m->x &&
|
||||
wp->yoff <= 1 + m->y &&
|
||||
wp->yoff + wp->sy >= m->y) ||
|
||||
(wp->yoff + wp->sy == m->y &&
|
||||
wp->xoff <= 1 + m->x &&
|
||||
wp->xoff + wp->sx >= m->x)) {
|
||||
pane_border = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pane_border)
|
||||
mouse->b |= MOUSE_RESIZE_PANE;
|
||||
m->flags |= MOUSE_RESIZE_PANE;
|
||||
else
|
||||
m->flags &= ~MOUSE_RESIZE_PANE;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -28,8 +28,7 @@
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
void server_client_check_mouse(struct client *, struct window_pane *,
|
||||
struct mouse_event *);
|
||||
void server_client_check_mouse(struct client *, struct window_pane *);
|
||||
void server_client_repeat_timer(int, short, void *);
|
||||
void server_client_check_exit(struct client *);
|
||||
void server_client_check_redraw(struct client *);
|
||||
@ -87,8 +86,12 @@ server_client_create(int fd)
|
||||
c->prompt_buffer = NULL;
|
||||
c->prompt_index = 0;
|
||||
|
||||
c->last_mouse.b = MOUSE_UP;
|
||||
c->last_mouse.x = c->last_mouse.y = -1;
|
||||
c->tty.mouse.xb = c->tty.mouse.button = 3;
|
||||
c->tty.mouse.x = c->tty.mouse.y = -1;
|
||||
c->tty.mouse.lx = c->tty.mouse.ly = -1;
|
||||
c->tty.mouse.sx = c->tty.mouse.sy = -1;
|
||||
c->tty.mouse.event = MOUSE_EVENT_UP;
|
||||
c->tty.mouse.flags = 0;
|
||||
|
||||
evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
|
||||
|
||||
@ -271,37 +274,28 @@ server_client_status_timer(void)
|
||||
|
||||
/* Check for mouse keys. */
|
||||
void
|
||||
server_client_check_mouse(
|
||||
struct client *c, struct window_pane *wp, struct mouse_event *mouse)
|
||||
server_client_check_mouse(struct client *c, struct window_pane *wp)
|
||||
{
|
||||
struct session *s = c->session;
|
||||
struct options *oo = &s->options;
|
||||
int statusat;
|
||||
struct session *s = c->session;
|
||||
struct options *oo = &s->options;
|
||||
struct mouse_event *m = &c->tty.mouse;
|
||||
int statusat;
|
||||
|
||||
statusat = status_at_line(c);
|
||||
|
||||
/* Is this a window selection click on the status line? */
|
||||
if (statusat != -1 && mouse->y == (u_int)statusat &&
|
||||
if (statusat != -1 && m->y == (u_int)statusat &&
|
||||
options_get_number(oo, "mouse-select-window")) {
|
||||
if (mouse->b == MOUSE_UP && c->last_mouse.b != MOUSE_UP) {
|
||||
status_set_window_at(c, mouse->x);
|
||||
recalculate_sizes();
|
||||
return;
|
||||
}
|
||||
if (mouse->b & MOUSE_45) {
|
||||
if ((mouse->b & MOUSE_BUTTON) == MOUSE_1) {
|
||||
if (m->event & MOUSE_EVENT_CLICK) {
|
||||
status_set_window_at(c, m->x);
|
||||
} else if (m->event == MOUSE_EVENT_WHEEL) {
|
||||
if (m->wheel == MOUSE_WHEEL_UP)
|
||||
session_previous(c->session, 0);
|
||||
server_redraw_session(s);
|
||||
recalculate_sizes();
|
||||
}
|
||||
if ((mouse->b & MOUSE_BUTTON) == MOUSE_2) {
|
||||
else if (m->wheel == MOUSE_WHEEL_DOWN)
|
||||
session_next(c->session, 0);
|
||||
server_redraw_session(s);
|
||||
recalculate_sizes();
|
||||
}
|
||||
return;
|
||||
server_redraw_session(s);
|
||||
}
|
||||
memcpy(&c->last_mouse, mouse, sizeof c->last_mouse);
|
||||
recalculate_sizes();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -310,27 +304,25 @@ server_client_check_mouse(
|
||||
* top and limit if at the bottom. From here on a struct mouse
|
||||
* represents the offset onto the window itself.
|
||||
*/
|
||||
if (statusat == 0 &&mouse->y > 0)
|
||||
mouse->y--;
|
||||
else if (statusat > 0 && mouse->y >= (u_int)statusat)
|
||||
mouse->y = statusat - 1;
|
||||
if (statusat == 0 && m->y > 0)
|
||||
m->y--;
|
||||
else if (statusat > 0 && m->y >= (u_int)statusat)
|
||||
m->y = statusat - 1;
|
||||
|
||||
/* Is this a pane selection? Allow down only in copy mode. */
|
||||
if (options_get_number(oo, "mouse-select-pane") &&
|
||||
((!(mouse->b & MOUSE_DRAG) && mouse->b != MOUSE_UP) ||
|
||||
wp->mode != &window_copy_mode)) {
|
||||
window_set_active_at(wp->window, mouse->x, mouse->y);
|
||||
(m->event == MOUSE_EVENT_DOWN || wp->mode != &window_copy_mode)) {
|
||||
window_set_active_at(wp->window, m->x, m->y);
|
||||
server_redraw_window_borders(wp->window);
|
||||
wp = wp->window->active; /* may have changed */
|
||||
}
|
||||
|
||||
/* Check if trying to resize pane. */
|
||||
if (options_get_number(oo, "mouse-resize-pane"))
|
||||
layout_resize_pane_mouse(c, mouse);
|
||||
layout_resize_pane_mouse(c);
|
||||
|
||||
/* Update last and pass through to client. */
|
||||
memcpy(&c->last_mouse, mouse, sizeof c->last_mouse);
|
||||
window_pane_mouse(wp, c->session, mouse);
|
||||
window_pane_mouse(wp, c->session, m);
|
||||
}
|
||||
|
||||
/* Handle data key input from client. */
|
||||
@ -385,7 +377,7 @@ server_client_handle_key(struct client *c, int key)
|
||||
if (key == KEYC_MOUSE) {
|
||||
if (c->flags & CLIENT_READONLY)
|
||||
return;
|
||||
server_client_check_mouse(c, wp, &c->tty.mouse);
|
||||
server_client_check_mouse(c, wp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -524,7 +516,7 @@ server_client_reset_state(struct client *c)
|
||||
* a smooth appearance.
|
||||
*/
|
||||
mode = s->mode;
|
||||
if ((c->last_mouse.b & MOUSE_RESIZE_PANE) &&
|
||||
if ((c->tty.mouse.flags & MOUSE_RESIZE_PANE) &&
|
||||
!(mode & (MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)))
|
||||
mode |= MODE_MOUSE_BUTTON;
|
||||
|
||||
|
72
tmux.h
72
tmux.h
@ -1119,29 +1119,6 @@ struct session {
|
||||
RB_HEAD(sessions, session);
|
||||
ARRAY_DECL(sessionslist, struct session *);
|
||||
|
||||
/*
|
||||
* Mouse input. xterm mouse mode is fairly silly. Buttons are in the bottom two
|
||||
* bits: 0 = button 1; 1 = button 2; 2 = button 3; 3 = buttons released. Bits
|
||||
* 3, 4 and 5 are for keys. Bit 6 is set for dragging and 7 for mouse buttons 4
|
||||
* and 5.
|
||||
*/
|
||||
struct mouse_event {
|
||||
u_int b;
|
||||
#define MOUSE_1 0
|
||||
#define MOUSE_2 1
|
||||
#define MOUSE_3 2
|
||||
#define MOUSE_UP 3
|
||||
#define MOUSE_BUTTON 3
|
||||
#define MOUSE_SHIFT 4
|
||||
#define MOUSE_ESCAPE 8
|
||||
#define MOUSE_CTRL 16
|
||||
#define MOUSE_DRAG 32
|
||||
#define MOUSE_45 64
|
||||
#define MOUSE_RESIZE_PANE 128 /* marker for resizing */
|
||||
u_int x;
|
||||
u_int y;
|
||||
};
|
||||
|
||||
/* TTY information. */
|
||||
struct tty_key {
|
||||
char ch;
|
||||
@ -1170,6 +1147,47 @@ struct tty_term {
|
||||
};
|
||||
LIST_HEAD(tty_terms, tty_term);
|
||||
|
||||
/* Mouse wheel states. */
|
||||
#define MOUSE_WHEEL_UP 0
|
||||
#define MOUSE_WHEEL_DOWN 1
|
||||
|
||||
/* Mouse events. */
|
||||
#define MOUSE_EVENT_DOWN (1 << 0)
|
||||
#define MOUSE_EVENT_DRAG (1 << 1)
|
||||
#define MOUSE_EVENT_UP (1 << 2)
|
||||
#define MOUSE_EVENT_CLICK (1 << 3)
|
||||
#define MOUSE_EVENT_WHEEL (1 << 4)
|
||||
|
||||
/* Mouse flags. */
|
||||
#define MOUSE_RESIZE_PANE (1 << 0)
|
||||
|
||||
/*
|
||||
* Mouse input. When sent by xterm:
|
||||
*
|
||||
* - buttons are in the bottom two bits: 0 = b1; 1 = b2; 2 = b3; 3 = released
|
||||
* - bits 3, 4 and 5 are for keys
|
||||
* - bit 6 is set for dragging
|
||||
* - bit 7 for buttons 4 and 5
|
||||
*/
|
||||
struct mouse_event {
|
||||
u_int xb;
|
||||
|
||||
u_int x;
|
||||
u_int lx;
|
||||
u_int sx;
|
||||
|
||||
u_int y;
|
||||
u_int ly;
|
||||
u_int sy;
|
||||
|
||||
u_int button;
|
||||
u_int clicks;
|
||||
|
||||
int wheel;
|
||||
int event;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct tty {
|
||||
struct client *client;
|
||||
|
||||
@ -1330,8 +1348,6 @@ struct client {
|
||||
struct session *session;
|
||||
struct session *last_session;
|
||||
|
||||
struct mouse_event last_mouse;
|
||||
|
||||
int wlmouse;
|
||||
|
||||
int references;
|
||||
@ -1926,7 +1942,8 @@ void input_parse(struct window_pane *);
|
||||
|
||||
/* input-key.c */
|
||||
void input_key(struct window_pane *, int);
|
||||
void input_mouse(struct window_pane *, struct mouse_event *);
|
||||
void input_mouse(struct window_pane *, struct session *,
|
||||
struct mouse_event *);
|
||||
|
||||
/* xterm-keys.c */
|
||||
char *xterm_keys_lookup(int);
|
||||
@ -2170,8 +2187,7 @@ void layout_free(struct window *);
|
||||
void layout_resize(struct window *, u_int, u_int);
|
||||
void layout_resize_pane(
|
||||
struct window_pane *, enum layout_type, int);
|
||||
void layout_resize_pane_mouse(
|
||||
struct client *c, struct mouse_event *mouse);
|
||||
void layout_resize_pane_mouse(struct client *c);
|
||||
void layout_assign_pane(struct layout_cell *, struct window_pane *);
|
||||
struct layout_cell *layout_split_pane(
|
||||
struct window_pane *, enum layout_type, int, int);
|
||||
|
56
tty-keys.c
56
tty-keys.c
@ -611,7 +611,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
||||
{
|
||||
struct mouse_event *m = &tty->mouse;
|
||||
struct utf8_data utf8data;
|
||||
u_int i, value;
|
||||
u_int i, value, x, y, b;
|
||||
|
||||
/*
|
||||
* Standard mouse sequences are \033[M followed by three characters
|
||||
@ -622,6 +622,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
||||
*/
|
||||
|
||||
*size = 0;
|
||||
x = y = b = 0;
|
||||
|
||||
/* First three bytes are always \033[M. */
|
||||
if (buf[0] != '\033')
|
||||
@ -661,21 +662,58 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
m->b = value;
|
||||
b = value;
|
||||
else if (i == 1)
|
||||
m->x = value;
|
||||
x = value;
|
||||
else
|
||||
m->y = value;
|
||||
y = value;
|
||||
}
|
||||
log_debug("mouse input: %.*s", (int) *size, buf);
|
||||
|
||||
/* Check and return the mouse input. */
|
||||
if (m->b < 32 || m->x < 33 || m->y < 33)
|
||||
if (b < 32 || x < 33 || y < 33)
|
||||
return (-1);
|
||||
m->b -= 32;
|
||||
m->x -= 33;
|
||||
m->y -= 33;
|
||||
log_debug("mouse position: x=%u y=%u b=%u", m->x, m->y, m->b);
|
||||
b -= 32;
|
||||
x -= 33;
|
||||
y -= 33;
|
||||
log_debug("mouse position: x=%u y=%u b=%u", x, y, b);
|
||||
|
||||
/* Fill in mouse structure. */
|
||||
if (~m->event & MOUSE_EVENT_WHEEL) {
|
||||
m->lx = m->x;
|
||||
m->ly = m->y;
|
||||
}
|
||||
m->xb = b;
|
||||
if (b & 64) { /* wheel button */
|
||||
b &= 3;
|
||||
if (b == 0)
|
||||
m->wheel = MOUSE_WHEEL_UP;
|
||||
else if (b == 1)
|
||||
m->wheel = MOUSE_WHEEL_DOWN;
|
||||
m->event = MOUSE_EVENT_WHEEL;
|
||||
} else if ((b & 3) == 3) {
|
||||
if (~m->event & MOUSE_EVENT_DRAG && x == m->x && y == m->y) {
|
||||
m->event = MOUSE_EVENT_CLICK;
|
||||
} else
|
||||
m->event = MOUSE_EVENT_DRAG;
|
||||
m->event |= MOUSE_EVENT_UP;
|
||||
} else {
|
||||
if (b & 32) /* drag motion */
|
||||
m->event = MOUSE_EVENT_DRAG;
|
||||
else {
|
||||
if (m->event & MOUSE_EVENT_UP && x == m->x && y == m->y)
|
||||
m->clicks = (m->clicks + 1) % 3;
|
||||
else
|
||||
m->clicks = 0;
|
||||
m->sx = x;
|
||||
m->sy = y;
|
||||
m->event = MOUSE_EVENT_DOWN;
|
||||
}
|
||||
m->button = (b & 3);
|
||||
}
|
||||
m->x = x;
|
||||
m->y = y;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -623,7 +623,7 @@ window_choose_mouse(
|
||||
struct window_choose_mode_item *item;
|
||||
u_int idx;
|
||||
|
||||
if ((m->b & 3) == 3)
|
||||
if (~m->event & MOUSE_EVENT_CLICK)
|
||||
return;
|
||||
if (m->x >= screen_size_x(s))
|
||||
return;
|
||||
|
@ -829,11 +829,11 @@ window_copy_mouse(
|
||||
return;
|
||||
|
||||
/* If mouse wheel (buttons 4 and 5), scroll. */
|
||||
if ((m->b & MOUSE_45)) {
|
||||
if ((m->b & MOUSE_BUTTON) == MOUSE_1) {
|
||||
if (m->event == MOUSE_EVENT_WHEEL) {
|
||||
if (m->wheel == MOUSE_WHEEL_UP) {
|
||||
for (i = 0; i < 5; i++)
|
||||
window_copy_cursor_up(wp, 0);
|
||||
} else if ((m->b & MOUSE_BUTTON) == MOUSE_2) {
|
||||
} else if (m->wheel == MOUSE_WHEEL_DOWN) {
|
||||
for (i = 0; i < 5; i++)
|
||||
window_copy_cursor_down(wp, 0);
|
||||
if (data->oy == 0)
|
||||
@ -847,7 +847,7 @@ window_copy_mouse(
|
||||
* pressed, or stop the selection on their release.
|
||||
*/
|
||||
if (s->mode & MODE_MOUSE_BUTTON) {
|
||||
if ((m->b & MOUSE_BUTTON) != MOUSE_UP) {
|
||||
if (~m->event & MOUSE_EVENT_UP) {
|
||||
window_copy_update_cursor(wp, m->x, m->y);
|
||||
if (window_copy_update_selection(wp))
|
||||
window_copy_redraw_screen(wp);
|
||||
@ -857,7 +857,7 @@ window_copy_mouse(
|
||||
}
|
||||
|
||||
/* Otherwise if other buttons pressed, start selection and motion. */
|
||||
if ((m->b & MOUSE_BUTTON) != MOUSE_UP) {
|
||||
if (~m->event & MOUSE_EVENT_UP) {
|
||||
s->mode &= ~MODE_MOUSE_STANDARD;
|
||||
s->mode |= MODE_MOUSE_BUTTON;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user