mirror of
https://github.com/neovim/neovim.git
synced 2025-09-15 07:48:18 +00:00
eventloop: FocusGained: schedule event instead of pseudokey
closes #4840 closes #6164
This commit is contained in:
48
src/nvim/aucmd.c
Normal file
48
src/nvim/aucmd.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
9
src/nvim/aucmd.h
Normal file
9
src/nvim/aucmd.h
Normal file
@@ -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
|
||||||
|
|
@@ -974,14 +974,6 @@ static int insert_handle_key(InsertState *s)
|
|||||||
multiqueue_process_events(main_loop.events);
|
multiqueue_process_events(main_loop.events);
|
||||||
break;
|
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_HOME: // <Home>
|
||||||
case K_KHOME:
|
case K_KHOME:
|
||||||
case K_S_HOME:
|
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. */
|
/* Ignore end of Select mode mapping and mouse scroll buttons. */
|
||||||
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
|
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
|
||||||
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
|
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT) {
|
||||||
|| c == K_FOCUSGAINED || c == K_FOCUSLOST) {
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1620,14 +1620,6 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
}
|
}
|
||||||
return command_line_not_changed(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:
|
default:
|
||||||
// Normal character with no special meaning. Just set mod_mask
|
// Normal character with no special meaning. Just set mod_mask
|
||||||
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
|
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
|
||||||
|
@@ -286,8 +286,6 @@ static struct key_name_entry {
|
|||||||
{K_SNR, (char_u *)"SNR"},
|
{K_SNR, (char_u *)"SNR"},
|
||||||
{K_PLUG, (char_u *)"Plug"},
|
{K_PLUG, (char_u *)"Plug"},
|
||||||
{K_PASTE, (char_u *)"Paste"},
|
{K_PASTE, (char_u *)"Paste"},
|
||||||
{K_FOCUSGAINED, (char_u *)"FocusGained"},
|
|
||||||
{K_FOCUSLOST, (char_u *)"FocusLost"},
|
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -428,8 +428,6 @@ enum key_extra {
|
|||||||
#define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
|
#define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
|
||||||
|
|
||||||
#define K_DROP TERMCAP2KEY(KS_EXTRA, KE_DROP)
|
#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_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
|
||||||
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
|
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
|
||||||
|
@@ -345,8 +345,6 @@ static const struct nv_cmd {
|
|||||||
{ K_F8, farsi_f8, 0, 0 },
|
{ K_F8, farsi_f8, 0, 0 },
|
||||||
{ K_F9, farsi_f9, 0, 0 },
|
{ K_F9, farsi_f9, 0, 0 },
|
||||||
{ K_EVENT, nv_event, NV_KEEPREG, 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[]. */
|
/* Number of commands in nv_cmds[]. */
|
||||||
@@ -7961,18 +7959,6 @@ static void nv_event(cmdarg_T *cap)
|
|||||||
finish_op = false;
|
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".
|
* Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
|
||||||
*/
|
*/
|
||||||
|
@@ -26,10 +26,11 @@ void state_enter(VimState *s)
|
|||||||
int check_result = s->check ? s->check(s) : 1;
|
int check_result = s->check ? s->check(s) : 1;
|
||||||
|
|
||||||
if (!check_result) {
|
if (!check_result) {
|
||||||
break;
|
break; // Terminate this state.
|
||||||
} else if (check_result == -1) {
|
} else if (check_result == -1) {
|
||||||
continue;
|
continue; // check() again.
|
||||||
}
|
}
|
||||||
|
// Execute this state.
|
||||||
|
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
|
@@ -432,14 +432,6 @@ static int terminal_execute(VimState *state, int key)
|
|||||||
TerminalState *s = (TerminalState *)state;
|
TerminalState *s = (TerminalState *)state;
|
||||||
|
|
||||||
switch (key) {
|
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
|
// Temporary fix until paste events gets implemented
|
||||||
case K_PASTE:
|
case K_PASTE:
|
||||||
break;
|
break;
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/main.h"
|
#include "nvim/main.h"
|
||||||
|
#include "nvim/aucmd.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/event/rstream.h"
|
#include "nvim/event/rstream.h"
|
||||||
@@ -280,9 +281,9 @@ static void timer_cb(TimeWatcher *watcher, void *data)
|
|||||||
|
|
||||||
/// Handle focus events.
|
/// Handle focus events.
|
||||||
///
|
///
|
||||||
/// If the upcoming sequence of bytes in the input stream matches either the
|
/// If the upcoming sequence of bytes in the input stream matches the termcode
|
||||||
/// escape code for focus gained `<ESC>[I` or focus lost `<ESC>[O` then consume
|
/// for "focus gained" or "focus lost", consume that sequence and schedule an
|
||||||
/// that sequence and push the appropriate event into the input queue
|
/// event on the main loop.
|
||||||
///
|
///
|
||||||
/// @param input the input stream
|
/// @param input the input stream
|
||||||
/// @return true iff handle_focus_event consumed some input
|
/// @return true iff handle_focus_event consumed some input
|
||||||
@@ -294,11 +295,7 @@ static bool handle_focus_event(TermInput *input)
|
|||||||
// Advance past the sequence
|
// Advance past the sequence
|
||||||
bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';
|
bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';
|
||||||
rbuffer_consumed(input->read_stream.buffer, 3);
|
rbuffer_consumed(input->read_stream.buffer, 3);
|
||||||
if (focus_gained) {
|
aucmd_schedule_focusgained(focus_gained);
|
||||||
enqueue_input(input, FOCUSGAINED_KEY, sizeof(FOCUSGAINED_KEY) - 1);
|
|
||||||
} else {
|
|
||||||
enqueue_input(input, FOCUSLOST_KEY, sizeof(FOCUSLOST_KEY) - 1);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
Reference in New Issue
Block a user