Need to create a child native window

Hi,
I am working on an UI app using GTK4
I am creating a window (top level) and some widgets.
I want to add a child widget which will have its unique native surface.
So far I always get the surface of the top level window

Something like QWidget Class | Qt Widgets 6.7.2

any suggestions?

1 Like

You can’t: GTK4 does not have “child” windows. Only top level windows can have a native surface.

What are you actually trying to achieve?

1 Like

My plan is to create a vulkan surface from that child window

Then you’ll have to draw on an off screen buffer and create a GdkTexture with the contents. If you can create a GL texture, you can use GdkGLTextureBuilder; if you can get a dmabuf object, you can use GdkDmabufTextureBuilder; and if it all fails, you can use GdkMemoryTexture (or GdkMemoryTextureBuilder with GTK 4.16 once it’s released). You can check how GtkGLArea is implemented, if you want to create the Vulkan equivalent.

What you cannot do is create a native surface and render on it on your own; that’s not how GTK works.

oh, okay then , my current implementation draws to a texture and then I create a cairo surface from it…the cairo surface is used in gtkdrawingarea

Thanks for the information

Wouldn’t it be more efficient to transfer Vulkan output to an OpenGL texture and then use GtkGLArea to render it? Is that possible? If it is, is there any example that demonstrates Vulkan usage in GTK4? That would be a great resource.
I have a feeling that approach with GL texture created by Vulkan was initially suggested.

not really, my vulkan Framebuffer object is setup to draw to a texture of my choosing. (not the texture owned by the swapchain object). and moving data from Vulkan texture object to opengl texture object will require use of some extension (which may not always be available).

If the extension is available, it should be used. Cairo textures are always going to be slower than OpenGL/Vulkan textures.

Also if GTK4 doesnt give a unique surface, wouldnt opengl use a similar trick of deferred rendering (like I have). Also QT OpenGL Wi8dget does this.

GTK already defers the rendering: that’s why you cannot use a native surface to draw whatever you want. You can only draw on an offscreen surface, backend by some memory, and then tell GTK to use that memory to draw when it submits the render commands to the GPU. The memory can be represented by a GL texture object, or by a dmabuf file descriptor, to avoid additional copies. Vulkan already has an extension for using dmabuf, and so does OpenGL.

As I said above, your code should use three approaches:

  1. check if you can use the dmabuf extension, and create a GdkDmabufTextureBuilder
  2. check if you can use the GL extension, and create a GdkGLTextureBuilder
  3. fall back to a texture upload, using GdkMemoryTexture to copy the pixels

Once you have a GdkTexture, you can use the following code in your snapshot() virtual function implementation:

float w = gtk_widget_get_width (widget);
float h = gtk_widget_get_height (widget);
gtk_snapshot_append_texture (snapshot,
                             texture,
                             &GRAPHENE_RECT_INIT (0, 0, w h));
1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.