1
0
forked from aniani/vim

patch 8.0.1005: terminal without job updates slowly in GUI

Problem:    Terminal without job updates slowly in GUI.
Solution:   Poll for input when a channel has the keep_open flag.
This commit is contained in:
Bram Moolenaar
2017-08-27 14:50:47 +02:00
parent 8d9f0ef5c6
commit 4ab7968aa9
4 changed files with 98 additions and 100 deletions

View File

@@ -3555,6 +3555,22 @@ channel_handle_events(int only_keep_open)
} }
# endif # endif
# if defined(FEAT_GUI) || defined(PROTO)
/*
* Return TRUE when there is any channel with a keep_open flag.
*/
int
channel_any_keep_open()
{
channel_T *channel;
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
if (channel->ch_keep_open)
return TRUE;
return FALSE;
}
# endif
/* /*
* Set "channel"/"part" to non-blocking. * Set "channel"/"part" to non-blocking.
* Only works for sockets and pipes. * Only works for sockets and pipes.

View File

@@ -789,6 +789,37 @@ property_event(GtkWidget *widget,
#endif /* defined(FEAT_CLIENTSERVER) */ #endif /* defined(FEAT_CLIENTSERVER) */
#if GTK_CHECK_VERSION(3,0,0)
typedef gboolean timeout_cb_type;
#else
typedef gint timeout_cb_type;
#endif
/*
* Start a timer that will invoke the specified callback.
* Returns the ID of the timer.
*/
static guint
timeout_add(int time, timeout_cb_type (*callback)(gpointer), int *flagp)
{
#if GTK_CHECK_VERSION(3,0,0)
return g_timeout_add((guint)time, (GSourceFunc)callback, flagp);
#else
return gtk_timeout_add((guint32)time, (GtkFunction)callback, flagp);
#endif
}
static void
timeout_remove(guint timer)
{
#if GTK_CHECK_VERSION(3,0,0)
g_source_remove(timer);
#else
gtk_timeout_remove(timer);
#endif
}
/**************************************************************************** /****************************************************************************
* Focus handlers: * Focus handlers:
*/ */
@@ -866,11 +897,7 @@ gui_mch_stop_blink(void)
{ {
if (blink_timer) if (blink_timer)
{ {
#if GTK_CHECK_VERSION(3,0,0) timeout_remove(blink_timer);
g_source_remove(blink_timer);
#else
gtk_timeout_remove(blink_timer);
#endif
blink_timer = 0; blink_timer = 0;
} }
if (blink_state == BLINK_OFF) if (blink_state == BLINK_OFF)
@@ -881,36 +908,20 @@ gui_mch_stop_blink(void)
blink_state = BLINK_NONE; blink_state = BLINK_NONE;
} }
#if GTK_CHECK_VERSION(3,0,0) static timeout_cb_type
static gboolean
#else
static gint
#endif
blink_cb(gpointer data UNUSED) blink_cb(gpointer data UNUSED)
{ {
if (blink_state == BLINK_ON) if (blink_state == BLINK_ON)
{ {
gui_undraw_cursor(); gui_undraw_cursor();
blink_state = BLINK_OFF; blink_state = BLINK_OFF;
#if GTK_CHECK_VERSION(3,0,0) blink_timer = timeout_add(blink_offtime, blink_cb, NULL);
blink_timer = g_timeout_add((guint)blink_offtime,
(GSourceFunc) blink_cb, NULL);
#else
blink_timer = gtk_timeout_add((guint32)blink_offtime,
(GtkFunction) blink_cb, NULL);
#endif
} }
else else
{ {
gui_update_cursor(TRUE, FALSE); gui_update_cursor(TRUE, FALSE);
blink_state = BLINK_ON; blink_state = BLINK_ON;
#if GTK_CHECK_VERSION(3,0,0) blink_timer = timeout_add(blink_ontime, blink_cb, NULL);
blink_timer = g_timeout_add((guint)blink_ontime,
(GSourceFunc) blink_cb, NULL);
#else
blink_timer = gtk_timeout_add((guint32)blink_ontime,
(GtkFunction) blink_cb, NULL);
#endif
} }
gui_mch_flush(); gui_mch_flush();
@@ -926,23 +937,13 @@ gui_mch_start_blink(void)
{ {
if (blink_timer) if (blink_timer)
{ {
#if GTK_CHECK_VERSION(3,0,0) timeout_remove(blink_timer);
g_source_remove(blink_timer);
#else
gtk_timeout_remove(blink_timer);
#endif
blink_timer = 0; blink_timer = 0;
} }
/* Only switch blinking on if none of the times is zero */ /* Only switch blinking on if none of the times is zero */
if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
{ {
#if GTK_CHECK_VERSION(3,0,0) blink_timer = timeout_add(blink_waittime, blink_cb, NULL);
blink_timer = g_timeout_add((guint)blink_waittime,
(GSourceFunc) blink_cb, NULL);
#else
blink_timer = gtk_timeout_add((guint32)blink_waittime,
(GtkFunction) blink_cb, NULL);
#endif
blink_state = BLINK_ON; blink_state = BLINK_ON;
gui_update_cursor(TRUE, FALSE); gui_update_cursor(TRUE, FALSE);
gui_mch_flush(); gui_mch_flush();
@@ -1733,7 +1734,6 @@ gui_mch_init_check(void)
return OK; return OK;
} }
/**************************************************************************** /****************************************************************************
* Mouse handling callbacks * Mouse handling callbacks
*/ */
@@ -1745,11 +1745,7 @@ static int mouse_timed_out = TRUE;
/* /*
* Timer used to recognize multiple clicks of the mouse button * Timer used to recognize multiple clicks of the mouse button
*/ */
#if GTK_CHECK_VERSION(3,0,0) static timeout_cb_type
static gboolean
#else
static gint
#endif
mouse_click_timer_cb(gpointer data) mouse_click_timer_cb(gpointer data)
{ {
/* we don't use this information currently */ /* we don't use this information currently */
@@ -1759,13 +1755,9 @@ mouse_click_timer_cb(gpointer data)
return FALSE; /* don't happen again */ return FALSE; /* don't happen again */
} }
static guint motion_repeat_timer = 0; static guint motion_repeat_timer = 0;
static int motion_repeat_offset = FALSE; static int motion_repeat_offset = FALSE;
#ifdef GTK_DEST_DEFAULT_ALL static timeout_cb_type motion_repeat_timer_cb(gpointer);
static gboolean motion_repeat_timer_cb(gpointer);
#else
static gint motion_repeat_timer_cb(gpointer);
#endif
static void static void
process_motion_notify(int x, int y, GdkModifierType state) process_motion_notify(int x, int y, GdkModifierType state)
@@ -1853,13 +1845,8 @@ process_motion_notify(int x, int y, GdkModifierType state)
/* shoot again */ /* shoot again */
if (!motion_repeat_timer) if (!motion_repeat_timer)
#if GTK_CHECK_VERSION(3,0,0) motion_repeat_timer = timeout_add(delay, motion_repeat_timer_cb,
motion_repeat_timer = g_timeout_add((guint)delay, NULL);
motion_repeat_timer_cb, NULL);
#else
motion_repeat_timer = gtk_timeout_add((guint32)delay,
motion_repeat_timer_cb, NULL);
#endif
} }
} }
@@ -1904,11 +1891,7 @@ gui_gtk_window_at_position(GtkWidget *widget,
/* /*
* Timer used to recognize multiple clicks of the mouse button. * Timer used to recognize multiple clicks of the mouse button.
*/ */
#if GTK_CHECK_VERSION(3,0,0) static timeout_cb_type
static gboolean
#else
static gint
#endif
motion_repeat_timer_cb(gpointer data UNUSED) motion_repeat_timer_cb(gpointer data UNUSED)
{ {
int x; int x;
@@ -2019,23 +2002,14 @@ button_press_event(GtkWidget *widget,
/* Handle multiple clicks */ /* Handle multiple clicks */
if (!mouse_timed_out && mouse_click_timer) if (!mouse_timed_out && mouse_click_timer)
{ {
#if GTK_CHECK_VERSION(3,0,0) timeout_remove(mouse_click_timer);
g_source_remove(mouse_click_timer);
#else
gtk_timeout_remove(mouse_click_timer);
#endif
mouse_click_timer = 0; mouse_click_timer = 0;
repeated_click = TRUE; repeated_click = TRUE;
} }
mouse_timed_out = FALSE; mouse_timed_out = FALSE;
#if GTK_CHECK_VERSION(3,0,0) mouse_click_timer = timeout_add(p_mouset, mouse_click_timer_cb,
mouse_click_timer = g_timeout_add((guint)p_mouset, &mouse_timed_out);
mouse_click_timer_cb, &mouse_timed_out);
#else
mouse_click_timer = gtk_timeout_add((guint32)p_mouset,
mouse_click_timer_cb, &mouse_timed_out);
#endif
switch (event->button) switch (event->button)
{ {
@@ -2129,11 +2103,7 @@ button_release_event(GtkWidget *widget UNUSED,
area .*/ area .*/
if (motion_repeat_timer) if (motion_repeat_timer)
{ {
#if GTK_CHECK_VERSION(3,0,0) timeout_remove(motion_repeat_timer);
g_source_remove(motion_repeat_timer);
#else
gtk_timeout_remove(motion_repeat_timer);
#endif
motion_repeat_timer = 0; motion_repeat_timer = 0;
} }
@@ -4578,7 +4548,7 @@ mainwin_destroy_cb(GtkObject *object UNUSED, gpointer data UNUSED)
* scrollbar init.), actually do the standard hints and stop the timer. * scrollbar init.), actually do the standard hints and stop the timer.
* We'll not let the default hints be set while this timer's active. * We'll not let the default hints be set while this timer's active.
*/ */
static gboolean static timeout_cb_type
check_startup_plug_hints(gpointer data UNUSED) check_startup_plug_hints(gpointer data UNUSED)
{ {
if (init_window_hints_state == 1) if (init_window_hints_state == 1)
@@ -4681,7 +4651,7 @@ gui_mch_open(void)
{ {
update_window_manager_hints(pixel_width, pixel_height); update_window_manager_hints(pixel_width, pixel_height);
init_window_hints_state = 1; init_window_hints_state = 1;
g_timeout_add(1000, check_startup_plug_hints, NULL); timeout_add(1000, check_startup_plug_hints, NULL);
} }
} }
@@ -6584,11 +6554,7 @@ gui_mch_update(void)
g_main_context_iteration(NULL, TRUE); g_main_context_iteration(NULL, TRUE);
} }
#if GTK_CHECK_VERSION(3,0,0) static timeout_cb_type
static gboolean
#else
static gint
#endif
input_timer_cb(gpointer data) input_timer_cb(gpointer data)
{ {
int *timed_out = (int *) data; int *timed_out = (int *) data;
@@ -6599,6 +6565,19 @@ input_timer_cb(gpointer data)
return FALSE; /* don't happen again */ return FALSE; /* don't happen again */
} }
#ifdef FEAT_JOB_CHANNEL
static timeout_cb_type
channel_poll_cb(gpointer data UNUSED)
{
/* Using an event handler for a channel that may be disconnected does
* not work, it hangs. Instead poll for messages. */
channel_handle_events(TRUE);
parse_queued_messages();
return TRUE; /* repeat */
}
#endif
/* /*
* GUI input routine called by gui_wait_for_chars(). Waits for a character * GUI input routine called by gui_wait_for_chars(). Waits for a character
* from the keyboard. * from the keyboard.
@@ -6615,20 +6594,26 @@ gui_mch_wait_for_chars(long wtime)
guint timer; guint timer;
static int timed_out; static int timed_out;
int retval = FAIL; int retval = FAIL;
#ifdef FEAT_JOB_CHANNEL
guint channel_timer = 0;
#endif
timed_out = FALSE; timed_out = FALSE;
/* this timeout makes sure that we will return if no characters arrived in /* this timeout makes sure that we will return if no characters arrived in
* time */ * time */
if (wtime > 0) if (wtime > 0)
#if GTK_CHECK_VERSION(3,0,0) timer = timeout_add(wtime, input_timer_cb, &timed_out);
timer = g_timeout_add((guint)wtime, input_timer_cb, &timed_out);
#else
timer = gtk_timeout_add((guint32)wtime, input_timer_cb, &timed_out);
#endif
else else
timer = 0; timer = 0;
#ifdef FEAT_JOB_CHANNEL
/* If there is a channel with the keep_open flag we need to poll for input
* on them. */
if (channel_any_keep_open())
channel_timer = timeout_add(20, channel_poll_cb, NULL);
#endif
focus = gui.in_focus; focus = gui.in_focus;
do do
@@ -6643,12 +6628,6 @@ gui_mch_wait_for_chars(long wtime)
focus = gui.in_focus; focus = gui.in_focus;
} }
# if defined(FEAT_JOB_CHANNEL)
/* Using an event handler for a channel that may be disconnected does
* not work, it hangs. Instead poll for messages. */
channel_handle_events(TRUE);
# endif
#ifdef MESSAGE_QUEUE #ifdef MESSAGE_QUEUE
# ifdef FEAT_TIMERS # ifdef FEAT_TIMERS
did_add_timer = FALSE; did_add_timer = FALSE;
@@ -6684,10 +6663,10 @@ gui_mch_wait_for_chars(long wtime)
theend: theend:
if (timer != 0 && !timed_out) if (timer != 0 && !timed_out)
#if GTK_CHECK_VERSION(3,0,0) timeout_remove(timer);
g_source_remove(timer); #ifdef FEAT_JOB_CHANNEL
#else if (channel_timer != 0)
gtk_timeout_remove(timer); timeout_remove(channel_timer);
#endif #endif
return retval; return retval;

View File

@@ -35,6 +35,7 @@ char_u *channel_read_block(channel_T *channel, ch_part_T part, int timeout);
void common_channel_read(typval_T *argvars, typval_T *rettv, int raw); void common_channel_read(typval_T *argvars, typval_T *rettv, int raw);
channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp); channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp);
void channel_handle_events(int only_keep_open); void channel_handle_events(int only_keep_open);
int channel_any_keep_open(void);
void channel_set_nonblock(channel_T *channel, ch_part_T part); void channel_set_nonblock(channel_T *channel, ch_part_T part);
int channel_send(channel_T *channel, ch_part_T part, char_u *buf_arg, int len_arg, char *fun); int channel_send(channel_T *channel, ch_part_T part, char_u *buf_arg, int len_arg, char *fun);
void ch_expr_common(typval_T *argvars, typval_T *rettv, int eval); void ch_expr_common(typval_T *argvars, typval_T *rettv, int eval);

View File

@@ -769,6 +769,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1005,
/**/ /**/
1004, 1004,
/**/ /**/