diff --git a/src/wl_window.c b/src/wl_window.c index 4220d17e0..f1d5dbe6c 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1356,6 +1356,7 @@ static void handleEvents(double* timeout) #endif GLFWbool event = GLFW_FALSE; + GLFWbool wlcanread = GLFW_FALSE; enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD, LIBDECOR_FD }; struct pollfd fds[] = { @@ -1370,42 +1371,75 @@ static void handleEvents(double* timeout) while (!event) { - while (wl_display_prepare_read(_glfw.wl.display) != 0) + while (!wlcanread && !event) { - if (wl_display_dispatch_pending(_glfw.wl.display) > 0) - return; + if (wl_display_prepare_read(_glfw.wl.display) == 0) + { + wlcanread = GLFW_TRUE; + } + else if (wl_display_dispatch_pending(_glfw.wl.display) > 0) + { + event = GLFW_TRUE; + break; + } } - // If an error other than EAGAIN happens, we have likely been disconnected - // from the Wayland session; try to handle that the best we can. - if (!flushDisplay()) - { - wl_display_cancel_read(_glfw.wl.display); + if (wlcanread) + { + // If an error other than EAGAIN happens, we have likely been disconnected + // from the Wayland session; try to handle that the best we can. + if (!flushDisplay()) + { + wl_display_cancel_read(_glfw.wl.display); - _GLFWwindow* window = _glfw.windowListHead; - while (window) - { - _glfwInputWindowCloseRequest(window); - window = window->next; - } + _GLFWwindow* window = _glfw.windowListHead; + while (window) + { + _glfwInputWindowCloseRequest(window); + window = window->next; + } - return; - } + return; + } - if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) - { - wl_display_cancel_read(_glfw.wl.display); - return; - } + if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) + { + wl_display_cancel_read(_glfw.wl.display); + return; + } - if (fds[DISPLAY_FD].revents & POLLIN) - { - wl_display_read_events(_glfw.wl.display); - if (wl_display_dispatch_pending(_glfw.wl.display) > 0) - event = GLFW_TRUE; - } - else - wl_display_cancel_read(_glfw.wl.display); + if (fds[DISPLAY_FD].revents & POLLIN) + { + wl_display_read_events(_glfw.wl.display); + if (wl_display_dispatch_pending(_glfw.wl.display) > 0) + event = GLFW_TRUE; + } + else + wl_display_cancel_read(_glfw.wl.display); + } + else + { + if (!flushDisplay()) + { + _GLFWwindow* window = _glfw.windowListHead; + while (window) + { + _glfwInputWindowCloseRequest(window); + window = window->next; + } + + return; + } + + fds[DISPLAY_FD].fd = -1; // ignore wl events + fds[LIBDECOR_FD].fd = -1; + //fds[CURSOR_FD].fd = -1; + double notimeout = 0.0; + if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), ¬imeout)) + { + return; + } + } if (fds[KEYREPEAT_FD].revents & POLLIN) { @@ -1431,7 +1465,7 @@ static void handleEvents(double* timeout) } } - if (fds[CURSOR_FD].revents & POLLIN) + if ((fds[CURSOR_FD].fd > 0 ) && (fds[CURSOR_FD].revents & POLLIN)) { uint64_t repeats; @@ -1439,7 +1473,7 @@ static void handleEvents(double* timeout) incrementCursorImage(_glfw.wl.pointerFocus); } - if (fds[LIBDECOR_FD].revents & POLLIN) + if ((fds[LIBDECOR_FD].fd > 0 ) && (fds[LIBDECOR_FD].revents & POLLIN)) { if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0) event = GLFW_TRUE;