1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-26 19:18:50 +00:00

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
This commit is contained in:
Jarek Czekalski 2014-04-21 11:55:28 -04:00 committed by Stefan Monnier
parent f982b37104
commit 6709d4dab9
3 changed files with 30 additions and 8 deletions

View 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.

View 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)

View 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;
}