I have a Linux, X11 application with main window (W0) and floating tool/palette window (Wt).
Wt must to be always above the W0 and when displayed for the first time it must appears in the upper-right corner of W0 in order to not overlap the view to W0.
Also, Wt must be decorated with title bar and resizable border by the Window manager.
Wt has the following properties set:
WM_TRANSIENT_FOR(WINDOW): window id # 0x5600002 <------ This is the id of the W0 window!
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_UTILITY
_NET_WM_STATE(ATOM) = _NET_WM_STATE_SKIP_PAGER, _NET_WM_STATE_SKIP_TASKBAR
The problem is with the WM_TRANSIENT_FOR property. When I don't set it, the window is properly positioned, but when the main window is activated, the Wt window falls behind and is overlapped by the main window.
When I set WM_TRANSIENT_FOR, the window is correctly always above W0, but the window manager positions Wt at the center of W0 ignoring the x and y passed to CreateWindow request.
I have tried different tricks with setting different values to _NET_WM_WINDOW_TYPE property, with WM_NORMAL_HINTS, setting PPosition (which seems to be deprecated), but all in vain.
At the end, as an act of desperation, I have tried to set WM_TRANSIENT_FOR after the window is mapped (and handled by WM). Like this:
Create Wt
Map Wt
Set WM_TRANSIENT_FOR to Wt
And this trick does not worked at all.
But later I have tried to put some pause between the mapping the window and WM_TRANSIENT_FOR property set:
Create Wt
Map Wt
Sleep(1ms)
Set WM_TRANSIENT_FOR to Wt
And at the end, this trick do the job - Wt is correctly positioned and the window manager is not messing with centering it.
But well, I am not really pleased with this "solution". It is very ugly and should not be used at all.
So, the questions are:
What is the proper solution of this problem. How to set simultaneously WM_TRANSIENT_FOR and the window position and windows manager not to center it against the main window?
Why the small pause so drastically changes the behavior of the Window manager? At the end, the whole X11 protocol should not be so sensitive to the delays in the client-server communications that can be caused by some network delays.
The Window manager is XFWM, but I am not sure it is so important. Will make some experiments with another WMs and will edit the question if there are differences.
P.S. Please, don't suggest Qt, GTK, FLTK, whatever toolkit. I know about their existence.
You won't want to hear this, but the proper solution is to leave window management to the window manager. Don't try to do this.
The question is "what is the state of your window by the time the window manager starts managing it". If you immediately change some state after sending a
MapWindow
request, this state change will likely be applied before the WM queries the window state. If you wait a bit, this state change is only applied afterwards.I think (but am not sure) that setting
WM_TRANSIENT_FOR
only makes sense before mapping your window.From the top of my head, I don't know about any properties / simple solution to do this.
I just opened
gimp
and un-docked some toolbar. Looking at this window withxprop
doesn't find any special / magic properties. I don't what Gimp / GTK does do have this toolbar above the main window. If you can figure this out, this might help you.However, there are no guarantees. From ICCCM § 4.1.5: