Mercurial > vim
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 |