Embedding external window in GTK window

Reparenting an external window (UFO) and hosting it in a GTK window.

Is there a way to let the UFO receive all the native events, so that
it can work according to whatever toolkit it was built with?

Not really. If you’re embedding the window into a GTK top level, then GTK will have to process the events for the top level windowing system surface. If the toolkit of the embedded window opens its own display connection and has an event filter, it will process the events involving its own windowing surface.

If the toolkit of the embedded window supports event injection, you can use a filter on the window and propagate the events.

I experimented with two PyGtk applications, one called “frame”, the other called “target”. The target gets reparented. I saw that the target could receive a button-press-event. Unfortunately, it could not get a key-press-event. That’s why i asked the question.

I wanted to check whether it could work without an adaptation layer on both sides by just relying on the common native stuff, but out of curiosity, i tried gdk_window_add_filter, leaving the target as it is while the filter function simply returns GDK_FILTER_REMOVE. Surprisingly, the target can also receive the key event.

I don’t know if ignoring the events in this way makes it only work by chance or if it’s reliable in all cases, though.

Remember that reparenting a window only works in X11, not in Wayland…

Also, do you need to reparent any kind of window, or only GTK applications into other GTK applications?

I was experimenting to seek a possibility to implement a plugin system which is ui toolkit agnostic.

I haven’t considered Wayland yet, but i see that it contains a compatibility layer (just in case).

Another idea, which i still haven’t checked for feasibility, is perhaps creating a Window Manager application. You can’t have more than one WM per root window but who knows if it’s technically feasible to hook a WM to a subwindow? Just an idea.

For X11, there is already the XEmbed protocol, which is ui agnostic https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html (if I understand right what you want to do).

For Gtk inside Gtk I did a proof-of-concept some time ago that took advantage of the Gtk signal and properties system, along with the Glade files, to do it in a generic way over DBus (so it does work under Wayland too). In case that you want to take ideas, you can find it at https://github.com/rastersoft/dbuilder

XEmbed seems to confirm that creating a “sub” Window Manager, like i said before, is feasible.

Anyway embedding an external window is a general solution to this specific problem: a plugin is an extension, it’s implemented as a shared library. If it has a gui and both the app and the library use the same ui toolkit, the gui could be developed as a widget. When the toolkits are different, you have two application loops and they can’t live in the same thread. Hence the idea of an external application (or another thread). But making them communicate (exchanging data) already adds some glue, so i hoped that the embedding (gui) was trivial (no glue). Propagating the events or developing a WM adds some glue and this is no gain since the application could notify the plugin’s gui directly through a function.

By the way,

i rewrote “frame” and “target” using the C api and it seems that GDK_FILTER_REMOVE in the event filter has a different behavior. In PyGtk, key events reach the reparented window and the frame cannot even close. In C, the frame closes anyway, but the key events reach neither the frame nor the target. button-press-event always reaches the target.

The problem is Wayland… There you will have to create an “embedded Wayland compositor widget” with a full Wayland compositor inside, and pass, during launch the socket of this compositor to the application to embed, thus all the windows of this embedded application will be shown inside that “compositor widget”… At least if you don’t want to modify the toolkit used by de embedded application.

Quite complex in my opinion…

Never use XEmbed directly; you should use GtkSocket and GtkPlug, which take care of a lot of the pitfalls and traps of the XEmbed protocol for you.

Since GtkSocket and GtkPlug are implementations of the XEmbed protocol, they only work on X11. Embedding out of process surfaces in other windowing systems is simply not supported by GTK.

My strong suggestion is to stop trying to do this. Is just not going to be future-proof or portable, and it comes with a huge list of caveats on X11 as well.

You are completely right, Ebassi. My comment was more in the line of avoiding to reinvent the wheel.

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