No events received after reparenting undecorated glfw window (x11)

tl:dr: I reparented an undecorated glfw window in another X11 window and get no events. Why?. reparenting a decorated window works fine.

My use case is that a host application provides a window handle for my plugin application (a vst plugin for those interested), the window provided by the host is a A HWND on Windows and an X11 Window on Linux. I’m using DearImGui with the glfw backend for this. As it currently doesn’t seem possible to create a glfw window from an existing native window handle (from this issue https://github.com/glfw/glfw/pull/25), my approach has been to “dock” a glfw window in the window provided by the host, i.e. repareting the native window handle of the glfw window to make it a child window of the window provided by the host.

So far so good. This worked and accieved the desired result, almost. Under linux (Mint 19 with Cinnamon) it turned out that the X11 window i needed to reparent was in fact not the one given by glfwGetX11Window(), but the parent of that window. Finding out the parent of that window with XQueryTree() and reparenting the parent instead did the trick. But then I ended up with double titlebars, one for the host provided window and one for the glfw window.

Next I disabled the title bar with glfwWindowHint(GLFW_DECORATED, GLFW_FALSE), and suddenly the glfw window does not have a hidden parent anymore, and I can reparent it directly. Then I only get a single title bar, success! But now I don’t get any window events so a can’t make anything useful with the window.

An ugly workaround so far has been to use the glfw window decorated, figure out the height of the title bar and pass that as a negative y argument to XReparentWindow() to move the glfw window up just enought to hide the title bar, but that doesn’t feel like the right way to do it. Or am I just missing something crucial about the way Xlib or glfw handles events?

So how can I succesfully reparent an undecorated window and still get all the events. I’m also open to the idea that I’m aproaching this completely the wrong way, please point me in the right direction if that’s the case :slight_smile:

On Windows 10, things actually worked much smoother. There I could set the glfw window undecorated, reparent it to the host window, and I got a docked glfw window with only a single title bar and a working event loop.

There is an issue tracking this feature request:

1 Like

Cool I’m following the thread on Github, is there any work being done on this recently or even a feature branch? I checked the most recently updated branches on Github, but couldn’t find anything.

I don’t know the current situation, sorry.

1 Like

Ok, thanks anyway. I’ll see if I can try any of the suggestions in the thread.

Dug some more into this today if anyone in interested in hearing. It turned out that calling XSetFocus() on the undecorated glfw window after reparenting it made it receive keyboard events again. But as soon as I moved the window or changed to another window and then back to the reparented glfw window, it stoped working.

So then I tried calling XSetFocus() for every EnterNotify event received when the mouse pointer enters the window. And now i can interact with the window using the mouse as intended. Now I’m not sure if it’s good practice to steal focus like this, QT seems to do this with button presses and it wasn’t always appreciated (https://bugreports.qt.io/browse/QTBUG-40202). Stealing focus when simply hovering seems even worse. But could work until I find a better solution.

I was trying log events using xev -id window_id but for some reason I couldn’t trace any ButtonPress/ButtonRelease events with it. Funnily enough KeyEvents seems to be always sent to the window, even without explicitly requesting focus. Could there be a pointer grab going on here? I haven’t really figured out how those work yet.