Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/guide/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ The App class is always the root of the DOM, so there is nowhere for the event t

Event handlers may stop this bubble behavior by calling the [stop()][textual.message.Message.stop] method on the event or message. You might want to do this if a widget has responded to the event in an authoritative way. For instance when a text input widget responds to a key event it stops the bubbling so that the key doesn't also invoke a key binding.

!!! tip

Because `Input` and other built-in widgets stop key events, an `on_key` handler on the `App` will not receive keys consumed by the focused widget. If you need App-level key handling that fires regardless of which widget has focus, use [`key_*` methods](../guide/input.md#key-methods) instead — they are called directly by the App's key dispatcher before event bubbling takes place.

## Custom messages

You can create custom messages for your application that may be used in the same way as events (recall that events are simply messages reserved for use by Textual).
Expand Down
14 changes: 13 additions & 1 deletion docs/guide/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,19 @@ Note the addition of a `key_space` method which is called in response to the spa

!!! note

Consider key methods to be a convenience for experimenting with Textual features. In nearly all cases, key [bindings](#bindings) and [actions](../guide/actions.md) are preferable.
For most cases, key [bindings](#bindings) and [actions](../guide/actions.md) are preferable to key methods.

However, `key_*` methods have one important advantage over `on_key` handlers: they are called directly by the App's internal key dispatcher, *regardless of whether a child widget has stopped the event's bubbling*. This makes them the right choice for App-level keys that must fire even when a focused widget (such as `Input`) consumes the key event.

```python
class MyApp(App):
# This fires even if the focused Input stopped the key event
def key_enter(self, event: Key) -> None:
if not isinstance(self.focused, Input):
self._handle_enter()
```

By contrast, an `on_key` handler on the App will *not* receive keys that were stopped by a focused widget.

## Input focus

Expand Down