Example #1
0
File: shape.go Project: justjake/j3
// compose a number of rectabgles into a window shape
func ComposeShape(X *xgbutil.XUtil, dst xproto.Window, rects []xrect.Rect) (err error) {

	combine_bounds := make([]shape.CombineCookie, len(rects))
	combine_clip := make([]shape.CombineCookie, len(rects))

	var operation shape.Op

	for i, rect := range rects {
		// make rectangular window of correct goemetry
		win, err := xwindow.Generate(X)
		if err != nil {
			log.Fatalf("ComposeShape: Error creating rectange %v window.", rect)
			return err
		}
		win.Create(X.RootWin(), rect.X(), rect.Y(), rect.Width(), rect.Height(), xproto.CwBackPixel, 0xffffff)

		// choose operation. on the first one, we want to set the shape.
		if i == 0 {
			operation = shape.SoSet
		} else {
			operation = shape.SoUnion
		}

		// combine window request
		x, y := int16(rect.X()), int16(rect.Y())

		combine_kind := shape.Kind(shape.SkBounding)
		combine_bounds[i] = shape.CombineChecked(X.Conn(), operation, combine_kind, combine_kind, dst, x, y, win.Id)
		combine_kind = shape.Kind(shape.SkClip)
		combine_clip[i] = shape.CombineChecked(X.Conn(), operation, combine_kind, combine_kind, dst, x, y, win.Id)
	}
	return nil
}
Example #2
0
func (c *Client) cbShapeNotify() xevent.ShapeNotifyFun {
	var err error

	f := func(X *xgbutil.XUtil, ev xevent.ShapeNotifyEvent) {
		// Many thanks to Openbox. I'll followed their lead.
		xoff, yoff := int16(c.frame.Left()), int16(c.frame.Top())
		// var xoff, yoff int16 = 0, 0

		// Update the client's shaped status.
		c.shaped = ev.Shaped

		// If the client is no longer shaped, clear the mask.
		if !c.shaped {
			err = shape.MaskChecked(wm.X.Conn(),
				shape.SoSet, ev.ShapeKind, c.frame.Parent().Id,
				xoff, yoff, xproto.PixmapNone).Check()
			if err != nil {
				logger.Warning.Printf("Error clearing Shape mask on '%s': %s",
					c, err)
			}
			return
		}

		// Now we have to shape the frame like the client.
		err = shape.CombineChecked(wm.X.Conn(),
			shape.SoSet, ev.ShapeKind, ev.ShapeKind,
			c.frame.Parent().Id, xoff, yoff, c.Id()).Check()
		if err != nil {
			logger.Warning.Printf("Error combining on '%s': %s", c, err)
			return
		}

		// If the client is being shaped and claims that it doesn't want
		// decorations, make sure it has "nada" instead of "slim".
		// We do this on startup, but maybe the client didn't say anything
		// about shaping then...
		// if !c.shouldDecor() {
		// c.FrameNada()
		// }

		// We don't even bother with shaping the frame if the client has any
		// kind of decoration. Unless I'm mistaken, shaping Wingo's decorations
		// to fit client shaping really isn't going to do anything...
		if _, ok := c.frame.(*frame.Nada); ok {
			return
		}

		// So this is only done with Slim/Borders/Full frames. It basically
		// negates the effects of shaping since we use one monolithic
		// rectangle.
		rect := xproto.Rectangle{
			X:      0,
			Y:      0,
			Width:  uint16(c.frame.Geom().Width()),
			Height: uint16(c.frame.Geom().Height()),
		}
		err = shape.RectanglesChecked(wm.X.Conn(),
			shape.SoUnion, shape.SkBounding, xproto.ClipOrderingUnsorted,
			c.frame.Parent().Id, 0, 0, []xproto.Rectangle{rect}).Check()
		if err != nil {
			logger.Warning.Printf("Error adding rectangles on '%s': %s", c, err)
			return
		}
	}
	return xevent.ShapeNotifyFun(f)
}