aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJarek Czekalski2014-04-21 11:55:28 -0400
committerStefan Monnier2014-04-21 11:55:28 -0400
commit6709d4dab9d434dcd1d797e081dfc796b735a1ff (patch)
treed3b0a7d1a084fb6cafa8c3ed0ac197bfb053cb1c /src
parentf982b37104acdd2b3aee4fe3bb08ae052990f869 (diff)
downloademacs-6709d4dab9d434dcd1d797e081dfc796b735a1ff.tar.gz
emacs-6709d4dab9d434dcd1d797e081dfc796b735a1ff.zip
Fix freezing with scroll bars of GTK3 Toolkit.
* src/keyboard.c (unblock_input): Add comment. * src/xgselect.c (xg_select): Prevent Glib main loop recursion. Fixes: debbugs:15801
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog6
-rw-r--r--src/keyboard.c7
-rw-r--r--src/xgselect.c25
3 files changed, 30 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c42679d54f4..e8fb5f63203 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
12014-04-21 Jarek Czekalski <jarekczek@poczta.onet.pl>
2
3 Fix freezing with scroll bars of GTK3 Toolkit (bug#15801).
4 * keyboard.c (unblock_input): Add comment.
5 * xgselect.c (xg_select): Prevent Glib main loop recursion.
6
12014-04-19 Stefan Monnier <monnier@iro.umontreal.ca> 72014-04-19 Stefan Monnier <monnier@iro.umontreal.ca>
2 8
3 * intervals.c (rotate_right, rotate_left): Fix up length computation. 9 * intervals.c (rotate_right, rotate_left): Fix up length computation.
diff --git a/src/keyboard.c b/src/keyboard.c
index 1f4b23d9905..90479375072 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7121,7 +7121,12 @@ unblock_input_to (int level)
7121/* End critical section. 7121/* End critical section.
7122 7122
7123 If doing signal-driven input, and a signal came in when input was 7123 If doing signal-driven input, and a signal came in when input was
7124 blocked, reinvoke the signal handler now to deal with it. */ 7124 blocked, reinvoke the signal handler now to deal with it.
7125
7126 It will also process queued input, if it was not read before.
7127 When a longer code sequence does not use block/unblock input
7128 at all, the whole input gathered up to the next call to
7129 unblock_input will be processed inside that call. */
7125 7130
7126void 7131void
7127unblock_input (void) 7132unblock_input (void)
diff --git a/src/xgselect.c b/src/xgselect.c
index 1d3f916c9f8..42fdfed0d34 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -28,6 +28,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include <stdbool.h> 28#include <stdbool.h>
29#include <timespec.h> 29#include <timespec.h>
30#include "frame.h" 30#include "frame.h"
31#include "blockinput.h"
32
33/* `xg_select' is a `pselect' replacement. Why do we need a separate function?
34 1. Timeouts. Glib and Gtk rely on timer events. If we did pselect
35 with a greater timeout then the one scheduled by Glib, we would
36 not allow Glib to process its timer events. We want Glib to
37 work smoothly, so we need to reduce our timeout to match Glib.
38 2. Descriptors. Glib may listen to more file descriptors than we do.
39 So we add Glib descriptors to our pselect pool, but we don't change
40 the value returned by the function. The return value matches only
41 the descriptors passed as arguments, making it compatible with
42 plain pselect. */
31 43
32int 44int
33xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, 45xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
@@ -47,12 +59,6 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
47 bool need_to_dispatch; 59 bool need_to_dispatch;
48 USE_SAFE_ALLOCA; 60 USE_SAFE_ALLOCA;
49 61
50 /* Do not try to optimize with an initial check with g_main_context_pending
51 and a call to pselect if it returns false. If Gdk has a timeout for 0.01
52 second, and Emacs has a timeout for 1 second, g_main_context_pending will
53 return false, but the timeout will be 1 second, thus missing the gdk
54 timeout with a lot. */
55
56 context = g_main_context_default (); 62 context = g_main_context_default ();
57 63
58 if (rfds) all_rfds = *rfds; 64 if (rfds) all_rfds = *rfds;
@@ -136,8 +142,13 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
136 if (need_to_dispatch) 142 if (need_to_dispatch)
137 { 143 {
138 int pselect_errno = errno; 144 int pselect_errno = errno;
145 /* Prevent g_main_dispatch recursion, that would occur without
146 block_input wrapper, because event handlers call
147 unblock_input. Event loop recursion was causing Bug#15801. */
148 block_input ();
139 while (g_main_context_pending (context)) 149 while (g_main_context_pending (context))
140 g_main_context_dispatch (context); 150 g_main_context_dispatch (context);
151 unblock_input ();
141 errno = pselect_errno; 152 errno = pselect_errno;
142 } 153 }
143 154