1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! Public full-redraw verb + focus-regain repaint opt-in (backlog
//! first-app/0299).
//!
//! The damage contract trusts the terminal to keep every cell the
//! engine ever painted. When that assumption breaks EXTERNALLY —
//! Cmd+K in Terminal.app, `printf '\033c'` from a stray process, an
//! emulator glitch — model-side damage cannot heal the screen: a
//! repaint that produces byte-identical cells emits NOTHING (the diff
//! correctly suppresses equal cells), so the loss is permanent. Only
//! the driver's "screen is unknown" resync repairs it: poison the
//! previous-frame model, invalidate the presenter's cursor/pen,
//! damage every layer, re-place protocol images — the pair resize and
//! suspend-resume already run.
//!
//! [`request_full_redraw`] is the component-reachable form of that
//! verb (the Ctrl+L class): a thread-local flag the driver drains at
//! its next turn's phase U — the `mouse_capture()` request shape,
//! without the handle. [`set_redraw_on_focus_gained`] opts into the
//! same resync whenever the terminal reports focus-in (DEC 1004): an
//! externally-cleared terminal is nearly always followed by a focus
//! round-trip before the user looks again, so the failure heals
//! without a keybinding. Default OFF — a full-frame emission per
//! focus-in is bounded and human-paced, but it is real byte cost
//! (tmux pane switches fire focus events constantly), so existing
//! sessions stay byte-identical unless the app opts in.
//!
//! OWNER: REACT (verb surface) with KERNEL (driver drain).
use Cell;
use craterequest_frame;
thread_local!
/// Repaint everything from scratch on the next frame — the Ctrl+L
/// verb. Use it when the TERMINAL's content can no longer be trusted
/// (an external clear, a corrupting burst from another process):
/// unlike `request_repaint`/tree invalidation — which damage the
/// MODEL and re-emit only cells whose bytes changed — this poisons
/// the engine's previous-frame model and re-anchors the presenter, so
/// the next frame re-emits EVERY cell and re-places protocol images.
///
/// Callable from any component handler or posted job on the app
/// thread; the driver drains the request at its next turn (a call
/// from a key handler is honored within the same turn). Bounded cost:
/// one full-frame emission, then idle returns to zero bytes.
/// Driver drain (once per turn, phase U): the pending request, if any.
pub
/// Opt into a full redraw whenever the terminal reports FOCUS-IN
/// (DEC 1004 — backlog first-app/0299 ask 2). An externally-cleared
/// terminal is nearly always followed by a focus round-trip, so the
/// damage heals silently, without a keybinding. Costs one full-frame
/// emission per focus-in (bounded, human-paced); default OFF so
/// existing sessions stay byte-identical. Terminal focus events are
/// otherwise dropped by routing (they are distinct from widget
/// focus), so enabling this consumes nothing an app could observe.
/// The current focus-regain policy (see [`set_redraw_on_focus_gained`]).