You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The preferred method on supporting terminals. Sends a single escape sequence and gets back a direct dark/light answer — no RGB parsing or luminance calculation needed.
242
+
243
+
```
244
+
CSI ? 996 n → CSI ? 997 ; 1 n (dark)
245
+
CSI ? 997 ; 2 n (light)
246
+
```
247
+
248
+
This is based on the [Contour VT extension](https://contour-terminal.org/vt-extensions/color-palette-update-notifications/) for color palette update notifications.
249
+
250
+
#### Using via Connection
251
+
252
+
```java
253
+
// One-shot query: returns DARK, LIGHT, or null (unsupported/timeout)
| tmux | — | Passes through to underlying terminal |
280
+
| VTE / GNOME Terminal | 0.82.0+ | Full support |
281
+
| Foot | — | Full support |
282
+
283
+
The `TerminalColorDetector` tries this method first when the terminal supports it, then falls back to OSC queries and environment detection.
284
+
285
+
### 2. OSC Color Queries (Most Accurate Fallback)
239
286
240
287
Queries the terminal directly for its background color using OSC 10/11 escape sequences:
241
288
@@ -373,7 +420,7 @@ if (bgColor != null) {
373
420
374
421
See [Terminal Colors](terminal-colors#ansi-color-utilities) for complete documentation of RGB/ANSI conversion utilities.
375
422
376
-
### 2. Environment Variables
423
+
### 3. Environment Variables
377
424
378
425
Checks standard environment variables via [`TerminalEnvironment`](terminal-environment):
379
426
@@ -390,7 +437,7 @@ Checks standard environment variables via [`TerminalEnvironment`](terminal-envir
390
437
391
438
The `TerminalEnvironment` class parses these once and caches the results. See [Terminal Environment](terminal-environment) for details on all supported environment variables and terminal types.
392
439
393
-
### 3. Terminal-Specific Detection
440
+
### 4. Terminal-Specific Detection
394
441
395
442
For terminals that don't support OSC queries, the detector reads configuration files:
396
443
@@ -468,6 +515,63 @@ set -g allow-passthrough on
468
515
tmux set -g allow-passthrough on
469
516
```
470
517
518
+
## Real-Time Theme Change Notifications
519
+
520
+
Terminals that support the CSI ? 996 n protocol can also send **unsolicited** notifications when the user switches between dark and light mode. This allows your application to adapt its colors in real time without polling.
521
+
522
+
### How It Works
523
+
524
+
1. Your application sends `CSI ? 2031 h` to **subscribe** to theme change notifications
525
+
2. The terminal sends `CSI ? 997 ; 1 n` (dark) or `CSI ? 997 ; 2 n` (light) whenever the theme changes
526
+
3. Your application sends `CSI ? 2031 l` to **unsubscribe**
527
+
528
+
The `EventDecoder` in the input pipeline automatically intercepts these unsolicited DSR sequences and routes them to a registered handler, preventing them from appearing as garbage in the readline buffer.
529
+
530
+
### Subscribing to Theme Changes
531
+
532
+
```java
533
+
importorg.aesh.terminal.utils.TerminalTheme;
534
+
535
+
// One-call setup: register handler and enable notifications
When no theme change handler is registered, the DSR filtering in `EventDecoder` has **zero overhead** — a single null check on the fast path. When a handler is registered but the input contains no ESC bytes, the overhead is a single linear scan with no allocation. The state machine only activates when an ESC byte is found in the input.
568
+
569
+
### Supported Terminals
570
+
571
+
Theme change notifications use the same terminal support as the CSI ? 996 n query. See the [Theme Mode Query](#1-theme-mode-query-csi--996-n--fastest--simplest) section above for the full compatibility table.
572
+
573
+
See the [Connection](connection#theme-mode-queries) documentation for the complete API reference.
574
+
471
575
## Example Application
472
576
473
577
Here's a complete example that adapts colors based on detection:
@@ -543,21 +647,23 @@ public class MyApp {
543
647
544
648
The following terminals have been tested with full detection support:
545
649
546
-
| Terminal | OSC Query | Config File | Notes |
547
-
|----------|-----------|-------------|-------|
548
-
| iTerm2 | Yes | - | Full support |
549
-
| Kitty | Yes | - | Full support |
550
-
| WezTerm | Yes | - | Full support |
551
-
| Alacritty | Yes | Yes | Both methods work |
552
-
| Ghostty | Yes | - | Full support |
553
-
| GNOME Terminal | Yes | - | Full support |
554
-
| Konsole | Yes | - | Full support |
555
-
| Windows Terminal | Yes | Yes | Both methods work |
Called when the terminal's theme changes (dark/light mode switch). Requires subscribing to theme change notifications with `enableThemeChangeNotification()`:
When a handler is registered, the `EventDecoder` in the input pipeline intercepts unsolicited `CSI ? 997 ; Ps n` responses and routes them to this handler, preventing them from appearing as input. See [Theme Mode Queries](#theme-mode-queries) for the full API.
// Always returns colors - actual if OSC works, estimated if not
332
350
```
333
351
352
+
## ThemeModeQueries
353
+
354
+
The `Connection` interfaceprovides methods for querying and subscribing to terminal theme changes using the `CSI ? 996 n` protocol. This is simpler and faster than OSC 10/11 RGB queries — it returns a direct `DARK` or `LIGHT` answer.
355
+
356
+
See [Color Detection](color-detection#1-theme-mode-query-csi--996-n--fastest--simplest) for background on the protocol.
357
+
358
+
### One-Shot Query
359
+
360
+
Query the current theme mode:
361
+
362
+
```java
363
+
// Returns DARK, LIGHT, or null (unsupported/timeout)
Support is determined by the `Device.TerminalType` enum — terminals like Kitty, Ghostty, Foot, Contour, GNOMETerminal, and tmux report `supportsThemeDsr() ==true`.
381
+
382
+
### Subscribing to LiveThemeChanges
383
+
384
+
Enable real-time notifications when the user switches dark/light mode:
385
+
386
+
```java
387
+
// One-call setup: register handler and enable notifications
@@ -316,3 +320,27 @@ if (connection.supportsOscQueries(da)) {
316
320
// DA1 indicates modern terminal features
317
321
}
318
322
```
323
+
324
+
## Theme Mode Detection
325
+
326
+
Modern terminals can report whether they are using a dark or light color scheme using the `CSI ? 996 n` protocol. This is faster and simpler than parsing OSC 10/11 RGB responses.
Supported terminals include Kitty (0.38.1+), Ghostty (1.0.0+), Contour (0.4.0+), Foot, VTE/GNOME Terminal (0.82.0+), and tmux.
345
+
346
+
See [Color Detection](color-detection#1-theme-mode-query-csi--996-n--fastest--simplest) for protocol details and [Connection](connection#theme-mode-queries) for the full API reference.
0 commit comments