diff --git a/pixelgl/input.go b/pixelgl/input.go
index cd701df1ae6241ddfbb35e5b289fd7fc9768b386..ea6c7fdea6eda4bc601a80021181bf351f2c5d07 100644
--- a/pixelgl/input.go
+++ b/pixelgl/input.go
@@ -21,6 +21,13 @@ func (w *Window) JustReleased(button Button) bool {
 	return !w.currInp.buttons[button] && w.prevInp.buttons[button]
 }
 
+// Repeated returns whether a repeat event has been triggered on button.
+//
+// Repeat event occurs repeatedly when a button is held down for some time.
+func (w *Window) Repeated(button Button) bool {
+	return w.currInp.repeat[button]
+}
+
 // MousePosition returns the current mouse position in the Window's Bounds.
 func (w *Window) MousePosition() pixel.Vec {
 	return w.currInp.mouse
@@ -342,6 +349,8 @@ func (w *Window) initInput() {
 				w.tempInp.buttons[Button(key)] = true
 			case glfw.Release:
 				w.tempInp.buttons[Button(key)] = false
+			case glfw.Repeat:
+				w.tempInp.repeat[Button(key)] = true
 			}
 		})
 
@@ -370,6 +379,7 @@ func (w *Window) updateInput() {
 	w.prevInp = w.currInp
 	w.currInp = w.tempInp
 
+	w.tempInp.repeat = [KeyLast + 1]bool{}
 	w.tempInp.scroll = 0
 	w.tempInp.typed = ""
 }
diff --git a/pixelgl/window.go b/pixelgl/window.go
index 68d0afc7a813d84aaecdc98084648ee6b5ad483b..29b28fd368a6c2e3e2e6042946b45157797549ff 100644
--- a/pixelgl/window.go
+++ b/pixelgl/window.go
@@ -68,6 +68,7 @@ type Window struct {
 	prevInp, currInp, tempInp struct {
 		mouse   pixel.Vec
 		buttons [KeyLast + 1]bool
+		repeat  [KeyLast + 1]bool
 		scroll  pixel.Vec
 		typed   string
 	}