Fix X11 fd polling initialization in glib main loop

This resolves Bug 1358
pull/2/head
Timothy Pearson 12 years ago
parent a7865cf691
commit 72eba91414

@ -86,6 +86,10 @@ class QEventLoopPrivate
public: public:
QEventLoopPrivate() QEventLoopPrivate()
{ {
#if defined(Q_WS_X11)
xfd = -1;
x_gPollFD.fd = -1;
#endif // Q_WS_X11
reset(); reset();
} }
@ -106,9 +110,7 @@ public:
#if defined(Q_WS_X11) #if defined(Q_WS_X11)
int xfd; int xfd;
GPollFD x_gPollFD;
GPollFD x_gPollFD;
#endif // Q_WS_X11 #endif // Q_WS_X11
int thread_pipe[2]; int thread_pipe[2];
@ -119,7 +121,7 @@ public:
QPtrList<QSockNotGPollFD> sn_pending_list; QPtrList<QSockNotGPollFD> sn_pending_list;
// store flags for one iteration // store flags for one iteration
uint pev_flags; uint pev_flags;
// My GSource // My GSource
GSource * gSource; GSource * gSource;

@ -82,15 +82,32 @@ static GSourceFuncs qt_gsource_funcs = {
static gboolean qt_gsource_prepare ( GSource *source, static gboolean qt_gsource_prepare ( GSource *source,
gint *timeout ) gint *timeout )
{ {
QtGSource * qtGSource; QtGSource * qtGSource = (QtGSource*) source;
qtGSource = (QtGSource*) source; QEventLoop* candidateEventLoop = qtGSource->qeventLoop;
return qtGSource->qeventLoop->gsourcePrepare(source, timeout); QEventLoop* activeThreadEventLoop = QApplication::eventLoop();
if (candidateEventLoop == activeThreadEventLoop) {
return candidateEventLoop->gsourcePrepare(source, timeout);
}
else {
// Prepare failed
return FALSE;
}
} }
static gboolean qt_gsource_check ( GSource *source ) static gboolean qt_gsource_check ( GSource *source )
{ {
QtGSource * qtGSource = (QtGSource*) source; QtGSource * qtGSource = (QtGSource*) source;
return qtGSource->qeventLoop->gsourceCheck(source); QEventLoop* candidateEventLoop = qtGSource->qeventLoop;
QEventLoop* activeThreadEventLoop = QApplication::eventLoop();
if (candidateEventLoop == activeThreadEventLoop) {
return candidateEventLoop->gsourceCheck(source);
}
else {
// Check failed
return FALSE;
}
} }
static gboolean qt_gsource_dispatch ( GSource *source, static gboolean qt_gsource_dispatch ( GSource *source,
@ -205,25 +222,24 @@ void QEventLoop::init()
qtGSource->qeventLoop = this; qtGSource->qeventLoop = this;
// init main loop and attach gsource // init main loop and attach gsource
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside init(1)\n"); printf("inside init(1)\n");
#endif #endif
g_main_loop_new (d->ctx, 1); g_main_loop_new (d->ctx, 1);
g_source_attach( (GSource*)qtGSource, d->ctx ); g_source_attach( (GSource*)qtGSource, d->ctx );
d->gSource = (GSource*) qtGSource; d->gSource = (GSource*)qtGSource;
// poll for X11 events // poll for X11 events
if ( qt_is_gui_used && QApplication::isGuiThread() ) { if ( qt_is_gui_used && QApplication::isGuiThread() ) {
d->x_gPollFD.fd = d->xfd; d->x_gPollFD.fd = d->xfd;
d->x_gPollFD.events = G_IO_IN | G_IO_HUP; d->x_gPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
g_source_add_poll(d->gSource, &d->x_gPollFD); g_source_add_poll(d->gSource, &d->x_gPollFD);
} }
// poll thread-pipe // poll thread-pipe
d->threadPipe_gPollFD.fd = d->thread_pipe[0]; d->threadPipe_gPollFD.fd = d->thread_pipe[0];
d->threadPipe_gPollFD.events = G_IO_IN | G_IO_HUP; d->threadPipe_gPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
g_source_add_poll(d->gSource, &d->threadPipe_gPollFD); g_source_add_poll(d->gSource, &d->threadPipe_gPollFD);
@ -279,7 +295,7 @@ bool QEventLoop::processX11Events()
ProcessEventsFlags flags = d->pev_flags; ProcessEventsFlags flags = d->pev_flags;
// process events from the X server // process events from the X server
XEvent event; XEvent event;
int nevents = 0; int nevents = 0;
#if defined(QT_THREAD_SUPPORT) #if defined(QT_THREAD_SUPPORT)
QMutexLocker locker( QApplication::qt_mutex ); QMutexLocker locker( QApplication::qt_mutex );
@ -295,49 +311,50 @@ bool QEventLoop::processX11Events()
// also flushes output buffer // also flushes output buffer
while ( XPending( QPaintDevice::x11AppDisplay() ) ) { while ( XPending( QPaintDevice::x11AppDisplay() ) ) {
if ( d->shortcut ) { if ( d->shortcut ) {
return FALSE; return FALSE;
} }
XNextEvent( QPaintDevice::x11AppDisplay(), &event ); XNextEvent( QPaintDevice::x11AppDisplay(), &event );
if ( flags & ExcludeUserInput ) { if ( flags & ExcludeUserInput ) {
switch ( event.type ) { switch ( event.type ) {
case ButtonPress: case ButtonPress:
case ButtonRelease: case ButtonRelease:
case MotionNotify: case MotionNotify:
case XKeyPress: case XKeyPress:
case XKeyRelease: case XKeyRelease:
case EnterNotify: case EnterNotify:
case LeaveNotify: case LeaveNotify:
continue;
case ClientMessage:
{
// from qapplication_x11.cpp
extern Atom qt_wm_protocols;
extern Atom qt_wm_take_focus;
extern Atom qt_qt_scrolldone;
// only keep the wm_take_focus and
// qt_qt_scrolldone protocols, discard all
// other client messages
if ( event.xclient.format != 32 )
continue; continue;
if ( event.xclient.message_type == qt_wm_protocols || case ClientMessage:
(Atom) event.xclient.data.l[0] == qt_wm_take_focus ) {
break; // from qapplication_x11.cpp
if ( event.xclient.message_type == qt_qt_scrolldone ) extern Atom qt_wm_protocols;
break; extern Atom qt_wm_take_focus;
} extern Atom qt_qt_scrolldone;
default: break; // only keep the wm_take_focus and
// qt_qt_scrolldone protocols, discard all
// other client messages
if ( event.xclient.format != 32 )
continue;
if ( event.xclient.message_type == qt_wm_protocols ||
(Atom) event.xclient.data.l[0] == qt_wm_take_focus )
break;
if ( event.xclient.message_type == qt_qt_scrolldone )
break;
}
default: break;
} }
} }
nevents++; nevents++;
if ( qApp->x11ProcessEvent( &event ) == 1 ) if ( qApp->x11ProcessEvent( &event ) == 1 ) {
return TRUE; return TRUE;
}
} }
} }
} }
@ -463,14 +480,9 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
printf("inside gsourceCheck(1)\n"); printf("inside gsourceCheck(1)\n");
#endif #endif
// Socketnotifier events? // Socketnotifier events?
QPtrList<QSockNotGPollFD> *list = &d->sn_list; QPtrList<QSockNotGPollFD> *list = &d->sn_list;
//if ( list ) { //if ( list ) {
QSockNotGPollFD *sn = list->first(); QSockNotGPollFD *sn = list->first();
while ( sn ) { while ( sn ) {
if ( sn->gPollFD.revents ) if ( sn->gPollFD.revents )
@ -500,10 +512,9 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
return TRUE; // we got more X11 events! return TRUE; // we got more X11 events!
} }
// check if we have timers to activate?
// check if we have timers to activate?
timeval * tm =qt_wait_timer(); timeval * tm =qt_wait_timer();
if (tm && (tm->tv_sec == 0 && tm->tv_usec == 0 )) { if (tm && (tm->tv_sec == 0 && tm->tv_usec == 0 )) {
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) qtwaittimer!\n"); printf("inside gsourceCheck(2) qtwaittimer!\n");
@ -513,7 +524,6 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
} }
// nothing to dispatch // nothing to dispatch
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) nothing to dispatch!\n"); printf("inside gsourceCheck(2) nothing to dispatch!\n");
#endif #endif
@ -534,7 +544,6 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
#endif #endif
int nevents=0; int nevents=0;
ProcessEventsFlags flags = d->pev_flags; ProcessEventsFlags flags = d->pev_flags;
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
@ -588,12 +597,10 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
//return (nevents > 0); //return (nevents > 0);
// now process x11 events! // now process x11 events!
#ifdef DEBUG_QT_GLIBMAINLOOP #ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceDispatch(2) hasPendingEvents=%d\n", hasPendingEvents()); printf("inside gsourceDispatch(2) hasPendingEvents=%d\n", hasPendingEvents());
#endif #endif
if (hasPendingEvents()) { if (hasPendingEvents()) {
// color approx. optimization - only on X11 // color approx. optimization - only on X11
qt_reset_color_avail(); qt_reset_color_avail();
@ -627,6 +634,11 @@ void QEventLoop::appStartingUp()
{ {
if ( qt_is_gui_used ) { if ( qt_is_gui_used ) {
d->xfd = XConnectionNumber( QPaintDevice::x11AppDisplay() ); d->xfd = XConnectionNumber( QPaintDevice::x11AppDisplay() );
if ( (d->x_gPollFD.fd == -1) && QApplication::isGuiThread() ) {
d->x_gPollFD.fd = d->xfd;
d->x_gPollFD.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
g_source_add_poll(d->gSource, &d->x_gPollFD);
}
} }
} }

Loading…
Cancel
Save