wezterm icon indicating copy to clipboard operation
wezterm copied to clipboard

Add bell_urgency_hint config option and window:request_attention() API

Open CyberShadow opened this issue 1 month ago • 0 comments

LLM Disclosure

This PR was generated with the help of Claude Code. However, I have closely reviewed it and take full responsibility for it.

Summary

This PR adds support for requesting user attention via window urgency hints when the BEL character is received, along with manual control through a Lua API. This addresses the feature request from PR #1636.

Included are implementations for all major platforms; however, all but X11 are best-effort, as I have not tested them manually.

Motivation

Terminal applications commonly need to request user attention (e.g., when a long-running command completes, an SSH session times out, or new messages arrive). Many popular terminal emulators already implement this feature:

  • urxvt: urgentOnBell option
  • xterm: bellIsUrgent resource
  • alacritty: Built-in support (automatic)
  • kitty: window_alert_on_bell option
  • konsole: Built-in bell notifications
  • terminator: urgent_bell configuration option
  • st: Available via patch

This PR brings wezterm to feature parity with these terminals.

Features

1. Configuration Option

config.bell_urgency_hint = "Enabled"  -- or "Disabled" (default)

When enabled, sets urgency hint when BEL is received while window is unfocused. Automatically clears when window regains focus.

2. Lua API

-- Request attention
window:request_attention(true)

-- Clear attention request
window:request_attention(false)

Allows custom attention logic (e.g., only for specific panes, tabs, or events).

Platform Support

Platform Implementation Behavior
X11 _NET_WM_STATE_DEMANDS_ATTENTION (EWMH) Window flashes/highlights in taskbar; can be cleared programmatically
Wayland xdg_activation_v1 protocol Compositor-dependent; clears automatically on focus
macOS NSApplication.requestUserAttention() Dock icon bounces once; can be cleared programmatically
Windows FlashWindowEx Win32 API Taskbar button flashes orange; can be stopped programmatically

Differences from #1636

PR #1636 was closed due to technical challenges. This implementation takes a different approach:

Aspect PR #1636 This PR
X11 Method ICCCM WM_HINTS urgency flag EWMH _NET_WM_STATE_DEMANDS_ATTENTION
Dependencies Required xcb-util crate (conflict) Uses existing xcb infrastructure
Code Complexity Read-modify-write approach (~50 lines) 4-line method reusing set_wm_state()
User Control Only Lua API Config option + Lua API
Auto-clear Not implemented Clears on focus gain

EWMH vs ICCCM:

  • EWMH: Uses client messages for state changes[^1]; reuses existing infrastructure (4 lines)
  • ICCCM: Requires read-modify-write to preserve all WM_HINTS fields[^2]; needs extra dependencies (~50 lines)

EWMH is a freedesktop.org standard (2005) that extends ICCCM (1980s) with modern desktop features[^3]. Most contemporary window managers implement EWMH.

[^1]: EWMH Specification § Application Window Properties [^2]: ICCCM Specification § WM_HINTS Property [^3]: Extended Window Manager Hints - Wikipedia

Implementation

Files modified: 17 files, 290 insertions, 5 deletions

Core changes:

  • window/src/lib.rs: Added set_attention_hint() to WindowOps trait
  • window/src/os/{x11,wayland,macos,windows}/: Platform-specific implementations
  • config/src/bell.rs: Added BellUrgencyHint enum
  • config/src/config.rs: Added bell_urgency_hint config field
  • wezterm-gui/src/termwindow/mod.rs: Hooks BEL handler and focus events
  • wezterm-gui/src/scripting/guiwin.rs: Lua API binding
  • docs/: New docs for config option and Lua API; updated cross-references in related bell docs

Testing

Build & Format:

  • ✅ Compiles successfully with cargo check
  • ✅ Code formatted with cargo fmt --all
  • ✅ CI checks pass

Manual Testing:

  • X11: Tested and working (BEL behavior, focus clearing, Lua API)
  • ⏸️ Wayland: Compiles, but not tested
  • ⏸️ macOS: Compiles, but not tested
  • ⏸️ Windows: Compiles, but not tested

Backward Compatibility

  • Default is "Disabled" - no behavior change unless explicitly enabled
  • No breaking changes to existing APIs
  • Follows existing bell configuration patterns (audible_bell, visual_bell)

CyberShadow avatar Nov 04 '25 09:11 CyberShadow