Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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,))
Ejemplo n.º 4
0
    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())
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
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)