]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix freezing with scroll bars of GTK3 Toolkit.
authorJarek Czekalski <jarekczek@poczta.onet.pl>
Mon, 21 Apr 2014 15:55:28 +0000 (11:55 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Mon, 21 Apr 2014 15:55:28 +0000 (11:55 -0400)
* src/keyboard.c (unblock_input): Add comment.
* src/xgselect.c (xg_select): Prevent Glib main loop recursion.

Fixes: debbugs:15801
src/ChangeLog
src/keyboard.c
src/xgselect.c

index c42679d54f4d516a23d41e19f1e169ee604d1ba1..e8fb5f6320356ee1b6c8e063271317e1b85eb05d 100644 (file)
@@ -1,3 +1,9 @@
+2014-04-21  Jarek Czekalski  <jarekczek@poczta.onet.pl>
+
+       Fix freezing with scroll bars of GTK3 Toolkit (bug#15801).
+       * keyboard.c (unblock_input): Add comment.
+       * xgselect.c (xg_select): Prevent Glib main loop recursion.
+
 2014-04-19  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * intervals.c (rotate_right, rotate_left): Fix up length computation.
index 1f4b23d9905af52a8752717380a6f9db79a48d96..90479375072261f3f61ca5aa4c07e3ef8c430008 100644 (file)
@@ -7121,7 +7121,12 @@ unblock_input_to (int level)
 /* End critical section.
 
    If doing signal-driven input, and a signal came in when input was
-   blocked, reinvoke the signal handler now to deal with it.  */
+   blocked, reinvoke the signal handler now to deal with it.
+
+   It will also process queued input, if it was not read before.
+   When a longer code sequence does not use block/unblock input
+   at all, the whole input gathered up to the next call to
+   unblock_input will be processed inside that call. */
 
 void
 unblock_input (void)
index 1d3f916c9f8284fdc88cf18c7ca7b36d343bd890..42fdfed0d3448c1311de48424c3ea5ae471e7095 100644 (file)
@@ -28,6 +28,18 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdbool.h>
 #include <timespec.h>
 #include "frame.h"
+#include "blockinput.h"
+
+/* `xg_select' is a `pselect' replacement.  Why do we need a separate function?
+   1. Timeouts.  Glib and Gtk rely on timer events.  If we did pselect
+      with a greater timeout then the one scheduled by Glib, we would
+      not allow Glib to process its timer events.  We want Glib to
+      work smoothly, so we need to reduce our timeout to match Glib.
+   2. Descriptors.  Glib may listen to more file descriptors than we do.
+      So we add Glib descriptors to our pselect pool, but we don't change
+      the value returned by the function.  The return value  matches only
+      the descriptors passed as arguments, making it compatible with
+      plain pselect.  */
 
 int
 xg_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,
   bool need_to_dispatch;
   USE_SAFE_ALLOCA;
 
-  /* Do not try to optimize with an initial check with g_main_context_pending
-     and a call to pselect if it returns false.  If Gdk has a timeout for 0.01
-     second, and Emacs has a timeout for 1 second, g_main_context_pending will
-     return false, but the timeout will be 1 second, thus missing the gdk
-     timeout with a lot.  */
-
   context = g_main_context_default ();
 
   if (rfds) all_rfds = *rfds;
@@ -136,8 +142,13 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
   if (need_to_dispatch)
     {
       int pselect_errno = errno;
+      /* Prevent g_main_dispatch recursion, that would occur without
+         block_input wrapper, because event handlers call
+         unblock_input.  Event loop recursion was causing Bug#15801.  */
+      block_input ();
       while (g_main_context_pending (context))
-       g_main_context_dispatch (context);
+        g_main_context_dispatch (context);
+      unblock_input ();
       errno = pselect_errno;
     }