diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2021-10-28 08:57:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-28 08:57:37 +0200 |
commit | d4067e661cf7d54ff24c223b7d0a7388dc08c6b2 (patch) | |
tree | 924ae5c1ba17e4cdab54a2c5356026dc23d1da0f | |
parent | 7bb568328ff6e7d2d774023aff4513d90cfef98d (diff) | |
parent | ba96fc6a4dff123c748d7c554147f8ade047f76c (diff) |
Merge pull request #54326 from nekomatata/x11-fix-input-delay
-rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 46 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.h | 1 |
2 files changed, 29 insertions, 18 deletions
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 212b6762e1..5fe28935b9 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -2725,27 +2725,34 @@ void DisplayServerX11::_poll_events() { { MutexLock mutex_lock(events_mutex); - // Non-blocking wait for next event and remove it from the queue. - XEvent ev; - while (XCheckIfEvent(x11_display, &ev, _predicate_all_events, nullptr)) { - // Check if the input manager wants to process the event. - if (XFilterEvent(&ev, None)) { - // Event has been filtered by the Input Manager, - // it has to be ignored and a new one will be received. - continue; - } + _check_pending_events(polled_events); + } + } +} - // Handle selection request events directly in the event thread, because - // communication through the x server takes several events sent back and forth - // and we don't want to block other programs while processing only one each frame. - if (ev.type == SelectionRequest) { - _handle_selection_request_event(&(ev.xselectionrequest)); - continue; - } +void DisplayServerX11::_check_pending_events(LocalVector<XEvent> &r_events) { + // Flush to make sure to gather all pending events. + XFlush(x11_display); - polled_events.push_back(ev); - } + // Non-blocking wait for next event and remove it from the queue. + XEvent ev; + while (XCheckIfEvent(x11_display, &ev, _predicate_all_events, nullptr)) { + // Check if the input manager wants to process the event. + if (XFilterEvent(&ev, None)) { + // Event has been filtered by the Input Manager, + // it has to be ignored and a new one will be received. + continue; + } + + // Handle selection request events directly in the event thread, because + // communication through the x server takes several events sent back and forth + // and we don't want to block other programs while processing only one each frame. + if (ev.type == SelectionRequest) { + _handle_selection_request_event(&(ev.xselectionrequest)); + continue; } + + r_events.push_back(ev); } } @@ -2798,6 +2805,9 @@ void DisplayServerX11::process_events() { MutexLock mutex_lock(events_mutex); events = polled_events; polled_events.clear(); + + // Check for more pending events to avoid an extra frame delay. + _check_pending_events(events); } for (uint32_t event_index = 0; event_index < events.size(); ++event_index) { diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index ded481f613..eb7725b768 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -268,6 +268,7 @@ class DisplayServerX11 : public DisplayServer { static void _poll_events_thread(void *ud); bool _wait_for_events() const; void _poll_events(); + void _check_pending_events(LocalVector<XEvent> &r_events); static Bool _predicate_all_events(Display *display, XEvent *event, XPointer arg); static Bool _predicate_clipboard_selection(Display *display, XEvent *event, XPointer arg); |