CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-glfw

A ctypes-based wrapper for GLFW3 that provides Python bindings for OpenGL, OpenGL ES, and Vulkan development on desktop platforms.

Pending
Overview
Eval results
Files

input-handling.mddocs/

Input Handling

Comprehensive input system supporting keyboard, mouse, joystick, and gamepad input with both polling and callback-based event handling for interactive applications.

Capabilities

Event Processing

Process input events and window system messages.

def poll_events() -> None:
    """
    Process all pending events.
    
    This function processes only those events that are already in the 
    event queue and then returns immediately.
    """

def wait_events() -> None:
    """
    Wait until events are queued and processes them.
    
    This function puts the calling thread to sleep until at least 
    one event is available in the event queue.
    """

def wait_events_timeout(timeout: float) -> None:
    """
    Wait with timeout until events are queued and processes them.
    
    Parameters:
        timeout: Maximum time to wait, in seconds
    """

def post_empty_event() -> None:
    """
    Post an empty event to the event queue.
    
    This function posts an empty event from the current thread 
    to the event queue, causing wait_events to return.
    """

Input Modes

Configure input behavior for windows.

def get_input_mode(window, mode: int) -> int:
    """
    Get the value of an input option for the window.
    
    Parameters:
        window: Window to query
        mode: Input mode to query
        
    Returns:
        int: Current mode value
    """

def set_input_mode(window, mode: int, value: int) -> None:
    """
    Set an input option for the window.
    
    Parameters:
        window: Window to configure
        mode: Input mode to set
        value: New mode value
    """

Input Mode Constants

# Input modes
CURSOR: int = 0x00033001
STICKY_KEYS: int = 0x00033002
STICKY_MOUSE_BUTTONS: int = 0x00033003
LOCK_KEY_MODS: int = 0x00033004
RAW_MOUSE_MOTION: int = 0x00033005

# Cursor mode values
CURSOR_NORMAL: int = 0x00034001
CURSOR_HIDDEN: int = 0x00034002
CURSOR_DISABLED: int = 0x00034003
CURSOR_CAPTURED: int = 0x00034004

Keyboard Input

Handle keyboard input with both polling and callbacks.

def get_key(window, key: int) -> int:
    """
    Get the last reported state of a keyboard key.
    
    Parameters:
        window: Window to query
        key: Keyboard key constant
        
    Returns:
        int: PRESS, RELEASE, or REPEAT
    """

def get_key_name(key: int, scancode: int) -> str:
    """
    Get the localized name of the specified printable key.
    
    Parameters:
        key: Key constant, or KEY_UNKNOWN
        scancode: Platform-specific scancode
        
    Returns:
        str: Key name, or None if unavailable
    """

def get_key_scancode(key: int) -> int:
    """
    Get the platform-specific scancode of the key.
    
    Parameters:
        key: Key constant
        
    Returns:
        int: Platform-specific scancode
    """

def set_key_callback(window, cbfun) -> callable:
    """
    Set the key callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, key: int, scancode: int, 
                              action: int, mods: int)
    """

def set_char_callback(window, cbfun) -> callable:
    """
    Set the Unicode character callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, codepoint: int)
    """

def set_char_mods_callback(window, cbfun) -> callable:
    """
    Set the Unicode character with modifiers callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, codepoint: int, mods: int)
    """

Keyboard Constants

# Key actions
RELEASE: int = 0
PRESS: int = 1
REPEAT: int = 2

# Modifier key bits
MOD_SHIFT: int = 0x0001
MOD_CONTROL: int = 0x0002
MOD_ALT: int = 0x0004
MOD_SUPER: int = 0x0008
MOD_CAPS_LOCK: int = 0x0010
MOD_NUM_LOCK: int = 0x0020

# Key constants (selection - 100+ available)
KEY_UNKNOWN: int = -1
KEY_SPACE: int = 32
KEY_APOSTROPHE: int = 39  # '
KEY_COMMA: int = 44       # ,
KEY_MINUS: int = 45       # -
KEY_PERIOD: int = 46      # .
KEY_SLASH: int = 47       # /

# Number keys
KEY_0: int = 48
KEY_1: int = 49
# ... through KEY_9: int = 57

# Letter keys  
KEY_A: int = 65
KEY_B: int = 66
# ... through KEY_Z: int = 90

# Function keys
KEY_F1: int = 290
KEY_F2: int = 291
# ... through KEY_F25: int = 314

# Arrow keys
KEY_RIGHT: int = 262
KEY_LEFT: int = 263
KEY_DOWN: int = 264
KEY_UP: int = 265

# Common special keys
KEY_ESCAPE: int = 256
KEY_ENTER: int = 257
KEY_TAB: int = 258
KEY_BACKSPACE: int = 259
KEY_INSERT: int = 260
KEY_DELETE: int = 261
KEY_HOME: int = 268
KEY_END: int = 269

# Modifier keys  
KEY_LEFT_SHIFT: int = 340
KEY_LEFT_CONTROL: int = 341
KEY_LEFT_ALT: int = 342
KEY_LEFT_SUPER: int = 343
KEY_RIGHT_SHIFT: int = 344
KEY_RIGHT_CONTROL: int = 345
KEY_RIGHT_ALT: int = 346
KEY_RIGHT_SUPER: int = 347

Mouse Input

Handle mouse button and cursor input.

def get_mouse_button(window, button: int) -> int:
    """
    Get the last reported state of a mouse button.
    
    Parameters:
        window: Window to query
        button: Mouse button constant
        
    Returns:
        int: PRESS or RELEASE
    """

def get_cursor_pos(window) -> tuple[float, float]:
    """
    Get the cursor position relative to the window's client area.
    
    Parameters:
        window: Window to query
        
    Returns:
        tuple: (x, y) cursor position
    """

def set_cursor_pos(window, xpos: float, ypos: float) -> None:
    """
    Set the cursor position relative to the window's client area.
    
    Parameters:
        window: Window to modify
        xpos: New x-coordinate
        ypos: New y-coordinate
    """

def raw_mouse_motion_supported() -> bool:
    """
    Check whether raw mouse motion is supported.
    
    Returns:
        bool: True if raw mouse motion is supported
    """

Mouse Button Constants

# Mouse buttons
MOUSE_BUTTON_1: int = 0
MOUSE_BUTTON_2: int = 1
MOUSE_BUTTON_3: int = 2
MOUSE_BUTTON_4: int = 3
MOUSE_BUTTON_5: int = 4
MOUSE_BUTTON_6: int = 5
MOUSE_BUTTON_7: int = 6
MOUSE_BUTTON_8: int = 7
MOUSE_BUTTON_LAST: int = MOUSE_BUTTON_8

# Mouse button aliases
MOUSE_BUTTON_LEFT: int = MOUSE_BUTTON_1
MOUSE_BUTTON_RIGHT: int = MOUSE_BUTTON_2
MOUSE_BUTTON_MIDDLE: int = MOUSE_BUTTON_3

Mouse Callbacks

Register callbacks for mouse events.

def set_mouse_button_callback(window, cbfun) -> callable:
    """
    Set the mouse button callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, button: int, action: int, mods: int)
    """

def set_cursor_pos_callback(window, cbfun) -> callable:
    """
    Set the cursor position callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, xpos: float, ypos: float)
    """

def set_cursor_enter_callback(window, cbfun) -> callable:
    """
    Set the cursor enter/exit callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, entered: int)
    """

def set_scroll_callback(window, cbfun) -> callable:
    """
    Set the scroll callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, xoffset: float, yoffset: float)
    """

Cursor Management

Create and manage custom cursors.

def create_cursor(image, xhot: int, yhot: int):
    """
    Create a custom cursor from an image.
    
    Parameters:
        image: Image data or PIL Image object
        xhot: X-coordinate of cursor hotspot
        yhot: Y-coordinate of cursor hotspot
        
    Returns:
        GLFWcursor: Cursor handle
    """

def create_standard_cursor(shape: int):
    """
    Create a cursor with a standard shape.
    
    Parameters:
        shape: Standard cursor shape constant
        
    Returns:
        GLFWcursor: Cursor handle
    """

def destroy_cursor(cursor) -> None:
    """
    Destroy a cursor.
    
    Parameters:
        cursor: Cursor to destroy
    """

def set_cursor(window, cursor) -> None:
    """
    Set the cursor for the window.
    
    Parameters:
        window: Window to modify
        cursor: Cursor to set, or None for default
    """

Cursor Shape Constants

# Standard cursor shapes
ARROW_CURSOR: int = 0x00036001
IBEAM_CURSOR: int = 0x00036002
CROSSHAIR_CURSOR: int = 0x00036003
HAND_CURSOR: int = 0x00036004
POINTING_HAND_CURSOR: int = 0x00036004
HRESIZE_CURSOR: int = 0x00036005
RESIZE_EW_CURSOR: int = 0x00036005
VRESIZE_CURSOR: int = 0x00036006
RESIZE_NS_CURSOR: int = 0x00036006
RESIZE_NWSE_CURSOR: int = 0x00036007
RESIZE_NESW_CURSOR: int = 0x00036008
RESIZE_ALL_CURSOR: int = 0x00036009
NOT_ALLOWED_CURSOR: int = 0x0003600A

Joystick Input

Query and handle joystick/controller input.

def joystick_present(joy: int) -> int:
    """
    Check whether the specified joystick is present.
    
    Parameters:
        joy: Joystick ID (JOYSTICK_1 through JOYSTICK_16)
        
    Returns:
        int: 1 if present, 0 if not present
    """

def get_joystick_axes(joy: int) -> tuple:
    """
    Get the values of all axes of the specified joystick.
    
    Parameters:
        joy: Joystick ID
        
    Returns:
        tuple: (axes_array, count) - axes values and count
    """

def get_joystick_buttons(joy: int) -> tuple:
    """
    Get the state of all buttons of the specified joystick.
    
    Parameters:
        joy: Joystick ID
        
    Returns:
        tuple: (buttons_array, count) - button states and count
    """

def get_joystick_hats(joystick_id: int) -> tuple:
    """
    Get the state of all hats of the specified joystick.
    
    Parameters:
        joystick_id: Joystick ID
        
    Returns:
        tuple: (hats_array, count) - hat states and count
    """

def get_joystick_name(joy: int) -> bytes:
    """
    Get the name of the specified joystick.
    
    Parameters:
        joy: Joystick ID
        
    Returns:
        bytes: Joystick name
    """

def get_joystick_guid(joystick_id: int) -> bytes:
    """
    Get the SDL compatible GUID of the specified joystick.
    
    Parameters:
        joystick_id: Joystick ID
        
    Returns:
        bytes: Joystick GUID
    """

def set_joystick_user_pointer(joystick_id: int, pointer) -> None:
    """Set user data for the joystick."""

def get_joystick_user_pointer(joystick_id: int):
    """Get user data for the joystick."""

def set_joystick_callback(cbfun) -> callable:
    """
    Set the joystick configuration callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(joy: int, event: int)
    """

Joystick Constants

# Joystick IDs
JOYSTICK_1: int = 0
JOYSTICK_2: int = 1
# ... through JOYSTICK_16: int = 15
JOYSTICK_LAST: int = JOYSTICK_16

# Joystick events
CONNECTED: int = 0x00040001
DISCONNECTED: int = 0x00040002

# Hat states
HAT_CENTERED: int = 0
HAT_UP: int = 1
HAT_RIGHT: int = 2
HAT_DOWN: int = 4
HAT_LEFT: int = 8
HAT_RIGHT_UP: int = HAT_RIGHT | HAT_UP
HAT_RIGHT_DOWN: int = HAT_RIGHT | HAT_DOWN
HAT_LEFT_UP: int = HAT_LEFT | HAT_UP
HAT_LEFT_DOWN: int = HAT_LEFT | HAT_DOWN

Gamepad Support

High-level gamepad interface with standardized button mapping.

def joystick_is_gamepad(joystick_id: int) -> bool:
    """
    Check whether the specified joystick has a gamepad mapping.
    
    Parameters:
        joystick_id: Joystick ID
        
    Returns:
        bool: True if joystick has gamepad mapping
    """

def get_gamepad_state(joystick_id: int):
    """
    Get the state of the specified joystick remapped as a gamepad.
    
    Parameters:
        joystick_id: Joystick ID
        
    Returns:
        GLFWgamepadstate: Gamepad state, or None if not available
    """

def get_gamepad_name(joystick_id: int) -> str:
    """
    Get the human-readable gamepad name for the specified joystick.
    
    Parameters:
        joystick_id: Joystick ID
        
    Returns:
        str: Gamepad name, or None if not available
    """

def update_gamepad_mappings(string: str) -> int:
    """
    Add the specified SDL_GameControllerDB gamepad mappings.
    
    Parameters:
        string: Gamepad mappings string
        
    Returns:
        int: 1 if successful, 0 if failed
    """

Gamepad Constants

# Gamepad buttons
GAMEPAD_BUTTON_A: int = 0
GAMEPAD_BUTTON_B: int = 1
GAMEPAD_BUTTON_X: int = 2
GAMEPAD_BUTTON_Y: int = 3
GAMEPAD_BUTTON_LEFT_BUMPER: int = 4
GAMEPAD_BUTTON_RIGHT_BUMPER: int = 5
GAMEPAD_BUTTON_BACK: int = 6
GAMEPAD_BUTTON_START: int = 7
GAMEPAD_BUTTON_GUIDE: int = 8
GAMEPAD_BUTTON_LEFT_THUMB: int = 9
GAMEPAD_BUTTON_RIGHT_THUMB: int = 10
GAMEPAD_BUTTON_DPAD_UP: int = 11
GAMEPAD_BUTTON_DPAD_RIGHT: int = 12
GAMEPAD_BUTTON_DPAD_DOWN: int = 13
GAMEPAD_BUTTON_DPAD_LEFT: int = 14
GAMEPAD_BUTTON_LAST: int = GAMEPAD_BUTTON_DPAD_LEFT

# PlayStation-style aliases
GAMEPAD_BUTTON_CROSS: int = GAMEPAD_BUTTON_A
GAMEPAD_BUTTON_CIRCLE: int = GAMEPAD_BUTTON_B
GAMEPAD_BUTTON_SQUARE: int = GAMEPAD_BUTTON_X
GAMEPAD_BUTTON_TRIANGLE: int = GAMEPAD_BUTTON_Y

# Gamepad axes
GAMEPAD_AXIS_LEFT_X: int = 0
GAMEPAD_AXIS_LEFT_Y: int = 1
GAMEPAD_AXIS_RIGHT_X: int = 2
GAMEPAD_AXIS_RIGHT_Y: int = 3
GAMEPAD_AXIS_LEFT_TRIGGER: int = 4
GAMEPAD_AXIS_RIGHT_TRIGGER: int = 5
GAMEPAD_AXIS_LAST: int = GAMEPAD_AXIS_RIGHT_TRIGGER

Clipboard

Access system clipboard for text data.

def set_clipboard_string(window, string: str) -> None:
    """
    Set the clipboard to the specified string.
    
    Parameters:
        window: Window (deprecated, can be None)
        string: String to set in clipboard
    """

def get_clipboard_string(window) -> bytes:
    """
    Get the contents of the clipboard as a string.
    
    Parameters:
        window: Window (deprecated, can be None)
        
    Returns:
        bytes: Clipboard contents
    """

Drag and Drop

Handle file drag and drop operations.

def set_drop_callback(window, cbfun) -> callable:
    """
    Set the file drop callback.
    
    Parameters:
        cbfun: Callback function or None
            Signature: callback(window, paths: list[str])
    """

Usage Examples

Basic Input Polling

import glfw

glfw.init()
window = glfw.create_window(640, 480, "Input Example", None, None)
glfw.make_context_current(window)

while not glfw.window_should_close(window):
    glfw.poll_events()
    
    # Check for escape key
    if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS:
        glfw.set_window_should_close(window, True)
    
    # Check mouse button
    if glfw.get_mouse_button(window, glfw.MOUSE_BUTTON_LEFT) == glfw.PRESS:
        x, y = glfw.get_cursor_pos(window)
        print(f"Mouse clicked at {x}, {y}")
    
    glfw.swap_buffers(window)

glfw.terminate()

Input Callbacks

import glfw

def key_callback(window, key, scancode, action, mods):
    if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
        glfw.set_window_should_close(window, True)
    elif action == glfw.PRESS:
        print(f"Key {key} pressed")

def mouse_button_callback(window, button, action, mods):
    if button == glfw.MOUSE_BUTTON_LEFT and action == glfw.PRESS:
        x, y = glfw.get_cursor_pos(window)
        print(f"Left mouse button pressed at {x}, {y}")

glfw.init()
window = glfw.create_window(640, 480, "Callbacks", None, None)

# Set callbacks
glfw.set_key_callback(window, key_callback)
glfw.set_mouse_button_callback(window, mouse_button_callback)

# Main loop...

Gamepad Input

import glfw

glfw.init()
window = glfw.create_window(640, 480, "Gamepad", None, None)

while not glfw.window_should_close(window):
    glfw.poll_events()
    
    # Check for connected gamepads
    for joy in range(glfw.JOYSTICK_1, glfw.JOYSTICK_LAST + 1):
        if glfw.joystick_present(joy) and glfw.joystick_is_gamepad(joy):
            state = glfw.get_gamepad_state(joy)
            if state:
                # Check A button
                if state.buttons[glfw.GAMEPAD_BUTTON_A]:
                    print("A button pressed")
                
                # Check left stick
                left_x = state.axes[glfw.GAMEPAD_AXIS_LEFT_X]
                left_y = state.axes[glfw.GAMEPAD_AXIS_LEFT_Y]
                if abs(left_x) > 0.1 or abs(left_y) > 0.1:
                    print(f"Left stick: {left_x}, {left_y}")
    
    glfw.swap_buffers(window)

glfw.terminate()

Install with Tessl CLI

npx tessl i tessl/pypi-glfw

docs

index.md

input-handling.md

library-management.md

monitor-display.md

opengl-context.md

vulkan-support.md

window-management.md

tile.json