Ejemplo n.º 1
0
// same as above, but moveresize instead of just move at the first step,
// then resize to the provided w/h instead of a snapshotted one
// this implementation differs from Move in that it makes no effort to be end-synchronous
// This function waits only on the window's inner geometry resizing, not on actual movement occuring
func MoveResize(win *xwindow.Window, x, y, width, height int) error {
	// snapshot window dimensions
	base, err := win.Geometry()
	if err != nil {
		return err
	}

	// move window then wait...
	err = win.WMMoveResize(x, y, width, height)
	if err != nil {
		return err
	}
	err = PollFor(win, GeometryDiffers(base))
	if err != nil {
		return err
	}

	// check that the new geometry is what we requested
	// this may be inadvisable: what about window hints?
	geom, err := win.Geometry()
	if err != nil {
		return err
	}
	if geom.Width() != width || geom.Height() != height {
		// something derped! resize to make it right!
		// if window hints constrained us, this won't upset them
		log.Println("MoveResize: resizing again after incorrect new dimensions")
		err = win.WMResize(width, height)
		if err != nil {
			return err
		}
	}

	return nil
}
Ejemplo n.º 2
0
func Geometries(win *xwindow.Window) (xrect.Rect, xrect.Rect, error) {
	decor, err := win.DecorGeometry()
	if err != nil {
		return nil, nil, err
	}
	base, err := win.Geometry()
	if err != nil {
		return nil, nil, err
	}
	return decor, base, nil
}
Ejemplo n.º 3
0
// resize a window by a certain number of pixels in a given direction.
// This function tries to prevent the window from moving
func ResizeDirection(X *xgbutil.XUtil, win *xwindow.Window, dir wm.Direction, px int) error {
	// we resize around the decor_geometry of the window

	if px == 0 {
		// no need to resize
		return nil
	}

	geom, err := win.Geometry()
	if err != nil {
		return fmt.Errorf("Resize: coudn't get normal geometry: %v", err)
	}
	w, h := geom.Width(), geom.Height()
	log.Printf("ResizeDirection: pre_geom == %v\n", geom)

	if dir == wm.Left || dir == wm.Right {
		// horizontal resize
		w += px
	} else {
		h += px
	}

	// two-step resize -> move process, to compensate for WM peculiarities and window sizing hints
	// first save the initial position info
	pre_decor, err := win.DecorGeometry()
	if err != nil {
		return fmt.Errorf("Resize: coudn't get decorated geometry: %v", err)
	}

	// resize the window
	err = win.WMResize(w, h)
	if err != nil {
		return err
	}

	// wait for the geometry to change
	// we use a goroutine to query X a bunch while waiting for the window
	// to finish resizing
	err = wm.PollFor(win, wm.DecorDiffers(pre_decor), wm.GeometryDiffers(geom))
	if err != nil {
		return fmt.Errorf("ResizeDirection: error waiting for window geometries to change: %v", err)
	}

	post_decor, post_geom, err := wm.Geometries(win)
	if err != nil {
		return err
	}
	log.Printf("ResizeDirection: post_decor == %v\n", post_decor)
	log.Printf("ResizeDirection: post_geom == %v\n", post_geom)

	// the opposite edge should stay in the same place
	op := dir.Opposite()
	pre_edge := EdgePos(pre_decor, op)
	post_edge := EdgePos(post_decor, op)
	delta := post_edge - pre_edge

	x, y := post_decor.X(), post_decor.Y()

	// move the window upwards by our height resize so that the bottom edge stays in the same place
	if dir == wm.Top || dir == wm.Bottom {
		y -= delta
	}

	// move the window right  by our resize so that the right stays in the same place
	if dir == wm.Left || dir == wm.Right {
		x -= delta
	}

	// move to lock opposite edge
	return wm.Move(win, x, y)
}