Subject: 24.3.50; bar scrolling freezes gtk emacs

From: Jarek Czekalski <[email-masked]>
Date: Mon, 21 Apr 2014 12:34:18 +0200

Patch rebased for r117003.
=== modified file 'src/ChangeLog'
*** src/ChangeLog	2014-04-19 20:32:05 +0000
--- src/ChangeLog	2014-04-21 10:32:13 +0000
***************
*** 2448,2453 ****
--- 2448,2459 ----
  
  	* alloc.c (Fmemory_limit): Avoid compiler warning.  Return 0 always.
  
+ 2013-12-08  Jarek Czekalski  <[email-masked]>
+ 
+ 	Fix freezing with scroll bars of GTK3 Toolkit (Bug#15801).
+ 	* keyboard.c: A comment to unblock_input.
+ 	* xgselect.c: Prevent Glib main loop recursion.
+ 
  2013-12-08  Jan Djärv  <[email-masked]>
  
  	* nsterm.m (updateFrameSize:): Fix GNUstep toolbar not updating.

=== modified file 'src/keyboard.c'
*** src/keyboard.c	2014-04-16 19:43:46 +0000
--- src/keyboard.c	2014-04-21 10:32:13 +0000
***************
*** 7117,7123 ****
  /* 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.  */
  
  void
  unblock_input (void)
--- 7117,7128 ----
  /* 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.
! 
!    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)

=== modified file 'src/xgselect.c'
*** src/xgselect.c	2014-04-16 19:43:46 +0000
--- src/xgselect.c	2014-04-21 10:32:13 +0000
***************
*** 28,33 ****
--- 28,45 ----
  #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,58 ****
    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;
--- 59,64 ----
***************
*** 136,143 ****
    if (need_to_dispatch)
      {
        int pselect_errno = errno;
        while (g_main_context_pending (context))
! 	g_main_context_dispatch (context);
        errno = pselect_errno;
      }
  
--- 142,154 ----
    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);
!       unblock_input();
        errno = pselect_errno;
      }