diff --git a/geometry.go b/geometry.go
index 5f16ba45355c3d9cb6faa66322011ec6e18d7188..72d148e0394f6439550a0cf147adda9ea04506b8 100644
--- a/geometry.go
+++ b/geometry.go
@@ -84,6 +84,14 @@ func (u Vec) Sub(v Vec) Vec {
 	}
 }
 
+// Floor converts x and y to their integer equivalents.
+func (u Vec) Floor() Vec {
+	return Vec{
+		math.Floor(u.X),
+		math.Floor(u.Y),
+	}
+}
+
 // To returns the vector from u to v. Equivalent to v.Sub(u).
 func (u Vec) To(v Vec) Vec {
 	return Vec{
diff --git a/pixelgl/input.go b/pixelgl/input.go
index a2ef8087e63df57c9f5b5700d7e0983c22cf3ebd..5cf2d9aabb95643a7594e0d82f18eb4c46c89650 100644
--- a/pixelgl/input.go
+++ b/pixelgl/input.go
@@ -33,6 +33,32 @@ func (w *Window) MousePosition() pixel.Vec {
 	return w.currInp.mouse
 }
 
+// MousePreviousPosition returns the previous mouse position in the Window's Bounds.
+func (w *Window) MousePreviousPosition() pixel.Vec {
+	return w.prevInp.mouse
+}
+
+// SetMousePosition positions the mouse cursor anywhere within the Window's Bounds.
+func (w *Window) SetMousePosition(v pixel.Vec) {
+	mainthread.Call(func() {
+		if (v.X >= 0 && v.X <= w.bounds.W()) &&
+			(v.Y >= 0 && v.Y <= w.bounds.H()) {
+			w.window.SetCursorPos(
+				v.X+w.bounds.Min.X,
+				(w.bounds.H()-v.Y)+w.bounds.Min.Y,
+			)
+			w.prevInp.mouse = v
+			w.currInp.mouse = v
+			w.tempInp.mouse = v
+		}
+	})
+}
+
+// MouseEntered returns true if the mouse position is within the Window's Bounds.
+func (w *Window) MouseInsideWindow() bool {
+	return w.cursorInsideWindow
+}
+
 // MouseScroll returns the mouse scroll amount (in both axes) since the last call to Window.Update.
 func (w *Window) MouseScroll() pixel.Vec {
 	return w.currInp.scroll
@@ -354,6 +380,10 @@ func (w *Window) initInput() {
 			}
 		})
 
+		w.window.SetCursorEnterCallback(func(_ *glfw.Window, entered bool) {
+			w.cursorInsideWindow = entered
+		})
+
 		w.window.SetCursorPosCallback(func(_ *glfw.Window, x, y float64) {
 			w.tempInp.mouse = pixel.V(
 				x+w.bounds.Min.X,
diff --git a/pixelgl/window.go b/pixelgl/window.go
index c124152b22dcd1d549a6d49b91ebdfbae1d56803..8e65277658febeb4891a6270a423e4b72a319795 100644
--- a/pixelgl/window.go
+++ b/pixelgl/window.go
@@ -55,10 +55,11 @@ type WindowConfig struct {
 type Window struct {
 	window *glfw.Window
 
-	bounds        pixel.Rect
-	canvas        *Canvas
-	vsync         bool
-	cursorVisible bool
+	bounds             pixel.Rect
+	canvas             *Canvas
+	vsync              bool
+	cursorVisible      bool
+	cursorInsideWindow bool
 
 	// need to save these to correctly restore a fullscreen window
 	restore struct {