def set_pixmap(): # The tricky part here is that the pixmap returned by # NameWindowPixmap gets invalidated every time the window's # viewable state changes. ("viewable" here is the X term that # means "mapped, and all ancestors are also mapped".) But # there is no X event that will tell you when a window's # viewability changes! Instead we have to find all ancestors, # and watch all of them for unmap and reparent events. But # what about races? I hear you cry. By doing things in the # exact order: # 1) select for StructureNotify # 2) QueryTree to get parent # 3) repeat 1 & 2 up to the root # 4) call NameWindowPixmap # we are safe. (I think.) listening = [] win = get_parent(self._window) while win is not None and win.get_parent() is not None: # We have to use a lowlevel function to manipulate the # event selection here, because SubstructureRedirectMask # does not roundtrip through the GDK event mask # functions. So if we used them, here, we would clobber # corral window selection masks, and those don't deserve # clobbering. They are our friends! X is driving me # slowly mad. addXSelectInput(win, const["StructureNotifyMask"]) add_event_receiver(win, self) listening.append(win) win = get_parent(win) handle = xcomposite_name_window_pixmap(self._window) self._contents_handle = handle # Don't save the listening set until after NameWindowPixmap # has succeeded, to maintain our invariant: self._listening_to = listening
def set_pixmap(): # The tricky part here is that the pixmap returned by # NameWindowPixmap gets invalidated every time the window's # viewable state changes. ("viewable" here is the X term that # means "mapped, and all ancestors are also mapped".) But # there is no X event that will tell you when a window's # viewability changes! Instead we have to find all ancestors, # and watch all of them for unmap and reparent events. But # what about races? I hear you cry. By doing things in the # exact order: # 1) select for StructureNotify # 2) QueryTree to get parent # 3) repeat 1 & 2 up to the root # 4) call NameWindowPixmap # we are safe. (I think.) listening = [] try: win = get_parent(self._window) while win is not None and win.get_parent() is not None: # We have to use a lowlevel function to manipulate the # event selection here, because SubstructureRedirectMask # does not roundtrip through the GDK event mask # functions. So if we used them, here, we would clobber # corral window selection masks, and those don't deserve # clobbering. They are our friends! X is driving me # slowly mad. addXSelectInput(win, const["StructureNotifyMask"]) add_event_receiver(win, self) listening.append(win) win = get_parent(win) handle = xcomposite_name_window_pixmap(self._window) except: try: self._cleanup_listening(listening) except: pass raise if handle is None: log.warn( "failed to name a window pixmap (expect an X error soon)", type="pixmap") self._cleanup_listening(listening) else: self._contents_handle = handle # Don't save the listening set until after # NameWindowPixmap has succeeded, to maintain our # invariant: self._listening_to = listening
def test_get_children_and_get_parent_and_reparent(self): d2 = self.clone_display() w1 = self.window(self.display) w2 = self.window(d2) gtk.gdk.flush() assert not l.get_children(w1) children = l.get_children(self.root()) xchildren = map(l.get_xwindow, children) xwins = map(l.get_xwindow, [w1, w2]) # GDK creates an invisible child of the root window on each # connection, so there are some windows we don't know about: for known in xwins: assert known in xchildren assert l.get_parent(w1) == w1.get_parent() w1.reparent(l.get_pywindow(w1, l.get_xwindow(w2)), 0, 0) gtk.gdk.flush() assert map(l.get_xwindow, l.get_children(w2)) == [l.get_xwindow(w1)] assert l.get_parent(w1).xid == w2.xid
def test_get_parent_of_root(self): assert l.get_parent(self.root()) is None