def __init__(self, name, replace_other_wm, display=None): gobject.GObject.__init__(self) self._name = name if display is None: display = gtk.gdk.display_manager_get().get_default_display() self._display = display self._alt_display = gtk.gdk.Display(self._display.get_name()) self._root = self._display.get_default_screen().get_root_window() self._ewmh_window = None self._windows = {} # EWMH says we have to know the order of our windows oldest to # youngest... self._windows_in_order = [] # Become the Official Window Manager of this year's display: self._wm_selection = wimpiggy.selection.ManagerSelection( self._display, "WM_S0") self._wm_selection.connect("selection-lost", self._lost_wm_selection) # May throw AlreadyOwned: if replace_other_wm: mode = self._wm_selection.FORCE else: mode = self._wm_selection.IF_UNOWNED self._wm_selection.acquire(mode) # (If we become a compositing manager, then we will want to do the # same thing with the _NET_WM_CM_S0 selection (says EWMH). AFAICT # this basically will just be used by clients to know that they can # use RGBA visuals.) # Set up the necessary EWMH properties on the root window. self._setup_ewmh_window() prop_set(self._root, "_NET_SUPPORTED", ["atom"], self._NET_SUPPORTED) prop_set(self._root, "_NET_DESKTOP_VIEWPORT", ["u32"], [0, 0]) # Load up our full-screen widget self._world_window = WorldWindow() self._world_window.set_screen(self._display.get_default_screen()) self.notify("toplevel") self._world_window.show_all() # Okay, ready to select for SubstructureRedirect and then load in all # the existing clients. add_event_receiver(self._root, self) substructureRedirect(self._root) for w in get_children(self._root): # Checking for FOREIGN here filters out anything that we've # created ourselves (like, say, the world window), and checking # for mapped filters out any withdrawn windows. if (w.get_window_type() == gtk.gdk.WINDOW_FOREIGN and not is_override_redirect(w) and is_mapped(w)): log("Wm managing pre-existing child") self._manage_client(w) # Also watch for focus change events on the root window selectFocusChange(self._root) selectBellNotification(self._root, True)
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 __init__(self, clobber, sockets): gobject.GObject.__init__(self) # Do this before creating the Wm object, to avoid clobbering its # selecting SubstructureRedirect. root = gtk.gdk.get_default_root_window() root.set_events(root.get_events() | gtk.gdk.SUBSTRUCTURE_MASK) add_event_receiver(root, self) ### Create the WM object self._wm = Wm("Xpra", clobber) self._wm.connect("new-window", self._new_window_signaled) self._wm.connect("quit", lambda _: self.quit(True)) ### Create our window managing data structures: self._desktop_manager = DesktopManager() self._wm.get_property("toplevel").add(self._desktop_manager) self._desktop_manager.show_all() self._window_to_id = {} self._id_to_window = {} # Window id 0 is reserved for "not a window" self._max_window_id = 1 ### Load in existing windows: for window in self._wm.get_property("windows"): self._add_new_window(window) for window in get_children(root): if (is_override_redirect(window) and is_mapped(window)): self._add_new_or_window(window) ### Set up keymap: self._keymap = gtk.gdk.keymap_get_default() self._keymap.connect("keys-changed", self._keys_changed) self._keys_changed() try: xmodmap = subprocess.Popen(["xmodmap", "-"], stdin=subprocess.PIPE) except OSError, e: sys.stderr.write("Error running xmodmap: %s\n" % (e,))
def test_save_set(self): w1 = self.window(self.display) w2 = self.window(self.display) w3 = self.window(self.display) gtk.gdk.flush() def do_child(disp_name, xwindow1, xwindow2, xwindow3): print("child: in do_child") d2 = gtk.gdk.Display(disp_name) w1on2 = l.get_pywindow(d2, xwindow1) w2on2 = l.get_pywindow(d2, xwindow2) w3on2 = l.get_pywindow(d2, xwindow3) mywin = self.window(d2) print("child: mywin == %s" % l.get_xwindow(mywin)) w1on2.reparent(mywin, 0, 0) w2on2.reparent(mywin, 0, 0) w3on2.reparent(mywin, 0, 0) gtk.gdk.flush() # w1 gets saved: l.XAddToSaveSet(w1on2) # w2 does not # w3 is saved, but then unsaved (to test RemoveFromSaveSet): l.XAddToSaveSet(w3on2) l.XRemoveFromSaveSet(w3on2) gtk.gdk.flush() print("child: finished") import os print("prefork: ", os.getpid()) pid = os.fork() if not pid: # Child try: print("child: pid ", os.getpid()) name = self.display.get_name() # This is very important, though I don't know why. If we # don't close this display then something inside # xcb_wait_for_reply gets Very Confused and the *parent* # process gets a spurious IO error with nonsense errno # (because errno is not actually being set, because there is # no IO error, just something going weird inside xcb). I'm # not even sure that this actually fixes the underlying # problem, but it makes the test pass, so... self.display.close() do_child(name, l.get_xwindow(w1), l.get_xwindow(w2), l.get_xwindow(w3)) finally: os._exit(0) # Parent print("parent: ", os.getpid()) print("parent: child is ", pid) print("parent: waiting for child") os.waitpid(pid, 0) print("parent: child exited") # Is there a race condition here, where the child exits but the X # server doesn't notice until after we send our commands? print(map(l.get_xwindow, [w1, w2, w3])) print(map(l.get_xwindow, l.get_children(self.root()))) assert w1 in l.get_children(self.root()) assert w2 not in l.get_children(self.root()) assert w3 not in l.get_children(self.root())
def __init__(self, name, replace_other_wm, display=None): gobject.GObject.__init__(self) self._name = name if display is None: display = gtk.gdk.display_manager_get().get_default_display() self._display = display self._alt_display = gtk.gdk.Display(self._display.get_name()) self._root = self._display.get_default_screen().get_root_window() self._ewmh_window = None self._windows = {} # EWMH says we have to know the order of our windows oldest to # youngest... self._windows_in_order = [] # Become the Official Window Manager of this year's display: self._wm_selection = wimpiggy.selection.ManagerSelection(self._display, "WM_S0") self._wm_selection.connect("selection-lost", self._lost_wm_selection) # May throw AlreadyOwned: if replace_other_wm: mode = self._wm_selection.FORCE else: mode = self._wm_selection.IF_UNOWNED self._wm_selection.acquire(mode) # (If we become a compositing manager, then we will want to do the # same thing with the _NET_WM_CM_S0 selection (says EWMH). AFAICT # this basically will just be used by clients to know that they can # use RGBA visuals.) # Set up the necessary EWMH properties on the root window. self._setup_ewmh_window() prop_set(self._root, "_NET_SUPPORTED", ["atom"], self._NET_SUPPORTED) prop_set(self._root, "_NET_DESKTOP_VIEWPORT", ["u32"], [0, 0]) # Load up our full-screen widget self._world_window = WorldWindow() self._world_window.set_screen(self._display.get_default_screen()) self.notify("toplevel") self._world_window.show_all() # Okay, ready to select for SubstructureRedirect and then load in all # the existing clients. add_event_receiver(self._root, self) substructureRedirect(self._root) for w in get_children(self._root): # Checking for FOREIGN here filters out anything that we've # created ourselves (like, say, the world window), and checking # for mapped filters out any withdrawn windows. if (w.get_window_type() == gtk.gdk.WINDOW_FOREIGN and not is_override_redirect(w) and is_mapped(w)): log("Wm managing pre-existing child") self._manage_client(w) # Also watch for focus change events on the root window selectFocusChange(self._root) selectBellNotification(self._root, True)
class XpraServer(gobject.GObject, X11ServerBase): __gsignals__ = { "wimpiggy-child-map-event": one_arg_signal, "wimpiggy-cursor-event": one_arg_signal, } def __init__(self, clobber, sockets, opts): self._tray = None gobject.GObject.__init__(self) X11ServerBase.__init__(self, clobber, sockets, opts) def x11_init(self, clobber): X11ServerBase.x11_init(self, clobber) init_x11_filter() self._has_focus = 0 # Do this before creating the Wm object, to avoid clobbering its # selecting SubstructureRedirect. root = gtk.gdk.get_default_root_window() root.set_events(root.get_events() | gtk.gdk.SUBSTRUCTURE_MASK) root.property_change(gtk.gdk.atom_intern("XPRA_SERVER", False), gtk.gdk.atom_intern("STRING", False), 8, gtk.gdk.PROP_MODE_REPLACE, xpra.__version__) add_event_receiver(root, self) ### Create the WM object self._wm = Wm("Xpra", clobber) self._wm.connect("new-window", self._new_window_signaled) self._wm.connect("window-resized", self._window_resized_signaled) self._wm.connect("bell", self._bell_signaled) self._wm.connect("quit", lambda _: self.quit(True)) self.default_cursor_data = None self.last_cursor_serial = None self.send_cursor_pending = False self.cursor_data = None def get_default_cursor(): self.default_cursor_data = get_cursor_image() log("get_default_cursor=%s", self.default_cursor_data) trap.swallow_synced(get_default_cursor) self._wm.enableCursors(True) def set_workarea(self, workarea): self._wm.set_workarea(workarea.x, workarea.y, workarea.width, workarea.height) def get_transient_for(self, window): return self._desktop_manager.get_transient_for(window, self._window_to_id) def is_shown(self, window): return self._desktop_manager.is_shown(window) def cleanup(self, *args): if self._tray: self._tray.cleanup() self._tray = None X11ServerBase.cleanup(self) def load_existing_windows(self, system_tray): # Tray handler: if system_tray: try: self._tray = SystemTray() except Exception, e: log.error("cannot setup tray forwarding: %s", e, exc_info=True) ### Create our window managing data structures: self._desktop_manager = DesktopManager() self._wm.get_property("toplevel").add(self._desktop_manager) self._desktop_manager.show_all() ### Load in existing windows: for window in self._wm.get_property("windows"): self._add_new_window(window) root = gtk.gdk.get_default_root_window() for window in get_children(root): if is_override_redirect(window) and is_mapped(window): self._add_new_or_window(window)