Wayland: Fix a freeze in rare circumstances when having multiple OS Windows

Fixes #2307
Fixes #1722
This commit is contained in:
Kovid Goyal 2020-01-23 15:07:22 +05:30
parent 0ea7d24ba4
commit 748ca81d4b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 18 additions and 9 deletions

View File

@ -19,6 +19,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Allow choosing OpenType features for individual fonts via the
:opt:`font_features` option. (:pull:`2248`)
- Wayland: Fix a freeze in rare circumstances when having multiple OS Windows
(:iss:`2307` and :iss:`1722`)
- Add an option :opt:`force_ltr` to turn off the display of text in RTL scripts
in right-to-left order (:pull:`2293`)

View File

@ -292,7 +292,7 @@ finalizePollData(EventLoopData *eld) {
}
int
pollForEvents(EventLoopData *eld, monotonic_t timeout) {
pollForEvents(EventLoopData *eld, monotonic_t timeout, watch_callback_func display_callback) {
int read_ok = 0;
timeout = prepareForPoll(eld, timeout);
EVDBG("pollForEvents final timeout: %.3f", monotonic_t_to_s_double(timeout));
@ -305,6 +305,7 @@ pollForEvents(EventLoopData *eld, monotonic_t timeout) {
errno = 0;
result = pollWithTimeout(eld->fds, eld->watches_count, timeout);
int saved_errno = errno;
if (display_callback) display_callback(result, eld->fds[0].revents && eld->watches[0].events, NULL);
dispatchTimers(eld);
if (result > 0) {
dispatchEvents(eld);
@ -319,6 +320,7 @@ pollForEvents(EventLoopData *eld, monotonic_t timeout) {
errno = 0;
result = poll(eld->fds, eld->watches_count, -1);
int saved_errno = errno;
if (display_callback) display_callback(result, eld->fds[0].revents && eld->watches[0].events, NULL);
dispatchTimers(eld);
if (result > 0) {
dispatchEvents(eld);

View File

@ -90,7 +90,7 @@ void toggleTimer(EventLoopData *eld, id_type timer_id, int enabled);
void changeTimerInterval(EventLoopData *eld, id_type timer_id, monotonic_t interval);
monotonic_t prepareForPoll(EventLoopData *eld, monotonic_t timeout);
int pollWithTimeout(struct pollfd *fds, nfds_t nfds, monotonic_t timeout);
int pollForEvents(EventLoopData *eld, monotonic_t timeout);
int pollForEvents(EventLoopData *eld, monotonic_t timeout, watch_callback_func);
unsigned dispatchTimers(EventLoopData *eld);
void finalizePollData(EventLoopData *eld);
bool initPollData(EventLoopData *eld, int display_fd);

16
glfw/wl_window.c vendored
View File

@ -754,6 +754,13 @@ abortOnFatalError(int last_error) {
_glfw.wl.eventLoopData.wakeup_data_read = true;
}
static void
wayland_read_events(int poll_result, int events, void *data UNUSED) {
EVDBG("wayland_read_events poll_result: %d events: %d", poll_result, events);
if (poll_result > 0 && events) wl_display_read_events(_glfw.wl.display);
else wl_display_cancel_read(_glfw.wl.display);
}
static void
handleEvents(monotonic_t timeout)
{
@ -779,18 +786,15 @@ handleEvents(monotonic_t timeout)
return;
}
bool display_read_ok = pollForEvents(&_glfw.wl.eventLoopData, timeout);
// we pass in wayland_read_events to ensure that the above wl_display_prepare_read call
// is followed by either wl_display_cancel_read or wl_display_read_events
bool display_read_ok = pollForEvents(&_glfw.wl.eventLoopData, timeout, wayland_read_events);
EVDBG("display_read_ok: %d", display_read_ok);
if (display_read_ok) {
wl_display_read_events(display);
int num = wl_display_dispatch_pending(display);
(void)num;
EVDBG("dispatched %d Wayland events", num);
}
else
{
wl_display_cancel_read(display);
}
glfw_ibus_dispatch(&_glfw.wl.xkb.ibus);
glfw_dbus_session_bus_dispatch();
EVDBG("other dispatch done");

2
glfw/x11_window.c vendored
View File

@ -68,7 +68,7 @@ static unsigned _glfwDispatchX11Events(void);
static void
handleEvents(monotonic_t timeout) {
EVDBG("starting handleEvents(%.2f)", monotonic_t_to_s_double(timeout));
int display_read_ok = pollForEvents(&_glfw.x11.eventLoopData, timeout);
int display_read_ok = pollForEvents(&_glfw.x11.eventLoopData, timeout, NULL);
EVDBG("display_read_ok: %d", display_read_ok);
if (display_read_ok) {
unsigned dispatched = _glfwDispatchX11Events();