def do_xpra_client_message_event(self, event): if (event.window is self._root and event.message_type == "MANAGER" and event.data[1] == get_xatom(self._selection)): log("XSettings manager changed") self._add_watch() self.emit("xsettings-changed")
def acquire(self, when): old_owner = self._owner() if when is self.IF_UNOWNED and old_owner != 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 #data is a timestamp, X11 datatype is Time which is CARD32, #(which is 64 bits on 64-bit systems!) Lsize = calcsize("@L") if len(ts_data)==Lsize: ts_num = unpack("@L", ts_data[:Lsize])[0] else: ts_num = 0 #CurrentTime log.warn("invalid data for 'TIMESTAMP': %s", ([hex(ord(x)) for x in ts_data])) # Calculate the X atom for this selection: selection_xatom = get_xatom(self.atom) # Ask X what window we used: self._xwindow = X11Window.XGetSelectionOwner(self.atom) root = self.clipboard.get_display().get_default_screen().get_root_window() X11Window.sendClientMessage(root.xid, root.xid, False, StructureNotifyMask, "MANAGER", ts_num, selection_xatom, self._xwindow, 0, 0) if old_owner != 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 acquire(self, when): old_owner = self._owner() if when is self.IF_UNOWNED and old_owner != XNone: raise AlreadyOwned #we can only set strings with GTK3, # we should try to be compliant with ICCCM version 2.0 (see section 4.3) # and use this format instead: # outdata.set("INTEGER", 32, pack("@ii", 2, 0)) thestring = "VERSION" self.clipboard.set_text(thestring, len(thestring)) # 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: timestamp_atom = Gdk.Atom.intern("TIMESTAMP", False) contents = self.clipboard.wait_for_contents(timestamp_atom) ts_data = contents.get_data() log("ManagerSelection.acquire(%s) %s.wait_for_contents(%s)=%s", when, self.clipboard, timestamp_atom, ts_data) #data is a timestamp, X11 datatype is Time which is CARD32, #(which is 64 bits on 64-bit systems!) Lsize = calcsize("@L") if len(ts_data)==Lsize: ts_num = unpack("@L", ts_data[:Lsize])[0] else: ts_num = 0 #CurrentTime log.warn("invalid data for 'TIMESTAMP': %s", ([hex(ord(x)) for x in ts_data])) log("selection timestamp(%s)=%s", ts_data, ts_num) # Calculate the X atom for this selection: selection_xatom = get_xatom(self.atom) # Ask X what window we used: self._xwindow = X11WindowBindings().XGetSelectionOwner(self.atom) root = self.clipboard.get_display().get_default_screen().get_root_window() xid = root.get_xid() X11WindowBindings().sendClientMessage(xid, xid, False, StructureNotifyMask, "MANAGER", ts_num, selection_xatom, self._xwindow) if old_owner != XNone and when is self.FORCE: # Block in a recursive mainloop until the previous owner has # cleared out. try: with xsync: window = get_pywindow(old_owner) window.set_events(window.get_events() | Gdk.EventMask.STRUCTURE_MASK) log("got window") except XError: log("Previous owner is already gone? not blocking", exc_info=True) else: log("Waiting for previous owner to exit...") add_event_receiver(window, self) self.exit_timer = GLib.timeout_add(SELECTION_EXIT_TIMEOUT*1000, self.exit_timeout) Gtk.main() if self.exit_timer: GLib.source_remove(self.exit_timer) self.exit_timer = None log("...they did.") window = get_pywindow(self._xwindow) window.set_title("Xpra-ManagerSelection-%s" % self.atom) self.clipboard.connect("owner-change", self._owner_change)
_prop_types = { # Python type, X type Atom, formatbits, serializer, deserializer, list # terminator "utf8": (unicode, "UTF8_STRING", 8, lambda disp, u: u.encode("UTF-8"), lambda disp, d: d.decode("UTF-8"), "\0"), # In theory, there should be something clever about COMPOUND_TEXT here. I # am not sufficiently clever to deal with COMPOUNT_TEXT. Even knowing # that Xutf8TextPropertyToTextList exists. "latin1": (unicode, "STRING", 8, lambda disp, u: u.encode("latin1"), lambda disp, d: d.decode("latin1"), "\0"), "atom": (str, "ATOM", 32, lambda disp, a: struct.pack("@I", get_xatom(a)), _get_atom, ""), "state": ((int, long), "WM_STATE", 32, lambda disp, c: struct.pack("=I", c), lambda disp, d: struct.unpack("=I", d)[0], ""), "u32": ((int, long), "CARDINAL", 32, lambda disp, c: struct.pack("=I", c), lambda disp, d: struct.unpack("=I", d)[0], ""), "visual": (gtk.gdk.Visual, "VISUALID", 32, lambda disp, c: struct.pack("=I", get_xvisual(c)), unsupported, ""), "window": (gtk.gdk.Window, "WINDOW", 32,
log.info("get_multiple value is not an atom: %s", d) return str(d) return _get_atom(disp, d) _prop_types = { # Python type, X type Atom, formatbits, serializer, deserializer, list # terminator "utf8": (unicode, "UTF8_STRING", 8, lambda disp, u: u.encode("UTF-8"), lambda disp, d: d.decode("UTF-8"), "\0"), # In theory, there should be something clever about COMPOUND_TEXT here. I # am not sufficiently clever to deal with COMPOUNT_TEXT. Even knowing # that Xutf8TextPropertyToTextList exists. "latin1": (unicode, "STRING", 8, lambda disp, u: u.encode("latin1"), lambda disp, d: d.decode("latin1"), "\0"), "atom": (str, "ATOM", 32, lambda disp, a: struct.pack("@I", get_xatom(a)), _get_atom, ""), "state": ((int, long), "WM_STATE", 32, lambda disp, c: struct.pack("=I", c), lambda disp, d: struct.unpack("=I", d)[0], ""), "u32": ((int, long), "CARDINAL", 32, lambda disp, c: struct.pack("=I", c), lambda disp, d: struct.unpack("=I", d)[0], ""), "integer": ((int, long), "INTEGER", 32, lambda disp, c: struct.pack("=I", c), lambda disp, d: struct.unpack("=I", d)[0], ""), "visual": (gtk.gdk.Visual, "VISUALID", 32, lambda disp, c: struct.pack("=I", get_xvisual(c)), unsupported, ""), "window": (gtk.gdk.Window, "WINDOW", 32, lambda disp, c: struct.pack("=I", get_xwindow(c)), lambda disp, d: get_pywindow(disp,
_prop_types = { # Python type, X type Atom, formatbits, serializer, deserializer, list # terminator "utf8": (unicode, "UTF8_STRING", 8, lambda disp, u: u.encode("UTF-8"), lambda disp, d: d.decode("UTF-8"), "\0"), # In theory, there should be something clever about COMPOUND_TEXT here. I # am not sufficiently clever to deal with COMPOUNT_TEXT. Even knowing # that Xutf8TextPropertyToTextList exists. "latin1": (unicode, "STRING", 8, lambda disp, u: u.encode("latin1"), lambda disp, d: d.decode("latin1"), "\0"), "atom": (str, "ATOM", 32, lambda disp, a: struct.pack("@I", get_xatom(a)), _get_atom, ""), "u32": ((int, long), "CARDINAL", 32, lambda disp, c: struct.pack("=I", c), lambda disp, d: struct.unpack("=I", d)[0], ""), "visual": (gtk.gdk.Visual, "VISUALID", 32, lambda disp, c: struct.pack("=I", get_xvisual(c)), unsupported, ""), "window": (gtk.gdk.Window, "WINDOW", 32, lambda disp, c: struct.pack("=I", get_xwindow(c)), lambda disp, d: get_pywindow(disp, struct.unpack("=I", d)[0]), ""), "wm-size-hints": (WMSizeHints, "WM_SIZE_HINTS", 32,