mirror of
https://github.com/tmate-io/tmate.git
synced 2025-04-11 05:00:16 +02:00
Rewrite of tmux mouse support which was a mess. Instead of having
options for "mouse-this" and "mouse-that", mouse events may be bound as keys and there is one option "mouse" that turns on mouse support entirely (set -g mouse on). See the new MOUSE SUPPORT section of the man page for description of the key names and new flags (-t= to specify the pane or window under mouse as a target, and send-keys -M to pass through a mouse event). The default builtin bindings for the mouse are: bind -n MouseDown1Pane select-pane -t=; send-keys -M bind -n MouseDown1Status select-window -t= bind -n MouseDrag1Pane copy-mode -M bind -n MouseDrag1Border resize-pane -M To get the effect of turning mode-mouse off, do: unbind -n MouseDrag1Pane unbind -temacs-copy MouseDrag1Pane The old mouse options are now gone, set-option -q may be used to suppress warnings if mixing configuration files.
This commit is contained in:
parent
ee123c2489
commit
bf635e7741
2
cfg.c
2
cfg.c
@ -75,7 +75,7 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
|
|||||||
|
|
||||||
if (cmdlist == NULL)
|
if (cmdlist == NULL)
|
||||||
continue;
|
continue;
|
||||||
cmdq_append(cmdq, cmdlist);
|
cmdq_append(cmdq, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ cmd_command_prompt_callback(void *data, const char *s)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdq_run(c->cmdq, cmdlist);
|
cmdq_run(c->cmdq, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
|
|
||||||
if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
|
if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
|
||||||
|
@ -105,7 +105,7 @@ cmd_confirm_before_callback(void *data, const char *s)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdq_run(c->cmdq, cmdlist);
|
cmdq_run(c->cmdq, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -28,8 +28,8 @@ enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *);
|
|||||||
|
|
||||||
const struct cmd_entry cmd_copy_mode_entry = {
|
const struct cmd_entry cmd_copy_mode_entry = {
|
||||||
"copy-mode", NULL,
|
"copy-mode", NULL,
|
||||||
"t:u", 0, 0,
|
"Mt:u", 0, 0,
|
||||||
"[-u] " CMD_TARGET_PANE_USAGE,
|
"[-Mu] " CMD_TARGET_PANE_USAGE,
|
||||||
0,
|
0,
|
||||||
cmd_copy_mode_exec
|
cmd_copy_mode_exec
|
||||||
};
|
};
|
||||||
@ -46,9 +46,16 @@ enum cmd_retval
|
|||||||
cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
|
cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
|
struct client *c = cmdq->client;
|
||||||
|
struct session *s;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
|
||||||
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
if (args_has(args, 'M')) {
|
||||||
|
if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL)
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
if (c == NULL || c->session != s)
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
} else if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
|
|
||||||
if (self->entry == &cmd_clock_mode_entry) {
|
if (self->entry == &cmd_clock_mode_entry) {
|
||||||
@ -61,6 +68,8 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
window_copy_init_from_pane(wp);
|
window_copy_init_from_pane(wp);
|
||||||
}
|
}
|
||||||
|
if (args_has(args, 'M'))
|
||||||
|
window_copy_start_drag(c, &cmdq->item->mouse);
|
||||||
if (wp->mode == &window_copy_mode && args_has(self->args, 'u'))
|
if (wp->mode == &window_copy_mode && args_has(self->args, 'u'))
|
||||||
window_copy_pageup(wp);
|
window_copy_pageup(wp);
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||||||
}
|
}
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
cmdq_run(cmdq, cmdlist);
|
cmdq_run(cmdq, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
@ -152,7 +152,7 @@ cmd_if_shell_callback(struct job *job)
|
|||||||
cmdq1->emptyfn = cmd_if_shell_done;
|
cmdq1->emptyfn = cmd_if_shell_done;
|
||||||
cmdq1->data = cdata;
|
cmdq1->data = cdata;
|
||||||
|
|
||||||
cmdq_run(cmdq1, cmdlist);
|
cmdq_run(cmdq1, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
cmd-queue.c
12
cmd-queue.c
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
@ -132,9 +133,9 @@ cmdq_guard(struct cmd_q *cmdq, const char *guard, int flags)
|
|||||||
|
|
||||||
/* Add command list to queue and begin processing if needed. */
|
/* Add command list to queue and begin processing if needed. */
|
||||||
void
|
void
|
||||||
cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist)
|
cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
cmdq_append(cmdq, cmdlist);
|
cmdq_append(cmdq, cmdlist, m);
|
||||||
|
|
||||||
if (cmdq->item == NULL) {
|
if (cmdq->item == NULL) {
|
||||||
cmdq->cmd = NULL;
|
cmdq->cmd = NULL;
|
||||||
@ -144,7 +145,7 @@ cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist)
|
|||||||
|
|
||||||
/* Add command list to queue. */
|
/* Add command list to queue. */
|
||||||
void
|
void
|
||||||
cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist)
|
cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
struct cmd_q_item *item;
|
struct cmd_q_item *item;
|
||||||
|
|
||||||
@ -152,6 +153,11 @@ cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist)
|
|||||||
item->cmdlist = cmdlist;
|
item->cmdlist = cmdlist;
|
||||||
TAILQ_INSERT_TAIL(&cmdq->queue, item, qentry);
|
TAILQ_INSERT_TAIL(&cmdq->queue, item, qentry);
|
||||||
cmdlist->references++;
|
cmdlist->references++;
|
||||||
|
|
||||||
|
if (m != NULL)
|
||||||
|
memcpy(&item->mouse, m, sizeof item->mouse);
|
||||||
|
else
|
||||||
|
item->mouse.valid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Continue processing command queue. Returns 1 if finishes empty. */
|
/* Continue processing command queue. Returns 1 if finishes empty. */
|
||||||
|
@ -28,10 +28,13 @@
|
|||||||
|
|
||||||
enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_q *);
|
enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_q *);
|
||||||
|
|
||||||
|
void cmd_resize_pane_mouse_update(struct client *, struct mouse_event *);
|
||||||
|
|
||||||
const struct cmd_entry cmd_resize_pane_entry = {
|
const struct cmd_entry cmd_resize_pane_entry = {
|
||||||
"resize-pane", "resizep",
|
"resize-pane", "resizep",
|
||||||
"DLRt:Ux:y:Z", 0, 1,
|
"DLMRt:Ux:y:Z", 0, 1,
|
||||||
"[-DLRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]",
|
"[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE
|
||||||
|
" [adjustment]",
|
||||||
0,
|
0,
|
||||||
cmd_resize_pane_exec
|
cmd_resize_pane_exec
|
||||||
};
|
};
|
||||||
@ -40,6 +43,8 @@ enum cmd_retval
|
|||||||
cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
|
struct client *c = cmdq->client;
|
||||||
|
struct session *s;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
@ -48,6 +53,16 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||||||
u_int adjust;
|
u_int adjust;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
if (args_has(args, 'M')) {
|
||||||
|
if (cmd_mouse_window(&cmdq->item->mouse, &s) == NULL)
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
if (c == NULL || c->session != s)
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update;
|
||||||
|
cmd_resize_pane_mouse_update(c, &cmdq->item->mouse);
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
|
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
w = wl->window;
|
w = wl->window;
|
||||||
@ -106,3 +121,50 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
|
||||||
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
struct window_pane *wp;
|
||||||
|
int found;
|
||||||
|
u_int y, ly;
|
||||||
|
|
||||||
|
wl = cmd_mouse_window(m, NULL);
|
||||||
|
if (wl == NULL) {
|
||||||
|
c->tty.mouse_drag_update = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
y = m->y;
|
||||||
|
if (m->statusat == 0 && y > 0)
|
||||||
|
y--;
|
||||||
|
else if (m->statusat > 0 && y >= (u_int)m->statusat)
|
||||||
|
y = m->statusat - 1;
|
||||||
|
ly = m->ly;
|
||||||
|
if (m->statusat == 0 && ly > 0)
|
||||||
|
ly--;
|
||||||
|
else if (m->statusat > 0 && ly >= (u_int)m->statusat)
|
||||||
|
ly = m->statusat - 1;
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
|
||||||
|
if (!window_pane_visible(wp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (wp->xoff + wp->sx == m->lx &&
|
||||||
|
wp->yoff <= 1 + ly && wp->yoff + wp->sy >= ly) {
|
||||||
|
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, m->x - m->lx);
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
if (wp->yoff + wp->sy == ly &&
|
||||||
|
wp->xoff <= 1 + m->lx && wp->xoff + wp->sx >= m->lx) {
|
||||||
|
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, y - ly);
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
server_redraw_window(wl->window);
|
||||||
|
else
|
||||||
|
c->tty.mouse_drag_update = NULL;
|
||||||
|
}
|
||||||
|
@ -31,8 +31,8 @@ enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_q *);
|
|||||||
|
|
||||||
const struct cmd_entry cmd_send_keys_entry = {
|
const struct cmd_entry cmd_send_keys_entry = {
|
||||||
"send-keys", "send",
|
"send-keys", "send",
|
||||||
"lRt:", 0, -1,
|
"lRMt:", 0, -1,
|
||||||
"[-lR] " CMD_TARGET_PANE_USAGE " key ...",
|
"[-lRM] " CMD_TARGET_PANE_USAGE " key ...",
|
||||||
0,
|
0,
|
||||||
cmd_send_keys_exec
|
cmd_send_keys_exec
|
||||||
};
|
};
|
||||||
@ -49,12 +49,23 @@ enum cmd_retval
|
|||||||
cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
|
struct mouse_event *m = &cmdq->item->mouse;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct session *s;
|
struct session *s;
|
||||||
struct input_ctx *ictx;
|
struct input_ctx *ictx;
|
||||||
const u_char *str;
|
const u_char *str;
|
||||||
int i, key;
|
int i, key;
|
||||||
|
|
||||||
|
if (args_has(args, 'M')) {
|
||||||
|
wp = cmd_mouse_pane(m, &s, NULL);
|
||||||
|
if (wp == NULL) {
|
||||||
|
cmdq_error(cmdq, "no mouse target");
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
window_pane_key(wp, NULL, s, m->key, m);
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
|
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
|
|
||||||
@ -63,7 +74,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||||||
key = options_get_number(&s->options, "prefix2");
|
key = options_get_number(&s->options, "prefix2");
|
||||||
else
|
else
|
||||||
key = options_get_number(&s->options, "prefix");
|
key = options_get_number(&s->options, "prefix");
|
||||||
window_pane_key(wp, s, key);
|
window_pane_key(wp, NULL, s, key, NULL);
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,10 +99,10 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||||||
|
|
||||||
if (!args_has(args, 'l') &&
|
if (!args_has(args, 'l') &&
|
||||||
(key = key_string_lookup_string(str)) != KEYC_NONE) {
|
(key = key_string_lookup_string(str)) != KEYC_NONE) {
|
||||||
window_pane_key(wp, s, key);
|
window_pane_key(wp, NULL, s, key, NULL);
|
||||||
} else {
|
} else {
|
||||||
for (; *str != '\0'; str++)
|
for (; *str != '\0'; str++)
|
||||||
window_pane_key(wp, s, *str);
|
window_pane_key(wp, NULL, s, *str, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
94
cmd.c
94
cmd.c
@ -348,6 +348,7 @@ cmd_current_session(struct cmd_q *cmdq, int prefer_unattached)
|
|||||||
const char *path;
|
const char *path;
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
|
/* Try the queue session. */
|
||||||
if (c != NULL && c->session != NULL)
|
if (c != NULL && c->session != NULL)
|
||||||
return (c->session);
|
return (c->session);
|
||||||
|
|
||||||
@ -504,6 +505,74 @@ cmd_choose_client(struct clients *cc)
|
|||||||
return (cbest);
|
return (cbest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Adjust current mouse position for a pane. */
|
||||||
|
int
|
||||||
|
cmd_mouse_at(struct window_pane *wp, struct mouse_event *m, u_int *xp,
|
||||||
|
u_int *yp, int last)
|
||||||
|
{
|
||||||
|
u_int x, y;
|
||||||
|
|
||||||
|
if (last) {
|
||||||
|
x = m->lx;
|
||||||
|
y = m->ly;
|
||||||
|
} else {
|
||||||
|
x = m->x;
|
||||||
|
y = m->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->statusat == 0 && y > 0)
|
||||||
|
y--;
|
||||||
|
else if (m->statusat > 0 && y >= (u_int)m->statusat)
|
||||||
|
y = m->statusat - 1;
|
||||||
|
|
||||||
|
if (x < wp->xoff || x >= wp->xoff + wp->sx)
|
||||||
|
return (-1);
|
||||||
|
if (y < wp->yoff || y >= wp->yoff + wp->sy)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
*xp = x - wp->xoff;
|
||||||
|
*yp = y - wp->yoff;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get current mouse window if any. */
|
||||||
|
struct winlink *
|
||||||
|
cmd_mouse_window(struct mouse_event *m, struct session **sp)
|
||||||
|
{
|
||||||
|
struct session *s;
|
||||||
|
struct window *w;
|
||||||
|
|
||||||
|
if (!m->valid || m->s == -1 || m->w == -1)
|
||||||
|
return (NULL);
|
||||||
|
if ((s = session_find_by_id(m->s)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
if ((w = window_find_by_id(m->w)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (sp != NULL)
|
||||||
|
*sp = s;
|
||||||
|
return (winlink_find_by_window(&s->windows, w));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get current mouse pane if any. */
|
||||||
|
struct window_pane *
|
||||||
|
cmd_mouse_pane(struct mouse_event *m, struct session **sp, struct winlink **wlp)
|
||||||
|
{
|
||||||
|
struct winlink *wl;
|
||||||
|
struct window_pane *wp;
|
||||||
|
|
||||||
|
if ((wl = cmd_mouse_window(m, sp)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
if ((wp = window_pane_find_by_id(m->wp)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
if (!window_has_pane(wl->window, wp))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (wlp != NULL)
|
||||||
|
*wlp = wl;
|
||||||
|
return (wp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the target client or report an error and return NULL. */
|
/* Find the target client or report an error and return NULL. */
|
||||||
struct client *
|
struct client *
|
||||||
cmd_find_client(struct cmd_q *cmdq, const char *arg, int quiet)
|
cmd_find_client(struct cmd_q *cmdq, const char *arg, int quiet)
|
||||||
@ -928,7 +997,12 @@ no_colon:
|
|||||||
* No colon in the string, first try special cases, then as a window
|
* No colon in the string, first try special cases, then as a window
|
||||||
* and lastly as a session.
|
* and lastly as a session.
|
||||||
*/
|
*/
|
||||||
if (arg[0] == '!' && arg[1] == '\0') {
|
if (arg[0] == '=' && arg[1] == '\0') {
|
||||||
|
if ((wl = cmd_mouse_window(&cmdq->item->mouse, &s)) == NULL) {
|
||||||
|
cmdq_error(cmdq, "no mouse target");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else if (arg[0] == '!' && arg[1] == '\0') {
|
||||||
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
|
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
} else if (arg[0] == '+' || arg[0] == '-') {
|
} else if (arg[0] == '+' || arg[0] == '-') {
|
||||||
@ -959,14 +1033,16 @@ no_session:
|
|||||||
cmdq_error(cmdq, "multiple sessions: %s", arg);
|
cmdq_error(cmdq, "multiple sessions: %s", arg);
|
||||||
else
|
else
|
||||||
cmdq_error(cmdq, "session not found: %s", arg);
|
cmdq_error(cmdq, "session not found: %s", arg);
|
||||||
free(sessptr);
|
goto error;
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
if (ambiguous)
|
if (ambiguous)
|
||||||
cmdq_error(cmdq, "multiple windows: %s", arg);
|
cmdq_error(cmdq, "multiple windows: %s", arg);
|
||||||
else
|
else
|
||||||
cmdq_error(cmdq, "window not found: %s", arg);
|
cmdq_error(cmdq, "window not found: %s", arg);
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
error:
|
||||||
free(sessptr);
|
free(sessptr);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -1228,6 +1304,18 @@ lookup_string:
|
|||||||
return (wl);
|
return (wl);
|
||||||
|
|
||||||
no_period:
|
no_period:
|
||||||
|
/* Check mouse event. */
|
||||||
|
if (arg[0] == '=' && arg[1] == '\0') {
|
||||||
|
*wpp = cmd_mouse_pane(&cmdq->item->mouse, &s, &wl);
|
||||||
|
if (*wpp == NULL) {
|
||||||
|
cmdq_error(cmdq, "no mouse target");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (sp != NULL)
|
||||||
|
*sp = s;
|
||||||
|
return (wl);
|
||||||
|
}
|
||||||
|
|
||||||
/* Try as a pane number alone. */
|
/* Try as a pane number alone. */
|
||||||
idx = strtonum(arg, 0, INT_MAX, &errstr);
|
idx = strtonum(arg, 0, INT_MAX, &errstr);
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
|
@ -81,7 +81,7 @@ control_callback(struct client *c, int closed, unused void *data)
|
|||||||
} else {
|
} else {
|
||||||
TAILQ_FOREACH(cmd, &cmdlist->list, qentry)
|
TAILQ_FOREACH(cmd, &cmdlist->list, qentry)
|
||||||
cmd->flags |= CMD_CONTROL;
|
cmd->flags |= CMD_CONTROL;
|
||||||
cmdq_run(c->cmdq, cmdlist);
|
cmdq_run(c->cmdq, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
input-keys.c
77
input-keys.c
@ -31,6 +31,8 @@
|
|||||||
* direction with output).
|
* direction with output).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void input_key_mouse(struct window_pane *, struct mouse_event *);
|
||||||
|
|
||||||
struct input_key_ent {
|
struct input_key_ent {
|
||||||
int key;
|
int key;
|
||||||
const char *data;
|
const char *data;
|
||||||
@ -135,7 +137,7 @@ const struct input_key_ent input_keys[] = {
|
|||||||
|
|
||||||
/* Translate a key code into an output key sequence. */
|
/* Translate a key code into an output key sequence. */
|
||||||
void
|
void
|
||||||
input_key(struct window_pane *wp, int key)
|
input_key(struct window_pane *wp, int key, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
const struct input_key_ent *ike;
|
const struct input_key_ent *ike;
|
||||||
u_int i;
|
u_int i;
|
||||||
@ -143,7 +145,14 @@ input_key(struct window_pane *wp, int key)
|
|||||||
char *out;
|
char *out;
|
||||||
u_char ch;
|
u_char ch;
|
||||||
|
|
||||||
log_debug("writing key 0x%x", key);
|
log_debug("writing key 0x%x (%s)", key, key_string_lookup_key(key));
|
||||||
|
|
||||||
|
/* If this is a mouse key, pass off to mouse function. */
|
||||||
|
if (KEYC_IS_MOUSE(key)) {
|
||||||
|
if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)
|
||||||
|
input_key_mouse(wp, m);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is a normal 7-bit key, just send it, with a leading escape
|
* If this is a normal 7-bit key, just send it, with a leading escape
|
||||||
@ -200,55 +209,47 @@ input_key(struct window_pane *wp, int key)
|
|||||||
|
|
||||||
/* Translate mouse and output. */
|
/* Translate mouse and output. */
|
||||||
void
|
void
|
||||||
input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m)
|
input_key_mouse(struct window_pane *wp, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
char buf[40];
|
char buf[40];
|
||||||
size_t len;
|
size_t len;
|
||||||
struct paste_buffer *pb;
|
u_int x, y;
|
||||||
int event;
|
|
||||||
|
if ((wp->screen->mode & ALL_MOUSE_MODES) == 0)
|
||||||
|
return;
|
||||||
|
if (!window_pane_visible(wp))
|
||||||
|
return;
|
||||||
|
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If this pane is not in button mode, discard motion events. */
|
||||||
|
if (!(wp->screen->mode & MODE_MOUSE_BUTTON) && (m->b & MOUSE_MASK_DRAG))
|
||||||
|
return;
|
||||||
|
|
||||||
if (wp->screen->mode & ALL_MOUSE_MODES) {
|
|
||||||
/*
|
/*
|
||||||
* Use the SGR (1006) extension only if the application
|
* Use the SGR (1006) extension only if the application requested it
|
||||||
* requested it and the underlying terminal also sent the event
|
* and the underlying terminal also sent the event in this format (this
|
||||||
* in this format (this is because an old style mouse release
|
* is because an old style mouse release event cannot be converted into
|
||||||
* event cannot be converted into the new SGR format, since the
|
* the new SGR format, since the released button is unknown). Otherwise
|
||||||
* released button is unknown). Otherwise pretend that tmux
|
* pretend that tmux doesn't speak this extension, and fall back to the
|
||||||
* doesn't speak this extension, and fall back to the UTF-8
|
* UTF-8 (1005) extension if the application requested, or to the
|
||||||
* (1005) extension if the application requested, or to the
|
|
||||||
* legacy format.
|
* legacy format.
|
||||||
*/
|
*/
|
||||||
if (m->sgr && (wp->screen->mode & MODE_MOUSE_SGR)) {
|
if (m->sgr_type != ' ' && (wp->screen->mode & MODE_MOUSE_SGR)) {
|
||||||
len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c",
|
len = xsnprintf(buf, sizeof buf, "\033[<%u;%u;%u%c",
|
||||||
m->sgr_xb, m->x + 1, m->y + 1,
|
m->sgr_b, x + 1, y + 1, m->sgr_type);
|
||||||
m->sgr_rel ? 'm' : 'M');
|
|
||||||
} else if (wp->screen->mode & MODE_MOUSE_UTF8) {
|
} else if (wp->screen->mode & MODE_MOUSE_UTF8) {
|
||||||
len = xsnprintf(buf, sizeof buf, "\033[M");
|
len = xsnprintf(buf, sizeof buf, "\033[M");
|
||||||
len += utf8_split2(m->xb + 32, &buf[len]);
|
len += utf8_split2(m->b + 32, &buf[len]);
|
||||||
len += utf8_split2(m->x + 33, &buf[len]);
|
len += utf8_split2(x + 33, &buf[len]);
|
||||||
len += utf8_split2(m->y + 33, &buf[len]);
|
len += utf8_split2(y + 33, &buf[len]);
|
||||||
} else {
|
} else {
|
||||||
if (m->xb > 223)
|
if (m->b > 223)
|
||||||
return;
|
return;
|
||||||
len = xsnprintf(buf, sizeof buf, "\033[M");
|
len = xsnprintf(buf, sizeof buf, "\033[M");
|
||||||
buf[len++] = m->xb + 32;
|
buf[len++] = m->b + 32;
|
||||||
buf[len++] = m->x + 33;
|
buf[len++] = x + 33;
|
||||||
buf[len++] = m->y + 33;
|
buf[len++] = y + 33;
|
||||||
}
|
}
|
||||||
bufferevent_write(wp->event, buf, len);
|
bufferevent_write(wp->event, buf, len);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options_get_number(&wp->window->options, "mode-mouse") != 1)
|
|
||||||
return;
|
|
||||||
event = m->event & (MOUSE_EVENT_CLICK|MOUSE_EVENT_WHEEL);
|
|
||||||
if (wp->mode == NULL && m->button == 1 && event == MOUSE_EVENT_CLICK) {
|
|
||||||
pb = paste_get_top();
|
|
||||||
if (pb != NULL)
|
|
||||||
paste_send_pane(pb, wp, "\r", 1);
|
|
||||||
} else 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, s, m);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,10 @@ key_bindings_init(void)
|
|||||||
"bind -r C-Down resize-pane -D",
|
"bind -r C-Down resize-pane -D",
|
||||||
"bind -r C-Left resize-pane -L",
|
"bind -r C-Left resize-pane -L",
|
||||||
"bind -r C-Right resize-pane -R",
|
"bind -r C-Right resize-pane -R",
|
||||||
|
"bind -n MouseDown1Pane select-pane -t=\\; send-keys -M",
|
||||||
|
"bind -n MouseDrag1Border resize-pane -M",
|
||||||
|
"bind -n MouseDown1Status select-window -t=",
|
||||||
|
"bind -n MouseDrag1Pane copy-mode -M",
|
||||||
};
|
};
|
||||||
u_int i;
|
u_int i;
|
||||||
struct cmd_list *cmdlist;
|
struct cmd_list *cmdlist;
|
||||||
@ -173,14 +177,15 @@ key_bindings_init(void)
|
|||||||
"<default-keys>", i, &cause);
|
"<default-keys>", i, &cause);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
fatalx("bad default key");
|
fatalx("bad default key");
|
||||||
cmdq_run(cmdq, cmdlist);
|
cmdq_run(cmdq, cmdlist, NULL);
|
||||||
cmd_list_free (cmdlist);
|
cmd_list_free (cmdlist);
|
||||||
}
|
}
|
||||||
cmdq_free(cmdq);
|
cmdq_free(cmdq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
key_bindings_dispatch(struct key_binding *bd, struct client *c)
|
key_bindings_dispatch(struct key_binding *bd, struct client *c,
|
||||||
|
struct mouse_event *m)
|
||||||
{
|
{
|
||||||
struct cmd *cmd;
|
struct cmd *cmd;
|
||||||
int readonly;
|
int readonly;
|
||||||
@ -195,5 +200,5 @@ key_bindings_dispatch(struct key_binding *bd, struct client *c)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdq_run(c->cmdq, bd->cmdlist);
|
cmdq_run(c->cmdq, bd->cmdlist, m);
|
||||||
}
|
}
|
||||||
|
17
key-string.c
17
key-string.c
@ -82,6 +82,19 @@ const struct {
|
|||||||
{ "KPEnter", KEYC_KP_ENTER },
|
{ "KPEnter", KEYC_KP_ENTER },
|
||||||
{ "KP0", KEYC_KP_ZERO },
|
{ "KP0", KEYC_KP_ZERO },
|
||||||
{ "KP.", KEYC_KP_PERIOD },
|
{ "KP.", KEYC_KP_PERIOD },
|
||||||
|
|
||||||
|
/* Mouse keys. */
|
||||||
|
KEYC_MOUSE_STRING(MOUSEDOWN1, MouseDown1),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEDOWN2, MouseDown2),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEDOWN3, MouseDown3),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEUP1, MouseUp1),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEUP2, MouseUp2),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEUP3, MouseUp3),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEDRAG1, MouseDrag1),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEDRAG2, MouseDrag2),
|
||||||
|
KEYC_MOUSE_STRING(MOUSEDRAG3, MouseDrag3),
|
||||||
|
KEYC_MOUSE_STRING(WHEELUP, WheelUp),
|
||||||
|
KEYC_MOUSE_STRING(WHEELDOWN, WheelDown),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Find key string in table. */
|
/* Find key string in table. */
|
||||||
@ -192,7 +205,9 @@ key_string_lookup_key(int key)
|
|||||||
|
|
||||||
/* Handle no key. */
|
/* Handle no key. */
|
||||||
if (key == KEYC_NONE)
|
if (key == KEYC_NONE)
|
||||||
return ("none");
|
return ("<NONE>");
|
||||||
|
if (key == KEYC_MOUSE)
|
||||||
|
return ("<MOUSE>");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case: display C-@ as C-Space. Could do this below in
|
* Special case: display C-@ as C-Space. Could do this below in
|
||||||
|
52
layout.c
52
layout.c
@ -519,58 +519,6 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change)
|
|||||||
notify_window_layout_changed(wp->window);
|
notify_window_layout_changed(wp->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize pane based on mouse events. */
|
|
||||||
void
|
|
||||||
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 (m->event & MOUSE_EVENT_DRAG && m->flags & MOUSE_RESIZE_PANE) {
|
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
|
||||||
if (!window_pane_visible(wp))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (wp->xoff + wp->sx == m->lx &&
|
|
||||||
wp->yoff <= 1 + m->ly &&
|
|
||||||
wp->yoff + wp->sy >= m->ly) {
|
|
||||||
layout_resize_pane(wp, LAYOUT_LEFTRIGHT,
|
|
||||||
m->x - m->lx);
|
|
||||||
pane_border = 1;
|
|
||||||
}
|
|
||||||
if (wp->yoff + wp->sy == m->ly &&
|
|
||||||
wp->xoff <= 1 + m->lx &&
|
|
||||||
wp->xoff + wp->sx >= m->lx) {
|
|
||||||
layout_resize_pane(wp, LAYOUT_TOPBOTTOM,
|
|
||||||
m->y - m->ly);
|
|
||||||
pane_border = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pane_border)
|
|
||||||
server_redraw_window(w);
|
|
||||||
} else if (m->event & MOUSE_EVENT_DOWN) {
|
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
|
||||||
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)
|
|
||||||
m->flags |= MOUSE_RESIZE_PANE;
|
|
||||||
else
|
|
||||||
m->flags &= ~MOUSE_RESIZE_PANE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper function to grow pane. */
|
/* Helper function to grow pane. */
|
||||||
int
|
int
|
||||||
layout_resize_pane_grow(
|
layout_resize_pane_grow(
|
||||||
|
14
mode-key.c
14
mode-key.c
@ -251,6 +251,10 @@ const struct mode_key_entry mode_key_vi_choice[] = {
|
|||||||
{ KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND },
|
{ KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND },
|
||||||
{ KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
|
{ KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
|
||||||
{ KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL },
|
{ KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL },
|
||||||
|
{ KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE },
|
||||||
|
{ KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE },
|
||||||
|
{ KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP },
|
||||||
|
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN },
|
||||||
|
|
||||||
{ 0, -1, 0 }
|
{ 0, -1, 0 }
|
||||||
};
|
};
|
||||||
@ -326,6 +330,9 @@ const struct mode_key_entry mode_key_vi_copy[] = {
|
|||||||
{ KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT },
|
{ KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT },
|
||||||
{ KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP },
|
{ KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP },
|
||||||
{ KEYC_UP, 0, MODEKEYCOPY_UP },
|
{ KEYC_UP, 0, MODEKEYCOPY_UP },
|
||||||
|
{ KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP },
|
||||||
|
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN },
|
||||||
|
{ KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION },
|
||||||
|
|
||||||
{ 0, -1, 0 }
|
{ 0, -1, 0 }
|
||||||
};
|
};
|
||||||
@ -405,6 +412,10 @@ const struct mode_key_entry mode_key_emacs_choice[] = {
|
|||||||
{ KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND },
|
{ KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND },
|
||||||
{ KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
|
{ KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
|
||||||
{ KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL },
|
{ KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL },
|
||||||
|
{ KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE },
|
||||||
|
{ KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE },
|
||||||
|
{ KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP },
|
||||||
|
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN },
|
||||||
|
|
||||||
{ 0, -1, 0 }
|
{ 0, -1, 0 }
|
||||||
};
|
};
|
||||||
@ -467,6 +478,9 @@ const struct mode_key_entry mode_key_emacs_copy[] = {
|
|||||||
{ KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP },
|
{ KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP },
|
||||||
{ KEYC_UP | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEUP },
|
{ KEYC_UP | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEUP },
|
||||||
{ KEYC_UP, 0, MODEKEYCOPY_UP },
|
{ KEYC_UP, 0, MODEKEYCOPY_UP },
|
||||||
|
{ KEYC_WHEELUP_PANE, 0, MODEKEYCOPY_SCROLLUP },
|
||||||
|
{ KEYC_WHEELDOWN_PANE, 0, MODEKEYCOPY_SCROLLDOWN },
|
||||||
|
{ KEYC_MOUSEDRAG1_PANE, 0, MODEKEYCOPY_STARTSELECTION },
|
||||||
|
|
||||||
{ 0, -1, 0 }
|
{ 0, -1, 0 }
|
||||||
};
|
};
|
||||||
|
@ -36,9 +36,6 @@
|
|||||||
const char *options_table_mode_keys_list[] = {
|
const char *options_table_mode_keys_list[] = {
|
||||||
"emacs", "vi", NULL
|
"emacs", "vi", NULL
|
||||||
};
|
};
|
||||||
const char *options_table_mode_mouse_list[] = {
|
|
||||||
"off", "on", "copy-mode", NULL
|
|
||||||
};
|
|
||||||
const char *options_table_clock_mode_style_list[] = {
|
const char *options_table_clock_mode_style_list[] = {
|
||||||
"12", "24", NULL
|
"12", "24", NULL
|
||||||
};
|
};
|
||||||
@ -255,17 +252,7 @@ const struct options_table_entry session_options_table[] = {
|
|||||||
.default_str = "bg=yellow,fg=black"
|
.default_str = "bg=yellow,fg=black"
|
||||||
},
|
},
|
||||||
|
|
||||||
{ .name = "mouse-resize-pane",
|
{ .name = "mouse",
|
||||||
.type = OPTIONS_TABLE_FLAG,
|
|
||||||
.default_num = 0
|
|
||||||
},
|
|
||||||
|
|
||||||
{ .name = "mouse-select-pane",
|
|
||||||
.type = OPTIONS_TABLE_FLAG,
|
|
||||||
.default_num = 0
|
|
||||||
},
|
|
||||||
|
|
||||||
{ .name = "mouse-select-window",
|
|
||||||
.type = OPTIONS_TABLE_FLAG,
|
.type = OPTIONS_TABLE_FLAG,
|
||||||
.default_num = 0
|
.default_num = 0
|
||||||
},
|
},
|
||||||
@ -575,12 +562,6 @@ const struct options_table_entry window_options_table[] = {
|
|||||||
.default_num = MODEKEY_EMACS
|
.default_num = MODEKEY_EMACS
|
||||||
},
|
},
|
||||||
|
|
||||||
{ .name = "mode-mouse",
|
|
||||||
.type = OPTIONS_TABLE_CHOICE,
|
|
||||||
.choices = options_table_mode_mouse_list,
|
|
||||||
.default_num = 0
|
|
||||||
},
|
|
||||||
|
|
||||||
{ .name = "mode-style",
|
{ .name = "mode-style",
|
||||||
.type = OPTIONS_TABLE_STYLE,
|
.type = OPTIONS_TABLE_STYLE,
|
||||||
.default_str = "bg=yellow,fg=black"
|
.default_str = "bg=yellow,fg=black"
|
||||||
|
319
server-client.c
319
server-client.c
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
void server_client_check_focus(struct window_pane *);
|
void server_client_check_focus(struct window_pane *);
|
||||||
void server_client_check_resize(struct window_pane *);
|
void server_client_check_resize(struct window_pane *);
|
||||||
void server_client_check_mouse(struct client *, struct window_pane *);
|
int server_client_check_mouse(struct client *);
|
||||||
void server_client_repeat_timer(int, short, void *);
|
void server_client_repeat_timer(int, short, void *);
|
||||||
void server_client_check_exit(struct client *);
|
void server_client_check_exit(struct client *);
|
||||||
void server_client_check_redraw(struct client *);
|
void server_client_check_redraw(struct client *);
|
||||||
@ -91,13 +91,6 @@ server_client_create(int fd)
|
|||||||
c->prompt_buffer = NULL;
|
c->prompt_buffer = NULL;
|
||||||
c->prompt_index = 0;
|
c->prompt_index = 0;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
c->flags |= CLIENT_FOCUSED;
|
c->flags |= CLIENT_FOCUSED;
|
||||||
|
|
||||||
evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
|
evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
|
||||||
@ -289,56 +282,228 @@ server_client_status_timer(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for mouse keys. */
|
/* Check for mouse keys. */
|
||||||
void
|
int
|
||||||
server_client_check_mouse(struct client *c, struct window_pane *wp)
|
server_client_check_mouse(struct client *c)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct options *oo = &s->options;
|
|
||||||
struct mouse_event *m = &c->tty.mouse;
|
struct mouse_event *m = &c->tty.mouse;
|
||||||
int statusat;
|
struct window *w;
|
||||||
|
struct window_pane *wp;
|
||||||
|
enum { NOTYPE, DOWN, UP, DRAG, WHEEL } type = NOTYPE;
|
||||||
|
enum { NOWHERE, PANE, STATUS, BORDER } where = NOWHERE;
|
||||||
|
u_int x, y, b;
|
||||||
|
int key;
|
||||||
|
|
||||||
statusat = status_at_line(c);
|
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);
|
||||||
|
|
||||||
/* Is this a window selection click on the status line? */
|
/* What type of event is this? */
|
||||||
if (statusat != -1 && m->y == (u_int)statusat &&
|
if (MOUSE_DRAG(m->b)) {
|
||||||
options_get_number(oo, "mouse-select-window")) {
|
type = DRAG;
|
||||||
if (m->event & MOUSE_EVENT_CLICK) {
|
if (c->tty.mouse_drag_flag) {
|
||||||
status_set_window_at(c, m->x);
|
x = m->x, y = m->y, b = m->b;
|
||||||
} else if (m->event == MOUSE_EVENT_WHEEL) {
|
log_debug("drag update at %u,%u", x, y);
|
||||||
if (m->wheel == MOUSE_WHEEL_UP)
|
} else {
|
||||||
session_previous(c->session, 0);
|
x = m->lx, y = m->ly, b = m->lb;
|
||||||
else if (m->wheel == MOUSE_WHEEL_DOWN)
|
log_debug("drag start at %u,%u", x, y);
|
||||||
session_next(c->session, 0);
|
|
||||||
server_redraw_session(s);
|
|
||||||
}
|
}
|
||||||
recalculate_sizes();
|
} else if (MOUSE_WHEEL(m->b)) {
|
||||||
return;
|
type = WHEEL;
|
||||||
|
x = m->x, y = m->y, b = m->b;
|
||||||
|
log_debug("wheel at %u,%u", x, y);
|
||||||
|
} else if (MOUSE_BUTTONS(m->b) == 3) {
|
||||||
|
type = UP;
|
||||||
|
x = m->x, y = m->y, b = m->lb;
|
||||||
|
log_debug("up at %u,%u", x, y);
|
||||||
|
} else {
|
||||||
|
type = DOWN;
|
||||||
|
x = m->x, y = m->y, b = m->b;
|
||||||
|
log_debug("down at %u,%u", x, y);
|
||||||
|
}
|
||||||
|
if (type == NOTYPE)
|
||||||
|
return (KEYC_NONE);
|
||||||
|
|
||||||
|
/* Always save the session. */
|
||||||
|
m->s = s->id;
|
||||||
|
|
||||||
|
/* 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_NONE);
|
||||||
|
m->w = w->id;
|
||||||
|
where = STATUS;
|
||||||
|
} else
|
||||||
|
m->w = -1;
|
||||||
|
|
||||||
|
/* Not on status line. Adjust position and check for border or pane. */
|
||||||
|
if (where == NOWHERE) {
|
||||||
|
if (m->statusat == 0 && y > 0)
|
||||||
|
y--;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (wp != NULL)
|
||||||
|
where = BORDER;
|
||||||
|
else {
|
||||||
|
wp = window_get_active_at(s->curw->window, x, y);
|
||||||
|
if (wp != NULL)
|
||||||
|
where = PANE;
|
||||||
|
}
|
||||||
|
if (where == NOWHERE)
|
||||||
|
return (KEYC_NONE);
|
||||||
|
m->wp = wp->id;
|
||||||
|
m->w = wp->window->id;
|
||||||
|
} else
|
||||||
|
m->wp = -1;
|
||||||
|
|
||||||
|
/* Stop dragging if needed. */
|
||||||
|
if (type != DRAG && c->tty.mouse_drag_flag) {
|
||||||
|
if (c->tty.mouse_drag_release != NULL)
|
||||||
|
c->tty.mouse_drag_release(c, m);
|
||||||
|
|
||||||
|
c->tty.mouse_drag_update = NULL;
|
||||||
|
c->tty.mouse_drag_release = NULL;
|
||||||
|
|
||||||
|
c->tty.mouse_drag_flag = 0;
|
||||||
|
return (KEYC_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Convert to a key binding. */
|
||||||
* Not on status line - adjust mouse position if status line is at the
|
key = KEYC_NONE;
|
||||||
* top and limit if at the bottom. From here on a struct mouse
|
switch (type) {
|
||||||
* represents the offset onto the window itself.
|
case NOTYPE:
|
||||||
*/
|
break;
|
||||||
if (statusat == 0 && m->y > 0)
|
case DRAG:
|
||||||
m->y--;
|
if (c->tty.mouse_drag_update != NULL)
|
||||||
else if (statusat > 0 && m->y >= (u_int)statusat)
|
c->tty.mouse_drag_update(c, m);
|
||||||
m->y = statusat - 1;
|
else {
|
||||||
|
switch (MOUSE_BUTTONS(b)) {
|
||||||
/* Is this a pane selection? */
|
case 0:
|
||||||
if (options_get_number(oo, "mouse-select-pane") &&
|
if (where == PANE)
|
||||||
(m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
|
key = KEYC_MOUSEDRAG1_PANE;
|
||||||
window_set_active_at(wp->window, m->x, m->y);
|
if (where == STATUS)
|
||||||
server_redraw_window(wp->window);
|
key = KEYC_MOUSEDRAG1_STATUS;
|
||||||
wp = wp->window->active; /* may have changed */
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEDRAG1_BORDER;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEDRAG2_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEDRAG2_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEDRAG2_BORDER;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEDRAG3_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEDRAG3_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEDRAG3_BORDER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if trying to resize pane. */
|
c->tty.mouse_drag_flag = 1;
|
||||||
if (options_get_number(oo, "mouse-resize-pane"))
|
break;
|
||||||
layout_resize_pane_mouse(c);
|
case WHEEL:
|
||||||
|
if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) {
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_WHEELUP_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_WHEELUP_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_WHEELUP_BORDER;
|
||||||
|
} else {
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_WHEELDOWN_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_WHEELDOWN_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_WHEELDOWN_BORDER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UP:
|
||||||
|
switch (MOUSE_BUTTONS(b)) {
|
||||||
|
case 0:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEUP1_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEUP1_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEUP1_BORDER;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEUP2_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEUP2_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEUP2_BORDER;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEUP3_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEUP3_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEUP3_BORDER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
switch (MOUSE_BUTTONS(b)) {
|
||||||
|
case 0:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEDOWN1_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEDOWN1_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEDOWN1_BORDER;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEDOWN2_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEDOWN2_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEDOWN2_BORDER;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (where == PANE)
|
||||||
|
key = KEYC_MOUSEDOWN3_PANE;
|
||||||
|
if (where == STATUS)
|
||||||
|
key = KEYC_MOUSEDOWN3_STATUS;
|
||||||
|
if (where == BORDER)
|
||||||
|
key = KEYC_MOUSEDOWN3_BORDER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (key == KEYC_NONE)
|
||||||
|
return (KEYC_NONE);
|
||||||
|
|
||||||
/* Update last and pass through to client. */
|
/* Apply modifiers if any. */
|
||||||
window_pane_mouse(wp, c->session, m);
|
if (b & MOUSE_MASK_META)
|
||||||
|
key |= KEYC_ESCAPE;
|
||||||
|
if (b & MOUSE_MASK_CTRL)
|
||||||
|
key |= KEYC_CTRL;
|
||||||
|
if (b & MOUSE_MASK_SHIFT)
|
||||||
|
key |= KEYC_SHIFT;
|
||||||
|
|
||||||
|
return (key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this fast enough to probably be a paste? */
|
/* Is this fast enough to probably be a paste? */
|
||||||
@ -361,6 +526,7 @@ server_client_assume_paste(struct session *s)
|
|||||||
void
|
void
|
||||||
server_client_handle_key(struct client *c, int key)
|
server_client_handle_key(struct client *c, int key)
|
||||||
{
|
{
|
||||||
|
struct mouse_event *m = &c->tty.mouse;
|
||||||
struct session *s;
|
struct session *s;
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
@ -372,21 +538,20 @@ server_client_handle_key(struct client *c, int key)
|
|||||||
if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
|
if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* No session, do nothing. */
|
||||||
if (c->session == NULL)
|
if (c->session == NULL)
|
||||||
return;
|
return;
|
||||||
s = c->session;
|
s = c->session;
|
||||||
|
w = c->session->curw->window;
|
||||||
|
wp = w->active;
|
||||||
|
|
||||||
/* Update the activity timer. */
|
/* Update the activity timer. */
|
||||||
if (gettimeofday(&c->activity_time, NULL) != 0)
|
if (gettimeofday(&c->activity_time, NULL) != 0)
|
||||||
fatal("gettimeofday failed");
|
fatal("gettimeofday failed");
|
||||||
|
|
||||||
memcpy(&s->last_activity_time, &s->activity_time,
|
memcpy(&s->last_activity_time, &s->activity_time,
|
||||||
sizeof s->last_activity_time);
|
sizeof s->last_activity_time);
|
||||||
memcpy(&s->activity_time, &c->activity_time, sizeof s->activity_time);
|
memcpy(&s->activity_time, &c->activity_time, sizeof s->activity_time);
|
||||||
|
|
||||||
w = c->session->curw->window;
|
|
||||||
wp = w->active;
|
|
||||||
|
|
||||||
/* Special case: number keys jump to pane in identify mode. */
|
/* Special case: number keys jump to pane in identify mode. */
|
||||||
if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') {
|
if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') {
|
||||||
if (c->flags & CLIENT_READONLY)
|
if (c->flags & CLIENT_READONLY)
|
||||||
@ -414,9 +579,19 @@ server_client_handle_key(struct client *c, int key)
|
|||||||
if (key == KEYC_MOUSE) {
|
if (key == KEYC_MOUSE) {
|
||||||
if (c->flags & CLIENT_READONLY)
|
if (c->flags & CLIENT_READONLY)
|
||||||
return;
|
return;
|
||||||
server_client_check_mouse(c, wp);
|
key = server_client_check_mouse(c);
|
||||||
|
if (key == KEYC_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m->valid = 1;
|
||||||
|
m->key = key;
|
||||||
|
|
||||||
|
if (!options_get_number(&s->options, "mouse")) {
|
||||||
|
window_pane_key(wp, c, s, key, m);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
m->valid = 0;
|
||||||
|
|
||||||
/* Is this a prefix key? */
|
/* Is this a prefix key? */
|
||||||
if (key == options_get_number(&s->options, "prefix"))
|
if (key == options_get_number(&s->options, "prefix"))
|
||||||
@ -442,9 +617,9 @@ server_client_handle_key(struct client *c, int key)
|
|||||||
/* Try as a non-prefix key binding. */
|
/* Try as a non-prefix key binding. */
|
||||||
if (ispaste || (bd = key_bindings_lookup(key)) == NULL) {
|
if (ispaste || (bd = key_bindings_lookup(key)) == NULL) {
|
||||||
if (!(c->flags & CLIENT_READONLY))
|
if (!(c->flags & CLIENT_READONLY))
|
||||||
window_pane_key(wp, s, key);
|
window_pane_key(wp, c, s, key, m);
|
||||||
} else
|
} else
|
||||||
key_bindings_dispatch(bd, c);
|
key_bindings_dispatch(bd, c, m);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +633,7 @@ server_client_handle_key(struct client *c, int key)
|
|||||||
if (isprefix)
|
if (isprefix)
|
||||||
c->flags |= CLIENT_PREFIX;
|
c->flags |= CLIENT_PREFIX;
|
||||||
else if (!(c->flags & CLIENT_READONLY))
|
else if (!(c->flags & CLIENT_READONLY))
|
||||||
window_pane_key(wp, s, key);
|
window_pane_key(wp, c, s, key, m);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -469,7 +644,7 @@ server_client_handle_key(struct client *c, int key)
|
|||||||
if (isprefix)
|
if (isprefix)
|
||||||
c->flags |= CLIENT_PREFIX;
|
c->flags |= CLIENT_PREFIX;
|
||||||
else if (!(c->flags & CLIENT_READONLY))
|
else if (!(c->flags & CLIENT_READONLY))
|
||||||
window_pane_key(wp, s, key);
|
window_pane_key(wp, c, s, key, m);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +660,7 @@ server_client_handle_key(struct client *c, int key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Dispatch the command. */
|
/* Dispatch the command. */
|
||||||
key_bindings_dispatch(bd, c);
|
key_bindings_dispatch(bd, c, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Client functions that need to happen every loop. */
|
/* Client functions that need to happen every loop. */
|
||||||
@ -622,7 +797,6 @@ server_client_reset_state(struct client *c)
|
|||||||
struct window_pane *wp = w->active;
|
struct window_pane *wp = w->active;
|
||||||
struct screen *s = wp->screen;
|
struct screen *s = wp->screen;
|
||||||
struct options *oo = &c->session->options;
|
struct options *oo = &c->session->options;
|
||||||
struct options *wo = &w->options;
|
|
||||||
int status, mode, o;
|
int status, mode, o;
|
||||||
|
|
||||||
if (c->flags & CLIENT_SUSPENDED)
|
if (c->flags & CLIENT_SUSPENDED)
|
||||||
@ -642,29 +816,12 @@ server_client_reset_state(struct client *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resizing panes with the mouse requires at least button mode to give
|
* Set mouse mode if requested. To support dragging, always use button
|
||||||
* a smooth appearance.
|
* mode.
|
||||||
*/
|
*/
|
||||||
mode = s->mode;
|
mode = s->mode;
|
||||||
if ((c->tty.mouse.flags & MOUSE_RESIZE_PANE) &&
|
if (options_get_number(oo, "mouse"))
|
||||||
!(mode & MODE_MOUSE_BUTTON))
|
mode = (mode & ~ALL_MOUSE_MODES) | MODE_MOUSE_BUTTON;
|
||||||
mode |= MODE_MOUSE_BUTTON;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Any mode will do for mouse-select-pane, but set standard mode if
|
|
||||||
* none.
|
|
||||||
*/
|
|
||||||
if ((mode & ALL_MOUSE_MODES) == 0) {
|
|
||||||
if (TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) != NULL &&
|
|
||||||
options_get_number(oo, "mouse-select-pane"))
|
|
||||||
mode |= MODE_MOUSE_STANDARD;
|
|
||||||
else if (options_get_number(oo, "mouse-resize-pane"))
|
|
||||||
mode |= MODE_MOUSE_STANDARD;
|
|
||||||
else if (options_get_number(oo, "mouse-select-window"))
|
|
||||||
mode |= MODE_MOUSE_STANDARD;
|
|
||||||
else if (options_get_number(wo, "mode-mouse"))
|
|
||||||
mode |= MODE_MOUSE_STANDARD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set UTF-8 mouse input if required. If the terminal is UTF-8, the
|
* Set UTF-8 mouse input if required. If the terminal is UTF-8, the
|
||||||
@ -945,9 +1102,9 @@ server_client_msg_command(struct client *c, struct imsg *imsg)
|
|||||||
cmd_free_argv(argc, argv);
|
cmd_free_argv(argc, argv);
|
||||||
|
|
||||||
if (c != cfg_client || cfg_finished)
|
if (c != cfg_client || cfg_finished)
|
||||||
cmdq_run(c->cmdq, cmdlist);
|
cmdq_run(c->cmdq, cmdlist, NULL);
|
||||||
else
|
else
|
||||||
cmdq_append(c->cmdq, cmdlist);
|
cmdq_append(c->cmdq, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -604,7 +604,8 @@ server_set_stdin_callback(struct client *c, void (*cb)(struct client *, int,
|
|||||||
void
|
void
|
||||||
server_unzoom_window(struct window *w)
|
server_unzoom_window(struct window *w)
|
||||||
{
|
{
|
||||||
window_unzoom(w);
|
if (window_unzoom(w) == 0) {
|
||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
server_status_window(w);
|
server_status_window(w);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
13
status.c
13
status.c
@ -118,9 +118,9 @@ status_redraw_get_right(struct client *c, time_t t, int utf8flag,
|
|||||||
return (right);
|
return (right);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set window at window list position. */
|
/* Get window at window list position. */
|
||||||
void
|
struct window *
|
||||||
status_set_window_at(struct client *c, u_int x)
|
status_get_window_at(struct client *c, u_int x)
|
||||||
{
|
{
|
||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
@ -130,12 +130,13 @@ status_set_window_at(struct client *c, u_int x)
|
|||||||
x += c->wlmouse;
|
x += c->wlmouse;
|
||||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||||
oo = &wl->window->options;
|
oo = &wl->window->options;
|
||||||
|
|
||||||
len = strlen(options_get_string(oo, "window-status-separator"));
|
len = strlen(options_get_string(oo, "window-status-separator"));
|
||||||
if (x < wl->status_width && session_select(s, wl->idx) == 0)
|
|
||||||
server_redraw_session(s);
|
if (x < wl->status_width)
|
||||||
|
return (wl->window);
|
||||||
x -= wl->status_width + len;
|
x -= wl->status_width + len;
|
||||||
}
|
}
|
||||||
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw status for client on the last lines of given context. */
|
/* Draw status for client on the last lines of given context. */
|
||||||
|
99
tmux.1
99
tmux.1
@ -1019,13 +1019,16 @@ The synopsis for the
|
|||||||
command is:
|
command is:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Xo Ic copy-mode
|
.It Xo Ic copy-mode
|
||||||
.Op Fl u
|
.Op Fl Mu
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
.Xc
|
.Xc
|
||||||
Enter copy mode.
|
Enter copy mode.
|
||||||
The
|
The
|
||||||
.Fl u
|
.Fl u
|
||||||
option scrolls one page up.
|
option scrolls one page up.
|
||||||
|
.Fl M
|
||||||
|
begins a mouse drag (only valid if bound to a mouse key binding, see
|
||||||
|
.Sx MOUSE SUPPORT Ns ).
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Each window displayed by
|
Each window displayed by
|
||||||
@ -1643,7 +1646,7 @@ Rename the current window, or the window at
|
|||||||
if specified, to
|
if specified, to
|
||||||
.Ar new-name .
|
.Ar new-name .
|
||||||
.It Xo Ic resize-pane
|
.It Xo Ic resize-pane
|
||||||
.Op Fl DLRUZ
|
.Op Fl DLMRUZ
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
.Op Fl x Ar width
|
.Op Fl x Ar width
|
||||||
.Op Fl y Ar height
|
.Op Fl y Ar height
|
||||||
@ -1672,6 +1675,10 @@ With
|
|||||||
.Fl Z ,
|
.Fl Z ,
|
||||||
the active pane is toggled between zoomed (occupying the whole of the window)
|
the active pane is toggled between zoomed (occupying the whole of the window)
|
||||||
and unzoomed (its normal position in the layout).
|
and unzoomed (its normal position in the layout).
|
||||||
|
.Pp
|
||||||
|
.Fl M
|
||||||
|
begins mouse resizing (only valid if bound to a mouse key binding, see
|
||||||
|
.Sx MOUSE SUPPORT Ns ).
|
||||||
.It Xo Ic respawn-pane
|
.It Xo Ic respawn-pane
|
||||||
.Op Fl k
|
.Op Fl k
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
@ -1980,7 +1987,7 @@ are listed; this may be one of:
|
|||||||
or
|
or
|
||||||
.Em emacs-copy .
|
.Em emacs-copy .
|
||||||
.It Xo Ic send-keys
|
.It Xo Ic send-keys
|
||||||
.Op Fl lR
|
.Op Fl lMR
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
.Ar key Ar ...
|
.Ar key Ar ...
|
||||||
.Xc
|
.Xc
|
||||||
@ -2001,6 +2008,10 @@ All arguments are sent sequentially from first to last.
|
|||||||
The
|
The
|
||||||
.Fl R
|
.Fl R
|
||||||
flag causes the terminal state to be reset.
|
flag causes the terminal state to be reset.
|
||||||
|
.Pp
|
||||||
|
.Fl M
|
||||||
|
passes through a mouse event (only valid if bound to a mouse key binding, see
|
||||||
|
.Sx MOUSE SUPPORT Ns ).
|
||||||
.It Xo Ic send-prefix
|
.It Xo Ic send-prefix
|
||||||
.Op Fl 2
|
.Op Fl 2
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
@ -2449,25 +2460,15 @@ For how to specify
|
|||||||
see the
|
see the
|
||||||
.Ic message-command-style
|
.Ic message-command-style
|
||||||
option.
|
option.
|
||||||
.It Xo Ic mouse-resize-pane
|
.It Xo Ic mouse
|
||||||
.Op Ic on | off
|
.Op Ic on | off
|
||||||
.Xc
|
.Xc
|
||||||
If on,
|
If on,
|
||||||
.Nm
|
.Nm
|
||||||
captures the mouse and allows panes to be resized by dragging on their borders.
|
captures the mouse and allows mouse events to be bound as key bindings.
|
||||||
.It Xo Ic mouse-select-pane
|
See the
|
||||||
.Op Ic on | off
|
.Sx MOUSE SUPPORT
|
||||||
.Xc
|
section for details.
|
||||||
If on,
|
|
||||||
.Nm
|
|
||||||
captures the mouse and when a window is split into multiple panes the mouse may
|
|
||||||
be used to select the current pane.
|
|
||||||
The mouse click is also passed through to the application as normal.
|
|
||||||
.It Xo Ic mouse-select-window
|
|
||||||
.Op Ic on | off
|
|
||||||
.Xc
|
|
||||||
If on, clicking the mouse on a window name in the status line will select that
|
|
||||||
window.
|
|
||||||
.It Xo Ic mouse-utf8
|
.It Xo Ic mouse-utf8
|
||||||
.Op Ic on | off
|
.Op Ic on | off
|
||||||
.Xc
|
.Xc
|
||||||
@ -2855,18 +2856,6 @@ or
|
|||||||
contains
|
contains
|
||||||
.Ql vi .
|
.Ql vi .
|
||||||
.Pp
|
.Pp
|
||||||
.It Xo Ic mode-mouse
|
|
||||||
.Op Ic on | off | copy-mode
|
|
||||||
.Xc
|
|
||||||
Mouse state in modes.
|
|
||||||
If on, the mouse may be used to enter copy mode and copy a selection by
|
|
||||||
dragging, to enter copy mode and scroll with the mouse wheel, or to select an
|
|
||||||
option in choice mode.
|
|
||||||
If set to
|
|
||||||
.Em copy-mode ,
|
|
||||||
the mouse behaves as set to on, but cannot be used to enter copy
|
|
||||||
mode.
|
|
||||||
.Pp
|
|
||||||
.It Ic mode-style Ar style
|
.It Ic mode-style Ar style
|
||||||
Set window modes style.
|
Set window modes style.
|
||||||
For how to specify
|
For how to specify
|
||||||
@ -3083,6 +3072,56 @@ is used.
|
|||||||
.Fl v
|
.Fl v
|
||||||
shows only the option value, not the name.
|
shows only the option value, not the name.
|
||||||
.El
|
.El
|
||||||
|
.Sh MOUSE SUPPORT
|
||||||
|
If the
|
||||||
|
.Ic mouse
|
||||||
|
option is on (the default is off),
|
||||||
|
.Nm
|
||||||
|
allows mouse events to be bound as keys.
|
||||||
|
The name of each key is made up of a mouse event (such as
|
||||||
|
.Ql MouseUp1 )
|
||||||
|
and a location suffix (one of
|
||||||
|
.Ql Pane
|
||||||
|
for the contents of a pane,
|
||||||
|
.Ql Border
|
||||||
|
for a pane border or
|
||||||
|
.Ql Status
|
||||||
|
for the status line).
|
||||||
|
The following mouse events are available:
|
||||||
|
.Bl -column "MouseDown1" "MouseDrag1" "WheelDown" -offset indent
|
||||||
|
.It Li "MouseDown1" Ta "MouseUp1" Ta "MouseDrag1"
|
||||||
|
.It Li "MouseDown2" Ta "MouseUp2" Ta "MouseDrag2"
|
||||||
|
.It Li "MouseDown3" Ta "MouseUp3" Ta "MouseDrag3"
|
||||||
|
.It Li "WheelUp" Ta "WheelDown"
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Each should be suffixed with a location, for example
|
||||||
|
.Ql MouseDown1Status .
|
||||||
|
.Pp
|
||||||
|
The special character
|
||||||
|
.Ql =
|
||||||
|
may be used as
|
||||||
|
.Ar target-window
|
||||||
|
or
|
||||||
|
.Ar target-pane
|
||||||
|
in commands bound to mouse key bindings.
|
||||||
|
It resolves to the window or pane over which the mouse event took place
|
||||||
|
(for example, the window in the status line over which button 1 was released for a
|
||||||
|
.Ql MouseUp1Status
|
||||||
|
binding, or the pane over which the wheel was scrolled for a
|
||||||
|
.Ql WheelDownPane
|
||||||
|
binding).
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Ic send-keys
|
||||||
|
.Fl M
|
||||||
|
flag may be used to forward a mouse event to a pane.
|
||||||
|
.Pp
|
||||||
|
The default key bindings allow the mouse to be used to select and resize panes,
|
||||||
|
to copy text and to change window using the status line.
|
||||||
|
These take effect if the
|
||||||
|
.Ic mouse
|
||||||
|
option is turned on.
|
||||||
.Sh FORMATS
|
.Sh FORMATS
|
||||||
Certain commands accept the
|
Certain commands accept the
|
||||||
.Fl F
|
.Fl F
|
||||||
|
140
tmux.h
140
tmux.h
@ -95,10 +95,39 @@ extern char **environ;
|
|||||||
#define KEYC_MASK_MOD (KEYC_ESCAPE|KEYC_CTRL|KEYC_SHIFT|KEYC_PREFIX)
|
#define KEYC_MASK_MOD (KEYC_ESCAPE|KEYC_CTRL|KEYC_SHIFT|KEYC_PREFIX)
|
||||||
#define KEYC_MASK_KEY (~KEYC_MASK_MOD)
|
#define KEYC_MASK_KEY (~KEYC_MASK_MOD)
|
||||||
|
|
||||||
/* Other key codes. */
|
/* Is this a mouse key? */
|
||||||
|
#define KEYC_IS_MOUSE(key) (((key) & KEYC_MASK_KEY) >= KEYC_MOUSE && \
|
||||||
|
((key) & KEYC_MASK_KEY) < KEYC_BSPACE)
|
||||||
|
|
||||||
|
/* Mouse key codes. */
|
||||||
|
#define KEYC_MOUSE_KEY(name) \
|
||||||
|
KEYC_ ## name ## _PANE, \
|
||||||
|
KEYC_ ## name ## _STATUS, \
|
||||||
|
KEYC_ ## name ## _BORDER
|
||||||
|
#define KEYC_MOUSE_STRING(name, s) \
|
||||||
|
{ #s "Pane", KEYC_ ## name ## _PANE }, \
|
||||||
|
{ #s "Status", KEYC_ ## name ## _STATUS }, \
|
||||||
|
{ #s "Border", KEYC_ ## name ## _BORDER }
|
||||||
|
|
||||||
|
/* Special key codes. */
|
||||||
enum key_code {
|
enum key_code {
|
||||||
/* Mouse key. */
|
/* Focus events. */
|
||||||
KEYC_MOUSE = KEYC_BASE,
|
KEYC_FOCUS_IN = KEYC_BASE,
|
||||||
|
KEYC_FOCUS_OUT,
|
||||||
|
|
||||||
|
/* Mouse keys. */
|
||||||
|
KEYC_MOUSE, /* unclassified mouse event */
|
||||||
|
KEYC_MOUSE_KEY(MOUSEDOWN1),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEDOWN2),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEDOWN3),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEUP1),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEUP2),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEUP3),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEDRAG1),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEDRAG2),
|
||||||
|
KEYC_MOUSE_KEY(MOUSEDRAG3),
|
||||||
|
KEYC_MOUSE_KEY(WHEELUP),
|
||||||
|
KEYC_MOUSE_KEY(WHEELDOWN),
|
||||||
|
|
||||||
/* Backspace key. */
|
/* Backspace key. */
|
||||||
KEYC_BSPACE,
|
KEYC_BSPACE,
|
||||||
@ -147,9 +176,6 @@ enum key_code {
|
|||||||
KEYC_KP_ENTER,
|
KEYC_KP_ENTER,
|
||||||
KEYC_KP_ZERO,
|
KEYC_KP_ZERO,
|
||||||
KEYC_KP_PERIOD,
|
KEYC_KP_PERIOD,
|
||||||
|
|
||||||
KEYC_FOCUS_IN,
|
|
||||||
KEYC_FOCUS_OUT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Termcap codes. */
|
/* Termcap codes. */
|
||||||
@ -818,16 +844,15 @@ struct input_ctx {
|
|||||||
* Window mode. Windows can be in several modes and this is used to call the
|
* Window mode. Windows can be in several modes and this is used to call the
|
||||||
* right function to handle input and output.
|
* right function to handle input and output.
|
||||||
*/
|
*/
|
||||||
|
struct client;
|
||||||
struct session;
|
struct session;
|
||||||
struct window;
|
|
||||||
struct mouse_event;
|
struct mouse_event;
|
||||||
struct window_mode {
|
struct window_mode {
|
||||||
struct screen *(*init)(struct window_pane *);
|
struct screen *(*init)(struct window_pane *);
|
||||||
void (*free)(struct window_pane *);
|
void (*free)(struct window_pane *);
|
||||||
void (*resize)(struct window_pane *, u_int, u_int);
|
void (*resize)(struct window_pane *, u_int, u_int);
|
||||||
void (*key)(struct window_pane *, struct session *, int);
|
void (*key)(struct window_pane *, struct client *, struct session *,
|
||||||
void (*mouse)(struct window_pane *,
|
int, struct mouse_event *);
|
||||||
struct session *, struct mouse_event *);
|
|
||||||
void (*timer)(struct window_pane *);
|
void (*timer)(struct window_pane *);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1114,54 +1139,35 @@ LIST_HEAD(tty_terms, tty_term);
|
|||||||
|
|
||||||
/* Mouse wheel states. */
|
/* Mouse wheel states. */
|
||||||
#define MOUSE_WHEEL_UP 0
|
#define MOUSE_WHEEL_UP 0
|
||||||
#define MOUSE_WHEEL_DOWN 1
|
#define MOUSE_WHEEL_DOWN 64
|
||||||
|
|
||||||
/* Mouse wheel multipler. */
|
/* Mouse helpers. */
|
||||||
#define MOUSE_WHEEL_SCALE 3
|
#define MOUSE_BUTTONS(b) ((b) & MOUSE_MASK_BUTTONS)
|
||||||
|
#define MOUSE_WHEEL(b) ((b) & MOUSE_MASK_WHEEL)
|
||||||
|
#define MOUSE_DRAG(b) ((b) & MOUSE_MASK_DRAG)
|
||||||
|
#define MOUSE_RELEASE(b) (((b) & MOUSE_MASK_BUTTONS) == 3)
|
||||||
|
|
||||||
/* Mouse event bits. */
|
/* Mouse input. */
|
||||||
#define MOUSE_EVENT_DOWN 0x1
|
|
||||||
#define MOUSE_EVENT_DRAG 0x2
|
|
||||||
#define MOUSE_EVENT_UP 0x4
|
|
||||||
#define MOUSE_EVENT_CLICK 0x8
|
|
||||||
#define MOUSE_EVENT_WHEEL 0x10
|
|
||||||
|
|
||||||
/* Mouse flag bits. */
|
|
||||||
#define MOUSE_RESIZE_PANE 0x1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* With the SGR 1006 extension the released button becomes known. Store these
|
|
||||||
* in separate fields and store the value converted to the old format in xb.
|
|
||||||
*/
|
|
||||||
struct mouse_event {
|
struct mouse_event {
|
||||||
u_int xb;
|
int valid;
|
||||||
|
|
||||||
|
int key;
|
||||||
|
int statusat;
|
||||||
|
|
||||||
u_int x;
|
u_int x;
|
||||||
u_int lx;
|
|
||||||
u_int sx;
|
|
||||||
|
|
||||||
u_int y;
|
u_int y;
|
||||||
|
u_int b;
|
||||||
|
|
||||||
|
u_int lx;
|
||||||
u_int ly;
|
u_int ly;
|
||||||
u_int sy;
|
u_int lb;
|
||||||
|
|
||||||
u_int sgr; /* whether the input arrived in SGR format */
|
int s;
|
||||||
u_int sgr_xb; /* only for SGR: the unmangled button */
|
int w;
|
||||||
u_int sgr_rel; /* only for SGR: if it is a release event */
|
int wp;
|
||||||
|
|
||||||
u_int button;
|
u_int sgr_type;
|
||||||
u_int clicks;
|
u_int sgr_b;
|
||||||
u_int scroll;
|
|
||||||
|
|
||||||
int wheel;
|
|
||||||
int event;
|
|
||||||
int flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tty {
|
struct tty {
|
||||||
@ -1207,6 +1213,11 @@ struct tty {
|
|||||||
int term_flags;
|
int term_flags;
|
||||||
|
|
||||||
struct mouse_event mouse;
|
struct mouse_event mouse;
|
||||||
|
int mouse_drag_flag;
|
||||||
|
void (*mouse_drag_update)(struct client *,
|
||||||
|
struct mouse_event *);
|
||||||
|
void (*mouse_drag_release)(struct client *,
|
||||||
|
struct mouse_event *);
|
||||||
|
|
||||||
struct event key_timer;
|
struct event key_timer;
|
||||||
struct tty_key *key_tree;
|
struct tty_key *key_tree;
|
||||||
@ -1382,6 +1393,9 @@ enum cmd_retval {
|
|||||||
/* Command queue entry. */
|
/* Command queue entry. */
|
||||||
struct cmd_q_item {
|
struct cmd_q_item {
|
||||||
struct cmd_list *cmdlist;
|
struct cmd_list *cmdlist;
|
||||||
|
|
||||||
|
struct mouse_event mouse;
|
||||||
|
|
||||||
TAILQ_ENTRY(cmd_q_item) qentry;
|
TAILQ_ENTRY(cmd_q_item) qentry;
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(cmd_q_items, cmd_q_item);
|
TAILQ_HEAD(cmd_q_items, cmd_q_item);
|
||||||
@ -1723,6 +1737,11 @@ void cmd_free_argv(int, char **);
|
|||||||
char *cmd_stringify_argv(int, char **);
|
char *cmd_stringify_argv(int, char **);
|
||||||
struct cmd *cmd_parse(int, char **, const char *, u_int, char **);
|
struct cmd *cmd_parse(int, char **, const char *, u_int, char **);
|
||||||
size_t cmd_print(struct cmd *, char *, size_t);
|
size_t cmd_print(struct cmd *, char *, size_t);
|
||||||
|
int cmd_mouse_at(struct window_pane *, struct mouse_event *,
|
||||||
|
u_int *, u_int *, int);
|
||||||
|
struct winlink *cmd_mouse_window(struct mouse_event *, struct session **);
|
||||||
|
struct window_pane *cmd_mouse_pane(struct mouse_event *, struct session **,
|
||||||
|
struct winlink **);
|
||||||
struct session *cmd_current_session(struct cmd_q *, int);
|
struct session *cmd_current_session(struct cmd_q *, int);
|
||||||
struct client *cmd_current_client(struct cmd_q *);
|
struct client *cmd_current_client(struct cmd_q *);
|
||||||
struct client *cmd_find_client(struct cmd_q *, const char *, int);
|
struct client *cmd_find_client(struct cmd_q *, const char *, int);
|
||||||
@ -1839,8 +1858,10 @@ int cmdq_free(struct cmd_q *);
|
|||||||
void printflike(2, 3) cmdq_print(struct cmd_q *, const char *, ...);
|
void printflike(2, 3) cmdq_print(struct cmd_q *, const char *, ...);
|
||||||
void printflike(2, 3) cmdq_error(struct cmd_q *, const char *, ...);
|
void printflike(2, 3) cmdq_error(struct cmd_q *, const char *, ...);
|
||||||
void cmdq_guard(struct cmd_q *, const char *, int);
|
void cmdq_guard(struct cmd_q *, const char *, int);
|
||||||
void cmdq_run(struct cmd_q *, struct cmd_list *);
|
void cmdq_run(struct cmd_q *, struct cmd_list *,
|
||||||
void cmdq_append(struct cmd_q *, struct cmd_list *);
|
struct mouse_event *);
|
||||||
|
void cmdq_append(struct cmd_q *, struct cmd_list *,
|
||||||
|
struct mouse_event *);
|
||||||
int cmdq_continue(struct cmd_q *);
|
int cmdq_continue(struct cmd_q *);
|
||||||
void cmdq_flush(struct cmd_q *);
|
void cmdq_flush(struct cmd_q *);
|
||||||
|
|
||||||
@ -1862,7 +1883,8 @@ struct key_binding *key_bindings_lookup(int);
|
|||||||
void key_bindings_add(int, int, struct cmd_list *);
|
void key_bindings_add(int, int, struct cmd_list *);
|
||||||
void key_bindings_remove(int);
|
void key_bindings_remove(int);
|
||||||
void key_bindings_init(void);
|
void key_bindings_init(void);
|
||||||
void key_bindings_dispatch(struct key_binding *, struct client *);
|
void key_bindings_dispatch(struct key_binding *, struct client *,
|
||||||
|
struct mouse_event *);
|
||||||
|
|
||||||
/* key-string.c */
|
/* key-string.c */
|
||||||
int key_string_lookup_string(const char *);
|
int key_string_lookup_string(const char *);
|
||||||
@ -1930,7 +1952,7 @@ RB_PROTOTYPE(status_out_tree, status_out, entry, status_out_cmp);
|
|||||||
int status_at_line(struct client *);
|
int status_at_line(struct client *);
|
||||||
void status_free_jobs(struct status_out_tree *);
|
void status_free_jobs(struct status_out_tree *);
|
||||||
void status_update_jobs(struct client *);
|
void status_update_jobs(struct client *);
|
||||||
void status_set_window_at(struct client *, u_int);
|
struct window *status_get_window_at(struct client *, u_int);
|
||||||
int status_redraw(struct client *);
|
int status_redraw(struct client *);
|
||||||
void printflike(2, 3) status_message_set(struct client *, const char *, ...);
|
void printflike(2, 3) status_message_set(struct client *, const char *, ...);
|
||||||
void status_message_clear(struct client *);
|
void status_message_clear(struct client *);
|
||||||
@ -1951,9 +1973,7 @@ void input_free(struct window_pane *);
|
|||||||
void input_parse(struct window_pane *);
|
void input_parse(struct window_pane *);
|
||||||
|
|
||||||
/* input-key.c */
|
/* input-key.c */
|
||||||
void input_key(struct window_pane *, int);
|
void input_key(struct window_pane *, int, struct mouse_event *);
|
||||||
void input_mouse(struct window_pane *, struct session *,
|
|
||||||
struct mouse_event *);
|
|
||||||
|
|
||||||
/* xterm-keys.c */
|
/* xterm-keys.c */
|
||||||
char *xterm_keys_lookup(int);
|
char *xterm_keys_lookup(int);
|
||||||
@ -2118,6 +2138,7 @@ void window_destroy(struct window *);
|
|||||||
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
|
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
|
||||||
void window_set_active_at(struct window *, u_int, u_int);
|
void window_set_active_at(struct window *, u_int, u_int);
|
||||||
struct window_pane *window_find_string(struct window *, const char *);
|
struct window_pane *window_find_string(struct window *, const char *);
|
||||||
|
int window_has_pane(struct window *, struct window_pane *);
|
||||||
int window_set_active_pane(struct window *, struct window_pane *);
|
int window_set_active_pane(struct window *, struct window_pane *);
|
||||||
struct window_pane *window_add_pane(struct window *, u_int);
|
struct window_pane *window_add_pane(struct window *, u_int);
|
||||||
void window_resize(struct window *, u_int, u_int);
|
void window_resize(struct window *, u_int, u_int);
|
||||||
@ -2148,9 +2169,8 @@ void window_pane_alternate_off(struct window_pane *,
|
|||||||
int window_pane_set_mode(
|
int window_pane_set_mode(
|
||||||
struct window_pane *, const struct window_mode *);
|
struct window_pane *, const struct window_mode *);
|
||||||
void window_pane_reset_mode(struct window_pane *);
|
void window_pane_reset_mode(struct window_pane *);
|
||||||
void window_pane_key(struct window_pane *, struct session *, int);
|
void window_pane_key(struct window_pane *, struct client *,
|
||||||
void window_pane_mouse(struct window_pane *,
|
struct session *, int, struct mouse_event *);
|
||||||
struct session *, struct mouse_event *);
|
|
||||||
int window_pane_visible(struct window_pane *);
|
int window_pane_visible(struct window_pane *);
|
||||||
char *window_pane_search(
|
char *window_pane_search(
|
||||||
struct window_pane *, const char *, u_int *);
|
struct window_pane *, const char *, u_int *);
|
||||||
@ -2186,7 +2206,6 @@ void layout_resize_pane(struct window_pane *, enum layout_type,
|
|||||||
int);
|
int);
|
||||||
void layout_resize_pane_to(struct window_pane *, enum layout_type,
|
void layout_resize_pane_to(struct window_pane *, enum layout_type,
|
||||||
u_int);
|
u_int);
|
||||||
void layout_resize_pane_mouse(struct client *);
|
|
||||||
void layout_assign_pane(struct layout_cell *, struct window_pane *);
|
void layout_assign_pane(struct layout_cell *, struct window_pane *);
|
||||||
struct layout_cell *layout_split_pane(
|
struct layout_cell *layout_split_pane(
|
||||||
struct window_pane *, enum layout_type, int, int);
|
struct window_pane *, enum layout_type, int, int);
|
||||||
@ -2215,6 +2234,7 @@ void window_copy_init_for_output(struct window_pane *);
|
|||||||
void printflike(2, 3) window_copy_add(struct window_pane *, const char *, ...);
|
void printflike(2, 3) window_copy_add(struct window_pane *, const char *, ...);
|
||||||
void window_copy_vadd(struct window_pane *, const char *, va_list);
|
void window_copy_vadd(struct window_pane *, const char *, va_list);
|
||||||
void window_copy_pageup(struct window_pane *);
|
void window_copy_pageup(struct window_pane *);
|
||||||
|
void window_copy_start_drag(struct client *, struct mouse_event *);
|
||||||
|
|
||||||
/* window-choose.c */
|
/* window-choose.c */
|
||||||
extern const struct window_mode window_choose_mode;
|
extern const struct window_mode window_choose_mode;
|
||||||
|
75
tty-keys.c
75
tty-keys.c
@ -644,8 +644,8 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
{
|
{
|
||||||
struct mouse_event *m = &tty->mouse;
|
struct mouse_event *m = &tty->mouse;
|
||||||
struct utf8_data utf8data;
|
struct utf8_data utf8data;
|
||||||
u_int i, value, x, y, b, sgr, sgr_b, sgr_rel;
|
u_int i, value, x, y, b, sgr_b;
|
||||||
unsigned char c;
|
u_char sgr_type, c;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Standard mouse sequences are \033[M followed by three characters
|
* Standard mouse sequences are \033[M followed by three characters
|
||||||
@ -661,7 +661,8 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
x = y = b = sgr = sgr_b = sgr_rel = 0;
|
x = y = b = sgr_b = 0;
|
||||||
|
sgr_type = ' ';
|
||||||
|
|
||||||
/* First two bytes are always \033[. */
|
/* First two bytes are always \033[. */
|
||||||
if (buf[0] != '\033')
|
if (buf[0] != '\033')
|
||||||
@ -755,15 +756,19 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
return (-1);
|
return (-1);
|
||||||
y = 10 * y + (c - '0');
|
y = 10 * y + (c - '0');
|
||||||
}
|
}
|
||||||
log_debug("mouse input (sgr): %.*s", (int) *size, buf);
|
log_debug("mouse input (SGR): %.*s", (int)*size, buf);
|
||||||
|
|
||||||
/* Check and return the mouse input. */
|
/* Check and return the mouse input. */
|
||||||
if (x < 1 || y < 1)
|
if (x < 1 || y < 1)
|
||||||
return (-1);
|
return (-1);
|
||||||
x--;
|
x--;
|
||||||
y--;
|
y--;
|
||||||
sgr = 1;
|
b = sgr_b;
|
||||||
sgr_rel = (c == 'm');
|
|
||||||
|
/* Type is M for press, m for release. */
|
||||||
|
sgr_type = c;
|
||||||
|
if (sgr_type == 'm')
|
||||||
|
b |= 3;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some terminals (like PuTTY 0.63) mistakenly send
|
* Some terminals (like PuTTY 0.63) mistakenly send
|
||||||
@ -771,64 +776,20 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
* Discard it before it reaches any program running inside
|
* Discard it before it reaches any program running inside
|
||||||
* tmux.
|
* tmux.
|
||||||
*/
|
*/
|
||||||
if (sgr_rel && (sgr_b & 64))
|
if (sgr_type == 'm' && (sgr_b & 64))
|
||||||
return (-2);
|
return (-2);
|
||||||
|
|
||||||
/* Figure out what b would be in old format. */
|
|
||||||
b = sgr_b;
|
|
||||||
if (sgr_rel)
|
|
||||||
b |= 3;
|
|
||||||
} else
|
} else
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
/* Fill in mouse structure. */
|
/* Fill mouse event. */
|
||||||
if (~m->event & MOUSE_EVENT_WHEEL) {
|
|
||||||
m->lx = m->x;
|
m->lx = m->x;
|
||||||
m->ly = m->y;
|
|
||||||
}
|
|
||||||
m->xb = b;
|
|
||||||
m->sgr = sgr;
|
|
||||||
m->sgr_xb = sgr_b;
|
|
||||||
m->sgr_rel = sgr_rel;
|
|
||||||
m->x = x;
|
m->x = x;
|
||||||
|
m->ly = m->y;
|
||||||
m->y = y;
|
m->y = y;
|
||||||
if (b & MOUSE_MASK_WHEEL) {
|
m->lb = m->b;
|
||||||
if (b & MOUSE_MASK_SHIFT)
|
m->b = b;
|
||||||
m->scroll = 1;
|
m->sgr_type = sgr_type;
|
||||||
else
|
m->sgr_b = sgr_b;
|
||||||
m->scroll = MOUSE_WHEEL_SCALE;
|
|
||||||
if (b & MOUSE_MASK_META)
|
|
||||||
m->scroll *= MOUSE_WHEEL_SCALE;
|
|
||||||
if (b & MOUSE_MASK_CTRL)
|
|
||||||
m->scroll *= MOUSE_WHEEL_SCALE;
|
|
||||||
|
|
||||||
b &= MOUSE_MASK_BUTTONS;
|
|
||||||
if (b == 0)
|
|
||||||
m->wheel = MOUSE_WHEEL_UP;
|
|
||||||
else if (b == 1)
|
|
||||||
m->wheel = MOUSE_WHEEL_DOWN;
|
|
||||||
m->event = MOUSE_EVENT_WHEEL;
|
|
||||||
|
|
||||||
m->button = 3;
|
|
||||||
} else if ((b & MOUSE_MASK_BUTTONS) == 3) {
|
|
||||||
if (~m->event & MOUSE_EVENT_DRAG && x == m->sx && y == m->sy) {
|
|
||||||
m->event = MOUSE_EVENT_CLICK;
|
|
||||||
m->clicks = (m->clicks + 1) % 3;
|
|
||||||
} else
|
|
||||||
m->event = MOUSE_EVENT_DRAG;
|
|
||||||
m->event |= MOUSE_EVENT_UP;
|
|
||||||
} else {
|
|
||||||
if (b & MOUSE_MASK_DRAG)
|
|
||||||
m->event = MOUSE_EVENT_DRAG;
|
|
||||||
else {
|
|
||||||
m->event = MOUSE_EVENT_DOWN;
|
|
||||||
if (x != m->sx || y != m->sy)
|
|
||||||
m->clicks = 0;
|
|
||||||
}
|
|
||||||
m->button = (b & MOUSE_MASK_BUTTONS);
|
|
||||||
}
|
|
||||||
m->sx = x;
|
|
||||||
m->sy = y;
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
4
tty.c
4
tty.c
@ -241,6 +241,10 @@ tty_start_tty(struct tty *tty)
|
|||||||
tty->flags |= TTY_STARTED;
|
tty->flags |= TTY_STARTED;
|
||||||
|
|
||||||
tty_force_cursor_colour(tty, "");
|
tty_force_cursor_colour(tty, "");
|
||||||
|
|
||||||
|
tty->mouse_drag_flag = 0;
|
||||||
|
tty->mouse_drag_update = NULL;
|
||||||
|
tty->mouse_drag_release = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
107
window-choose.c
107
window-choose.c
@ -27,11 +27,12 @@
|
|||||||
struct screen *window_choose_init(struct window_pane *);
|
struct screen *window_choose_init(struct window_pane *);
|
||||||
void window_choose_free(struct window_pane *);
|
void window_choose_free(struct window_pane *);
|
||||||
void window_choose_resize(struct window_pane *, u_int, u_int);
|
void window_choose_resize(struct window_pane *, u_int, u_int);
|
||||||
void window_choose_key(struct window_pane *, struct session *, int);
|
void window_choose_key(struct window_pane *, struct client *,
|
||||||
void window_choose_mouse(
|
struct session *, int, struct mouse_event *);
|
||||||
struct window_pane *, struct session *, struct mouse_event *);
|
|
||||||
|
|
||||||
void window_choose_default_callback(struct window_choose_data *);
|
void window_choose_default_callback(struct window_choose_data *);
|
||||||
|
struct window_choose_mode_item *window_choose_get_item(struct window_pane *,
|
||||||
|
int, struct mouse_event *);
|
||||||
|
|
||||||
void window_choose_fire_callback(
|
void window_choose_fire_callback(
|
||||||
struct window_pane *, struct window_choose_data *);
|
struct window_pane *, struct window_choose_data *);
|
||||||
@ -42,7 +43,7 @@ void window_choose_write_line(
|
|||||||
void window_choose_scroll_up(struct window_pane *);
|
void window_choose_scroll_up(struct window_pane *);
|
||||||
void window_choose_scroll_down(struct window_pane *);
|
void window_choose_scroll_down(struct window_pane *);
|
||||||
|
|
||||||
void window_choose_collapse(struct window_pane *, struct session *);
|
void window_choose_collapse(struct window_pane *, struct session *, u_int);
|
||||||
void window_choose_expand(struct window_pane *, struct session *, u_int);
|
void window_choose_expand(struct window_pane *, struct session *, u_int);
|
||||||
|
|
||||||
enum window_choose_input_type {
|
enum window_choose_input_type {
|
||||||
@ -55,7 +56,6 @@ const struct window_mode window_choose_mode = {
|
|||||||
window_choose_free,
|
window_choose_free,
|
||||||
window_choose_resize,
|
window_choose_resize,
|
||||||
window_choose_key,
|
window_choose_key,
|
||||||
window_choose_mouse,
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -160,8 +160,6 @@ window_choose_init(struct window_pane *wp)
|
|||||||
s = &data->screen;
|
s = &data->screen;
|
||||||
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
|
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
|
||||||
s->mode &= ~MODE_CURSOR;
|
s->mode &= ~MODE_CURSOR;
|
||||||
if (options_get_number(&wp->window->options, "mode-mouse"))
|
|
||||||
s->mode |= MODE_MOUSE_STANDARD;
|
|
||||||
|
|
||||||
keys = options_get_number(&wp->window->options, "mode-keys");
|
keys = options_get_number(&wp->window->options, "mode-keys");
|
||||||
if (keys == MODEKEY_EMACS)
|
if (keys == MODEKEY_EMACS)
|
||||||
@ -237,7 +235,7 @@ window_choose_data_run(struct window_choose_data *cdata)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdq_run(cdata->start_client->cmdq, cmdlist);
|
cmdq_run(cdata->start_client->cmdq, cmdlist, NULL);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +323,7 @@ window_choose_prompt_input(enum window_choose_input_type input_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_choose_collapse(struct window_pane *wp, struct session *s)
|
window_choose_collapse(struct window_pane *wp, struct session *s, u_int pos)
|
||||||
{
|
{
|
||||||
struct window_choose_mode_data *data = wp->modedata;
|
struct window_choose_mode_data *data = wp->modedata;
|
||||||
struct window_choose_mode_item *item, *chosen;
|
struct window_choose_mode_item *item, *chosen;
|
||||||
@ -335,7 +333,7 @@ window_choose_collapse(struct window_pane *wp, struct session *s)
|
|||||||
ARRAY_DECL(, struct window_choose_mode_item) list_copy;
|
ARRAY_DECL(, struct window_choose_mode_item) list_copy;
|
||||||
ARRAY_INIT(&list_copy);
|
ARRAY_INIT(&list_copy);
|
||||||
|
|
||||||
chosen = &ARRAY_ITEM(&data->list, data->selected);
|
chosen = &ARRAY_ITEM(&data->list, pos);
|
||||||
chosen->state &= ~TREE_EXPANDED;
|
chosen->state &= ~TREE_EXPANDED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -383,7 +381,7 @@ window_choose_collapse_all(struct window_pane *wp)
|
|||||||
chosen = ARRAY_ITEM(&data->list, data->selected).wcd->start_session;
|
chosen = ARRAY_ITEM(&data->list, data->selected).wcd->start_session;
|
||||||
|
|
||||||
RB_FOREACH(s, sessions, &sessions)
|
RB_FOREACH(s, sessions, &sessions)
|
||||||
window_choose_collapse(wp, s);
|
window_choose_collapse(wp, s, data->selected);
|
||||||
|
|
||||||
/* Reset the selection back to the starting session. */
|
/* Reset the selection back to the starting session. */
|
||||||
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) {
|
||||||
@ -483,8 +481,27 @@ window_choose_expand(struct window_pane *wp, struct session *s, u_int pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct window_choose_mode_item *
|
||||||
|
window_choose_get_item(struct window_pane *wp, int key, struct mouse_event *m)
|
||||||
|
{
|
||||||
|
struct window_choose_mode_data *data = wp->modedata;
|
||||||
|
u_int x, y, idx;
|
||||||
|
|
||||||
|
if (!KEYC_IS_MOUSE(key))
|
||||||
|
return (&ARRAY_ITEM(&data->list, data->selected));
|
||||||
|
|
||||||
|
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
idx = data->top + y;
|
||||||
|
if (idx >= ARRAY_LENGTH(&data->list))
|
||||||
|
return (NULL);
|
||||||
|
return (&ARRAY_ITEM(&data->list, idx));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
|
window_choose_key(struct window_pane *wp, unused struct client *c,
|
||||||
|
unused struct session *sess, int key, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
struct window_choose_mode_data *data = wp->modedata;
|
struct window_choose_mode_data *data = wp->modedata;
|
||||||
struct screen *s = &data->screen;
|
struct screen *s = &data->screen;
|
||||||
@ -533,23 +550,28 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
|
|||||||
window_choose_fire_callback(wp, NULL);
|
window_choose_fire_callback(wp, NULL);
|
||||||
break;
|
break;
|
||||||
case MODEKEYCHOICE_CHOOSE:
|
case MODEKEYCHOICE_CHOOSE:
|
||||||
item = &ARRAY_ITEM(&data->list, data->selected);
|
if ((item = window_choose_get_item(wp, key, m)) == NULL)
|
||||||
|
break;
|
||||||
window_choose_fire_callback(wp, item->wcd);
|
window_choose_fire_callback(wp, item->wcd);
|
||||||
break;
|
break;
|
||||||
case MODEKEYCHOICE_TREE_TOGGLE:
|
case MODEKEYCHOICE_TREE_TOGGLE:
|
||||||
item = &ARRAY_ITEM(&data->list, data->selected);
|
if ((item = window_choose_get_item(wp, key, m)) == NULL)
|
||||||
if (item->state & TREE_EXPANDED)
|
break;
|
||||||
window_choose_collapse(wp, item->wcd->tree_session);
|
if (item->state & TREE_EXPANDED) {
|
||||||
else {
|
window_choose_collapse(wp, item->wcd->tree_session,
|
||||||
|
item->wcd->idx);
|
||||||
|
} else {
|
||||||
window_choose_expand(wp, item->wcd->tree_session,
|
window_choose_expand(wp, item->wcd->tree_session,
|
||||||
data->selected);
|
item->wcd->idx);
|
||||||
}
|
}
|
||||||
window_choose_redraw_screen(wp);
|
window_choose_redraw_screen(wp);
|
||||||
break;
|
break;
|
||||||
case MODEKEYCHOICE_TREE_COLLAPSE:
|
case MODEKEYCHOICE_TREE_COLLAPSE:
|
||||||
item = &ARRAY_ITEM(&data->list, data->selected);
|
if ((item = window_choose_get_item(wp, key, m)) == NULL)
|
||||||
|
break;
|
||||||
if (item->state & TREE_EXPANDED) {
|
if (item->state & TREE_EXPANDED) {
|
||||||
window_choose_collapse(wp, item->wcd->tree_session);
|
window_choose_collapse(wp, item->wcd->tree_session,
|
||||||
|
data->selected);
|
||||||
window_choose_redraw_screen(wp);
|
window_choose_redraw_screen(wp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -557,7 +579,8 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
|
|||||||
window_choose_collapse_all(wp);
|
window_choose_collapse_all(wp);
|
||||||
break;
|
break;
|
||||||
case MODEKEYCHOICE_TREE_EXPAND:
|
case MODEKEYCHOICE_TREE_EXPAND:
|
||||||
item = &ARRAY_ITEM(&data->list, data->selected);
|
if ((item = window_choose_get_item(wp, key, m)) == NULL)
|
||||||
|
break;
|
||||||
if (!(item->state & TREE_EXPANDED)) {
|
if (!(item->state & TREE_EXPANDED)) {
|
||||||
window_choose_expand(wp, item->wcd->tree_session,
|
window_choose_expand(wp, item->wcd->tree_session,
|
||||||
data->selected);
|
data->selected);
|
||||||
@ -711,48 +734,6 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
window_choose_mouse(struct window_pane *wp, struct session *sess,
|
|
||||||
struct mouse_event *m)
|
|
||||||
{
|
|
||||||
struct window_choose_mode_data *data = wp->modedata;
|
|
||||||
struct screen *s = &data->screen;
|
|
||||||
struct window_choose_mode_item *item;
|
|
||||||
u_int idx, i, n;
|
|
||||||
|
|
||||||
if (m->event == MOUSE_EVENT_WHEEL) {
|
|
||||||
/*
|
|
||||||
* Multiple line scrolling by default is annoying, so scale
|
|
||||||
* m->scroll back down.
|
|
||||||
*/
|
|
||||||
n = m->scroll;
|
|
||||||
if (n >= MOUSE_WHEEL_SCALE)
|
|
||||||
n /= MOUSE_WHEEL_SCALE;
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
if (m->wheel == MOUSE_WHEEL_UP)
|
|
||||||
window_choose_key(wp, sess, KEYC_UP);
|
|
||||||
else
|
|
||||||
window_choose_key(wp, sess, KEYC_DOWN);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (~m->event & MOUSE_EVENT_CLICK)
|
|
||||||
return;
|
|
||||||
if (m->x >= screen_size_x(s))
|
|
||||||
return;
|
|
||||||
if (m->y >= screen_size_y(s))
|
|
||||||
return;
|
|
||||||
|
|
||||||
idx = data->top + m->y;
|
|
||||||
if (idx >= ARRAY_LENGTH(&data->list))
|
|
||||||
return;
|
|
||||||
data->selected = idx;
|
|
||||||
|
|
||||||
item = &ARRAY_ITEM(&data->list, data->selected);
|
|
||||||
window_choose_fire_callback(wp, item->wcd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
window_choose_write_line(
|
window_choose_write_line(
|
||||||
struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
|
struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
struct screen *window_clock_init(struct window_pane *);
|
struct screen *window_clock_init(struct window_pane *);
|
||||||
void window_clock_free(struct window_pane *);
|
void window_clock_free(struct window_pane *);
|
||||||
void window_clock_resize(struct window_pane *, u_int, u_int);
|
void window_clock_resize(struct window_pane *, u_int, u_int);
|
||||||
void window_clock_key(struct window_pane *, struct session *, int);
|
void window_clock_key(struct window_pane *, struct client *,
|
||||||
|
struct session *, int, struct mouse_event *);
|
||||||
void window_clock_timer(struct window_pane *);
|
void window_clock_timer(struct window_pane *);
|
||||||
|
|
||||||
void window_clock_draw_screen(struct window_pane *);
|
void window_clock_draw_screen(struct window_pane *);
|
||||||
@ -37,7 +38,6 @@ const struct window_mode window_clock_mode = {
|
|||||||
window_clock_free,
|
window_clock_free,
|
||||||
window_clock_resize,
|
window_clock_resize,
|
||||||
window_clock_key,
|
window_clock_key,
|
||||||
NULL,
|
|
||||||
window_clock_timer,
|
window_clock_timer,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,8 +157,8 @@ window_clock_resize(struct window_pane *wp, u_int sx, u_int sy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_clock_key(
|
window_clock_key(struct window_pane *wp, unused struct client *c,
|
||||||
struct window_pane *wp, unused struct session *sess, unused int key)
|
unused struct session *sess, unused int key, unused struct mouse_event *m)
|
||||||
{
|
{
|
||||||
window_pane_reset_mode(wp);
|
window_pane_reset_mode(wp);
|
||||||
}
|
}
|
||||||
|
160
window-copy.c
160
window-copy.c
@ -27,11 +27,10 @@
|
|||||||
struct screen *window_copy_init(struct window_pane *);
|
struct screen *window_copy_init(struct window_pane *);
|
||||||
void window_copy_free(struct window_pane *);
|
void window_copy_free(struct window_pane *);
|
||||||
void window_copy_resize(struct window_pane *, u_int, u_int);
|
void window_copy_resize(struct window_pane *, u_int, u_int);
|
||||||
void window_copy_key(struct window_pane *, struct session *, int);
|
void window_copy_key(struct window_pane *, struct client *, struct session *,
|
||||||
|
int, struct mouse_event *);
|
||||||
int window_copy_key_input(struct window_pane *, int);
|
int window_copy_key_input(struct window_pane *, int);
|
||||||
int window_copy_key_numeric_prefix(struct window_pane *, int);
|
int window_copy_key_numeric_prefix(struct window_pane *, int);
|
||||||
void window_copy_mouse(struct window_pane *, struct session *,
|
|
||||||
struct mouse_event *);
|
|
||||||
|
|
||||||
void window_copy_redraw_selection(struct window_pane *, u_int);
|
void window_copy_redraw_selection(struct window_pane *, u_int);
|
||||||
void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
|
void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
|
||||||
@ -84,13 +83,14 @@ void window_copy_cursor_previous_word(struct window_pane *, const char *);
|
|||||||
void window_copy_scroll_up(struct window_pane *, u_int);
|
void window_copy_scroll_up(struct window_pane *, u_int);
|
||||||
void window_copy_scroll_down(struct window_pane *, u_int);
|
void window_copy_scroll_down(struct window_pane *, u_int);
|
||||||
void window_copy_rectangle_toggle(struct window_pane *);
|
void window_copy_rectangle_toggle(struct window_pane *);
|
||||||
|
void window_copy_drag_update(struct client *, struct mouse_event *);
|
||||||
|
void window_copy_drag_release(struct client *, struct mouse_event *);
|
||||||
|
|
||||||
const struct window_mode window_copy_mode = {
|
const struct window_mode window_copy_mode = {
|
||||||
window_copy_init,
|
window_copy_init,
|
||||||
window_copy_free,
|
window_copy_free,
|
||||||
window_copy_resize,
|
window_copy_resize,
|
||||||
window_copy_key,
|
window_copy_key,
|
||||||
window_copy_mouse,
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ struct window_copy_mode_data {
|
|||||||
struct screen screen;
|
struct screen screen;
|
||||||
|
|
||||||
struct screen *backing;
|
struct screen *backing;
|
||||||
int backing_written; /* backing display has started */
|
int backing_written; /* backing display started */
|
||||||
|
|
||||||
struct mode_key_data mdata;
|
struct mode_key_data mdata;
|
||||||
|
|
||||||
@ -141,8 +141,8 @@ struct window_copy_mode_data {
|
|||||||
u_int cx;
|
u_int cx;
|
||||||
u_int cy;
|
u_int cy;
|
||||||
|
|
||||||
u_int lastcx; /* position in last line with content */
|
u_int lastcx; /* position in last line w/ content */
|
||||||
u_int lastsx; /* size of last line with content */
|
u_int lastsx; /* size of last line w/ content */
|
||||||
|
|
||||||
enum window_copy_input_type inputtype;
|
enum window_copy_input_type inputtype;
|
||||||
const char *inputprompt;
|
const char *inputprompt;
|
||||||
@ -193,8 +193,6 @@ window_copy_init(struct window_pane *wp)
|
|||||||
|
|
||||||
s = &data->screen;
|
s = &data->screen;
|
||||||
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
|
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
|
||||||
if (options_get_number(&wp->window->options, "mode-mouse"))
|
|
||||||
s->mode |= MODE_MOUSE_STANDARD;
|
|
||||||
|
|
||||||
keys = options_get_number(&wp->window->options, "mode-keys");
|
keys = options_get_number(&wp->window->options, "mode-keys");
|
||||||
if (keys == MODEKEY_EMACS)
|
if (keys == MODEKEY_EMACS)
|
||||||
@ -367,19 +365,20 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_key(struct window_pane *wp, struct session *sess, int key)
|
window_copy_key(struct window_pane *wp, struct client *c, struct session *sess,
|
||||||
|
int key, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
const char *word_separators;
|
const char *word_separators;
|
||||||
struct window_copy_mode_data *data = wp->modedata;
|
struct window_copy_mode_data *data = wp->modedata;
|
||||||
struct screen *s = &data->screen;
|
struct screen *s = &data->screen;
|
||||||
u_int n;
|
u_int n, np;
|
||||||
int np, keys;
|
int keys;
|
||||||
enum mode_key_cmd cmd;
|
enum mode_key_cmd cmd;
|
||||||
const char *arg, *ss;
|
const char *arg, *ss;
|
||||||
|
|
||||||
np = data->numprefix;
|
|
||||||
if (np <= 0)
|
|
||||||
np = 1;
|
np = 1;
|
||||||
|
if (data->numprefix > 0)
|
||||||
|
np = data->numprefix;
|
||||||
|
|
||||||
if (data->inputtype == WINDOW_COPY_JUMPFORWARD ||
|
if (data->inputtype == WINDOW_COPY_JUMPFORWARD ||
|
||||||
data->inputtype == WINDOW_COPY_JUMPBACK ||
|
data->inputtype == WINDOW_COPY_JUMPBACK ||
|
||||||
@ -536,9 +535,14 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
|
|||||||
window_copy_redraw_screen(wp);
|
window_copy_redraw_screen(wp);
|
||||||
break;
|
break;
|
||||||
case MODEKEYCOPY_STARTSELECTION:
|
case MODEKEYCOPY_STARTSELECTION:
|
||||||
|
if (KEYC_IS_MOUSE(key)) {
|
||||||
|
if (c != NULL)
|
||||||
|
window_copy_start_drag(c, m);
|
||||||
|
} else {
|
||||||
s->sel.lineflag = LINE_SEL_NONE;
|
s->sel.lineflag = LINE_SEL_NONE;
|
||||||
window_copy_start_selection(wp);
|
window_copy_start_selection(wp);
|
||||||
window_copy_redraw_screen(wp);
|
window_copy_redraw_screen(wp);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MODEKEYCOPY_SELECTLINE:
|
case MODEKEYCOPY_SELECTLINE:
|
||||||
s->sel.lineflag = LINE_SEL_LEFT_RIGHT;
|
s->sel.lineflag = LINE_SEL_LEFT_RIGHT;
|
||||||
@ -887,75 +891,6 @@ window_copy_key_numeric_prefix(struct window_pane *wp, int key)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
window_copy_mouse(struct window_pane *wp, struct session *sess,
|
|
||||||
struct mouse_event *m)
|
|
||||||
{
|
|
||||||
struct window_copy_mode_data *data = wp->modedata;
|
|
||||||
struct screen *s = &data->screen;
|
|
||||||
u_int i, old_cy;
|
|
||||||
|
|
||||||
if (m->x >= screen_size_x(s))
|
|
||||||
return;
|
|
||||||
if (m->y >= screen_size_y(s))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* If mouse wheel (buttons 4 and 5), scroll. */
|
|
||||||
if (m->event == MOUSE_EVENT_WHEEL) {
|
|
||||||
for (i = 0; i < m->scroll; i++) {
|
|
||||||
if (m->wheel == MOUSE_WHEEL_UP)
|
|
||||||
window_copy_cursor_up(wp, 1);
|
|
||||||
else {
|
|
||||||
window_copy_cursor_down(wp, 1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We reached the bottom, leave copy mode, but
|
|
||||||
* only if no selection is in progress.
|
|
||||||
*/
|
|
||||||
if (data->oy == 0 && !s->sel.flag &&
|
|
||||||
s->sel.lineflag == LINE_SEL_NONE)
|
|
||||||
goto reset_mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If already reading motion, move the cursor while buttons are still
|
|
||||||
* pressed, or stop the selection on their release.
|
|
||||||
*/
|
|
||||||
if (s->mode & MODE_MOUSE_BUTTON) {
|
|
||||||
if (~m->event & MOUSE_EVENT_UP) {
|
|
||||||
old_cy = data->cy;
|
|
||||||
window_copy_update_cursor(wp, m->x, m->y);
|
|
||||||
if (window_copy_update_selection(wp, 1))
|
|
||||||
window_copy_redraw_selection(wp, old_cy);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
goto reset_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise if other buttons pressed, start selection and motion. */
|
|
||||||
if (~m->event & MOUSE_EVENT_UP) {
|
|
||||||
s->mode &= ~MODE_MOUSE_STANDARD;
|
|
||||||
s->mode |= MODE_MOUSE_BUTTON;
|
|
||||||
|
|
||||||
window_copy_update_cursor(wp, m->x, m->y);
|
|
||||||
window_copy_start_selection(wp);
|
|
||||||
window_copy_redraw_screen(wp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
reset_mode:
|
|
||||||
s->mode &= ~MODE_MOUSE_BUTTON;
|
|
||||||
s->mode |= MODE_MOUSE_STANDARD;
|
|
||||||
if (sess != NULL) {
|
|
||||||
window_copy_copy_selection(wp, NULL);
|
|
||||||
window_pane_reset_mode(wp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py)
|
window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py)
|
||||||
{
|
{
|
||||||
@ -2274,3 +2209,62 @@ window_copy_rectangle_toggle(struct window_pane *wp)
|
|||||||
window_copy_update_selection(wp, 1);
|
window_copy_update_selection(wp, 1);
|
||||||
window_copy_redraw_screen(wp);
|
window_copy_redraw_screen(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_copy_start_drag(struct client *c, unused struct mouse_event *m)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
struct window_copy_mode_data *data;
|
||||||
|
u_int x, y;
|
||||||
|
|
||||||
|
wp = cmd_mouse_pane(m, NULL, NULL);
|
||||||
|
if (wp->mode != &window_copy_mode)
|
||||||
|
return;
|
||||||
|
data = wp->modedata;
|
||||||
|
|
||||||
|
if (cmd_mouse_at(wp, m, &x, &y, 1) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c->tty.mouse_drag_update = window_copy_drag_update;
|
||||||
|
c->tty.mouse_drag_release = window_copy_drag_release;
|
||||||
|
|
||||||
|
window_copy_update_cursor(wp, x, y);
|
||||||
|
window_copy_start_selection(wp);
|
||||||
|
window_copy_redraw_screen(wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_copy_drag_update(unused struct client *c, struct mouse_event *m)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
struct window_copy_mode_data *data;
|
||||||
|
u_int x, y, old_cy;
|
||||||
|
|
||||||
|
wp = cmd_mouse_pane(m, NULL, NULL);
|
||||||
|
if (wp->mode != &window_copy_mode)
|
||||||
|
return;
|
||||||
|
data = wp->modedata;
|
||||||
|
|
||||||
|
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
|
||||||
|
return;
|
||||||
|
old_cy = data->cy;
|
||||||
|
|
||||||
|
window_copy_update_cursor(wp, x, y);
|
||||||
|
if (window_copy_update_selection(wp, 1))
|
||||||
|
window_copy_redraw_selection(wp, old_cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_copy_drag_release(unused struct client *c, struct mouse_event *m)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
struct window_copy_mode_data *data;
|
||||||
|
|
||||||
|
wp = cmd_mouse_pane(m, NULL, NULL);
|
||||||
|
if (wp->mode != &window_copy_mode)
|
||||||
|
return;
|
||||||
|
data = wp->modedata;
|
||||||
|
|
||||||
|
window_copy_copy_selection(wp, NULL);
|
||||||
|
window_pane_reset_mode(wp);
|
||||||
|
}
|
||||||
|
49
window.c
49
window.c
@ -386,6 +386,18 @@ window_resize(struct window *w, u_int sx, u_int sy)
|
|||||||
w->sy = sy;
|
w->sy = sy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
window_has_pane(struct window *w, struct window_pane *wp)
|
||||||
|
{
|
||||||
|
struct window_pane *wp1;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(wp1, &w->panes, entry) {
|
||||||
|
if (wp1 == wp)
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
window_set_active_pane(struct window *w, struct window_pane *wp)
|
window_set_active_pane(struct window *w, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@ -1052,52 +1064,37 @@ window_pane_reset_mode(struct window_pane *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_pane_key(struct window_pane *wp, struct session *sess, int key)
|
window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
||||||
|
int key, struct mouse_event *m)
|
||||||
{
|
{
|
||||||
struct window_pane *wp2;
|
struct window_pane *wp2;
|
||||||
|
|
||||||
|
if (KEYC_IS_MOUSE(key) && m == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (wp->mode != NULL) {
|
if (wp->mode != NULL) {
|
||||||
if (wp->mode->key != NULL)
|
if (wp->mode->key != NULL)
|
||||||
wp->mode->key(wp, sess, key);
|
wp->mode->key(wp, c, s, key, m);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wp->fd == -1 || wp->flags & PANE_INPUTOFF)
|
if (wp->fd == -1 || wp->flags & PANE_INPUTOFF)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
input_key(wp, key);
|
input_key(wp, key, m);
|
||||||
|
|
||||||
|
if (KEYC_IS_MOUSE(key))
|
||||||
|
return;
|
||||||
if (options_get_number(&wp->window->options, "synchronize-panes")) {
|
if (options_get_number(&wp->window->options, "synchronize-panes")) {
|
||||||
TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
|
TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
|
||||||
if (wp2 == wp || wp2->mode != NULL)
|
if (wp2 == wp || wp2->mode != NULL)
|
||||||
continue;
|
continue;
|
||||||
if (wp2->fd != -1 && window_pane_visible(wp2))
|
if (wp2->fd != -1 && window_pane_visible(wp2))
|
||||||
input_key(wp2, key);
|
input_key(wp2, key, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
window_pane_mouse(struct window_pane *wp, struct session *sess,
|
|
||||||
struct mouse_event *m)
|
|
||||||
{
|
|
||||||
if (!window_pane_visible(wp))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m->x < wp->xoff || m->x >= wp->xoff + wp->sx)
|
|
||||||
return;
|
|
||||||
if (m->y < wp->yoff || m->y >= wp->yoff + wp->sy)
|
|
||||||
return;
|
|
||||||
m->x -= wp->xoff;
|
|
||||||
m->y -= wp->yoff;
|
|
||||||
|
|
||||||
if (wp->mode != NULL) {
|
|
||||||
if (wp->mode->mouse != NULL &&
|
|
||||||
options_get_number(&wp->window->options, "mode-mouse"))
|
|
||||||
wp->mode->mouse(wp, sess, m);
|
|
||||||
} else if (wp->fd != -1)
|
|
||||||
input_mouse(wp, sess, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
window_pane_visible(struct window_pane *wp)
|
window_pane_visible(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user