def process_client_message_event(self, event): if event.message_type == "_NET_MOVERESIZE_WINDOW": #TODO: honour gravity, show source indication geom = self.corral_window.get_geometry() x, y, w, h, _ = geom if event.data[0] & 0x100: x = event.data[1] if event.data[0] & 0x200: y = event.data[2] if event.data[0] & 0x400: w = event.data[3] if event.data[0] & 0x800: h = event.data[4] self._internal_set_property("set-initial-position", (event.data[0] & 0x100) or (event.data[0] & 0x200)) #honour hints: hints = self.get_property("size-hints") w, h = calc_constrained_size(w, h, hints) geomlog( "_NET_MOVERESIZE_WINDOW on %s (data=%s, current geometry=%s, new geometry=%s)", self, event.data, geom, (x, y, w, h)) with xswallow: X11Window.configureAndNotify(self.xid, x, y, w, h) return True return BaseWindowModel.process_client_message_event(self, event)
def resize_corral_window(self, x, y, w, h): #the client window may have been resized or moved (generally programmatically) #so we may need to update the corral_window to match cox, coy, cow, coh = self.corral_window.get_geometry()[:4] #size changes (and position if any): hints = self.get_property("size-hints") w, h = calc_constrained_size(w, h, hints) cx, cy, cw, ch = self.get_property("geometry") resized = cow != w or coh != h moved = (x, y) != (0, 0) if resized: if moved: self._internal_set_property("set-initial-position", True) geomlog("resize_corral_window() move and resize from %s to %s", (cox, coy, cow, coh), (x, y, w, h)) self.corral_window.move_resize(x, y, w, h) self.client_window.move(0, 0) self._updateprop("geometry", (x, y, w, h)) else: geomlog("resize_corral_window() resize from %s to %s", (cow, coh), (w, h)) self.corral_window.resize(w, h) self._updateprop("geometry", (cx, cy, w, h)) elif moved: self._internal_set_property("set-initial-position", True) geomlog( "resize_corral_window() moving corral window from %s to %s", (cox, coy), (x, y)) self.corral_window.move(x, y) self.client_window.move(0, 0) self._updateprop("geometry", (x, y, cw, ch))
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()
def _do_update_client_geometry(self, window_size_cb, window_position_cb): allocated_w, allocated_h = window_size_cb() geomlog("_do_update_client_geometry: allocated %ix%i", allocated_w, allocated_h) hints = self.get_property("size-hints") w, h = calc_constrained_size(allocated_w, allocated_h, hints) geomlog("_do_update_client_geometry: size(%s)=%ix%i", hints, w, h) x, y = window_position_cb(w, h) geomlog("_do_update_client_geometry: position=%ix%i", x, y) self.corral_window.move_resize(x, y, w, h) self._updateprop("geometry", (x, y, w, h)) with xswallow: X11Window.configureAndNotify(self.xid, 0, 0, w, h)
def do_child_configure_request_event(self, event): hints = self.get_property("size-hints") geomlog( "do_child_configure_request_event(%s) client=%#x, corral=%#x, value_mask=%s, size-hints=%s", event, self.xid, self.corral_window.xid, configure_bits(event.value_mask), hints) if event.value_mask & CWStackMode: geomlog(" restack above=%s, detail=%s", event.above, event.detail) # Also potentially update our record of what the app has requested: ogeom = self.get_property("geometry") x, y, w, h = ogeom[:4] rx, ry = self.get_property("requested-position") if event.value_mask & CWX: x = event.x rx = x if event.value_mask & CWY: y = event.y ry = y if event.value_mask & CWX or event.value_mask & CWY: self._internal_set_property("set-initial-position", True) self._updateprop("requested-position", (rx, ry)) rw, rh = self.get_property("requested-size") if event.value_mask & CWWidth: w = event.width rw = w if event.value_mask & CWHeight: h = event.height rh = h if event.value_mask & CWWidth or event.value_mask & CWHeight: self._updateprop("requested-size", (rw, rh)) if VALIDATE_CONFIGURE_REQUEST: w, h = calc_constrained_size(w, h, hints) #update the geometry now, as another request may come in #before we've had a chance to process the ConfigureNotify that the code below will generate self._updateprop("geometry", (x, y, w, h)) geomlog( "do_child_configure_request_event updated requested geometry from %s to %s", ogeom, (x, y, w, h)) # As per ICCCM 4.1.5, even if we ignore the request # send back a synthetic ConfigureNotify telling the client that nothing has happened. with xswallow: X11Window.configureAndNotify(self.xid, x, y, w, h)