Focus events
Focus Events (Mode 1004) is a DECSET/DECRST mode that causes the terminal to report when it gains or loses input focus.
Syntax
CSI ? 1004 h DECSET — Enable focus event reporting
CSI ? 1004 l DECRST — Disable focus event reporting
DECSET-mode1004 = 0x1b, "[", "?", "1", "0", "0", "4", "h" ; DECRST-mode1004 = 0x1b, "[", "?", "1", "0", "0", "4", "l" ;
Description
Mode 1004 is an XTerm extension that enables focus event reporting. When enabled, the terminal sends an escape sequence to the application whenever the terminal window gains or loses focus.
- Set — The terminal sends focus-in and focus-out events.
- Reset — Focus changes are not reported. This is the default.
Report format
When focus changes occur, the terminal sends:
| Sequence | Meaning |
|---|---|
CSI I | Focus in (terminal gained focus) |
CSI O | Focus out (terminal lost focus) |
These are the literal bytes ESC [ I (hex 1b 5b 49) and ESC [ O (hex 1b 5b 4f).
Common uses
Focus event reporting is useful for applications that need to:
- Refresh their display when regaining focus (e.g., checking for file changes)
- Pause background activity when the terminal is not in focus
- Change cursor appearance or status bar indicators based on focus state
- Implement "smart paste" behavior by detecting when the terminal regains focus after a clipboard operation
Interaction with multiplexers
Terminal multiplexers like tmux and screen can synthesize focus events for individual panes. When the user switches between panes, the multiplexer sends focus-out to the old pane and focus-in to the new pane, even though the outer terminal window focus has not changed.
The CSI O focus-out sequence can conflict with SS3 (Single Shift 3) sequences if the application is not careful to distinguish them by context. Applications should only interpret CSI O as a focus event when Mode 1004 is enabled.
Examples
printf '\e[?1004h' # Enable focus event reporting
printf '\e[?1004l' # Disable focus event reporting
# In a shell script, read focus events:
printf '\e[?1004h'
while IFS= read -r -n1 char; do
# Parse incoming sequences for CSI I and CSI O
:
done
printf '\e[?1004l'
Specifications
| Specification | Section |
|---|---|
| XTerm ctlseqs | — |
Terminal support
| Terminal | Support | Version | Notes |
|---|---|---|---|
| Terminal Emulators | |||
| Alacritty | ✓ | Yes | |
| Bobcat | ? | ? | Not explicitly configured in Bobcat. TerminalCtrl may support this, but cannot confirm from Bobcat's code. |
| contour | ✓ | v0.3.10.257 | Implemented as DECMode::FocusTracking at primitives.h:689, handled in Terminal.cpp:2392 |
| foot | ✓ | Yes | |
| Ghostty | ✓ | v1.0.0 | |
| iTerm2 | ✓ | v20260216-nightly | Requires focus reporting to be allowed by delegate |
| Kitty | ✓ | Yes | |
| Konsole | ✓ | Yes | Uses _reportFocusEvents flag, sends CSI I/O sequences |
| mintty | ✓ | Yes | Implemented at src/termout.c:2496 |
| mlterm | ✓ | rel-3_8_2 | |
| PuTTY | ✗ | No | Focus tracking exists but no CSI I/O reporting |
| Rio | ✓ | v0.1.13 | |
| rxvt-unicode | ✓ | 9.25 | Requires ENABLE_FRILLS (default on) |
| st | ✓ | 0.5 | |
| terminology | ✓ | v1.11.0 | Uses focus_reporting flag and termpty_focus_report function |
| VT100 | ✗ | No | |
| VTE | ✓ | Yes | |
| WezTerm | ✓ | Yes | |
| Windows Terminal | ✓ | Yes | FOCUS_EVENT_MODE at adaptDispatch.cpp:1862-1869 |
| xterm | ✓ | Yes | Requires OPT_FOCUS_EVENT compile flag (enabled by default) |
| xterm.js | ✓ | 4.15.0 | |
| Multiplexers | |||
| cy | ✓ | Yes | |
| GNU Screen | ✗ | No | |
| tmux | ✓ | 1.8 | |
| tuios | ✓ | v0.0.15 | |
| Zellij | ✓ | v0.33.0 | |
See also
- Normal Mouse Tracking — Mode 1000 — Mouse event reporting
- Bracketed Paste — Mode 2004 — Another input-wrapping mode