summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-12-09 16:33:47 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-12-09 16:33:47 -0600
commit72eba91414074b25fe9cd227a3fc6fe0dc612bf4 (patch)
tree118279b027acc0686a0b1a7e57b92a8fc746e935
parenta7865cf6918fc3457d0141522e791a92bcf62810 (diff)
downloadqt3-72eba91414074b25fe9cd227a3fc6fe0dc612bf4.tar.gz
qt3-72eba91414074b25fe9cd227a3fc6fe0dc612bf4.zip
Fix X11 fd polling initialization in glib main loop
This resolves Bug 1358
-rw-r--r--src/kernel/qeventloop_glib_p.h10
-rw-r--r--src/kernel/qeventloop_x11_glib.cpp116
2 files changed, 70 insertions, 56 deletions
diff --git a/src/kernel/qeventloop_glib_p.h b/src/kernel/qeventloop_glib_p.h
index ef0e6ac..663f20e 100644
--- a/src/kernel/qeventloop_glib_p.h
+++ b/src/kernel/qeventloop_glib_p.h
@@ -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;
diff --git a/src/kernel/qeventloop_x11_glib.cpp b/src/kernel/qeventloop_x11_glib.cpp
index 771428b..877ff44 100644
--- a/src/kernel/qeventloop_x11_glib.cpp
+++ b/src/kernel/qeventloop_x11_glib.cpp
@@ -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);
+ }
}
}