diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2019-09-07 13:00:51 +0200 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2019-09-08 15:24:14 +0200 |
commit | 19993bca4afaade5d0fbaf132ff66064370bacb0 (patch) | |
tree | 6d81b8d88d70e83cd02b1ab2079d6415f973ae2a /src | |
parent | bf9ff5148a57c64c26dd3786a4028418a6047e4a (diff) | |
download | rneovim-19993bca4afaade5d0fbaf132ff66064370bacb0.tar.gz rneovim-19993bca4afaade5d0fbaf132ff66064370bacb0.tar.bz2 rneovim-19993bca4afaade5d0fbaf132ff66064370bacb0.zip |
rpc: allow handling of nvim_ui_try_resize at the pager
This makes external UI behave consistenly with TUI w.r.t resizes.
Which will be needed anyway as TUI will use the external UI protocol
soon.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/event/multiqueue.c | 37 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/channel.c | 13 |
2 files changed, 48 insertions, 2 deletions
diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index ef9f3f1870..a1b75f66a5 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -78,6 +78,13 @@ struct multiqueue { size_t size; }; +typedef struct { + Event event; + bool fired; + int refcount; +} SplitEvent; + + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/multiqueue.c.generated.h" #endif @@ -245,3 +252,33 @@ static MultiQueueItem *multiqueue_node_data(QUEUE *q) { return QUEUE_DATA(q, MultiQueueItem, node); } + +/// Allow an event to be processed by multiple child queues to the main queue +/// +/// The handler will be fired once by the _first_ queue that processes the +/// event. Later processing will do nothing (just memory cleanup). +/// +/// @param ev the event +/// @param num number of queues that the split event will be put on +/// @return an Event that is safe to put onto `num` queues +Event event_split(Event ev, int num) +{ + SplitEvent *data = xmalloc(sizeof(*data)); + data->event = ev; + data->fired = false; + data->refcount = num; + return event_create(split_event, 1, data); +} +static void split_event(void ** argv) +{ + SplitEvent *data = argv[0]; + if (!data->fired) { + data->fired = true; + if (data->event.handler) { + data->event.handler(data->event.argv); + } + } + if ((--data->refcount) == 0) { + xfree(data); + } +} diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 81c9f1e3f4..19f626c63b 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -31,6 +31,7 @@ #include "nvim/misc1.h" #include "nvim/lib/kvec.h" #include "nvim/os/input.h" +#include "nvim/ui.h" #if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL #define log_client_msg(...) @@ -355,11 +356,19 @@ static void handle_request(Channel *channel, msgpack_object *request) request_event((void **)&evdata); } } else { - multiqueue_put(channel->events, request_event, 1, evdata); - DLOG("RPC: scheduled %.*s", method->via.bin.size, method->via.bin.ptr); + bool is_resize = handler.fn == handle_nvim_ui_try_resize; + if (is_resize) { + Event ev = event_split(event_create(request_event, 1, evdata), 2); + multiqueue_put_event(channel->events, ev); + multiqueue_put_event(resize_events, ev); + } else { + multiqueue_put(channel->events, request_event, 1, evdata); + DLOG("RPC: scheduled %.*s", method->via.bin.size, method->via.bin.ptr); + } } } + /// Handles a message, depending on the type: /// - Request: invokes method and writes the response (or error). /// - Notification: invokes method (emits `nvim_error_event` on error). |