Esempio n. 1
0
File: core.py Progetto: qmutz/xpra
 def call_setup(self):
     """
         Call this method to prepare the window:
         * makes sure it still exists
           (by querying its geometry which may raise an XError)
         * setup composite redirection
         * calls setup
         The difficulty comes from X11 errors and synchronization:
         we want to catch errors and undo what we've done.
         The mix of GTK and pure-X11 calls is not helping.
     """
     try:
         with xsync:
             geom = X11Window.geometry_with_border(self.xid)
             if geom is None:
                 raise Unmanageable("window %#x disappeared already" %
                                    self.xid)
             self._internal_set_property("geometry", geom[:4])
             self._read_initial_X11_properties()
     except XError as e:
         log("failed to manage %#x", self.xid, exc_info=True)
         raise Unmanageable(e) from e
     add_event_receiver(self.client_window, self)
     # Keith Packard says that composite state is undefined following a
     # reparent, so I'm not sure doing this here in the superclass,
     # before we reparent, actually works... let's wait and see.
     try:
         self._composite = CompositeHelper(self.client_window)
         with xsync:
             self._composite.setup()
             if X11Window.displayHasXShape():
                 X11Window.XShapeSelectInput(self.xid)
     except Exception as e:
         remove_event_receiver(self.client_window, self)
         log("%s %#x does not support compositing: %s", self._MODELTYPE,
             self.xid, e)
         with xswallow:
             self._composite.destroy()
         self._composite = None
         if isinstance(e, Unmanageable):
             raise
         raise Unmanageable(e) from e
     #compositing is now enabled,
     #from now on we must call setup_failed to clean things up
     self._managed = True
     try:
         with xsync:
             self.setup()
     except XError as e:
         log("failed to setup %#x", self.xid, exc_info=True)
         try:
             with xsync:
                 self.setup_failed(e)
         except Exception as ex:
             log.error("error in cleanup handler: %s", ex)
         raise Unmanageable(e) from None
     self._setup_done = True
Esempio n. 2
0
    def setup(self):
        super(WindowModel, self).setup()

        x, y, w, h, _ = self.client_window.get_geometry()
        # We enable PROPERTY_CHANGE_MASK so that we can call
        # x11_get_server_time on this window.
        # clamp this window to the desktop size:
        x, y = self._clamp_to_desktop(x, y, w, h)
        self.corral_window = gdk.Window(self.parking_window,
                                        x=x, y=y, width=w, height=h,
                                        window_type=gdk.WINDOW_CHILD,
                                        wclass=gdk.INPUT_OUTPUT,
                                        event_mask=gdk.PROPERTY_CHANGE_MASK,
                                        title = "CorralWindow-%#x" % self.xid)
        log("setup() corral_window=%#x", self.corral_window.xid)
        prop_set(self.corral_window, "_NET_WM_NAME", "utf8", u"Xpra-CorralWindow-%#x" % self.xid)
        X11Window.substructureRedirect(self.corral_window.xid)
        add_event_receiver(self.corral_window, self)

        # The child might already be mapped, in case we inherited it from
        # a previous window manager.  If so, we unmap it now, and save the
        # serial number of the request -- this way, when we get an
        # UnmapNotify later, we'll know that it's just from us unmapping
        # the window, not from the client withdrawing the window.
        if X11Window.is_mapped(self.xid):
            log("hiding inherited window")
            self.last_unmap_serial = X11Window.Unmap(self.xid)

        log("setup() adding to save set")
        X11Window.XAddToSaveSet(self.xid)
        self.in_save_set = True

        log("setup() reparenting")
        X11Window.Reparent(self.xid, self.corral_window.xid, 0, 0)
        self.client_reparented = True

        geomlog("setup() geometry")
        geom = X11Window.geometry_with_border(self.xid)
        if geom is None:
            raise Unmanageable("window %#x disappeared already" % self.xid)
        w, h = geom[2:4]
        hints = self.get_property("size-hints")
        geomlog("setup() hints=%s size=%ix%i", hints, w, h)
        nw, nh = calc_constrained_size(w, h, hints)
        if nw>=MAX_WINDOW_SIZE or nh>=MAX_WINDOW_SIZE:
            #we can't handle windows that big!
            raise Unmanageable("window constrained size is too large: %sx%s (from client geometry: %s,%s with size hints=%s)" % (nw, nh, w, h, hints))
        self._updateprop("geometry", (x, y, nw, nh))
        geomlog("setup() resizing windows to %sx%s", nw, nh)
        self.corral_window.resize(nw, nh)
        self.client_window.resize(nw, nh)
        self.client_window.show_unraised()
        #this is here to trigger X11 errors if any are pending
        #or if the window is deleted already:
        self.client_window.get_geometry()
Esempio n. 3
0
 def setup(self):
     super(OverrideRedirectWindowModel, self).setup()
     # So now if the window becomes unmapped in the future then we will
     # notice... but it might be unmapped already, and any event
     # already generated, and our request for that event is too late!
     # So double check now, *after* putting in our request:
     if not X11Window.is_mapped(self.xid):
         raise Unmanageable("window already unmapped")
     ch = self._composite.get_contents_handle()
     if ch is None:
         raise Unmanageable("failed to get damage handle")
Esempio n. 4
0
File: window.py Progetto: qmutz/xpra
    def setup(self):
        super().setup()

        ox, oy, ow, oh = self.client_window.get_geometry()[:4]
        # We enable PROPERTY_CHANGE_MASK so that we can call
        # x11_get_server_time on this window.
        # clamp this window to the desktop size:
        x, y = self._clamp_to_desktop(ox, oy, ow, oh)
        self.corral_window = GDKX11Window(
            self.parking_window,
            x=x,
            y=y,
            width=ow,
            height=oh,
            window_type=Gdk.WindowType.CHILD,
            event_mask=Gdk.EventMask.PROPERTY_CHANGE_MASK,
            title="CorralWindow-%#x" % self.xid)
        cxid = self.corral_window.get_xid()
        log("setup() corral_window=%#x", cxid)
        prop_set(self.corral_window, "_NET_WM_NAME", "utf8",
                 "Xpra-CorralWindow-%#x" % self.xid)
        X11Window.substructureRedirect(cxid)
        add_event_receiver(self.corral_window, self)

        # The child might already be mapped, in case we inherited it from
        # a previous window manager.  If so, we unmap it now, and save the
        # serial number of the request -- this way, when we get an
        # UnmapNotify later, we'll know that it's just from us unmapping
        # the window, not from the client withdrawing the window.
        if X11Window.is_mapped(self.xid):
            log("hiding inherited window")
            self.last_unmap_serial = X11Window.Unmap(self.xid)

        log("setup() adding to save set")
        X11Window.XAddToSaveSet(self.xid)
        self.in_save_set = True

        log("setup() reparenting")
        X11Window.Reparent(self.xid, cxid, 0, 0)
        self.client_reparented = True

        geomlog("setup() geometry")
        geom = X11Window.geometry_with_border(self.xid)
        if geom is None:
            raise Unmanageable("window %#x disappeared already" % self.xid)
        w, h = geom[2:4]
        hints = self.get_property("size-hints")
        geomlog("setup() hints=%s size=%ix%i", hints, w, h)
        nw, nh = self.calc_constrained_size(w, h, hints)
        self._updateprop("geometry", (x, y, nw, nh))
        geomlog("setup() resizing windows to %sx%s", nw, nh)
        #don't trigger a resize unless we have to:
        if ow != nw or oh != nh:
            self.corral_window.resize(nw, nh)
        if w != nw or h != nh:
            self.client_window.resize(nw, nh)
        self.client_window.show_unraised()
        #this is here to trigger X11 errors if any are pending
        #or if the window is deleted already:
        self.client_window.get_geometry()
Esempio n. 5
0
 def setup(self):
     self.invalidate_pixmap()
     geom = X11Window.geometry_with_border(self.xid)
     if geom is None:
         raise Unmanageable("window %#x disappeared already" % self.xid)
     self._border_width = geom[-1]
     self.create_damage_handle()
     add_event_receiver(self.client_window, self)
Esempio n. 6
0
 def _read_initial_X11_properties(self):
     metalog("read_initial_X11_properties() window")
     # WARNING: have to handle _NET_WM_STATE before we look at WM_HINTS;
     # WM_HINTS assumes that our "state" property is already set.  This is
     # because there are four ways a window can get its urgency
     # ("attention-requested") bit set:
     #   1) _NET_WM_STATE_DEMANDS_ATTENTION in the _initial_ state hints
     #   2) setting the bit WM_HINTS, at _any_ time
     #   3) sending a request to the root window to add
     #      _NET_WM_STATE_DEMANDS_ATTENTION to their state hints
     #   4) if we (the wm) decide they should be and set it
     # To implement this, we generally track the urgency bit via
     # _NET_WM_STATE (since that is under our sole control during normal
     # operation).  Then (1) is accomplished through the normal rule that
     # initial states are read off from the client, and (2) is accomplished
     # by having WM_HINTS affect _NET_WM_STATE.  But this means that
     # WM_HINTS and _NET_WM_STATE handling become intertangled.
     def set_if_unset(propname, value):
         #the property may not be initialized yet,
         #if that's the case then calling get_property throws an exception:
         try:
             if self.get_property(propname) not in (None, ""):
                 return
         except TypeError:
             pass
         self._internal_set_property(propname, value)
     #"decorations" needs to be set before reading the X11 properties
     #because handle_wm_normal_hints_change reads it:
     set_if_unset("decorations", -1)
     super()._read_initial_X11_properties()
     net_wm_state = self.get_property("state")
     assert net_wm_state is not None, "_NET_WM_STATE should have been read already"
     geom = X11Window.getGeometry(self.xid)
     if not geom:
         raise Unmanageable("failed to get geometry for %#x" % self.xid)
     #initial position and size, from the Window object,
     #but allow size hints to override it if specified
     x, y, w, h = geom[:4]
     size_hints = self.get_property("size-hints")
     ax, ay = size_hints.get("position", (0, 0))
     if ax==ay==0 and (x!=0 or y!=0):
         #don't override with 0,0
         size_hints.pop("position", None)
         ax, ay = x, y
     aw, ah = size_hints.get("size", (w, h))
     geomlog("initial X11 position and size: requested(%s, %s, %s)=%s",
             (x, y, w, h), size_hints, geom, (ax, ay, aw, ah))
     set_if_unset("modal", "_NET_WM_STATE_MODAL" in net_wm_state)
     set_if_unset("requested-position", (ax, ay))
     set_if_unset("requested-size", (aw, ah))
     #it may have been set already:
     sip = self.get_property("set-initial-position")
     if not sip and ("position" in size_hints):
         self._internal_set_property("set-initial-position", True)
     elif sip is None:
         self._internal_set_property("set-initial-position", False)
     self.update_children()