aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2019-09-07 13:00:51 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2019-09-08 15:24:14 +0200
commit19993bca4afaade5d0fbaf132ff66064370bacb0 (patch)
tree6d81b8d88d70e83cd02b1ab2079d6415f973ae2a /src
parentbf9ff5148a57c64c26dd3786a4028418a6047e4a (diff)
downloadrneovim-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.c37
-rw-r--r--src/nvim/msgpack_rpc/channel.c13
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).