[osg-users] osgViewer GraphicsWindowX11 Event Handling

Eric Stancliff ericstancliff at yahoo.com
Fri Oct 11 14:23:40 PDT 2019

I finally figured this issue out!  I kept coming back to it with no luck, but I finally figured out that Qt was capturing all my events before the viewer had the chance to intercept them.  The below code works perfectly!


#include <QWidget> //must include before any x11

#ifdef WIN32

#include <QWidget>
#include <osgViewer/api/Win32/GraphicsWindowWin32>
#define OSG_PLATFORM_WINDOW osgViewer::GraphicsWindowWin32
#include <osgViewer/api/X11/GraphicsWindowX11>
#define OSG_PLATFORM_WINDOW osgViewer::GraphicsWindowX11
#define WINDOW_HANDLE Window
#include <X11/extensions/XInput2.h>
#include <QtX11Extras/QX11Info>

osg::GraphicsContext::Traits* createWindowTraits(QWidget* OwningWidget)
    auto traits = new osg::GraphicsContext::Traits();
    traits->x = OwningWidget->x();
    traits->y = OwningWidget->y();
    traits->width = OwningWidget->size().width();
    traits->height = OwningWidget->size().height();
    traits->doubleBuffer = true;
    if (OwningWidget)
        OSG_PLATFORM_WINDOW::WindowData* data = new OSG_PLATFORM_WINDOW::WindowData(OwningWidget->winId());
        traits->inheritedWindowData = data;
    return traits;

void setOwningWidgetOnGraphicsContext(QWidget* widget, osg::GraphicsContext* context)
#ifdef __GNUC__
    auto bmwindow = dynamic_cast<osgViewer::GraphicsWindowX11*>(context);
    //Clear the event mask.  We don't want Qt stealing our events, let OSG have them
    XSetWindowAttributes swatt;
    swatt.event_mask =  0;
    XChangeWindowAttributes(QX11Info::display(), widget->winId(), CWEventMask, &swatt);

    //XI2 Mouse Events
    int n;
    XIEventMask *xi_masks = XIGetSelectedEvents( QX11Info::display(), widget->winId(), &n );
    if( xi_masks != nullptr )
        for( int i = 0; i < n; i++ )
            if( xi_masks[i].mask_len >= 1 )
                xi_masks[i].mask[0] &= ~XI_ButtonPressMask;
                xi_masks[i].mask[0] &= ~XI_ButtonReleaseMask;
                xi_masks[i].mask[0] &= ~XI_MotionMask;

        XISelectEvents(  QX11Info::display(), widget->winId(), xi_masks, n );
        XFree( xi_masks );

    //Now subscribe for ourselves

    XSelectInput( bmwindow->getEventDisplay(), widget->winId(), ExposureMask | StructureNotifyMask |
                  KeyPressMask | KeyReleaseMask |
                  PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
                  KeymapStateMask | FocusChangeMask | EnterWindowMask );

    XFlush( bmwindow->getEventDisplay() );
    XSync( bmwindow->getEventDisplay(), 0 );

Read this topic online here:

More information about the osg-users mailing list