diff --git a/pixelgl/input.go b/pixelgl/input.go
index 94f2406bef357740e6e0e06b5a2aa537153421b0..6668ec5ba2d96b4b3f60a0e0604a16c549e1728b 100644
--- a/pixelgl/input.go
+++ b/pixelgl/input.go
@@ -23,17 +23,7 @@ func (w *Window) JustReleased(button Button) bool {
 
 // MousePosition returns the current mouse position relative to the window.
 func (w *Window) MousePosition() pixel.Vec {
-	var x, y, width, height float64
-	mainthread.Call(func() {
-		x, y = w.window.GetCursorPos()
-		wi, hi := w.window.GetSize()
-		width, height = float64(wi), float64(hi)
-	})
-
-	return pixel.V(
-		x/width*w.bounds.W()+w.bounds.X(),
-		(height-y)/height*w.bounds.H()+w.bounds.Y(),
-	)
+	return w.currInp.mouse
 }
 
 // MouseScroll returns the scroll amount (in both axis) since the last call to Window.Update.
@@ -363,6 +353,15 @@ func (w *Window) updateInput() {
 	// get events (usually calls callbacks, but callbacks can be called outside too)
 	mainthread.Call(func() {
 		glfw.PollEvents()
+
+		x, y := w.window.GetCursorPos()
+		wi, hi := w.window.GetSize()
+		width, height := float64(wi), float64(hi)
+
+		w.currInp.mouse = pixel.V(
+			x/width*w.bounds.W()+w.bounds.X(),
+			(height-y)/height*w.bounds.H()+w.bounds.Y(),
+		)
 	})
 
 	// cache current state to temp (so that if there are callbacks outside this function,
diff --git a/pixelgl/window.go b/pixelgl/window.go
index 731fee22cd56063fbeafbcb6f42d61837aa6e701..70dc422a366b951dbbefd3949af689217dfc0608 100644
--- a/pixelgl/window.go
+++ b/pixelgl/window.go
@@ -62,6 +62,7 @@ type Window struct {
 	}
 
 	prevInp, tempInp, currInp struct {
+		mouse   pixel.Vec
 		buttons [KeyLast + 1]bool
 		scroll  pixel.Vec
 	}