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

@ -82,15 +82,32 @@ static GSourceFuncs qt_gsource_funcs = {
static gboolean qt_gsource_prepare ( GSource *source,
gint *timeout )
{
QtGSource * qtGSource;
qtGSource = (QtGSource*) source;
return qtGSource->qeventLoop->gsourcePrepare(source, timeout);
QtGSource * qtGSource = (QtGSource*) source;
QEventLoop* candidateEventLoop = qtGSource->qeventLoop;
QEventLoop* activeThreadEventLoop = QApplication::eventLoop();
if (candidateEventLoop == activeThreadEventLoop) {
return candidateEventLoop->gsourcePrepare(source, timeout);
}
else {
// Prepare failed
return FALSE;
}
}
static gboolean qt_gsource_check ( GSource *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,
@ -205,25 +222,24 @@ void QEventLoop::init()
qtGSource->qeventLoop = this;
// init main loop and attach gsource
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside init(1)\n");
#endif
g_main_loop_new (d->ctx, 1);
g_source_attach( (GSource*)qtGSource, d->ctx );
d->gSource = (GSource*) qtGSource;
d->gSource = (GSource*)qtGSource;
// poll for X11 events
if ( qt_is_gui_used && QApplication::isGuiThread() ) {
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);
}
// poll thread-pipe
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);
@ -279,7 +295,7 @@ bool QEventLoop::processX11Events()
ProcessEventsFlags flags = d->pev_flags;
// process events from the X server
XEvent event;
int nevents = 0;
int nevents = 0;
#if defined(QT_THREAD_SUPPORT)
QMutexLocker locker( QApplication::qt_mutex );
@ -295,49 +311,50 @@ bool QEventLoop::processX11Events()
// also flushes output buffer
while ( XPending( QPaintDevice::x11AppDisplay() ) ) {
if ( d->shortcut ) {
return FALSE;
return FALSE;
}
XNextEvent( QPaintDevice::x11AppDisplay(), &event );
if ( flags & ExcludeUserInput ) {
switch ( event.type ) {
case ButtonPress:
case ButtonRelease:
case MotionNotify:
case XKeyPress:
case XKeyRelease:
case EnterNotify:
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 )
case ButtonPress:
case ButtonRelease:
case MotionNotify:
case XKeyPress:
case XKeyRelease:
case EnterNotify:
case LeaveNotify:
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;
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;
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++;
if ( qApp->x11ProcessEvent( &event ) == 1 )
return TRUE;
if ( qApp->x11ProcessEvent( &event ) == 1 ) {
return TRUE;
}
}
}
}
@ -463,14 +480,9 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
printf("inside gsourceCheck(1)\n");
#endif
// Socketnotifier events?
QPtrList<QSockNotGPollFD> *list = &d->sn_list;
//if ( list ) {
QSockNotGPollFD *sn = list->first();
while ( sn ) {
if ( sn->gPollFD.revents )
@ -500,10 +512,9 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
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();
if (tm && (tm->tv_sec == 0 && tm->tv_usec == 0 )) {
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) qtwaittimer!\n");
@ -513,7 +524,6 @@ bool QEventLoop::gsourceCheck(GSource *gs) {
}
// nothing to dispatch
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceCheck(2) nothing to dispatch!\n");
#endif
@ -534,7 +544,6 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
#endif
int nevents=0;
ProcessEventsFlags flags = d->pev_flags;
#ifdef DEBUG_QT_GLIBMAINLOOP
@ -588,12 +597,10 @@ bool QEventLoop::gsourceDispatch(GSource *gs) {
//return (nevents > 0);
// now process x11 events!
#ifdef DEBUG_QT_GLIBMAINLOOP
printf("inside gsourceDispatch(2) hasPendingEvents=%d\n", hasPendingEvents());
#endif
if (hasPendingEvents()) {
// color approx. optimization - only on X11
qt_reset_color_avail();
@ -627,6 +634,11 @@ void QEventLoop::appStartingUp()
{
if ( qt_is_gui_used ) {
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