aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/aucmd.c48
-rw-r--r--src/nvim/aucmd.h9
-rw-r--r--src/nvim/edit.c11
-rw-r--r--src/nvim/ex_getln.c8
-rw-r--r--src/nvim/keymap.c2
-rw-r--r--src/nvim/keymap.h2
-rw-r--r--src/nvim/normal.c14
-rw-r--r--src/nvim/state.c5
-rw-r--r--src/nvim/terminal.c8
-rw-r--r--src/nvim/tui/input.c13
10 files changed, 66 insertions, 54 deletions
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;
+}
+
diff --git a/src/nvim/aucmd.h b/src/nvim/aucmd.h
new file mode 100644
index 0000000000..6570ba7a92
--- /dev/null
+++ b/src/nvim/aucmd.h
@@ -0,0 +1,9 @@
+#ifndef NVIM_AUCMD_H
+#define NVIM_AUCMD_H
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "aucmd.h.generated.h"
+#endif
+
+#endif // NVIM_AUCMD_H
+
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 17f0b8ef82..2bafb77fef 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -974,14 +974,6 @@ static int insert_handle_key(InsertState *s)
multiqueue_process_events(main_loop.events);
break;
- case K_FOCUSGAINED: // Neovim has been given focus
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
- break;
-
- case K_FOCUSLOST: // Neovim has lost focus
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
- break;
-
case K_HOME: // <Home>
case K_KHOME:
case K_S_HOME:
@@ -3167,8 +3159,7 @@ static bool ins_compl_prep(int c)
/* Ignore end of Select mode mapping and mouse scroll buttons. */
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
- || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
- || c == K_FOCUSGAINED || c == K_FOCUSLOST) {
+ || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT) {
return retval;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 5e216925df..fd7ad7a4b5 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1620,14 +1620,6 @@ static int command_line_handle_key(CommandLineState *s)
}
return command_line_not_changed(s);
- case K_FOCUSGAINED: // Neovim has been given focus
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
- return command_line_not_changed(s);
-
- case K_FOCUSLOST: // Neovim has lost focus
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
- return command_line_not_changed(s);
-
default:
// Normal character with no special meaning. Just set mod_mask
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 3d7ebb6382..cfe038693a 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -286,8 +286,6 @@ static struct key_name_entry {
{K_SNR, (char_u *)"SNR"},
{K_PLUG, (char_u *)"Plug"},
{K_PASTE, (char_u *)"Paste"},
- {K_FOCUSGAINED, (char_u *)"FocusGained"},
- {K_FOCUSLOST, (char_u *)"FocusLost"},
{0, NULL}
};
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index b8fed77a90..ee64854c98 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -428,8 +428,6 @@ enum key_extra {
#define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
#define K_DROP TERMCAP2KEY(KS_EXTRA, KE_DROP)
-#define K_FOCUSGAINED TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
-#define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index f9017164af..6415bec846 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -345,8 +345,6 @@ static const struct nv_cmd {
{ K_F8, farsi_f8, 0, 0 },
{ K_F9, farsi_f9, 0, 0 },
{ K_EVENT, nv_event, NV_KEEPREG, 0 },
- { K_FOCUSGAINED, nv_focusgained, NV_KEEPREG, 0 },
- { K_FOCUSLOST, nv_focuslost, NV_KEEPREG, 0 },
};
/* Number of commands in nv_cmds[]. */
@@ -7961,18 +7959,6 @@ static void nv_event(cmdarg_T *cap)
finish_op = false;
}
-/// Trigger FocusGained event.
-static void nv_focusgained(cmdarg_T *cap)
-{
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
-}
-
-/// Trigger FocusLost event.
-static void nv_focuslost(cmdarg_T *cap)
-{
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
-}
-
/*
* Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
*/
diff --git a/src/nvim/state.c b/src/nvim/state.c
index eb0b590a9b..24248ec66c 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -26,10 +26,11 @@ void state_enter(VimState *s)
int check_result = s->check ? s->check(s) : 1;
if (!check_result) {
- break;
+ break; // Terminate this state.
} else if (check_result == -1) {
- continue;
+ continue; // check() again.
}
+ // Execute this state.
int key;
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index deec930ebd..1c764d302d 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -432,14 +432,6 @@ static int terminal_execute(VimState *state, int key)
TerminalState *s = (TerminalState *)state;
switch (key) {
- case K_FOCUSGAINED: // nvim has been given focus
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
- break;
-
- case K_FOCUSLOST: // nvim has lost focus
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
- break;
-
// Temporary fix until paste events gets implemented
case K_PASTE:
break;
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 03587d68f0..8bb5971bd4 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -8,6 +8,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/main.h"
+#include "nvim/aucmd.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
#include "nvim/event/rstream.h"
@@ -280,9 +281,9 @@ static void timer_cb(TimeWatcher *watcher, void *data)
/// Handle focus events.
///
-/// If the upcoming sequence of bytes in the input stream matches either the
-/// escape code for focus gained `<ESC>[I` or focus lost `<ESC>[O` then consume
-/// that sequence and push the appropriate event into the input queue
+/// If the upcoming sequence of bytes in the input stream matches the termcode
+/// for "focus gained" or "focus lost", consume that sequence and schedule an
+/// event on the main loop.
///
/// @param input the input stream
/// @return true iff handle_focus_event consumed some input
@@ -294,11 +295,7 @@ static bool handle_focus_event(TermInput *input)
// Advance past the sequence
bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';
rbuffer_consumed(input->read_stream.buffer, 3);
- if (focus_gained) {
- enqueue_input(input, FOCUSGAINED_KEY, sizeof(FOCUSGAINED_KEY) - 1);
- } else {
- enqueue_input(input, FOCUSLOST_KEY, sizeof(FOCUSLOST_KEY) - 1);
- }
+ aucmd_schedule_focusgained(focus_gained);
return true;
}
return false;