Python: tell X to reserve screen space for application

送分小仙女□ 提交于 2019-12-03 15:47:47

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.

Hmm, I am not sure if you can. Your OS reserves a page in memory for user processes. A process may malloc() memory space, but this would be within the reserved chunks provided by the kernel for the current process's address space. Would you be forking the application as a child process? or executing a new instance?

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!