3 Input and Actions
dxtr edited this page 2026-10-20 02:06:16 +02:00

Input and Actions

The input of a tree's windows reaches its nodes as Godot's does, as events dispatched through the tree and as state the nodes ask about; actions name what a game asks about rather than keys, and shortcuts fire buttons and menus' items.

  • Input comes two ways, as in Godot. Events (key-event, text-event, motion-event, button-event, scroll-event, and an input method's preedit-event and delete-surrounding-event) go to input on every node, the last in the tree's order first, until one sets event-handled-p; then to the root's ui-input, the user interface's turn; then the same way as input to unhandled-input, where game controls go so that a user interface takes its events first. A window attached to a node with (setf node-window), as a popup's is, has its input go the same way through that node's part of the tree instead, the node and those below it, and the window system asking to close it calls close-requested on the node; so does the engine's own window's closing on the root, when the engine was started with :auto-accept-quit nil (see Stopping). An embedded-window, one the program draws inside another's, as an embedded popup is, takes that window's input first: the pointer's over it, or while a press on it is held, in its own coordinates, and the keys while it has that window's keyboard focus, which one that takes the keyboard gets as it is attached, raised or pressed, and a press on the window's own part takes back; window-focus-changed tells a window's node as its window gains or loses the keys. A modal one keeps the input from what is below it. What names a window is a window-designator: a window of the engine, an embedded window, or any other object but nil, as a test names a window by a keyword. And state: key-pressed-p, key-just-pressed-p, key-just-released-p, the same for buttons, any-button-pressed-p, pointer-position and pointer-inside-p. Keys are physical keys, named for their place on a US keyboard, so WASD is where it is on every layout; a key event's event-symbol is what the layout makes of it. The key queries take a cl-windowing:key and the button queries a cl-windowing:button, so a misspelt key is refused rather than never held. event-modifier-p tells whether a modifier, :shift, :control, :alt, :super, :caps-lock or :num-lock, was in effect as an event happened.
  • Where the pointer is: a pointer event's event-x and event-y, and pointer-position and node-pointer-position, are in the coordinates of the node heading the part of the tree its window's input goes to, as Godot's viewports make their input local: a viewport's own, back through its content scale and global canvas transform, which are the window's units while it has neither, and an embedded window's in its host's. window-to-node takes a point there, a generic function a node class of one's own may specialize.
  • Events are the tree's: a tree keeps one event of each class and fills it for each event it dispatches, so input allocates nothing, and a node copies what it keeps. A program reads events and marks them handled; the tree writes the rest, and the events' writers are exported for that, for a user interface that gives a pointer event in a control's coordinates, and for tests that stand in for a window.
  • Actions, as Godot's input map has them, are what a game asks about rather than keys, so that the keys can change: action-pressed-p, action-just-pressed-p and action-just-released-p, as for keys, and event-action-p, whether an event is one of an action's, with :exact t only with the binding's modifiers, as Godot's is_action with exact_match, and :ignore naming modifiers that count for nothing, as a text field leaves Shift to extend its selection. A tree's tree-input-map lists its actions, each a keyword and its bindings: (:key :w), a physical key; (:symbol :z :control), a key as the layout makes it, with Control; (:button :left), a pointer button; (:button :wheel-up :control), a way the wheel turns, a wheel-direction, which a scroll event presses and releases in its frame, as Godot's wheel buttons, so action-just-pressed-p tells of it. A press triggers a binding while its modifiers are held, whatever else is, so Shift held to run does not stop a jump, and the release of the key or button releases it. A tree starts with its session's input-map, which a project's settings give, unless make-scene-tree or run is given another as :input-map.
  • Godot's built-in actions: every tree's map has Godot's ui_ actions after its own, as keywords, :ui-accept for ui_accept, with Godot's keys off macOS, which builtin-input-map lists, and pyssel/ui's controls act on them, as Godot's do: :ui-accept presses a focused button, :ui-cancel closes a popup, :ui-focus-next moves the focus, :ui-text-caret-left moves a text field's caret, and so on. A game rebinds its interface's keys by binding these in its own map, as (:ui-accept (:symbol :return)) leaves Space to the game; the ones it leaves keep Godot's keys.
  • Shortcuts: a key event that no node's input and no control took goes to shortcut-input before unhandled-input, where buttons and menus fire their shortcuts, so a focused text field keeps Control+Z for its own undo. A shortcut is an action or a binding, and fires only with exactly its modifiers held, so Control+Shift+S does not fire Control+S's; event-shortcut-p tells whether an event fires one, and shortcut-text shows it, as "Ctrl+S".