Skip to content

feat: event-driven keyboard input (no Input Monitoring needed) - #10

Merged
Periicles merged 1 commit into
mainfrom
feat/event-driven-input
Jun 17, 2026
Merged

feat: event-driven keyboard input (no Input Monitoring needed)#10
Periicles merged 1 commit into
mainfrom
feat/event-driven-input

Conversation

@Periicles

Copy link
Copy Markdown
Owner

Why

sfKeyboard_isKeyPressed polls the OS keyboard state. On macOS that returns
false unless the running app has the Input Monitoring permission, so on a
fresh machine movement, attack, interact and Escape all silently did nothing
(mouse-driven menus still worked, which is why it looked like "the keyboard is
dead"). Event-based input only needs window focus, so the game plays anywhere.

What

  • New input module: input_handle_event() updates a per-key pressed state from
    the window's KeyPressed / KeyReleased events and clears it on FocusLost;
    is_key_held() reads that state.
  • Every sfKeyboard_isKeyPressed(...) is replaced by is_key_held(game, ...)
    (player + raycast movement, attack, NPC interact, the Ctrl-zoom/inventory
    modifier).
  • The 2D, raycasting and intro-dialog event loops now call input_handle_event,
    and Escape is handled straight from the event.
  • game_t gains a keystate[sfKeyCount] array (zero-initialised).

No keybindings or controls change — only how a held key is detected.

Verification

  • make re: warning-free.
  • Banana: full project back to 0 findings.
  • make tests_run / make tests_asan: 20/20, no ASan/UBSan findings.

Please test (behaviour change)

This changes the input model, so a quick play is worth it:

  • Movement (arrows / ZQSD after switching layout), attack, talking to NPCs (E),
    Escape to open/close the pause menu, Ctrl+wheel zoom.
  • Ideally confirm it now works without granting Input Monitoring (the original
    symptom).

sfKeyboard_isKeyPressed polls the OS directly, which on macOS returns
false unless the app has the "Input Monitoring" permission — so movement,
attack, interact and Escape silently did nothing on a fresh machine.

Add an input module that maintains a per-key pressed state from the
window's KeyPressed/KeyReleased events (and clears it on focus loss), and
replace every sfKeyboard_isKeyPressed call with is_key_held(). The event
loops (2D, raycasting and the intro dialog) now feed input_handle_event,
and Escape is handled purely from the event. This only needs window
focus, so the game is playable everywhere without any system permission.

Build warning-free, full Banana scan back to 0, 20/20 tests pass under
ASan/UBSan.
@Periicles
Periicles merged commit 5e6d59e into main Jun 17, 2026
8 checks passed
@Periicles
Periicles deleted the feat/event-driven-input branch June 17, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant