X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b555c37c8ec878413674e72734ecc1594bd8bf95..ba637f22e61113ab2296936f9a101e929cc05711:/src/x11/evtloop.cpp?ds=sidebyside diff --git a/src/x11/evtloop.cpp b/src/x11/evtloop.cpp index dd8a8f030e..15e344b6f0 100644 --- a/src/x11/evtloop.cpp +++ b/src/x11/evtloop.cpp @@ -32,6 +32,9 @@ #include "wx/x11/private.h" #include "X11/Xlib.h" +#include +#include + // ---------------------------------------------------------------------------- // wxEventLoopImpl // ---------------------------------------------------------------------------- @@ -42,8 +45,8 @@ public: // ctor wxEventLoopImpl() { SetExitCode(0); m_keepGoing = FALSE; } - // process an XEvent - void ProcessEvent(XEvent* event); + // process an XEvent, return TRUE if it was processed + bool ProcessEvent(XEvent* event); // generate an idle message, return TRUE if more idle time requested bool SendIdleEvent(); @@ -71,15 +74,17 @@ public: // wxEventLoopImpl message processing // ---------------------------------------------------------------------------- -void wxEventLoopImpl::ProcessEvent(XEvent *event) +bool wxEventLoopImpl::ProcessEvent(XEvent *event) { // give us the chance to preprocess the message first - if ( !PreProcessEvent(event) ) - { - // if it wasn't done, dispatch it to the corresponding window - if (wxTheApp) - wxTheApp->ProcessXEvent((WXEvent*) event); - } + if ( PreProcessEvent(event) ) + return TRUE; + + // if it wasn't done, dispatch it to the corresponding window + if (wxTheApp) + return wxTheApp->ProcessXEvent((WXEvent*) event); + + return FALSE; } bool wxEventLoopImpl::PreProcessEvent(XEvent *event) @@ -168,7 +173,7 @@ int wxEventLoop::Run() #endif if (!m_impl->SendIdleEvent()) { -#if 0 // wxUSE_THREADS +#if wxUSE_THREADS // leave the main loop to give other threads a chance to // perform their GUI work wxMutexGuiLeave(); @@ -221,8 +226,53 @@ bool wxEventLoop::Dispatch() // TODO allowing for threads, as per e.g. wxMSW +#if 0 XNextEvent((Display*) wxGetDisplay(), & event); - m_impl->ProcessEvent(& event); +#endif + + // This now waits until either an X event is received, + // or the select times out. So we should now process + // wxTimers in a reasonably timely fashion. However it + // does also mean that idle processing will happen more + // often, so we should probably limit idle processing to + // not be repeated more than every N milliseconds. + + if (XPending((Display*) wxGetDisplay()) == 0) + { +#if wxUSE_NANOX + GR_TIMEOUT timeout = 10; // Milliseconds + // Wait for next event, or timeout + GrGetNextEventTimeout(& event, timeout); + + // Fall through to ProcessEvent. + // we'll assume that ProcessEvent will just ignore + // the event if there was a timeout and no event. + +#else + struct timeval tv; + tv.tv_sec=0; + tv.tv_usec=10000; // TODO make this configurable + int fd = ConnectionNumber((Display*) wxGetDisplay()); + fd_set readset; + FD_ZERO(&readset); + FD_SET(fd, &readset); + if (select(fd+1, &readset, NULL, NULL, & tv) == 0) + { + // Timed out, so no event to process + return TRUE; + } + else + { + // An event was pending, so get it + XNextEvent((Display*) wxGetDisplay(), & event); + } +#endif + } else + { + XNextEvent((Display*) wxGetDisplay(), & event); + } + + (void) m_impl->ProcessEvent(& event); return TRUE; }