def acquire(self, when): old_owner = self._owner() if when is self.IF_UNOWNED and old_owner != const["XNone"]: raise AlreadyOwned self.clipboard.set_with_data([("VERSION", 0, 0)], self._get, self._clear, None) # Having acquired the selection, we have to announce our existence # (ICCCM 2.8, still). The details here probably don't matter too # much; I've never heard of an app that cares about these messages, # and metacity actually gets the format wrong in several ways (no # MANAGER or owner_window atoms). But might as well get it as right # as possible. # To announce our existence, we need: # -- the timestamp we arrived at # -- the manager selection atom # -- the window that registered the selection # Of course, because Gtk is doing so much magic for us, we have to do # some weird tricks to get at these. # Ask ourselves when we acquired the selection: ts_data = self.clipboard.wait_for_contents("TIMESTAMP").data ts_num = unpack("@i", ts_data[:4])[0] # Calculate the X atom for this selection: selection_xatom = get_xatom(self.atom) # Ask X what window we used: self._xwindow = myGetSelectionOwner(self.clipboard, self.atom) root = self.clipboard.get_display().get_default_screen().get_root_window() sendClientMessage(root, root, False, const["StructureNotifyMask"], "MANAGER", ts_num, selection_xatom, self._xwindow, 0, 0) if old_owner != const["XNone"] and when is self.FORCE: # Block in a recursive mainloop until the previous owner has # cleared out. def getwin(): window = get_pywindow(self.clipboard, old_owner) window.set_events(window.get_events() | gtk.gdk.STRUCTURE_MASK) return window try: window = trap.call_synced(getwin) log("got window") except XError: log("Previous owner is already gone, not blocking") else: log("Waiting for previous owner to exit...") add_event_receiver(window, self) gtk.main() log("...they did.") window = get_pywindow(self.clipboard, self._xwindow) window.set_title("Xpra-ManagerSelection")
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 setup_tray_window(self): display = gtk.gdk.display_get_default() root = gtk.gdk.get_default_root_window() screen = root.get_screen() if TRANSPARENCY: colormap, visual = screen.get_rgba_colormap( ), screen.get_rgba_visual() if colormap is None or visual is None: log.warn("setup tray: using rgb visual fallback") colormap, visual = screen.get_rgb_colormap( ), screen.get_rgb_visual() assert colormap is not None and visual is not None, "failed to obtain visual or colormap" owner = myGetSelectionOwner(root, SELECTION) log("setup tray: current selection owner=%s", owner) if owner != const["XNone"]: raise Exception("%s already owned by %s" % (SELECTION, owner)) self.tray_window = gtk.gdk.Window(root, width=1, height=1, window_type=gtk.gdk.WINDOW_TOPLEVEL, event_mask=0, wclass=gtk.gdk.INPUT_OUTPUT, title="Xpra-SystemTray", visual=visual, colormap=colormap) set_tray_visual(self.tray_window, visual) set_tray_orientation(self.tray_window, TRAY_ORIENTATION_HORZ) log("setup tray: tray window %s", get_xwindow(self.tray_window)) display.request_selection_notification(SELECTION) setsel = mySetSelectionOwner(root, self.tray_window, SELECTION) log("setup tray: set selection owner returned %s", setsel) event_mask = const["StructureNotifyMask"] sendClientMessage(root, root, False, event_mask, "MANAGER", const["CurrentTime"], SELECTION, get_xwindow(self.tray_window), 0, 0) owner = myGetSelectionOwner(root, SELECTION) #FIXME: cleanup if we fail! assert owner == get_xwindow( self.tray_window ), "we failed to get ownership of the tray selection" add_event_receiver(self.tray_window, self) log("setup tray: done")
def setup_tray_window(self): display = gtk.gdk.display_get_default() root = gtk.gdk.get_default_root_window() screen = root.get_screen() if TRANSPARENCY: colormap, visual = screen.get_rgba_colormap(), screen.get_rgba_visual() if colormap is None or visual is None: log.warn("setup tray: using rgb visual fallback") colormap, visual = screen.get_rgb_colormap(), screen.get_rgb_visual() assert colormap is not None and visual is not None, "failed to obtain visual or colormap" owner = myGetSelectionOwner(root, SELECTION) log("setup tray: current selection owner=%s", owner) if owner!=const["XNone"]: raise Exception("%s already owned by %s" % (SELECTION, owner)) self.tray_window = gtk.gdk.Window(root, width=1, height=1, window_type=gtk.gdk.WINDOW_TOPLEVEL, event_mask = 0, wclass=gtk.gdk.INPUT_OUTPUT, title="Xpra-SystemTray", visual=visual, colormap=colormap) set_tray_visual(self.tray_window, visual) set_tray_orientation(self.tray_window, TRAY_ORIENTATION_HORZ) log("setup tray: tray window %s", get_xwindow(self.tray_window)) display.request_selection_notification(SELECTION) setsel = mySetSelectionOwner(root, self.tray_window, SELECTION) log("setup tray: set selection owner returned %s", setsel) event_mask = const["StructureNotifyMask"] sendClientMessage(root, root, False, event_mask, "MANAGER", const["CurrentTime"], SELECTION, get_xwindow(self.tray_window), 0, 0) owner = myGetSelectionOwner(root, SELECTION) #FIXME: cleanup if we fail! assert owner==get_xwindow(self.tray_window), "we failed to get ownership of the tray selection" add_event_receiver(self.tray_window, self) log("setup tray: done")