2

I have an existing (large) X application based on raw XLib. I would like to add additional windows to this application using Qt 4. What is the best way to do this?

Research so far:

(If it matters for the details, I'm looking at Qt 4.7.4 right now.)

My existing application calls XtAppNextEvent in a loop to handle its events. What I am hoping to do is replace this event loop with a Qt-based event loop, let Qt handle its own events, and make calls to XtDispatchEvent for non-Qt events.

I have located the part of Qt that processes X events (in src/gui/kernel/qapplication_x11.cpp, QApplication::x11ProcessEvent). I believe the key part of this function is:

QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window);

which determines whether the event refers to a window that Qt knows about. For non-Qt windows, this returns NULL. There are a couple of processing exceptions after this, then a block like:

if (!widget) {                     // don't know this windows
    QWidget *popup = QApplication::activePopupWidget();
    if (popup) {
        // ... bunch of stuff not involving widget ...
    }
    return -1;
}

What I was hoping was there would be an event callback at this point that was called for non-Qt related window events, so I could simply implement a virtual function in my derived QApplication and proceed with the application's existing event processing. I can add such a function and rebuild Qt, but I would rather avoid that if possible.

Am I on the right track with this, or might there be a better way?

I have found existing questions similar to this, but they're all for Windows (MFC or .NET). This is specific to X.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • I don't believe you need to replace the existing event loop. You could let the original event loop continue handling the existing events, and just add a Qt event loop to handle Qt events. See http://stackoverflow.com/questions/22289423/how-to-avoid-qt-app-exec-blocking-main-thread/22290909#22290909 for info on how to start a Qt event loop in a secondary thread. If you want to embed the Qt window into your existing window, see QX11EmbedWidget: http://qt-project.org/doc/qt-4.8/qx11embedwidget.html I'm not 100% sure if this fits your use case though -- does it? – JKSH Nov 20 '14 at 08:01
  • @JKSH: Unfortunately, threads won't work for me because both the Qt parts and non-Qt parts depend on shared components which aren't thread safe (that is, if they're in the same process, there must only be one thread). I will look into XEmbed, that may be a good way to handle this. – Greg Hewgill Nov 20 '14 at 18:37

1 Answers1

2

The solution I ended up with was to find a copy of the Qt Motif Extension (it's no longer available from Digia directly as it is now unsupported, but you can still find copies of qtmotifextension-2.7-opensource.zip). In there, the qtmotif.h and qtmotif.cpp modules show how to create a QAbstractEventDispatcher that handles X events for both Xt/Motif and Qt components.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285