summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2021-10-28 08:57:37 +0200
committerGitHub <noreply@github.com>2021-10-28 08:57:37 +0200
commitd4067e661cf7d54ff24c223b7d0a7388dc08c6b2 (patch)
tree924ae5c1ba17e4cdab54a2c5356026dc23d1da0f
parent7bb568328ff6e7d2d774023aff4513d90cfef98d (diff)
parentba96fc6a4dff123c748d7c554147f8ade047f76c (diff)
Merge pull request #54326 from nekomatata/x11-fix-input-delay
-rw-r--r--platform/linuxbsd/display_server_x11.cpp46
-rw-r--r--platform/linuxbsd/display_server_x11.h1
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);