From 3f5af6c1c4815c5fb2a492292212b244abe23759 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 24 Jul 2015 10:38:35 -0300 Subject: loop: Simplify loop.c and move some code to input.c - Declare poll timer in Loop structure instead of a loop_poll_events local variable. - Move deferred event management to input.c --- src/nvim/terminal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/nvim/terminal.c') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 47fef692db..0285ce72d4 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -69,6 +69,7 @@ #include "nvim/fileio.h" #include "nvim/event/loop.h" #include "nvim/event/time.h" +#include "nvim/os/input.h" #include "nvim/api/private/helpers.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -354,13 +355,13 @@ void terminal_enter(bool process_deferred) while (term->buf == curbuf) { if (process_deferred) { - loop_enable_deferred_events(&loop); + input_enable_events(); } c = safe_vgetc(); if (process_deferred) { - loop_disable_deferred_events(&loop); + input_disable_events(); } switch (c) { -- cgit From bef0c03b250b1cb671ad8f130228e6b4a7ae74d3 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 24 Jul 2015 12:14:31 -0300 Subject: terminal: Ensure terminal buffers are flushed on exit When a terminal closed, make sure it is refreshed before the Terminal structure is freed. Also extract `refresh_terminal` from `on_refresh`. --- src/nvim/terminal.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'src/nvim/terminal.c') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 0285ce72d4..cf68143ac7 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -428,7 +428,13 @@ void terminal_destroy(Terminal *term) term->buf->terminal = NULL; } term->buf = NULL; - pmap_del(ptr_t)(invalidated_terminals, term); + if (pmap_has(ptr_t)(invalidated_terminals, term)) { + // flush any pending changes to the buffer + block_autocmds(); + refresh_terminal(term); + unblock_autocmds(); + pmap_del(ptr_t)(invalidated_terminals, term); + } for (size_t i = 0 ; i < term->sb_current; i++) { xfree(term->sb_buffer[i]); } @@ -884,6 +890,26 @@ static void invalidate_terminal(Terminal *term, int start_row, int end_row) } } +static void refresh_terminal(Terminal *term) +{ + // TODO(SplinterOfChaos): Find the condition that makes term->buf invalid. + bool valid = true; + if (!term->buf || !(valid = buf_valid(term->buf))) { + // destroyed by `close_buffer`. Dont do anything else + if (!valid) { + term->buf = NULL; + } + return; + } + bool pending_resize = term->pending_resize; + WITH_BUFFER(term->buf, { + refresh_size(term); + refresh_scrollback(term); + refresh_screen(term); + redraw_buf_later(term->buf, NOT_VALID); + }); + adjust_topline(term, pending_resize); +} // libuv timer callback. This will enqueue on_refresh to be processed as an // event. static void refresh_timer_cb(TimeWatcher *watcher, void *data) @@ -905,23 +931,7 @@ static void on_refresh(Event event) // don't process autocommands while updating terminal buffers block_autocmds(); map_foreach(invalidated_terminals, term, stub, { - // TODO(SplinterOfChaos): Find the condition that makes term->buf invalid. - bool valid = true; - if (!term->buf || !(valid = buf_valid(term->buf))) { - // destroyed by `close_buffer`. Dont do anything else - if (!valid) { - term->buf = NULL; - } - continue; - } - bool pending_resize = term->pending_resize; - WITH_BUFFER(term->buf, { - refresh_size(term); - refresh_scrollback(term); - refresh_screen(term); - redraw_buf_later(term->buf, NOT_VALID); - }); - adjust_topline(term, pending_resize); + refresh_terminal(term); }); pmap_clear(ptr_t)(invalidated_terminals); unblock_autocmds(); -- cgit From 502aee690c980fcb3cfcb3f211dcfad06103db46 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 7 Aug 2015 22:54:02 -0300 Subject: event: Refactor async event processing - Improve the implementation of deferred/immediate events. - Use the new queue module to change how/when events are queued/processed by giving a private queue to each emitter. - Immediate events(which only exist to break uv_run recursion) are now represented in the `loop->fast_events` queue. - Events pushed to child queues are propagated to the event loop main queue and processed as K_EVENT keys. --- src/nvim/terminal.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'src/nvim/terminal.c') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index cf68143ac7..b9bc4c6d78 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -325,7 +325,7 @@ void terminal_resize(Terminal *term, uint16_t width, uint16_t height) invalidate_terminal(term, -1, -1); } -void terminal_enter(bool process_deferred) +void terminal_enter(void) { Terminal *term = curbuf->terminal; assert(term && "should only be called when curbuf has a terminal"); @@ -354,15 +354,9 @@ void terminal_enter(bool process_deferred) bool got_bs = false; // True if the last input was while (term->buf == curbuf) { - if (process_deferred) { - input_enable_events(); - } - + input_enable_events(); c = safe_vgetc(); - - if (process_deferred) { - input_disable_events(); - } + input_disable_events(); switch (c) { case K_LEFTMOUSE: @@ -382,7 +376,7 @@ void terminal_enter(bool process_deferred) break; case K_EVENT: - loop_process_event(&loop); + queue_process_events(loop.events); break; case Ctrl_N: @@ -913,18 +907,11 @@ static void refresh_terminal(Terminal *term) // libuv timer callback. This will enqueue on_refresh to be processed as an // event. static void refresh_timer_cb(TimeWatcher *watcher, void *data) -{ - loop_push_event(&loop, (Event) {.handler = on_refresh}, false); - refresh_pending = false; -} - -// Refresh all invalidated terminals -static void on_refresh(Event event) { if (exiting) { // bad things can happen if we redraw when exiting, and there's no need to // update the buffer. - return; + goto end; } Terminal *term; void *stub; (void)(stub); @@ -936,6 +923,8 @@ static void on_refresh(Event event) pmap_clear(ptr_t)(invalidated_terminals); unblock_autocmds(); redraw(true); +end: + refresh_pending = false; } static void refresh_size(Terminal *term) -- cgit