Fredrik Fornwall
5 years ago
3 changed files with 2 additions and 367 deletions
@ -1,344 +0,0 @@ |
|||
From 33298d6df67e2ba3d90abdc94250eeaa963c3730 Mon Sep 17 00:00:00 2001 |
|||
From: nicm <nicm> |
|||
Date: Fri, 3 May 2019 14:51:30 +0000 |
|||
Subject: [PATCH] Instead of processing keys all together, put them up on the |
|||
client command queue so they are ordered correctly with the commands that |
|||
they execute. |
|||
|
|||
---
|
|||
server-client.c | 63 ++++++++++++++++++++++++++++++------------------- |
|||
tmux.h | 13 +++++++--- |
|||
tty-keys.c | 60 +++++++++++++++++++++++++++------------------- |
|||
3 files changed, 85 insertions(+), 51 deletions(-) |
|||
|
|||
diff --git a/server-client.c b/server-client.c
|
|||
index 4cd5be745..a3d6aebf5 100644
|
|||
--- a/server-client.c
|
|||
+++ b/server-client.c
|
|||
@@ -35,7 +35,7 @@
|
|||
static void server_client_free(int, short, void *); |
|||
static void server_client_check_focus(struct window_pane *); |
|||
static void server_client_check_resize(struct window_pane *); |
|||
-static key_code server_client_check_mouse(struct client *);
|
|||
+static key_code server_client_check_mouse(struct client *, struct key_event *);
|
|||
static void server_client_repeat_timer(int, short, void *); |
|||
static void server_client_click_timer(int, short, void *); |
|||
static void server_client_check_exit(struct client *); |
|||
@@ -407,10 +407,10 @@ server_client_exec(struct client *c, const char *cmd)
|
|||
|
|||
/* Check for mouse keys. */ |
|||
static key_code |
|||
-server_client_check_mouse(struct client *c)
|
|||
+server_client_check_mouse(struct client *c, struct key_event *event)
|
|||
{ |
|||
+ struct mouse_event *m = &event->m;
|
|||
struct session *s = c->session; |
|||
- struct mouse_event *m = &c->tty.mouse;
|
|||
struct winlink *wl; |
|||
struct window_pane *wp; |
|||
u_int x, y, b, sx, sy, px, py; |
|||
@@ -419,7 +419,13 @@ server_client_check_mouse(struct client *c)
|
|||
struct timeval tv; |
|||
struct style_range *sr; |
|||
enum { NOTYPE, MOVE, DOWN, UP, DRAG, WHEEL, DOUBLE, TRIPLE } type; |
|||
- enum { NOWHERE, PANE, STATUS, STATUS_LEFT, STATUS_RIGHT, STATUS_DEFAULT, BORDER } where;
|
|||
+ enum { NOWHERE,
|
|||
+ PANE,
|
|||
+ STATUS,
|
|||
+ STATUS_LEFT,
|
|||
+ STATUS_RIGHT,
|
|||
+ STATUS_DEFAULT,
|
|||
+ BORDER } where;
|
|||
|
|||
type = NOTYPE; |
|||
where = NOWHERE; |
|||
@@ -976,11 +982,17 @@ server_client_assume_paste(struct session *s)
|
|||
return (0); |
|||
} |
|||
|
|||
-/* Handle data key input from client. */
|
|||
-void
|
|||
-server_client_handle_key(struct client *c, key_code key)
|
|||
+/*
|
|||
+ * Handle data key input from client. This owns and can modify the key event it
|
|||
+ * is given and is responsible for freeing it.
|
|||
+ */
|
|||
+enum cmd_retval
|
|||
+server_client_key_callback(struct cmdq_item *item, void *data)
|
|||
{ |
|||
- struct mouse_event *m = &c->tty.mouse;
|
|||
+ struct client *c = item->client;
|
|||
+ struct key_event *event = data;
|
|||
+ key_code key = event->key;
|
|||
+ struct mouse_event *m = &event->m;
|
|||
struct session *s = c->session; |
|||
struct winlink *wl; |
|||
struct window *w; |
|||
@@ -995,7 +1007,7 @@ server_client_handle_key(struct client *c, key_code key)
|
|||
|
|||
/* Check the client is good to accept input. */ |
|||
if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) |
|||
- return;
|
|||
+ goto out;
|
|||
wl = s->curw; |
|||
w = wl->window; |
|||
|
|||
@@ -1007,11 +1019,11 @@ server_client_handle_key(struct client *c, key_code key)
|
|||
/* Number keys jump to pane in identify mode. */ |
|||
if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') { |
|||
if (c->flags & CLIENT_READONLY) |
|||
- return;
|
|||
+ goto out;
|
|||
window_unzoom(w); |
|||
wp = window_pane_at_index(w, key - '0'); |
|||
server_client_clear_identify(c, wp); |
|||
- return;
|
|||
+ goto out;
|
|||
} |
|||
|
|||
/* Handle status line. */ |
|||
@@ -1021,19 +1033,19 @@ server_client_handle_key(struct client *c, key_code key)
|
|||
} |
|||
if (c->prompt_string != NULL) { |
|||
if (c->flags & CLIENT_READONLY) |
|||
- return;
|
|||
+ goto out;
|
|||
if (status_prompt_key(c, key) == 0) |
|||
- return;
|
|||
+ goto out;
|
|||
} |
|||
|
|||
/* Check for mouse keys. */ |
|||
m->valid = 0; |
|||
if (key == KEYC_MOUSE) { |
|||
if (c->flags & CLIENT_READONLY) |
|||
- return;
|
|||
- key = server_client_check_mouse(c);
|
|||
+ goto out;
|
|||
+ key = server_client_check_mouse(c, event);
|
|||
if (key == KEYC_UNKNOWN) |
|||
- return;
|
|||
+ goto out;
|
|||
|
|||
m->valid = 1; |
|||
m->key = key; |
|||
@@ -1044,10 +1056,9 @@ server_client_handle_key(struct client *c, key_code key)
|
|||
*/ |
|||
if (key == KEYC_DRAGGING) { |
|||
c->tty.mouse_drag_update(c, m); |
|||
- return;
|
|||
+ goto out;
|
|||
} |
|||
- } else
|
|||
- m->valid = 0;
|
|||
+ }
|
|||
|
|||
/* Find affected pane. */ |
|||
if (!KEYC_IS_MOUSE(key) || cmd_find_from_mouse(&fs, m, 0) != 0) |
|||
@@ -1086,7 +1097,7 @@ server_client_handle_key(struct client *c, key_code key)
|
|||
strcmp(table->name, "prefix") != 0) { |
|||
server_client_set_key_table(c, "prefix"); |
|||
server_status_client(c); |
|||
- return;
|
|||
+ goto out;
|
|||
} |
|||
flags = c->flags; |
|||
|
|||
@@ -1144,9 +1155,9 @@ server_client_handle_key(struct client *c, key_code key)
|
|||
server_status_client(c); |
|||
|
|||
/* Execute the key binding. */ |
|||
- key_bindings_dispatch(bd, NULL, c, m, &fs);
|
|||
+ key_bindings_dispatch(bd, item, c, m, &fs);
|
|||
key_bindings_unref_table(table); |
|||
- return;
|
|||
+ goto out;
|
|||
} |
|||
|
|||
/* |
|||
@@ -1181,14 +1192,18 @@ server_client_handle_key(struct client *c, key_code key)
|
|||
if (first != table && (~flags & CLIENT_REPEAT)) { |
|||
server_client_set_key_table(c, NULL); |
|||
server_status_client(c); |
|||
- return;
|
|||
+ goto out;
|
|||
} |
|||
|
|||
forward_key: |
|||
if (c->flags & CLIENT_READONLY) |
|||
- return;
|
|||
+ goto out;
|
|||
if (wp != NULL) |
|||
window_pane_key(wp, c, s, wl, key, m); |
|||
+
|
|||
+out:
|
|||
+ free(event);
|
|||
+ return (CMD_RETURN_NORMAL);
|
|||
} |
|||
|
|||
/* Client functions that need to happen every loop. */ |
|||
diff --git a/tmux.h b/tmux.h
|
|||
index 0e79d4295..4f69301f7 100644
|
|||
--- a/tmux.h
|
|||
+++ b/tmux.h
|
|||
@@ -1052,6 +1052,12 @@ struct mouse_event {
|
|||
u_int sgr_b; |
|||
}; |
|||
|
|||
+/* Key event. */
|
|||
+struct key_event {
|
|||
+ key_code key;
|
|||
+ struct mouse_event m;
|
|||
+};
|
|||
+
|
|||
/* TTY information. */ |
|||
struct tty_key { |
|||
char ch; |
|||
@@ -1143,7 +1149,8 @@ struct tty {
|
|||
TTY_UNKNOWN |
|||
} term_type; |
|||
|
|||
- struct mouse_event mouse;
|
|||
+ u_int mouse_last_x;
|
|||
+ u_int mouse_last_y;
|
|||
int mouse_drag_flag; |
|||
void (*mouse_drag_update)(struct client *, |
|||
struct mouse_event *); |
|||
@@ -1864,7 +1871,7 @@ const char *tty_acs_get(struct tty *, u_char);
|
|||
/* tty-keys.c */ |
|||
void tty_keys_build(struct tty *); |
|||
void tty_keys_free(struct tty *); |
|||
-key_code tty_keys_next(struct tty *);
|
|||
+int tty_keys_next(struct tty *);
|
|||
|
|||
/* arguments.c */ |
|||
void args_set(struct args *, u_char, const char *); |
|||
@@ -2002,7 +2009,7 @@ void server_client_set_identify(struct client *, u_int);
|
|||
void server_client_set_key_table(struct client *, const char *); |
|||
const char *server_client_get_key_table(struct client *); |
|||
int server_client_check_nested(struct client *); |
|||
-void server_client_handle_key(struct client *, key_code);
|
|||
+enum cmd_retval server_client_key_callback(struct cmdq_item *, void *);
|
|||
struct client *server_client_create(int); |
|||
int server_client_open(struct client *, char **); |
|||
void server_client_unref(struct client *); |
|||
diff --git a/tty-keys.c b/tty-keys.c
|
|||
index 850c91197..1aecbcb24 100644
|
|||
--- a/tty-keys.c
|
|||
+++ b/tty-keys.c
|
|||
@@ -46,7 +46,8 @@ static struct tty_key *tty_keys_find(struct tty *, const char *, size_t,
|
|||
static int tty_keys_next1(struct tty *, const char *, size_t, key_code *, |
|||
size_t *, int); |
|||
static void tty_keys_callback(int, short, void *); |
|||
-static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *);
|
|||
+static int tty_keys_mouse(struct tty *, const char *, size_t, size_t *,
|
|||
+ struct mouse_event *);
|
|||
static int tty_keys_clipboard(struct tty *, const char *, size_t, |
|||
size_t *); |
|||
static int tty_keys_device_attributes(struct tty *, const char *, size_t, |
|||
@@ -560,25 +561,26 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
|
|||
return (-1); |
|||
} |
|||
|
|||
-/*
|
|||
- * Process at least one key in the buffer and invoke tty->key_callback. Return
|
|||
- * 0 if there are no further keys, or 1 if there could be more in the buffer.
|
|||
- */
|
|||
-key_code
|
|||
+/* Process at least one key in the buffer. Return 0 if no keys present. */
|
|||
+int
|
|||
tty_keys_next(struct tty *tty) |
|||
{ |
|||
- struct client *c = tty->client;
|
|||
- struct timeval tv;
|
|||
- const char *buf;
|
|||
- size_t len, size;
|
|||
- cc_t bspace;
|
|||
- int delay, expired = 0, n;
|
|||
- key_code key;
|
|||
+ struct client *c = tty->client;
|
|||
+ struct timeval tv;
|
|||
+ const char *buf;
|
|||
+ size_t len, size;
|
|||
+ cc_t bspace;
|
|||
+ int delay, expired = 0, n;
|
|||
+ key_code key;
|
|||
+ struct cmdq_item *item;
|
|||
+ struct mouse_event m = { 0 };
|
|||
+ struct key_event *event;
|
|||
+
|
|||
+ gettimeofday(&tv, NULL);
|
|||
|
|||
/* Get key buffer. */ |
|||
buf = EVBUFFER_DATA(tty->in); |
|||
len = EVBUFFER_LENGTH(tty->in); |
|||
-
|
|||
if (len == 0) |
|||
return (0); |
|||
log_debug("%s: keys are %zu (%.*s)", c->name, len, (int)len, buf); |
|||
@@ -606,7 +608,7 @@ tty_keys_next(struct tty *tty)
|
|||
} |
|||
|
|||
/* Is this a mouse key press? */ |
|||
- switch (tty_keys_mouse(tty, buf, len, &size)) {
|
|||
+ switch (tty_keys_mouse(tty, buf, len, &size, &m)) {
|
|||
case 0: /* yes */ |
|||
key = KEYC_MOUSE; |
|||
goto complete_key; |
|||
@@ -725,8 +727,14 @@ tty_keys_next(struct tty *tty)
|
|||
} |
|||
|
|||
/* Fire the key. */ |
|||
- if (key != KEYC_UNKNOWN)
|
|||
- server_client_handle_key(tty->client, key);
|
|||
+ if (key != KEYC_UNKNOWN) {
|
|||
+ event = xmalloc(sizeof *event);
|
|||
+ event->key = key;
|
|||
+ memcpy(&event->m, &m, sizeof event->m);
|
|||
+
|
|||
+ item = cmdq_get_callback(server_client_key_callback, event);
|
|||
+ cmdq_append(c, item);
|
|||
+ }
|
|||
|
|||
return (1); |
|||
|
|||
@@ -756,12 +764,12 @@ tty_keys_callback(__unused int fd, __unused short events, void *data)
|
|||
* (probably a mouse sequence but need more data). |
|||
*/ |
|||
static int |
|||
-tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||
+tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size,
|
|||
+ struct mouse_event *m)
|
|||
{ |
|||
- struct client *c = tty->client;
|
|||
- struct mouse_event *m = &tty->mouse;
|
|||
- u_int i, x, y, b, sgr_b;
|
|||
- u_char sgr_type, ch;
|
|||
+ struct client *c = tty->client;
|
|||
+ u_int i, x, y, b, sgr_b;
|
|||
+ u_char sgr_type, ch;
|
|||
|
|||
/* |
|||
* Standard mouse sequences are \033[M followed by three characters |
|||
@@ -882,15 +890,19 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||
return (-1); |
|||
|
|||
/* Fill mouse event. */ |
|||
- m->lx = m->x;
|
|||
+ m->lx = tty->mouse_last_x;
|
|||
m->x = x; |
|||
- m->ly = m->y;
|
|||
+ m->ly = tty->mouse_last_y;
|
|||
m->y = y; |
|||
m->lb = m->b; |
|||
m->b = b; |
|||
m->sgr_type = sgr_type; |
|||
m->sgr_b = sgr_b; |
|||
|
|||
+ /* Update last mouse state. */
|
|||
+ tty->mouse_last_x = x;
|
|||
+ tty->mouse_last_y = y;
|
|||
+
|
|||
return (0); |
|||
} |
|||
|
@ -1,20 +0,0 @@ |
|||
diff -u -r ../tmux-2.2/session.c ./session.c
|
|||
--- ../tmux-2.2/session.c 2016-01-20 19:00:28.000000000 -0500
|
|||
+++ ./session.c 2016-04-11 05:28:53.669311770 -0400
|
|||
@@ -22,6 +22,7 @@
|
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
#include <unistd.h> |
|||
+#include <pwd.h>
|
|||
#include <time.h> |
|||
|
|||
#include "tmux.h" |
|||
@@ -340,7 +341,7 @@
|
|||
|
|||
shell = options_get_string(s->options, "default-shell"); |
|||
if (*shell == '\0' || areshell(shell)) |
|||
- shell = _PATH_BSHELL;
|
|||
+ shell = getpwuid(getuid())->pw_shell;
|
|||
|
|||
hlimit = options_get_number(s->options, "history-limit"); |
|||
w = window_create(name, argc, argv, path, shell, cwd, env, s->tio, |
Loading…
Reference in new issue