Crash on Linux when initializing display

I'm getting a crash when creating a new Xw_Window object. We're using a wxWidgets panel to display but I get a crash
in the Aspect Window creation section below. Is there something I'm doing wrong? Works fine on Windows.
Thanks very much.

/* --------------------------------------------------------------------------------------------------- */
    static Handle(Aspect_DisplayConnection) displayConnection;
    if( displayConnection.IsNull() )
        displayConnection = new Aspect_DisplayConnection();

    // Create OCCT viewer.
    Handle(OpenGl_GraphicDriver) graphicDriver = new OpenGl_GraphicDriver(displayConnection, false);

    m_viewer = new V3d_Viewer(graphicDriver);

    // Lighting code ....

    // AIS context.
    m_context = new AIS_InteractiveContext(m_viewer);

    // Configure some global props.
    const Handle(Prs3d_Drawer) &contextDrawer = m_context->DefaultDrawer();
    if( !contextDrawer.IsNull() )
    {
        const Handle(Prs3d_ShadingAspect) &SA = contextDrawer->ShadingAspect();
        const Handle(Graphic3d_AspectFillArea3d) &FA = SA->Aspect();
        contextDrawer->SetFaceBoundaryDraw(true) ; // Draw edges.
        FA->SetEdgeOff();

        // Fix for inifinite lines has been reduced to 1000 from its default value 500000.
        contextDrawer->SetMaximalParameterValue(1000);
    }

    // Main view creation.
    m_view = m_viewer->CreateView();
    m_view->SetImmediateUpdate(false);

    // Event manager is constructed when both contex and view become available.
    m_evtMgr = new OcctViewer(m_view, m_context);

    WXWidget handle = (WXWidget) this->GetHandle() ;
    if( handle == NULL )
        return ;

    // Aspect window creation
#ifdef _LINUX_TARGET
    m_Window = new Xw_Window(displayConnection, (Aspect_Handle) handle); // CRASHES HERE EVERYTIME
    // m_Window = new Xw_Window(displayConnection, "3D Window", 0, 0, 400, 600); // DOES NOT CRASH WHEN USING THIS LINE.
#else
    m_Window = new WNT_Window((Aspect_Handle) handle);
#endif
    m_view->SetWindow(m_Window, nullptr);

    if( !m_Window->IsMapped() )
    {
        m_Window->Map();
    }
    m_view->MustBeResized();

/* --------------------------------------------------------------------------------------------------- */
Kirill Gavrilov's picture

m_Window = new Xw_Window(displayConnection, (Aspect_Handle) handle); // CRASHES HERE EVERYTIME

How exactly does this crash? If it throws Aspect_WindowDefinitionError, then you are likely passing 0 instead of X11 window handle (but I see you have a NULL check above). If it crashes on calling XGetWindowAttributes() - then probably the window returned by (WXWidget)this->GetHandle() is not X11 window or comes from another X11 display (in case if you have multiple X11 servers running and WxWidgets uses non-default somehow).

If I understand wxWindow::GetHandle() description correctly:

Returns the platform-specific handle of the physical window. Cast it to an appropriate handle, such as HWND for Windows, Widget for Motif, GtkWidget for GTK or WinHandle for PalmOS.

this method doesn't return X11 window at all! Most likely it returns GtkWidget on Linux platform (just guessing) - so that you need to do a round trip and fetch X11 window id from GtkWidget. This doesn't guarantee, though, that 3D Viewer will work like that, but at least it should not crash... And on modern Linux platforms GtkWidget might create a Wayland window within Wayland interactive session instead of X11!

Robert Bachman's picture

You are right. It returns a GtkWidget and I needed to convert it to a window handle.

I updated the code and it now works. See below.

Thanks.

    WXWidget handle = (WXWidget) this->GetHandle() ;
    if( handle == NULL )
        return ;

    // Aspect window creation
#ifdef _LINUX_TARGET
    Window Xwin = gdk_x11_drawable_get_xid(gtk_widget_get_window(handle));
    m_Window = new Xw_Window(displayConnection, (Aspect_Drawable) Xwin);
#else
    m_Window = new WNT_Window((Aspect_Handle) handle);
#endif