def __init__(self, disp, data): data = _force_length("WM_HINTS", data, 9 * 4) (flags, _input, initial_state, #@UnusedVariable icon_pixmap, icon_window, #@UnusedVariable icon_x, icon_y, icon_mask, #@UnusedVariable window_group) = struct.unpack("=" + "i" * 9, data) # NB the last field is missing from at least some ICCCM 2.0's (typo). # FIXME: extract icon stuff too self.urgency = bool(flags & XUrgencyHint) if flags & WindowGroupHint: try: pywin = get_pywindow(disp, window_group) except: pywin = None self.group_leader = (window_group, pywin) else: self.group_leader = None if flags & StateHint: self.start_iconic = (initial_state == IconicState) else: self.start_iconic = None if flags & InputHint: self.input = _input else: self.input = None
def __init__(self, disp, data): data = _force_length("WM_HINTS", data, 9 * 4) (flags, _input, initial_state, #@UnusedVariable icon_pixmap, icon_window, #@UnusedVariable icon_x, icon_y, icon_mask, #@UnusedVariable window_group) = struct.unpack("=" + "i" * 9, data) # NB the last field is missing from at least some ICCCM 2.0's (typo). # FIXME: extract icon stuff too self.urgency = bool(flags & const["XUrgencyHint"]) if flags & const["WindowGroupHint"]: try: pywin = get_pywindow(disp, window_group) except: pywin = None self.group_leader = (window_group, pywin) else: self.group_leader = None if flags & const["StateHint"]: self.start_iconic = (initial_state == const["IconicState"]) else: self.start_iconic = None if flags & const["InputHint"]: self.input = _input else: self.input = None
def _handle_wm_hints_change(self): with xswallow: wm_hints = X11Window.getWMHints(self.xid) metalog("getWMHints(%#x)=%s", self.xid, wm_hints) if wm_hints is None: return # GdkWindow or None group_leader = None if "window_group" in wm_hints: xid = wm_hints.get("window_group") if xid: try: group_leader = get_pywindow(xid) except Exception: log.error("Error locating group leader window %#x", xid) self._updateprop("group-leader", group_leader) self._updateprop("attention-requested", wm_hints.get("urgency", False)) _input = wm_hints.get("input") metalog("wm_hints.input = %s", _input) #we only set this value once: #(input_field always starts as True, and we then set it to an int) if self._input_field is True and _input is not None: #keep the value as an int to differentiate from the start value: self._input_field = int(_input) self._update_can_focus()
def xsettings_owner(self): with xlog: from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() owner_x = X11Window.XGetSelectionOwner(self._selection) log("XGetSelectionOwner(%s)=%#x", self._selection, owner_x) if owner_x == XNone: return None return get_pywindow(self._clipboard, owner_x)
def xsettings_owner(self): try: with xsync: owner_x = X11Window.XGetSelectionOwner(self._selection) log("XGetSelectionOwner(%s)=%s", self._selection, owner_x) if owner_x == XNone: return None return get_pywindow(self._clipboard, owner_x) except XError: log("X error while fetching owner of XSettings data; ignored") return None
def xsettings_owner(self): owner_x = X11Window.XGetSelectionOwner(self._selection) log("XGetSelectionOwner(%s)=%s", self._selection, owner_x) if owner_x == XNone: return None try: with xsync: return get_pywindow(self._clipboard, owner_x) except XError: log("X error while fetching owner of XSettings data; ignored") return None
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 window(self): if self._xwindow is None: return None return get_pywindow(self.clipboard, self._xwindow)
def getwin(): window = get_pywindow(self.clipboard, old_owner) window.set_events(window.get_events() | gtk.gdk.STRUCTURE_MASK) return window
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)
""), "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, 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, unsupported, WMSizeHints, None), "wm-hints": (WMHints, "WM_HINTS", 32, unsupported, WMHints, None), "strut": (NetWMStrut, "CARDINAL", 32, unsupported, NetWMStrut, None), "strut-partial": (NetWMStrut, "CARDINAL", 32, unsupported, NetWMStrut, None), "motif-hints": (MotifWMHints, "_MOTIF_WM_HINTS", 32, unsupported, MotifWMHints, None),
"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, struct.unpack("=I", d)[0]), ""), "strut": (NetWMStrut, "CARDINAL", 32, unsupported, NetWMStrut, None), "strut-partial": (NetWMStrut, "CARDINAL", 32, unsupported, NetWMStrut, None), "motif-hints": (MotifWMHints, "_MOTIF_WM_HINTS", 32, unsupported, MotifWMHints, None), "icon": (cairo.ImageSurface, "CARDINAL", 32, unsupported, NetWMIcons, None), "xsettings-settings": (tuple, "_XSETTINGS_SETTINGS", 8, set_settings, get_settings, None), # For uploading ad-hoc instances of the above complex structures to the # server, so we can test reading them out again: "debug-CARDINAL": (str, "CARDINAL", 32, lambda disp, c: c, lambda disp, d: d, None), # For fetching the extra information on a MULTIPLE clipboard conversion # request. The exciting thing about MULTIPLE is that it's not actually
def get_window(disp, w): return get_pywindow(disp, struct.unpack(b"@L", w)[0])