diff options
author | Thomas Adam <thomas@xteddy.org> | 2019-05-07 13:02:27 +0100 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2019-05-07 13:02:27 +0100 |
commit | d9767b81123cc8913c63c42cc754cccbf34ccb6c (patch) | |
tree | 94e0a8cdb822db6145080c02907ad626c0d0fa89 | |
parent | eac30a86d78879f2dec802b0d246eba0afa79b3e (diff) | |
parent | 85a9c2f52b8855560fa9fdaa033d1c7bca738429 (diff) | |
download | rtmux-d9767b81123cc8913c63c42cc754cccbf34ccb6c.tar.gz rtmux-d9767b81123cc8913c63c42cc754cccbf34ccb6c.tar.bz2 rtmux-d9767b81123cc8913c63c42cc754cccbf34ccb6c.zip |
Merge branch 'obsd-master'
-rw-r--r-- | cmd-copy-mode.c | 8 | ||||
-rw-r--r-- | control-notify.c | 7 | ||||
-rw-r--r-- | input.c | 25 | ||||
-rw-r--r-- | notify.c | 4 | ||||
-rw-r--r-- | server-client.c | 40 | ||||
-rw-r--r-- | tmux.h | 7 | ||||
-rw-r--r-- | tty-keys.c | 6 | ||||
-rw-r--r-- | window.c | 8 |
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. @@ -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). */ @@ -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) @@ -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 *); @@ -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); @@ -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 |