简体   繁体   中英

How do I connect wxWidgets, GTK2 widgets, and X11 windows?

I gather from the various wxWidgets class references in the documentation ( example ) that the wxWidgets used to build a GUI basically inherit from wxWindow . I see from the comments in the source of wxWidgets/window.cpp that each wxWindow has a pointer to some GtkWidget which is stored in the m_widget member of the wxWidget object. From the same source code comments I also see that m_wxwindow is a member of the wxWindow class, and may hold a pointer to a wxPizza object in the case of a wxWindow that has a client area for drawing and children.

I am working on an application that requires this sort of functionality. I am extending a wxWidgets class to create my own widget, which needs to contain a drawable X11 window, and I'm not really sure how to connect it all up and I'm having trouble finding a solution using the documentation.

When I am creating my custom widget (in the Create method), I can see that m_widget and m_wxwindow are both NULL , so from this and what I mentioned above, I gather these are the GtkWidget objects that I should be creating to form my client area. First, I tried this:

m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);

Which kind of works but not quite like I want it to. I'm able to get the XID from the GtkWidget and the X11 window behaves as expected. But this creates a new window outside of my main wxWidgets app window. What I want is this exact functionality except embedded inside my main wxWidgets app window. My custom class has been added to a wxBoxSizer like this:

sizer->Add(my_widget, 1, wxEXPAND | wxALL, 0);

Where sizer is a wxBoxSizer and my_widget is my custom widget.

I then tried creating m_widget as a few different types of GtkWidget but these all resulted in run-time errors when trying to use gtk_widget_realize and trying to get the XID .

// These don't work
m_widget = gtk_drawing_area_new();
m_widget = gtk_vbox_new(false, 0);

These are the error messages I'm getting when I tried the above:

Gtk: IA__gtk_widget_realize: assertion 'GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
Check failed: xwindow.

So I this is a multi-part question:

  • What is an appropriate GtkWidget type to get this accomplished? I need to be able to obtain a drawable X11 window ID ( XID ) and to embed it within the parent widget ( wxBoxSizer ).
  • Do I need to use both m_widget and m_wxwindow ? How do I set these up?
  • Do I need to do anything other than call sizer->Add() in order to connect this up with my wxBoxSizer ?

Thanks!

UPDATE: Sorry I forgot to mention, this is for GTK2. Thanks @andlabs for pointing this out.

UPDATE 2: @VZ. recommended that I clarify what I'm trying to do.

I'm using a library that needs access to an X11 window, but does not create that window itself. When I initialize the library, I need to pass it an X11 window handle ( XID ). The library will then draw into that window. I want to create this window to be inside my wxWidgets application. I'm trying to extend a wxWidgets class so that I will be able to add these X11 windows to widgets based on wxSizer in my application.

I know that gtk_window_new() is not what I'm looking for because it creates a new top-level window, while I want a window embedded in my wxWidgets application. It's just something I tried along the way.

It would be really helpful to know what exactly are you trying to do. You speak about GtkWidgets s but then show gtk_window_new() call which creates a new (top level) window, which is something quite different and can only be represented by wxTopLevelWindow at wx level.

Do you need to wrap an existing GtkWidget in a wxWidgets application? If so, you should just use wxNativeWindow . Even if you don't use the latest version with it, you can still easily reuse/duplicate its code.

Do you need to wrap an existing XWindow ? Then it's more difficult because you can't easily do it with wxGTK. You could use wxX11, but this port is not in a good state, so it's probably not the best idea, unless your needs are very limited. The best would probably be to wrap X window in a GtkWidget first and then proceed as above.


After the update, it seems that you just need a XID of an existing window. This is even simpler than embedding a GTK+ widget as you can get the GtkWidget using wxWindow::GetHandle() , then use gtk_widget_get_window() to get its GdkWindow and finally use GDK_WINDOW_XID() to get the XID.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM