After some research i found the solution using Python-Xlib.
In the code that generates the window, it is possible to get the window ID, which is the reference for the window on X. Depending on the GUI kit used, the method to get this ID may vary. Qt4 provides QWidget.winId()
, Gtk+2 has its own means to reserve space for a window, and i have not tried with Gtk+3, but i have been told there should be a window_id
attribute.
Since the call to X to reserve space for the window can be done only once the window is displayed, in most cases it will be necessary to make the query after the main event loop was entered.
The example below shows a case example with Qt4 using PyQt4. In order to get the window once it is displayed, a thread is launched before the QApplication enters its main loop and that thread keeps polling X until it has managed to "grab" the window. In the following example space is reserved at the top of the screen, with a height equivalent to that of the QWidget we reserve space for.
def fix_window(self):
set = False
while set == False:
try:
window = myXwindow.Window(self.parent().winId())
if window != None:
height = self.parent().height()
window.reserve_space(0, 0, height, 0)
set = True
else:
self.sleep(1)
except:
raise
In the example here above, the myXwindow
is a custom module using Python-Xlib. The following is the content of the module, where Xlib queries X for Display() and subsequently creates a window object which is an abstract model to reference our window as displayed by X. After changing the attributes of this model we can Display().sync() in order to apply changes. The method to reserve space is change_property()
in which a series of arguments are passed according to the Freedesktop.org Standards.
class Window(object):
def __init__(self, windowID):
self._display = Display()
self._window = self._display.create_resource_object('window', windowID)
def reserve_space(self, left=0, right=0, top=0, bottom=0):
LEFT = left
RIGHT = right
TOP = top
BOTTOM = bottom
self._window.change_property(self._display.intern_atom('_NET_WM_STRUT'),
self._display.intern_atom('CARDINAL'),
32, [LEFT, RIGHT, TOP, BOTTOM])
self._display.sync()
NB: it is important to keep the same instance of Display() which has created the window object, in order to change the window properties, hence it is stored into a variable.