comparison src/gui_gtk_x11.c @ 12250:ac8b2f9c1409 v8.0.1005

patch 8.0.1005: terminal without job updates slowly in GUI commit https://github.com/vim/vim/commit/4ab7968aa9d8a624cd56f55b5cad2bedb240eb73 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Aug 27 14:50:47 2017 +0200 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.
author Christian Brabandt <cb@256bit.org>
date Sun, 27 Aug 2017 15:00:04 +0200
parents 24abce52ad20
children 2a8890b80923
comparison
equal deleted inserted replaced
12249:6669330ba85d 12250:ac8b2f9c1409
787 return FALSE; 787 return FALSE;
788 } 788 }
789 #endif /* defined(FEAT_CLIENTSERVER) */ 789 #endif /* defined(FEAT_CLIENTSERVER) */
790 790
791 791
792 #if GTK_CHECK_VERSION(3,0,0)
793 typedef gboolean timeout_cb_type;
794 #else
795 typedef gint timeout_cb_type;
796 #endif
797
798 /*
799 * Start a timer that will invoke the specified callback.
800 * Returns the ID of the timer.
801 */
802 static guint
803 timeout_add(int time, timeout_cb_type (*callback)(gpointer), int *flagp)
804 {
805 #if GTK_CHECK_VERSION(3,0,0)
806 return g_timeout_add((guint)time, (GSourceFunc)callback, flagp);
807 #else
808 return gtk_timeout_add((guint32)time, (GtkFunction)callback, flagp);
809 #endif
810 }
811
812 static void
813 timeout_remove(guint timer)
814 {
815 #if GTK_CHECK_VERSION(3,0,0)
816 g_source_remove(timer);
817 #else
818 gtk_timeout_remove(timer);
819 #endif
820 }
821
822
792 /**************************************************************************** 823 /****************************************************************************
793 * Focus handlers: 824 * Focus handlers:
794 */ 825 */
795 826
796 827
864 void 895 void
865 gui_mch_stop_blink(void) 896 gui_mch_stop_blink(void)
866 { 897 {
867 if (blink_timer) 898 if (blink_timer)
868 { 899 {
869 #if GTK_CHECK_VERSION(3,0,0) 900 timeout_remove(blink_timer);
870 g_source_remove(blink_timer);
871 #else
872 gtk_timeout_remove(blink_timer);
873 #endif
874 blink_timer = 0; 901 blink_timer = 0;
875 } 902 }
876 if (blink_state == BLINK_OFF) 903 if (blink_state == BLINK_OFF)
877 { 904 {
878 gui_update_cursor(TRUE, FALSE); 905 gui_update_cursor(TRUE, FALSE);
879 gui_mch_flush(); 906 gui_mch_flush();
880 } 907 }
881 blink_state = BLINK_NONE; 908 blink_state = BLINK_NONE;
882 } 909 }
883 910
884 #if GTK_CHECK_VERSION(3,0,0) 911 static timeout_cb_type
885 static gboolean
886 #else
887 static gint
888 #endif
889 blink_cb(gpointer data UNUSED) 912 blink_cb(gpointer data UNUSED)
890 { 913 {
891 if (blink_state == BLINK_ON) 914 if (blink_state == BLINK_ON)
892 { 915 {
893 gui_undraw_cursor(); 916 gui_undraw_cursor();
894 blink_state = BLINK_OFF; 917 blink_state = BLINK_OFF;
895 #if GTK_CHECK_VERSION(3,0,0) 918 blink_timer = timeout_add(blink_offtime, blink_cb, NULL);
896 blink_timer = g_timeout_add((guint)blink_offtime,
897 (GSourceFunc) blink_cb, NULL);
898 #else
899 blink_timer = gtk_timeout_add((guint32)blink_offtime,
900 (GtkFunction) blink_cb, NULL);
901 #endif
902 } 919 }
903 else 920 else
904 { 921 {
905 gui_update_cursor(TRUE, FALSE); 922 gui_update_cursor(TRUE, FALSE);
906 blink_state = BLINK_ON; 923 blink_state = BLINK_ON;
907 #if GTK_CHECK_VERSION(3,0,0) 924 blink_timer = timeout_add(blink_ontime, blink_cb, NULL);
908 blink_timer = g_timeout_add((guint)blink_ontime,
909 (GSourceFunc) blink_cb, NULL);
910 #else
911 blink_timer = gtk_timeout_add((guint32)blink_ontime,
912 (GtkFunction) blink_cb, NULL);
913 #endif
914 } 925 }
915 gui_mch_flush(); 926 gui_mch_flush();
916 927
917 return FALSE; /* don't happen again */ 928 return FALSE; /* don't happen again */
918 } 929 }
924 void 935 void
925 gui_mch_start_blink(void) 936 gui_mch_start_blink(void)
926 { 937 {
927 if (blink_timer) 938 if (blink_timer)
928 { 939 {
929 #if GTK_CHECK_VERSION(3,0,0) 940 timeout_remove(blink_timer);
930 g_source_remove(blink_timer);
931 #else
932 gtk_timeout_remove(blink_timer);
933 #endif
934 blink_timer = 0; 941 blink_timer = 0;
935 } 942 }
936 /* Only switch blinking on if none of the times is zero */ 943 /* Only switch blinking on if none of the times is zero */
937 if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) 944 if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
938 { 945 {
939 #if GTK_CHECK_VERSION(3,0,0) 946 blink_timer = timeout_add(blink_waittime, blink_cb, NULL);
940 blink_timer = g_timeout_add((guint)blink_waittime,
941 (GSourceFunc) blink_cb, NULL);
942 #else
943 blink_timer = gtk_timeout_add((guint32)blink_waittime,
944 (GtkFunction) blink_cb, NULL);
945 #endif
946 blink_state = BLINK_ON; 947 blink_state = BLINK_ON;
947 gui_update_cursor(TRUE, FALSE); 948 gui_update_cursor(TRUE, FALSE);
948 gui_mch_flush(); 949 gui_mch_flush();
949 } 950 }
950 } 951 }
1731 } 1732 }
1732 1733
1733 return OK; 1734 return OK;
1734 } 1735 }
1735 1736
1736
1737 /**************************************************************************** 1737 /****************************************************************************
1738 * Mouse handling callbacks 1738 * Mouse handling callbacks
1739 */ 1739 */
1740 1740
1741 1741
1743 static int mouse_timed_out = TRUE; 1743 static int mouse_timed_out = TRUE;
1744 1744
1745 /* 1745 /*
1746 * Timer used to recognize multiple clicks of the mouse button 1746 * Timer used to recognize multiple clicks of the mouse button
1747 */ 1747 */
1748 #if GTK_CHECK_VERSION(3,0,0) 1748 static timeout_cb_type
1749 static gboolean
1750 #else
1751 static gint
1752 #endif
1753 mouse_click_timer_cb(gpointer data) 1749 mouse_click_timer_cb(gpointer data)
1754 { 1750 {
1755 /* we don't use this information currently */ 1751 /* we don't use this information currently */
1756 int *timed_out = (int *) data; 1752 int *timed_out = (int *) data;
1757 1753
1758 *timed_out = TRUE; 1754 *timed_out = TRUE;
1759 return FALSE; /* don't happen again */ 1755 return FALSE; /* don't happen again */
1760 } 1756 }
1761 1757
1762 static guint motion_repeat_timer = 0; 1758 static guint motion_repeat_timer = 0;
1763 static int motion_repeat_offset = FALSE; 1759 static int motion_repeat_offset = FALSE;
1764 #ifdef GTK_DEST_DEFAULT_ALL 1760 static timeout_cb_type motion_repeat_timer_cb(gpointer);
1765 static gboolean motion_repeat_timer_cb(gpointer);
1766 #else
1767 static gint motion_repeat_timer_cb(gpointer);
1768 #endif
1769 1761
1770 static void 1762 static void
1771 process_motion_notify(int x, int y, GdkModifierType state) 1763 process_motion_notify(int x, int y, GdkModifierType state)
1772 { 1764 {
1773 int button; 1765 int button;
1851 delay = (130 * (127 - offshoot)) / 127 + 5; 1843 delay = (130 * (127 - offshoot)) / 127 + 5;
1852 } 1844 }
1853 1845
1854 /* shoot again */ 1846 /* shoot again */
1855 if (!motion_repeat_timer) 1847 if (!motion_repeat_timer)
1856 #if GTK_CHECK_VERSION(3,0,0) 1848 motion_repeat_timer = timeout_add(delay, motion_repeat_timer_cb,
1857 motion_repeat_timer = g_timeout_add((guint)delay, 1849 NULL);
1858 motion_repeat_timer_cb, NULL);
1859 #else
1860 motion_repeat_timer = gtk_timeout_add((guint32)delay,
1861 motion_repeat_timer_cb, NULL);
1862 #endif
1863 } 1850 }
1864 } 1851 }
1865 1852
1866 #if GTK_CHECK_VERSION(3,0,0) 1853 #if GTK_CHECK_VERSION(3,0,0)
1867 static GdkDevice * 1854 static GdkDevice *
1902 #endif 1889 #endif
1903 1890
1904 /* 1891 /*
1905 * Timer used to recognize multiple clicks of the mouse button. 1892 * Timer used to recognize multiple clicks of the mouse button.
1906 */ 1893 */
1907 #if GTK_CHECK_VERSION(3,0,0) 1894 static timeout_cb_type
1908 static gboolean
1909 #else
1910 static gint
1911 #endif
1912 motion_repeat_timer_cb(gpointer data UNUSED) 1895 motion_repeat_timer_cb(gpointer data UNUSED)
1913 { 1896 {
1914 int x; 1897 int x;
1915 int y; 1898 int y;
1916 GdkModifierType state; 1899 GdkModifierType state;
2017 y = event->y; 2000 y = event->y;
2018 2001
2019 /* Handle multiple clicks */ 2002 /* Handle multiple clicks */
2020 if (!mouse_timed_out && mouse_click_timer) 2003 if (!mouse_timed_out && mouse_click_timer)
2021 { 2004 {
2022 #if GTK_CHECK_VERSION(3,0,0) 2005 timeout_remove(mouse_click_timer);
2023 g_source_remove(mouse_click_timer);
2024 #else
2025 gtk_timeout_remove(mouse_click_timer);
2026 #endif
2027 mouse_click_timer = 0; 2006 mouse_click_timer = 0;
2028 repeated_click = TRUE; 2007 repeated_click = TRUE;
2029 } 2008 }
2030 2009
2031 mouse_timed_out = FALSE; 2010 mouse_timed_out = FALSE;
2032 #if GTK_CHECK_VERSION(3,0,0) 2011 mouse_click_timer = timeout_add(p_mouset, mouse_click_timer_cb,
2033 mouse_click_timer = g_timeout_add((guint)p_mouset, 2012 &mouse_timed_out);
2034 mouse_click_timer_cb, &mouse_timed_out);
2035 #else
2036 mouse_click_timer = gtk_timeout_add((guint32)p_mouset,
2037 mouse_click_timer_cb, &mouse_timed_out);
2038 #endif
2039 2013
2040 switch (event->button) 2014 switch (event->button)
2041 { 2015 {
2042 /* Keep in sync with gui_x11.c. 2016 /* Keep in sync with gui_x11.c.
2043 * Buttons 4-7 are handled in scroll_event() */ 2017 * Buttons 4-7 are handled in scroll_event() */
2127 /* Remove any motion "machine gun" timers used for automatic further 2101 /* Remove any motion "machine gun" timers used for automatic further
2128 extension of allocation areas if outside of the applications window 2102 extension of allocation areas if outside of the applications window
2129 area .*/ 2103 area .*/
2130 if (motion_repeat_timer) 2104 if (motion_repeat_timer)
2131 { 2105 {
2132 #if GTK_CHECK_VERSION(3,0,0) 2106 timeout_remove(motion_repeat_timer);
2133 g_source_remove(motion_repeat_timer);
2134 #else
2135 gtk_timeout_remove(motion_repeat_timer);
2136 #endif
2137 motion_repeat_timer = 0; 2107 motion_repeat_timer = 0;
2138 } 2108 }
2139 2109
2140 x = event->x; 2110 x = event->x;
2141 y = event->y; 2111 y = event->y;
4576 * Thus set hints at start-up to ensure correct init. size, then a 4546 * Thus set hints at start-up to ensure correct init. size, then a
4577 * second after the final attempt to reset the real minimum hints (done by 4547 * second after the final attempt to reset the real minimum hints (done by
4578 * scrollbar init.), actually do the standard hints and stop the timer. 4548 * scrollbar init.), actually do the standard hints and stop the timer.
4579 * We'll not let the default hints be set while this timer's active. 4549 * We'll not let the default hints be set while this timer's active.
4580 */ 4550 */
4581 static gboolean 4551 static timeout_cb_type
4582 check_startup_plug_hints(gpointer data UNUSED) 4552 check_startup_plug_hints(gpointer data UNUSED)
4583 { 4553 {
4584 if (init_window_hints_state == 1) 4554 if (init_window_hints_state == 1)
4585 { 4555 {
4586 /* Safe to use normal hints now */ 4556 /* Safe to use normal hints now */
4679 */ 4649 */
4680 if (gtk_socket_id != 0 && (mask & WidthValue || mask & HeightValue)) 4650 if (gtk_socket_id != 0 && (mask & WidthValue || mask & HeightValue))
4681 { 4651 {
4682 update_window_manager_hints(pixel_width, pixel_height); 4652 update_window_manager_hints(pixel_width, pixel_height);
4683 init_window_hints_state = 1; 4653 init_window_hints_state = 1;
4684 g_timeout_add(1000, check_startup_plug_hints, NULL); 4654 timeout_add(1000, check_startup_plug_hints, NULL);
4685 } 4655 }
4686 } 4656 }
4687 4657
4688 pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width); 4658 pixel_width = (guint)(gui_get_base_width() + Columns * gui.char_width);
4689 pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height); 4659 pixel_height = (guint)(gui_get_base_height() + Rows * gui.char_height);
6582 { 6552 {
6583 while (g_main_context_pending(NULL) && !vim_is_input_buf_full()) 6553 while (g_main_context_pending(NULL) && !vim_is_input_buf_full())
6584 g_main_context_iteration(NULL, TRUE); 6554 g_main_context_iteration(NULL, TRUE);
6585 } 6555 }
6586 6556
6587 #if GTK_CHECK_VERSION(3,0,0) 6557 static timeout_cb_type
6588 static gboolean
6589 #else
6590 static gint
6591 #endif
6592 input_timer_cb(gpointer data) 6558 input_timer_cb(gpointer data)
6593 { 6559 {
6594 int *timed_out = (int *) data; 6560 int *timed_out = (int *) data;
6595 6561
6596 /* Just inform the caller about the occurrence of it */ 6562 /* Just inform the caller about the occurrence of it */
6597 *timed_out = TRUE; 6563 *timed_out = TRUE;
6598 6564
6599 return FALSE; /* don't happen again */ 6565 return FALSE; /* don't happen again */
6600 } 6566 }
6567
6568 #ifdef FEAT_JOB_CHANNEL
6569 static timeout_cb_type
6570 channel_poll_cb(gpointer data UNUSED)
6571 {
6572 /* Using an event handler for a channel that may be disconnected does
6573 * not work, it hangs. Instead poll for messages. */
6574 channel_handle_events(TRUE);
6575 parse_queued_messages();
6576
6577 return TRUE; /* repeat */
6578 }
6579 #endif
6601 6580
6602 /* 6581 /*
6603 * GUI input routine called by gui_wait_for_chars(). Waits for a character 6582 * GUI input routine called by gui_wait_for_chars(). Waits for a character
6604 * from the keyboard. 6583 * from the keyboard.
6605 * wtime == -1 Wait forever. 6584 * wtime == -1 Wait forever.
6613 { 6592 {
6614 int focus; 6593 int focus;
6615 guint timer; 6594 guint timer;
6616 static int timed_out; 6595 static int timed_out;
6617 int retval = FAIL; 6596 int retval = FAIL;
6597 #ifdef FEAT_JOB_CHANNEL
6598 guint channel_timer = 0;
6599 #endif
6618 6600
6619 timed_out = FALSE; 6601 timed_out = FALSE;
6620 6602
6621 /* this timeout makes sure that we will return if no characters arrived in 6603 /* this timeout makes sure that we will return if no characters arrived in
6622 * time */ 6604 * time */
6623 if (wtime > 0) 6605 if (wtime > 0)
6624 #if GTK_CHECK_VERSION(3,0,0) 6606 timer = timeout_add(wtime, input_timer_cb, &timed_out);
6625 timer = g_timeout_add((guint)wtime, input_timer_cb, &timed_out);
6626 #else
6627 timer = gtk_timeout_add((guint32)wtime, input_timer_cb, &timed_out);
6628 #endif
6629 else 6607 else
6630 timer = 0; 6608 timer = 0;
6609
6610 #ifdef FEAT_JOB_CHANNEL
6611 /* If there is a channel with the keep_open flag we need to poll for input
6612 * on them. */
6613 if (channel_any_keep_open())
6614 channel_timer = timeout_add(20, channel_poll_cb, NULL);
6615 #endif
6631 6616
6632 focus = gui.in_focus; 6617 focus = gui.in_focus;
6633 6618
6634 do 6619 do
6635 { 6620 {
6641 else 6626 else
6642 gui_mch_stop_blink(); 6627 gui_mch_stop_blink();
6643 focus = gui.in_focus; 6628 focus = gui.in_focus;
6644 } 6629 }
6645 6630
6646 # if defined(FEAT_JOB_CHANNEL)
6647 /* Using an event handler for a channel that may be disconnected does
6648 * not work, it hangs. Instead poll for messages. */
6649 channel_handle_events(TRUE);
6650 # endif
6651
6652 #ifdef MESSAGE_QUEUE 6631 #ifdef MESSAGE_QUEUE
6653 # ifdef FEAT_TIMERS 6632 # ifdef FEAT_TIMERS
6654 did_add_timer = FALSE; 6633 did_add_timer = FALSE;
6655 # endif 6634 # endif
6656 parse_queued_messages(); 6635 parse_queued_messages();
6682 */ 6661 */
6683 gui_mch_update(); 6662 gui_mch_update();
6684 6663
6685 theend: 6664 theend:
6686 if (timer != 0 && !timed_out) 6665 if (timer != 0 && !timed_out)
6687 #if GTK_CHECK_VERSION(3,0,0) 6666 timeout_remove(timer);
6688 g_source_remove(timer); 6667 #ifdef FEAT_JOB_CHANNEL
6689 #else 6668 if (channel_timer != 0)
6690 gtk_timeout_remove(timer); 6669 timeout_remove(channel_timer);
6691 #endif 6670 #endif
6692 6671
6693 return retval; 6672 return retval;
6694 } 6673 }
6695 6674