mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-03 17:24:29 +00:00 
			
		
		
		
	tui.c: request focus-reporting (fix regression) #7670
ref #7649 ref #766427f9b1c7b0caused a regression: it uses loop_schedule_deferred() to defer emitting the "enable focus reporting" termcode. tui_main() never processes `tui_loop.events` (which loop_schedule_deferred() depends on), so the event was never actually processed. But fixing that (by processing `tui_loop.events`) would bring back the problem27f9b1c7b0tried to fix: it still emits the event too soon. Instead, do a little dance: schedule the event on `main_loop` and then forward it to `tui_loop`. NOTE: after this commit, in tmux 2.3 with `focus-events` enabled, FocusGained is fired on startup and when resuming from suspend. Using `script` to record the terminal session (and `vterm-dump` to post-process the result): BEFORE: {DECSM 1049}{DECSM 1}{ESC =} {CUP *}{ED *}{DECSM 2004}{DECSM 1004}{CSI 1,43 r} {CUP 1,1} {CUP *}{ED *}{SM 34}{DECSM 25} {DECRM 25}{CSI 2 q}{CSI 2 q} {CUP *}{ED *}{LF} {SGR *}{LS1}{SGR 94}~ ... AFTER: {CUP *}{ED *}{CSI 1,43 r} {CUP 1,1} {CUP *}{ED *}{SM 34}{DECSM 25} {DECRM 25}{CSI 2 q}{CSI 2 q} {CUP *}{ED *}{DECSM 2004}{DECSM 1004}{LF} {SGR *}{LS1}{SGR 94}~ ...
This commit is contained in:
		@@ -19,12 +19,11 @@ typedef struct loop {
 | 
			
		||||
  MultiQueue *events;
 | 
			
		||||
  MultiQueue *thread_events;
 | 
			
		||||
  // Immediate events:
 | 
			
		||||
  //    "Events that should be processed after exiting uv_run() (to avoid
 | 
			
		||||
  //    recursion), but before returning from loop_poll_events()."
 | 
			
		||||
  //    502aee690c980fcb3cfcb3f211dcfad06103db46
 | 
			
		||||
  // Practical consequence: these events are processed by
 | 
			
		||||
  //    "Processed after exiting uv_run() (to avoid recursion), but before
 | 
			
		||||
  //    returning from loop_poll_events()." 502aee690c98
 | 
			
		||||
  // Practical consequence (for main_loop): these events are processed by
 | 
			
		||||
  //    state_enter()..os_inchar()
 | 
			
		||||
  // whereas "regular" (main_loop.events) events are processed by
 | 
			
		||||
  // whereas "regular" events (main_loop.events) are processed by
 | 
			
		||||
  //    state_enter()..VimState.execute()
 | 
			
		||||
  // But state_enter()..os_inchar() can be "too early" if you want the event
 | 
			
		||||
  // to trigger UI updates and other user-activity-related side-effects.
 | 
			
		||||
 
 | 
			
		||||
@@ -169,10 +169,16 @@ static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index,
 | 
			
		||||
 | 
			
		||||
/// Emits some termcodes after Nvim startup, which were observed to slowdown
 | 
			
		||||
/// rendering during startup in tmux 2.3 (+focus-events). #7649
 | 
			
		||||
static void terminfo_start_event(void **argv)
 | 
			
		||||
static void terminfo_after_startup_event(void **argv)
 | 
			
		||||
{
 | 
			
		||||
  UI *ui = argv[0];
 | 
			
		||||
  bool defer = argv[1] != NULL;  // clever(?) boolean without malloc() dance.
 | 
			
		||||
  TUIData *data = ui->data;
 | 
			
		||||
  if (defer) {  // We're on the main-loop. Now forward to the TUI loop.
 | 
			
		||||
    loop_schedule(data->loop,
 | 
			
		||||
                  event_create(terminfo_after_startup_event, 2, ui, NULL));
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // Enable bracketed paste
 | 
			
		||||
  unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
 | 
			
		||||
  // Enable focus reporting
 | 
			
		||||
@@ -268,6 +274,9 @@ static void terminfo_start(UI *ui)
 | 
			
		||||
    uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0);
 | 
			
		||||
    uv_pipe_open(&data->output_handle.pipe, data->out_fd);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  loop_schedule(&main_loop,
 | 
			
		||||
                event_create(terminfo_after_startup_event, 2, ui, ui));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void terminfo_stop(UI *ui)
 | 
			
		||||
@@ -304,8 +313,6 @@ static void tui_terminal_start(UI *ui)
 | 
			
		||||
  update_size(ui);
 | 
			
		||||
  signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
 | 
			
		||||
  term_input_start(&data->input);
 | 
			
		||||
  loop_schedule_deferred(data->loop,
 | 
			
		||||
                         event_create(terminfo_start_event, 1, ui));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tui_terminal_stop(UI *ui)
 | 
			
		||||
@@ -352,7 +359,7 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
 | 
			
		||||
  CONTINUE(bridge);
 | 
			
		||||
 | 
			
		||||
  while (!data->stop) {
 | 
			
		||||
    loop_poll_events(&tui_loop, -1);
 | 
			
		||||
    loop_poll_events(&tui_loop, -1);  // tui_loop.events is never processed
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ui_bridge_stopped(bridge);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user