From b6b6e4a96f37ba6a54d194ecbc042d5ef7d595e6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 28 Aug 2017 01:27:57 +0200 Subject: eventloop: FocusGained: schedule event instead of pseudokey closes #4840 closes #6164 --- src/nvim/aucmd.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/nvim/aucmd.c (limited to 'src/nvim/aucmd.c') diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c new file mode 100644 index 0000000000..8b86d89bf2 --- /dev/null +++ b/src/nvim/aucmd.c @@ -0,0 +1,48 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +#include "nvim/os/os.h" +#include "nvim/fileio.h" +#include "nvim/vim.h" +#include "nvim/main.h" +#include "nvim/screen.h" +#include "nvim/ui.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "aucmd.c.generated.h" +#endif + +static void focusgained_event(void **argv) +{ + bool *gained = argv[0]; + do_autocmd_focusgained(*gained); + xfree(gained); +} +void aucmd_schedule_focusgained(bool gained) +{ + bool *gainedp = xmalloc(sizeof(*gainedp)); + *gainedp = gained; + loop_schedule(&main_loop, event_create(focusgained_event, 1, gainedp)); +} + +static void do_autocmd_focusgained(bool gained) + FUNC_ATTR_NONNULL_ALL +{ + static bool recursive = false; + + if (recursive) { + return; // disallow recursion + } + recursive = true; + bool has_any = has_event(EVENT_FOCUSGAINED) || has_event(EVENT_FOCUSLOST); + bool did_any = apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST), + NULL, NULL, false, curbuf); + if (has_any && !did_any) { + // HACK: Reschedule, hoping that the next event-loop tick will pick this up + // during a "regular" state (as opposed to a weird implicit state, e.g. + // early_init()..win_alloc_first() which disables autocommands). + aucmd_schedule_focusgained(gained); + } + recursive = false; +} + -- cgit From d30abd8857a41f439de01f8c0e6d1075acf124d9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 2 Sep 2017 11:35:14 +0200 Subject: eventloop: FocusGained: schedule the schedule main_loop.fast_events does not manifest as K_EVENT, because it is processed at a different stage than main_loop.events. In order to queue into main_loop.events, we need to go through the threadsafe loop_schedule(), which queues into main_loop.thread_events and eventually main_loop.fast_events. _Then_ it is safe to directly queue into main_loop.events. This makes it more likely that the event is treated as K_EVENT. --- src/nvim/aucmd.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/nvim/aucmd.c') diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c index 8b86d89bf2..a69881431e 100644 --- a/src/nvim/aucmd.c +++ b/src/nvim/aucmd.c @@ -14,15 +14,20 @@ static void focusgained_event(void **argv) { - bool *gained = argv[0]; - do_autocmd_focusgained(*gained); - xfree(gained); + bool *gainedp = argv[0]; + do_autocmd_focusgained(*gainedp); + xfree(gainedp); +} +static void schedule_event(void **argv) +{ + bool *gainedp = argv[0]; + multiqueue_put(main_loop.events, focusgained_event, 1, gainedp); } void aucmd_schedule_focusgained(bool gained) { bool *gainedp = xmalloc(sizeof(*gainedp)); *gainedp = gained; - loop_schedule(&main_loop, event_create(focusgained_event, 1, gainedp)); + loop_schedule(&main_loop, event_create(schedule_event, 1, gainedp)); } static void do_autocmd_focusgained(bool gained) @@ -34,15 +39,8 @@ static void do_autocmd_focusgained(bool gained) return; // disallow recursion } recursive = true; - bool has_any = has_event(EVENT_FOCUSGAINED) || has_event(EVENT_FOCUSLOST); - bool did_any = apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST), - NULL, NULL, false, curbuf); - if (has_any && !did_any) { - // HACK: Reschedule, hoping that the next event-loop tick will pick this up - // during a "regular" state (as opposed to a weird implicit state, e.g. - // early_init()..win_alloc_first() which disables autocommands). - aucmd_schedule_focusgained(gained); - } + apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST), + NULL, NULL, false, curbuf); recursive = false; } -- cgit From c00a33ed19c1372bf5880e2f32adf37c9bea165b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 3 Sep 2017 14:31:38 +0200 Subject: eventloop: loop_schedule_deferred() Generalize the "schedule schedule" technique. --- src/nvim/aucmd.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/nvim/aucmd.c') diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c index a69881431e..fc421116ea 100644 --- a/src/nvim/aucmd.c +++ b/src/nvim/aucmd.c @@ -5,7 +5,6 @@ #include "nvim/fileio.h" #include "nvim/vim.h" #include "nvim/main.h" -#include "nvim/screen.h" #include "nvim/ui.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -18,16 +17,12 @@ static void focusgained_event(void **argv) do_autocmd_focusgained(*gainedp); xfree(gainedp); } -static void schedule_event(void **argv) -{ - bool *gainedp = argv[0]; - multiqueue_put(main_loop.events, focusgained_event, 1, gainedp); -} void aucmd_schedule_focusgained(bool gained) { bool *gainedp = xmalloc(sizeof(*gainedp)); *gainedp = gained; - loop_schedule(&main_loop, event_create(schedule_event, 1, gainedp)); + loop_schedule_deferred(&main_loop, + event_create(focusgained_event, 1, gainedp)); } static void do_autocmd_focusgained(bool gained) -- cgit