def do_xpra_shape_event(self, event): shapelog("shape event: %s, kind=%s", event, SHAPE_KIND.get(event.kind, event.kind)) cur_shape = self.get_property("shape") if cur_shape and cur_shape.get("serial", 0)>=event.serial: shapelog("same or older xshape serial no: %#x (current=%#x)", event.serial, cur_shape.get("serial", 0)) return #remove serial before comparing dicts: try: cur_shape["serial"] except: pass #read new xshape: with xswallow: #should we pass the x and y offsets here? #v = self._read_xshape(event.x, event.y) if event.shaped: v = self._read_xshape() else: v = {} if cur_shape==v: shapelog("xshape unchanged") return v["serial"] = int(event.serial) shapelog("xshape updated with serial %#x", event.serial) self._internal_set_property("shape", v)
def _read_xshape(self, x=0, y=0): if not X11Window.displayHasXShape() or not XSHAPE: return {} extents = X11Window.XShapeQueryExtents(self.xid) if not extents: shapelog("read_shape for window %#x: no extents", self.xid) return {} #w,h = X11Window.getGeometry(xid)[2:4] shapelog("read_shape for window %#x: extents=%s", self.xid, extents) bextents = extents[0] cextents = extents[1] if bextents[0]==0 and cextents[0]==0: shapelog("read_shape for window %#x: none enabled", self.xid) return {} v = { "x" : x, "y" : y, "Bounding.extents" : bextents, "Clip.extents" : cextents, } for kind in SHAPE_KIND.keys(): kind_name = SHAPE_KIND[kind] rectangles = X11Window.XShapeGetRectangles(self.xid, kind) v[kind_name+".rectangles"] = rectangles shapelog("_read_shape()=%s", v) return v
def _read_xshape(self, x=0, y=0): if not X11Window.displayHasXShape(): return {} extents = X11Window.XShapeQueryExtents(self.xid) if not extents: shapelog("read_shape for window %#x: no extents", self.xid) return {} #w,h = X11Window.getGeometry(xid)[2:4] shapelog("read_shape for window %#x: extents=%s", self.xid, extents) bextents = extents[0] cextents = extents[1] if bextents[0]==0 and cextents[0]==0: shapelog("read_shape for window %#x: none enabled", self.xid) return {} v = { "x" : x, "y" : y, "Bounding.extents" : bextents, "Clip.extents" : cextents, } for kind in SHAPE_KIND.keys(): kind_name = SHAPE_KIND[kind] rectangles = X11Window.XShapeGetRectangles(self.xid, kind) v[kind_name+".rectangles"] = rectangles shapelog("_read_shape()=%s", v) return v
def do_set_shape(): xid = get_xid(self.get_window()) for kind, name in SHAPE_KIND.items(): rectangles = shape.get("%s.rectangles" % name) #ie: Bounding.rectangles = [(0, 0, 150, 100)] if rectangles is not None: #adjust for scaling: if self._client.xscale!=1 or self._client.yscale!=1: try: from PIL import Image, ImageDraw #@UnresolvedImport except: Image, ImageDraw = None, None if Image and ImageDraw: ww, wh = self._size sw, sh = self._client.cp(ww, wh) img = Image.new('1', (sw, sh), color=0) shapelog("drawing %s on bitmap(%s,%s)=%s", kind, sw, sh, img) d = ImageDraw.Draw(img) for x,y,w,h in rectangles: d.rectangle([x, y, x+w, y+h], fill=1) img = img.resize((ww, wh)) shapelog("resized %s bitmap to window size %sx%s: %s", kind, ww, wh, img) #now convert back to rectangles... rectangles = [] for y in range(wh): #for debugging, this is very useful, but costly! #shapelog("pixels[%3i]=%s", y, "".join([str(img.getpixel((x, y))) for x in range(ww)])) x = 0 start = None while x<ww: #find first white pixel: while x<ww and img.getpixel((x, y))==0: x += 1 start = x #find next black pixel: while x<ww and img.getpixel((x, y))!=0: x += 1 end = x if start<end: rectangles.append((start, y, end-start, 1)) else: #scale the rectangles without a bitmap... #results aren't so good! (but better than nothing?) srect = self._client.srect rectangles = [srect(*x) for x in rectangles] #FIXME: are we supposed to get the offset from the "extents"? x_off, y_off = 0, 0 shapelog("XShapeCombineRectangles %s=%i rectangles", name, len(rectangles)) #too expensive to log: #shapelog("XShapeCombineRectangles %s=%s", name, rectangles) with xsync: X11Window.XShapeCombineRectangles(xid, kind, x_off, y_off, rectangles)
def do_set_shape(): xid = get_xid(self.get_window()) x_off, y_off = shape.get("x", 0), shape.get("y", 0) for kind, name in SHAPE_KIND.items(): rectangles = shape.get("%s.rectangles" % name) #ie: Bounding.rectangles = [(0, 0, 150, 100)] if rectangles: #adjust for scaling: if self._client.xscale!=1 or self._client.yscale!=1: x_off, y_off = self._client.sp(x_off, y_off) rectangles = self.scale_shape_rectangles(name, rectangles) #too expensive to log with actual rectangles: shapelog("XShapeCombineRectangles(%#x, %s, %i, %i, %i rects)", xid, name, x_off, y_off, len(rectangles)) with xsync: X11Window.XShapeCombineRectangles(xid, kind, x_off, y_off, rectangles)
def dump_xshape(xid): extents = X11Window.XShapeQueryExtents(xid) if not extents: print("read_shape for window %#x: no extents" % xid) return {} v = {} bextents = extents[0] cextents = extents[1] if bextents[0]==0 and cextents[0]==0: print("read_shape for window %#x: none enabled" % xid) return {} v["Bounding.extents"] = bextents v["Clip.extents"] = cextents for kind in SHAPE_KIND.keys(): kind_name = SHAPE_KIND[kind] rectangles = X11Window.XShapeGetRectangles(xid, kind) v[kind_name+".rectangles"] = rectangles print("read_shape()=%s" % v)
def dump_xshape(xid): extents = X11Window.XShapeQueryExtents(xid) if not extents: print("read_shape for window %#x: no extents" % xid) return {} v = {} bextents = extents[0] cextents = extents[1] if bextents[0] == 0 and cextents[0] == 0: print("read_shape for window %#x: none enabled" % xid) return {} v["Bounding.extents"] = bextents v["Clip.extents"] = cextents for kind in SHAPE_KIND.keys(): kind_name = SHAPE_KIND[kind] rectangles = X11Window.XShapeGetRectangles(xid, kind) v[kind_name + ".rectangles"] = rectangles print("read_shape()=%s" % v)
def do_xpra_shape_event(self, event): shapelog("shape event: %s, kind=%s", event, SHAPE_KIND.get(event.kind, event.kind)) cur_shape = self.get_property("shape") if cur_shape and cur_shape.get("serial", 0)>=event.serial: shapelog("same or older xshape serial no: %#x", event.serial) return #remove serial before comparing dicts: try: cur_shape["serial"] except: pass #read new xshape: with xswallow: v = self._read_xshape() if cur_shape==v: shapelog("xshape unchanged") return v["serial"] = int(event.serial) shapelog("xshape updated with serial %#x", event.serial) self._internal_set_property("shape", v)
def do_xpra_shape_event(self, event): shapelog("shape event: %s, kind=%s", event, SHAPE_KIND.get(event.kind, event.kind)) cur_shape = self.get_property("shape") if cur_shape and cur_shape.get("serial", 0) >= event.serial: shapelog("same or older xshape serial no: %#x", event.serial) return #remove serial before comparing dicts: try: cur_shape["serial"] except: pass #read new xshape: with xswallow: v = self._read_xshape() if cur_shape == v: shapelog("xshape unchanged") return v["serial"] = int(event.serial) shapelog("xshape updated with serial %#x", event.serial) self._internal_set_property("shape", v)
def _read_xshape(self): if not X11Window.displayHasXShape(): return {} extents = X11Window.XShapeQueryExtents(self.xid) if not extents: shapelog("read_shape for window %#x: no extents", self.xid) return {} v = {} #w,h = X11Window.getGeometry(xid)[2:4] bextents = extents[0] cextents = extents[1] if bextents[0] == 0 and cextents[0] == 0: shapelog("read_shape for window %#x: none enabled", self.xid) return {} v["Bounding.extents"] = bextents v["Clip.extents"] = cextents for kind in SHAPE_KIND.keys(): kind_name = SHAPE_KIND[kind] rectangles = X11Window.XShapeGetRectangles(self.xid, kind) v[kind_name + ".rectangles"] = rectangles shapelog("_read_shape()=%s", v) return v