On this page:
14.1 Polling Events
in-events
poll-event
wait-event
wait-event-timeout
should-quit?
14.2 Event Types
14.2.1 Application Events
quit-event
14.2.2 Window Events
window-event
14.2.3 Keyboard Events
key-event
key-name
14.2.3.1 Modifier Key Predicates
mod-shift?
mod-ctrl?
mod-alt?
mod-gui?
14.2.4 Text Input Events
text-input-event
14.2.5 Mouse Events
mouse-motion-event
mouse-button-event
mouse-wheel-event
14.2.6 Gamepad Events
gamepad-button-event
gamepad-axis-event
gamepad-device-event
14.2.7 Joystick Events
joy-axis-event
joy-button-event
joy-hat-event
joy-device-event
14.2.8 Touch Events
touch-finger-event
14.2.9 Drop Events
drop-event
14.2.10 Clipboard Events
clipboard-event
14.2.11 Audio/  Camera Device Events
audio-device-event
camera-device-event
14.2.12 Unknown Events
unknown-event
14.3 Event Handling Patterns
14.3.1 Basic Event Loop
14.3.2 Event-Driven vs State Polling
9.0.0.11

14 Events🔗ℹ

SDL3 communicates user input and system notifications through events. The safe API provides transparent Racket structs that work seamlessly with match.

14.1 Polling Events🔗ℹ

procedure

(in-events)  sequence?

Returns a sequence of all pending events. Use with for to process events each frame:

(for ([ev (in-events)])
  (match ev
    [(quit-event) (exit)]
    [(key-event 'down 'escape _ _ _) (exit)]
    [_ (void)]))

procedure

(poll-event)  (or/c sdl-event? #f)

Returns the next pending event, or #f if none are available. Prefer in-events for typical event loops.

procedure

(wait-event)  sdl-event?

Blocks until an event is available, then returns it. Useful for applications that don’t need continuous rendering.

procedure

(wait-event-timeout timeout)  (or/c sdl-event? #f)

  timeout : exact-nonnegative-integer?
Blocks until an event is available or timeout milliseconds have passed. Returns #f on timeout.

procedure

(should-quit?)  boolean?

Returns #t if a quit event is pending (without consuming it).

14.2 Event Types🔗ℹ

All event structs are transparent and can be used with match. Field names follow a consistent pattern for easy pattern matching.

14.2.1 Application Events🔗ℹ

struct

(struct quit-event ()
    #:transparent)
Sent when the user requests to quit (e.g., closes the window, presses Cmd+Q on macOS).

(match ev
  [(quit-event) (set! running? #f)]
  ...)

14.2.2 Window Events🔗ℹ

struct

(struct window-event (type)
    #:transparent)
  type : symbol?
Sent when a window’s state changes.

The type field indicates what happened:
  • 'close-requested User requested window close

  • 'shown Window became visible

  • 'hidden Window was hidden

  • 'exposed Window needs redrawing

  • 'moved Window was moved

  • 'resized Window was resized

  • 'minimized Window was minimized

  • 'maximized Window was maximized

  • 'restored Window was restored

  • 'focus-gained Window gained keyboard focus

  • 'focus-lost Window lost keyboard focus

  • 'mouse-enter Mouse entered window

  • 'mouse-leave Mouse left window

(match ev
  [(window-event 'close-requested) (set! running? #f)]
  [(window-event 'resized) (handle-resize)]
  ...)

14.2.3 Keyboard Events🔗ℹ

struct

(struct key-event (type key scancode mod repeat?)
    #:transparent)
  type : (or/c 'down 'up)
  key : symbol?
  scancode : exact-nonnegative-integer?
  mod : exact-nonnegative-integer?
  repeat? : boolean?
Sent when a key is pressed or released.

  • type 'down for key press, 'up for release

  • key Key symbol (e.g., 'a, 'space, 'escape)

  • scancode Physical key code (keyboard-layout independent)

  • mod Modifier key bitmask (use mod-shift?, etc.)

  • repeat? #t if this is a key repeat event

Common key symbols include: 'a through 'z, '0 through '9, 'space, 'escape, 'return, 'backspace, 'tab, 'up, 'down, 'left, 'right, 'f1 through 'f12.

(match ev
  ;; Simple key matching
  [(key-event 'down 'escape _ _ _) (exit)]
  [(key-event 'down 'space _ _ _) (fire-bullet!)]
 
  ;; With modifiers
  [(key-event 'down 's _ mod _)
   #:when (mod-ctrl? mod)
   (save-file!)]
 
  ;; Ignore key repeats
  [(key-event 'down 'w _ _ #f) (start-moving)]
  [(key-event 'up 'w _ _ _) (stop-moving)]
  ...)

procedure

(key-name key)  string?

  key : symbol?
Returns a human-readable name for a key symbol.

(key-name 'escape)  ; => "Escape"
(key-name 'space)   ; => "Space"
14.2.3.1 Modifier Key Predicates🔗ℹ

These predicates check if modifier keys are held in a key-event’s mod field:

procedure

(mod-shift? mod)  boolean?

  mod : exact-nonnegative-integer?
Returns #t if Shift is held.

procedure

(mod-ctrl? mod)  boolean?

  mod : exact-nonnegative-integer?
Returns #t if Control is held.

procedure

(mod-alt? mod)  boolean?

  mod : exact-nonnegative-integer?
Returns #t if Alt/Option is held.

procedure

(mod-gui? mod)  boolean?

  mod : exact-nonnegative-integer?
Returns #t if the GUI key (Cmd on macOS, Windows key on Windows) is held.

14.2.4 Text Input Events🔗ℹ

struct

(struct text-input-event (text)
    #:transparent)
  text : string?
Sent when text is entered. Use this for text input fields instead of key-event, as it handles international keyboards, IME, etc.

Must be enabled with start-text-input! first.

(match ev
  [(text-input-event txt)
   (set! input-string (string-append input-string txt))]
  ...)

14.2.5 Mouse Events🔗ℹ

struct

(struct mouse-motion-event (x y xrel yrel state)
    #:transparent)
  x : real?
  y : real?
  xrel : real?
  yrel : real?
  state : exact-nonnegative-integer?
Sent when the mouse moves.

  • x, y Current mouse position

  • xrel, yrel Relative motion since last event

  • state Button state bitmask

struct

(struct mouse-button-event (type button x y clicks)
    #:transparent)
  type : (or/c 'down 'up)
  button : (or/c 'left 'middle 'right symbol?)
  x : real?
  y : real?
  clicks : exact-nonnegative-integer?
Sent when a mouse button is pressed or released.

  • type 'down or 'up

  • button 'left, 'middle, 'right, or a number for extra buttons

  • x, y Mouse position

  • clicks Click count (1 for single, 2 for double-click, etc.)

(match ev
  [(mouse-button-event 'down 'left x y 1)
   (handle-click x y)]
  [(mouse-button-event 'down 'left x y 2)
   (handle-double-click x y)]
  ...)

struct

(struct mouse-wheel-event (x y direction mouse-x mouse-y)
    #:transparent)
  x : real?
  y : real?
  direction : symbol?
  mouse-x : real?
  mouse-y : real?
Sent when the mouse wheel is scrolled.

  • x, y Scroll amounts (y is typically vertical scroll)

  • direction 'normal or 'flipped

  • mouse-x, mouse-y Mouse position

14.2.6 Gamepad Events🔗ℹ

struct

(struct gamepad-button-event (type which button)
    #:transparent)
  type : (or/c 'down 'up)
  which : exact-nonnegative-integer?
  button : symbol?
Sent when a gamepad button is pressed or released.

  • type 'down or 'up

  • which Gamepad instance ID

  • button Button symbol (e.g., 'a, 'b, 'start)

struct

(struct gamepad-axis-event (which axis value)
    #:transparent)
  which : exact-nonnegative-integer?
  axis : symbol?
  value : real?
Sent when a gamepad axis moves.

  • which Gamepad instance ID

  • axis Axis symbol (e.g., 'leftx, 'lefty)

  • value Axis value (-1.0 to 1.0)

struct

(struct gamepad-device-event (type which)
    #:transparent)
  type : (or/c 'added 'removed)
  which : exact-nonnegative-integer?
Sent when a gamepad is connected or disconnected.

14.2.7 Joystick Events🔗ℹ

struct

(struct joy-axis-event (which axis value)
    #:transparent)
  which : exact-nonnegative-integer?
  axis : exact-nonnegative-integer?
  value : real?
Sent when a joystick axis moves.

struct

(struct joy-button-event (type which button)
    #:transparent)
  type : (or/c 'down 'up)
  which : exact-nonnegative-integer?
  button : exact-nonnegative-integer?
Sent when a joystick button is pressed or released.

struct

(struct joy-hat-event (which hat value)
    #:transparent)
  which : exact-nonnegative-integer?
  hat : exact-nonnegative-integer?
  value : exact-nonnegative-integer?
Sent when a joystick hat switch moves.

struct

(struct joy-device-event (type which)
    #:transparent)
  type : (or/c 'added 'removed)
  which : exact-nonnegative-integer?
Sent when a joystick is connected or disconnected.

14.2.8 Touch Events🔗ℹ

struct

(struct touch-finger-event (type
    touch-id
    finger-id
    x
    y
    dx
    dy
    pressure)
    #:transparent)
  type : (or/c 'down 'up 'motion)
  touch-id : exact-nonnegative-integer?
  finger-id : exact-nonnegative-integer?
  x : real?
  y : real?
  dx : real?
  dy : real?
  pressure : real?
Sent for touch input.

  • x, y Normalized position (0.0 to 1.0)

  • dx, dy Normalized motion delta

  • pressure Touch pressure (0.0 to 1.0)

14.2.9 Drop Events🔗ℹ

struct

(struct drop-event (type x y source data)
    #:transparent)
  type : (or/c 'file 'text 'begin 'complete 'position)
  x : real?
  y : real?
  source : string?
  data : (or/c string? #f)
Sent when files or text are dropped onto the window.

For 'file type, data contains the file path. For 'text type, data contains the dropped text.

14.2.10 Clipboard Events🔗ℹ

struct

(struct clipboard-event (owner? mime-types)
    #:transparent)
  owner? : boolean?
  mime-types : (listof string?)
Sent when the clipboard contents change.

14.2.11 Audio/Camera Device Events🔗ℹ

struct

(struct audio-device-event (type which recording?)
    #:transparent)
  type : (or/c 'added 'removed)
  which : exact-nonnegative-integer?
  recording? : boolean?
Sent when an audio device is connected or disconnected.

struct

(struct camera-device-event (type which)
    #:transparent)
  type : (or/c 'added 'removed 'approved 'denied)
  which : exact-nonnegative-integer?
Sent when a camera device state changes.

14.2.12 Unknown Events🔗ℹ

struct

(struct unknown-event (type)
    #:transparent)
  type : exact-nonnegative-integer?
Used for event types not yet supported by the safe API. The type field contains the raw SDL event type constant.

14.3 Event Handling Patterns🔗ℹ

14.3.1 Basic Event Loop🔗ℹ

(let loop ()
  (define quit?
    (for/or ([ev (in-events)])
      (match ev
        [(quit-event) #t]
        [(key-event 'down 'escape _ _ _) #t]
        [_ #f])))
 
  (unless quit?
    ;; Update and render
    (render-frame!)
    (loop)))

14.3.2 Event-Driven vs State Polling🔗ℹ

Use event-driven input for:
  • Discrete actions (menu selection, firing a weapon)

  • Text input

  • Detecting specific key presses

Use state polling (see Keyboard Functions) for:
  • Smooth continuous movement

  • Checking if a key is currently held

Many games use both: events for actions, polling for movement.