summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2019-05-07 13:02:27 +0100
committerThomas Adam <thomas@xteddy.org>2019-05-07 13:02:27 +0100
commitd9767b81123cc8913c63c42cc754cccbf34ccb6c (patch)
tree94e0a8cdb822db6145080c02907ad626c0d0fa89
parenteac30a86d78879f2dec802b0d246eba0afa79b3e (diff)
parent85a9c2f52b8855560fa9fdaa033d1c7bca738429 (diff)
Merge branch 'obsd-master'
-rw-r--r--cmd-copy-mode.c8
-rw-r--r--control-notify.c7
-rw-r--r--input.c25
-rw-r--r--notify.c4
-rw-r--r--server-client.c40
-rw-r--r--tmux.h7
-rw-r--r--tty-keys.c6
-rw-r--r--window.c8
8 files changed, 70 insertions, 35 deletions
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c
index bd05f8a2..b35d0af1 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -73,10 +73,10 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
}
- if (window_pane_set_mode(wp, &window_copy_mode, NULL, args) != 0)
- return (CMD_RETURN_NORMAL);
- if (args_has(args, 'M'))
- window_copy_start_drag(c, &shared->mouse);
+ if (!window_pane_set_mode(wp, &window_copy_mode, NULL, args)) {
+ if (args_has(args, 'M'))
+ window_copy_start_drag(c, &shared->mouse);
+ }
if (args_has(self->args, 'u'))
window_copy_pageup(wp, 0);
diff --git a/control-notify.c b/control-notify.c
index 7b28e8f0..340dab73 100644
--- a/control-notify.c
+++ b/control-notify.c
@@ -28,19 +28,14 @@
void
control_notify_input(struct client *c, struct window_pane *wp,
- struct evbuffer *input)
+ const u_char *buf, size_t len)
{
- u_char *buf;
- size_t len;
struct evbuffer *message;
u_int i;
if (c->session == NULL)
return;
- buf = EVBUFFER_DATA(input);
- len = EVBUFFER_LENGTH(input);
-
/*
* Only write input if the window pane is linked to a window belonging
* to the client's session.
diff --git a/input.c b/input.c
index 20272a62..285de2d2 100644
--- a/input.c
+++ b/input.c
@@ -874,18 +874,27 @@ input_set_state(struct window_pane *wp, const struct input_transition *itr)
void
input_parse(struct window_pane *wp)
{
+ struct evbuffer *evb = wp->event->input;
+
+ input_parse_buffer(wp, EVBUFFER_DATA(evb), EVBUFFER_LENGTH(evb));
+ evbuffer_drain(evb, EVBUFFER_LENGTH(evb));
+}
+
+/* Parse given input. */
+void
+input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
+{
struct input_ctx *ictx = wp->ictx;
struct screen_write_ctx *sctx = &ictx->ctx;
const struct input_transition *itr;
- struct evbuffer *evb = wp->event->input;
- u_char *buf;
- size_t len, off;
+ size_t off = 0;
- if (EVBUFFER_LENGTH(evb) == 0)
+ if (len == 0)
return;
window_update_activity(wp->window);
wp->flags |= PANE_CHANGED;
+ notify_input(wp, buf, len);
/*
* Open the screen. Use NULL wp if there is a mode set as don't want to
@@ -897,12 +906,6 @@ input_parse(struct window_pane *wp)
screen_write_start(sctx, NULL, &wp->base);
ictx->wp = wp;
- buf = EVBUFFER_DATA(evb);
- len = EVBUFFER_LENGTH(evb);
- off = 0;
-
- notify_input(wp, evb);
-
log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id,
ictx->state->name, len, (int)len, buf);
@@ -950,8 +953,6 @@ input_parse(struct window_pane *wp)
/* Close the screen. */
screen_write_stop(sctx);
-
- evbuffer_drain(evb, len);
}
/* Split the parameter list (if any). */
diff --git a/notify.c b/notify.c
index 163aa1a9..8bd8f98f 100644
--- a/notify.c
+++ b/notify.c
@@ -198,13 +198,13 @@ notify_hook(struct cmdq_item *item, const char *name)
}
void
-notify_input(struct window_pane *wp, struct evbuffer *input)
+notify_input(struct window_pane *wp, const u_char *buf, size_t len)
{
struct client *c;
TAILQ_FOREACH(c, &clients, entry) {
if (c->flags & CLIENT_CONTROL)
- control_notify_input(c, wp, input);
+ control_notify_input(c, wp, buf, len);
}
}
diff --git a/server-client.c b/server-client.c
index b6d450a0..9ff86671 100644
--- a/server-client.c
+++ b/server-client.c
@@ -984,7 +984,7 @@ server_client_assume_paste(struct session *s)
* 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
+static enum cmd_retval
server_client_key_callback(struct cmdq_item *item, void *data)
{
struct client *c = item->client;
@@ -1204,6 +1204,44 @@ out:
return (CMD_RETURN_NORMAL);
}
+/* Handle a key event. */
+int
+server_client_handle_key(struct client *c, struct key_event *event)
+{
+ struct session *s = c->session;
+ struct window *w;
+ struct window_pane *wp = NULL;
+ struct cmdq_item *item;
+
+ /* Check the client is good to accept input. */
+ if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
+ return (0);
+ w = s->curw->window;
+
+ /*
+ * Key presses in identify mode are a special case. The queue might be
+ * blocked so they need to be processed immediately rather than queued.
+ */
+ if (c->flags & CLIENT_IDENTIFY) {
+ if (c->flags & CLIENT_READONLY)
+ return (0);
+ if (event->key >= '0' && event->key <= '9') {
+ window_unzoom(w);
+ wp = window_pane_at_index(w, event->key - '0');
+ }
+ server_client_clear_identify(c, wp);
+ return (0);
+ }
+
+ /*
+ * Add the key to the queue so it happens after any commands queued by
+ * previous keys.
+ */
+ item = cmdq_get_callback(server_client_key_callback, event);
+ cmdq_append(c, item);
+ return (1);
+}
+
/* Client functions that need to happen every loop. */
void
server_client_loop(void)
diff --git a/tmux.h b/tmux.h
index e8305d93..bbdd40f7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1701,7 +1701,7 @@ char *format_trim_right(const char *, u_int);
/* notify.c */
void notify_hook(struct cmdq_item *, const char *);
-void notify_input(struct window_pane *, struct evbuffer *);
+void notify_input(struct window_pane *, const u_char *, size_t);
void notify_client(const char *, struct client *);
void notify_session(const char *, struct session *);
void notify_winlink(const char *, struct winlink *);
@@ -2014,7 +2014,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 *);
-enum cmd_retval server_client_key_callback(struct cmdq_item *, void *);
+int server_client_handle_key(struct client *, struct key_event *);
struct client *server_client_create(int);
int server_client_open(struct client *, char **);
void server_client_unref(struct client *);
@@ -2089,6 +2089,7 @@ void input_free(struct window_pane *);
void input_reset(struct window_pane *, int);
struct evbuffer *input_pending(struct window_pane *);
void input_parse(struct window_pane *);
+void input_parse_buffer(struct window_pane *, u_char *, size_t);
/* input-key.c */
void input_key(struct window_pane *, key_code, struct mouse_event *);
@@ -2430,7 +2431,7 @@ void control_write_buffer(struct client *, struct evbuffer *);
/* control-notify.c */
void control_notify_input(struct client *, struct window_pane *,
- struct evbuffer *);
+ const u_char *, size_t);
void control_notify_pane_mode_changed(int);
void control_notify_window_layout_changed(struct window *);
void control_notify_window_pane_changed(struct window *);
diff --git a/tty-keys.c b/tty-keys.c
index 90f34877..3ab7f184 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -573,7 +573,6 @@ tty_keys_next(struct tty *tty)
cc_t bspace;
int delay, expired = 0, n;
key_code key;
- struct cmdq_item *item;
struct mouse_event m = { 0 };
struct key_event *event;
@@ -732,9 +731,8 @@ complete_key:
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);
+ if (!server_client_handle_key(c, event))
+ free(event);
}
return (1);
diff --git a/window.c b/window.c
index e4cc51d3..1b30c793 100644
--- a/window.c
+++ b/window.c
@@ -1478,6 +1478,9 @@ window_pane_input_callback(struct client *c, int closed, void *data)
{
struct window_pane_input_data *cdata = data;
struct window_pane *wp;
+ struct evbuffer *evb = c->stdin_data;
+ u_char *buf = EVBUFFER_DATA(evb);
+ size_t len = EVBUFFER_LENGTH(evb);
wp = window_pane_find_by_id(cdata->wp);
if (wp == NULL || closed || c->flags & CLIENT_DEAD) {
@@ -1490,9 +1493,8 @@ window_pane_input_callback(struct client *c, int closed, void *data)
return;
}
- if (evbuffer_add_buffer(wp->event->input, c->stdin_data) != 0)
- evbuffer_drain(c->stdin_data, EVBUFFER_LENGTH(c->stdin_data));
- input_parse(wp);
+ input_parse_buffer(wp, buf, len);
+ evbuffer_drain(evb, len);
}
int