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 test_select_clientmessage_and_xselectinput(self): self.evs = [] self.w = self.window() gtk.gdk.flush() l.add_event_receiver(self.w, self) l.add_event_receiver(self.root(), self) data = (0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314) l.sendClientMessage(self.root(), False, 0, "NOMASK", *data) l.sendClientMessage(self.w, False, 0, "NOMASK", *data) gtk.main() # Should have gotten message to w, not to root assert len(self.evs) == 1 ev = self.evs[0] assert ev.window is self.w assert ev.message_type == "NOMASK" assert ev.format == 32 assert ev.data == data self.evs = [] l.sendClientMessage(self.root(), False, l.const["Button1MotionMask"], "BAD", *data) l.addXSelectInput(self.root(), l.const["Button1MotionMask"]) l.sendClientMessage(self.root(), False, l.const["Button1MotionMask"], "GOOD", *data) gtk.main() assert len(self.evs) == 1 ev = self.evs[0] assert ev.window is self.root() assert ev.message_type == "GOOD" assert ev.format == 32 assert ev.data == data
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