@deepseek-harness-tui/dsh-tui 0.8.7 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -10
- package/bin/dsh-tui.js +1 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +4 -2
- package/lib/types/components/ActivityPicker.d.ts +4 -1
- package/lib/types/components/ActivityPicker.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.js +2 -2
- package/lib/types/components/BtwPanel.d.ts.map +1 -1
- package/lib/types/components/BtwPanel.js +1 -1
- package/lib/types/components/Chat/SubagentMessage.d.ts +2 -1
- package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -1
- package/lib/types/components/Chat/SubagentMessage.js +11 -3
- package/lib/types/components/CommandSuggestions.d.ts +21 -4
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +41 -14
- package/lib/types/components/EffortSlider.d.ts +4 -1
- package/lib/types/components/EffortSlider.d.ts.map +1 -1
- package/lib/types/components/EffortSlider.js +4 -2
- package/lib/types/components/ExtensionDialog.js +6 -2
- package/lib/types/components/FileSuggestions.d.ts +26 -5
- package/lib/types/components/FileSuggestions.d.ts.map +1 -1
- package/lib/types/components/FileSuggestions.js +53 -16
- package/lib/types/components/GoalTodoPanel.d.ts +26 -2
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/GoalTodoPanel.js +86 -17
- package/lib/types/components/HelpMenu.d.ts +7 -1
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +12 -4
- package/lib/types/components/HistorySearchDialog.d.ts +4 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +2 -2
- package/lib/types/components/LangPicker.d.ts +14 -0
- package/lib/types/components/LangPicker.d.ts.map +1 -0
- package/lib/types/components/LangPicker.js +17 -0
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LoadedContextPanel.js +3 -1
- package/lib/types/components/LogoV2.d.ts +5 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +12 -3
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +12 -3
- package/lib/types/components/MessageList.d.ts +43 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +553 -41
- package/lib/types/components/ModelPicker.d.ts +4 -1
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +2 -2
- package/lib/types/components/PermissionsPicker.d.ts +21 -0
- package/lib/types/components/PermissionsPicker.d.ts.map +1 -0
- package/lib/types/components/PermissionsPicker.js +27 -0
- package/lib/types/components/PlanPicker.d.ts +15 -0
- package/lib/types/components/PlanPicker.d.ts.map +1 -0
- package/lib/types/components/PlanPicker.js +18 -0
- package/lib/types/components/PresetPicker.d.ts +4 -1
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +2 -2
- package/lib/types/components/PromptInput.d.ts +4 -3
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +273 -50
- package/lib/types/components/RewindPicker.d.ts +12 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +6 -4
- package/lib/types/components/ScrollbarGutter.d.ts +28 -0
- package/lib/types/components/ScrollbarGutter.d.ts.map +1 -0
- package/lib/types/components/ScrollbarGutter.js +68 -0
- package/lib/types/components/Select.d.ts +8 -1
- package/lib/types/components/Select.d.ts.map +1 -1
- package/lib/types/components/Select.js +4 -2
- package/lib/types/components/SkillsPicker.d.ts +4 -1
- package/lib/types/components/SkillsPicker.d.ts.map +1 -1
- package/lib/types/components/SkillsPicker.js +2 -2
- package/lib/types/components/SubagentCard.d.ts +2 -1
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +6 -1
- package/lib/types/components/SubagentDashboard.d.ts +4 -0
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
- package/lib/types/components/SubagentDashboard.js +9 -1
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +5 -4
- package/lib/types/components/SuggestionCard.d.ts +63 -0
- package/lib/types/components/SuggestionCard.d.ts.map +1 -0
- package/lib/types/components/SuggestionCard.js +77 -0
- package/lib/types/components/ThemePicker.d.ts +4 -1
- package/lib/types/components/ThemePicker.d.ts.map +1 -1
- package/lib/types/components/ThemePicker.js +2 -2
- package/lib/types/components/ThinkingToggle.d.ts +4 -1
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
- package/lib/types/components/ThinkingToggle.js +2 -2
- package/lib/types/components/TimelineRail.d.ts +53 -0
- package/lib/types/components/TimelineRail.d.ts.map +1 -0
- package/lib/types/components/TimelineRail.js +190 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts +6 -1
- package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -1
- package/lib/types/components/WorkspaceFlowPicker.js +4 -2
- package/lib/types/components/WorkspaceMenuPicker.d.ts +19 -0
- package/lib/types/components/WorkspaceMenuPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceMenuPicker.js +19 -0
- package/lib/types/components/WorkspacePicker.d.ts +4 -1
- package/lib/types/components/WorkspacePicker.d.ts.map +1 -1
- package/lib/types/components/WorkspacePicker.js +2 -2
- package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
- package/lib/types/components/approvals/ApprovalPanel.js +5 -1
- package/lib/types/components/design-system/ListItem.d.ts +8 -1
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
- package/lib/types/components/design-system/ListItem.js +8 -3
- package/lib/types/components/messages/AssistantTextMessage.d.ts +5 -2
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantTextMessage.js +6 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +10 -4
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +8 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +4 -2
- package/lib/types/components/messages/UserPromptMessage.d.ts +2 -1
- package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +34 -2
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +13 -2
- package/lib/types/components/sessions/SessionListRow.d.ts +4 -1
- package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
- package/lib/types/components/sessions/SessionListRow.js +4 -2
- package/lib/types/components/trajectory/HotspotView.d.ts +7 -1
- package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -1
- package/lib/types/components/trajectory/HotspotView.js +8 -2
- package/lib/types/components/trajectory/Ledger.d.ts +9 -1
- package/lib/types/components/trajectory/Ledger.d.ts.map +1 -1
- package/lib/types/components/trajectory/Ledger.js +23 -5
- package/lib/types/components/trajectory/WaveBand.d.ts +10 -1
- package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -1
- package/lib/types/components/trajectory/WaveBand.js +7 -2
- package/lib/types/dsh-adapter/channel.d.ts +27 -6
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +432 -66
- package/lib/types/dsh-adapter/contract.d.ts +58 -18
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +124 -36
- package/lib/types/dsh-adapter/index.d.ts +10 -2
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +10 -13
- package/lib/types/dsh-adapter/plugin.d.ts +0 -9
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +136 -6
- package/lib/types/i18n.d.ts +194 -16
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +73 -10
- package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -1
- package/lib/types/ink/components/AlternateScreen.js +13 -1
- package/lib/types/ink/components/App.d.ts +12 -1
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +101 -4
- package/lib/types/ink/components/ClockContext.d.ts.map +1 -1
- package/lib/types/ink/components/ClockContext.js +2 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
- package/lib/types/ink/components/ScrollBox.js +170 -91
- package/lib/types/ink/constants.d.ts +9 -0
- package/lib/types/ink/constants.d.ts.map +1 -1
- package/lib/types/ink/constants.js +9 -0
- package/lib/types/ink/events/click-event.d.ts +7 -16
- package/lib/types/ink/events/click-event.d.ts.map +1 -1
- package/lib/types/ink/events/click-event.js +16 -19
- package/lib/types/ink/events/event-handlers.d.ts +11 -1
- package/lib/types/ink/events/event-handlers.d.ts.map +1 -1
- package/lib/types/ink/events/event-handlers.js +2 -0
- package/lib/types/ink/events/input-event.d.ts +9 -0
- package/lib/types/ink/events/input-event.d.ts.map +1 -1
- package/lib/types/ink/events/input-event.js +4 -0
- package/lib/types/ink/events/pointer-event.d.ts +61 -0
- package/lib/types/ink/events/pointer-event.d.ts.map +1 -0
- package/lib/types/ink/events/pointer-event.js +61 -0
- package/lib/types/ink/events/wheel-event.d.ts +17 -0
- package/lib/types/ink/events/wheel-event.d.ts.map +1 -0
- package/lib/types/ink/events/wheel-event.js +20 -0
- package/lib/types/ink/geometry-trace.d.ts +51 -0
- package/lib/types/ink/geometry-trace.d.ts.map +1 -0
- package/lib/types/ink/geometry-trace.js +83 -0
- package/lib/types/ink/hit-test.d.ts +56 -1
- package/lib/types/ink/hit-test.d.ts.map +1 -1
- package/lib/types/ink/hit-test.js +146 -8
- package/lib/types/ink/ink.d.ts +58 -1
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +268 -52
- package/lib/types/ink/node-cache.d.ts +5 -0
- package/lib/types/ink/node-cache.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.d.ts +8 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +101 -12
- package/lib/types/ink/render-node-to-output.d.ts +16 -3
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +144 -25
- package/lib/types/ink/selection.d.ts +29 -4
- package/lib/types/ink/selection.d.ts.map +1 -1
- package/lib/types/ink/selection.js +41 -5
- package/lib/types/ink/timeline-rail.d.ts +138 -0
- package/lib/types/ink/timeline-rail.d.ts.map +1 -0
- package/lib/types/ink/timeline-rail.js +179 -0
- package/lib/types/ink/wrap-text.d.ts.map +1 -1
- package/lib/types/ink/wrap-text.js +47 -5
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +819 -337
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +56 -29
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +64 -22
- package/lib/types/screens/StatusLine.d.ts +2 -1
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +17 -1
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -1
- package/lib/types/screens/TrajectoryScene.js +81 -14
- package/lib/types/screens/chatOverlay.d.ts +221 -0
- package/lib/types/screens/chatOverlay.d.ts.map +1 -0
- package/lib/types/screens/chatOverlay.js +114 -0
- package/lib/types/tips.d.ts.map +1 -1
- package/lib/types/tips.js +64 -10
- package/lib/types/tuiDisplayPrefs.d.ts +15 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +9 -0
- package/lib/types/utils/debug.d.ts +10 -0
- package/lib/types/utils/debug.d.ts.map +1 -1
- package/lib/types/utils/debug.js +24 -0
- package/lib/types/utils/fileSuggestions.d.ts +19 -0
- package/lib/types/utils/fileSuggestions.d.ts.map +1 -0
- package/lib/types/utils/fileSuggestions.js +40 -0
- package/lib/types/utils/mentions.d.ts.map +1 -1
- package/lib/types/utils/mentions.js +3 -1
- package/lib/types/utils/paths.d.ts.map +1 -1
- package/lib/types/utils/paths.js +1 -0
- package/package.json +69 -66
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useImperativeHandle, useRef, useState } from 'react';
|
|
2
|
+
import { useCallback, useImperativeHandle, useRef, useState } from 'react';
|
|
3
|
+
import { FRAME_INTERVAL_MS } from '../constants.js';
|
|
3
4
|
import { markScrollActivity } from '../../bootstrap/state.js';
|
|
4
5
|
import { markDirty, scheduleRenderFrom } from '../dom.js';
|
|
6
|
+
import { noteFrameCause } from '../geometry-trace.js';
|
|
5
7
|
import { markCommitStart } from '../reconciler.js';
|
|
6
8
|
import Box from './Box.js';
|
|
7
9
|
/**
|
|
@@ -27,18 +29,56 @@ function ScrollBox({ children, ref, stickyScroll, ...style }) {
|
|
|
27
29
|
const [, forceRender] = useState(0);
|
|
28
30
|
const listenersRef = useRef(new Set());
|
|
29
31
|
const renderQueuedRef = useRef(false);
|
|
32
|
+
// The imperative handle, kept in a ref so the onWheel handler below can
|
|
33
|
+
// call scrollBy through the full public path (clamp bounds, sticky
|
|
34
|
+
// clearing, subscriber notify) instead of duplicating its logic.
|
|
35
|
+
const handleRef = useRef(null);
|
|
30
36
|
const notify = () => {
|
|
31
37
|
for (const l of listenersRef.current)
|
|
32
38
|
l();
|
|
33
39
|
};
|
|
40
|
+
// Input-edge intent coalescing (Qwen Code's 16ms wheel merge, Crush's
|
|
41
|
+
// pre-queue filter): subscribers drive React state (MessageList's mount
|
|
42
|
+
// window, Chat's sticky flag, the timeline rail), so notifying per wheel
|
|
43
|
+
// EVENT runs a full React commit per event — a fast flick is 10-30
|
|
44
|
+
// events, each re-running the offsets/window/timeline loops on a big
|
|
45
|
+
// session. The scrollTop mutation and the ink render are already
|
|
46
|
+
// frame-throttled; this aligns the React commits to the same frame
|
|
47
|
+
// budget. Both edges defer to a microtask: the remaining input events of
|
|
48
|
+
// the same stdin batch then land BEFORE any commit, and one commit
|
|
49
|
+
// covers the whole batch (the sync leading edge used to run a full
|
|
50
|
+
// commit inside the wheel dispatch itself — pure input latency).
|
|
51
|
+
const notifyQueuedRef = useRef(false);
|
|
52
|
+
const lastNotifyAtRef = useRef(-Infinity);
|
|
53
|
+
const notifyCoalesced = () => {
|
|
54
|
+
const since = performance.now() - lastNotifyAtRef.current;
|
|
55
|
+
if (!notifyQueuedRef.current && since >= FRAME_INTERVAL_MS) {
|
|
56
|
+
notifyQueuedRef.current = true;
|
|
57
|
+
lastNotifyAtRef.current = performance.now();
|
|
58
|
+
queueMicrotask(() => {
|
|
59
|
+
notifyQueuedRef.current = false;
|
|
60
|
+
notify();
|
|
61
|
+
});
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (notifyQueuedRef.current)
|
|
65
|
+
return;
|
|
66
|
+
notifyQueuedRef.current = true;
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
notifyQueuedRef.current = false;
|
|
69
|
+
lastNotifyAtRef.current = performance.now();
|
|
70
|
+
notify();
|
|
71
|
+
}, Math.max(0, FRAME_INTERVAL_MS - since));
|
|
72
|
+
};
|
|
34
73
|
function scrollMutated(el) {
|
|
35
74
|
// Signal background intervals (IDE poll, LSP poll, GCS fetch, orphan
|
|
36
75
|
// check) to skip their next tick — they compete for the event loop and
|
|
37
76
|
// contributed to 1402ms max frame gaps during scroll drain.
|
|
38
77
|
markScrollActivity();
|
|
78
|
+
noteFrameCause('scroll');
|
|
39
79
|
markDirty(el);
|
|
40
80
|
markCommitStart();
|
|
41
|
-
|
|
81
|
+
notifyCoalesced();
|
|
42
82
|
if (renderQueuedRef.current)
|
|
43
83
|
return;
|
|
44
84
|
renderQueuedRef.current = true;
|
|
@@ -47,99 +87,138 @@ function ScrollBox({ children, ref, stickyScroll, ...style }) {
|
|
|
47
87
|
scheduleRenderFrom(el);
|
|
48
88
|
});
|
|
49
89
|
}
|
|
50
|
-
useImperativeHandle(ref, () =>
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
90
|
+
useImperativeHandle(ref, () => {
|
|
91
|
+
const handle = {
|
|
92
|
+
scrollTo(y) {
|
|
93
|
+
const el = domRef.current;
|
|
94
|
+
if (!el)
|
|
95
|
+
return;
|
|
96
|
+
// Explicit false overrides the DOM attribute so manual scroll
|
|
97
|
+
// breaks stickiness. Render code checks ?? precedence.
|
|
98
|
+
el.stickyScroll = false;
|
|
99
|
+
el.pendingScrollDelta = undefined;
|
|
100
|
+
el.scrollAnchor = undefined;
|
|
101
|
+
el.scrollTop = Math.max(0, Math.floor(y));
|
|
102
|
+
scrollMutated(el);
|
|
103
|
+
},
|
|
104
|
+
scrollToElement(el, offset = 0) {
|
|
105
|
+
const box = domRef.current;
|
|
106
|
+
if (!box)
|
|
107
|
+
return;
|
|
108
|
+
box.stickyScroll = false;
|
|
109
|
+
box.pendingScrollDelta = undefined;
|
|
110
|
+
box.scrollAnchor = {
|
|
111
|
+
el,
|
|
112
|
+
offset
|
|
113
|
+
};
|
|
114
|
+
scrollMutated(box);
|
|
115
|
+
},
|
|
116
|
+
scrollBy(dy) {
|
|
117
|
+
const el = domRef.current;
|
|
118
|
+
if (!el)
|
|
119
|
+
return;
|
|
120
|
+
el.stickyScroll = false;
|
|
121
|
+
// Wheel input cancels any in-flight anchor seek — user override.
|
|
122
|
+
el.scrollAnchor = undefined;
|
|
123
|
+
// Accumulate in pendingScrollDelta; renderer drains it at a capped
|
|
124
|
+
// rate so fast flicks show intermediate frames. Pure accumulator:
|
|
125
|
+
// scroll-up followed by scroll-down naturally cancels.
|
|
126
|
+
el.pendingScrollDelta = (el.pendingScrollDelta ?? 0) + Math.floor(dy);
|
|
127
|
+
scrollMutated(el);
|
|
128
|
+
},
|
|
129
|
+
scrollToBottom() {
|
|
130
|
+
const el = domRef.current;
|
|
131
|
+
if (!el)
|
|
132
|
+
return;
|
|
133
|
+
el.scrollAnchor = undefined;
|
|
134
|
+
const viewportH = el.scrollViewportHeight ?? 0;
|
|
135
|
+
const maxScroll = Math.max(0, (el.scrollHeight ?? 0) - viewportH);
|
|
136
|
+
const distance = maxScroll - (el.scrollTop ?? 0);
|
|
137
|
+
if (distance > viewportH && viewportH > 0) {
|
|
138
|
+
// FAR jump: drain instead of teleport. The viewport would land on
|
|
139
|
+
// rows that were never mounted — their spacer heights are
|
|
140
|
+
// DEFAULT_ROW_HEIGHT estimates, so the topPad swallows the view
|
|
141
|
+
// (blank transcript) AND it is a fixed point: unmounted rows never
|
|
142
|
+
// measure, nothing retried until the next wheel event. The drain
|
|
143
|
+
// walks the exact wheel path instead: proportional steps, the
|
|
144
|
+
// virtualization window follows per commit (it mounts the union of
|
|
145
|
+
// committed + pending), the visual clamp pins to the mounted edge
|
|
146
|
+
// while rows measure as they enter — no blank at any distance. The
|
|
147
|
+
// renderer's at-bottom re-pin restores sticky when it lands
|
|
148
|
+
// (stickyScroll=false + pending undefined + scrollTop >= maxScroll).
|
|
149
|
+
el.stickyScroll = false;
|
|
150
|
+
el.pendingScrollDelta = (el.pendingScrollDelta ?? 0) + distance;
|
|
151
|
+
scrollMutated(el);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
el.pendingScrollDelta = undefined;
|
|
155
|
+
el.stickyScroll = true;
|
|
156
|
+
// DOM-direct pre-write of the target (near jumps only): the notify
|
|
157
|
+
// below triggers MessageList's window recompute, and its React commit
|
|
158
|
+
// must read the NEW scrollTop — the old order (notify first, renderer
|
|
159
|
+
// moves scrollTop later) left the window one commit behind. The
|
|
160
|
+
// renderer's sticky branch re-pins scrollTop to the exact fresh
|
|
161
|
+
// maxScroll next frame, so a stale cached height costs one frame.
|
|
162
|
+
el.scrollTop = maxScroll;
|
|
163
|
+
scrollMutated(el);
|
|
164
|
+
forceRender(n => n + 1);
|
|
165
|
+
},
|
|
166
|
+
getScrollTop() {
|
|
167
|
+
return domRef.current?.scrollTop ?? 0;
|
|
168
|
+
},
|
|
169
|
+
getPendingDelta() {
|
|
170
|
+
// Accumulated-but-not-yet-drained delta. useVirtualScroll needs
|
|
171
|
+
// this to mount the union [committed, committed+pending] range —
|
|
172
|
+
// otherwise intermediate drain frames find no children (blank).
|
|
173
|
+
return domRef.current?.pendingScrollDelta ?? 0;
|
|
174
|
+
},
|
|
175
|
+
getScrollHeight() {
|
|
176
|
+
return domRef.current?.scrollHeight ?? 0;
|
|
177
|
+
},
|
|
178
|
+
getFreshScrollHeight() {
|
|
179
|
+
const content = domRef.current?.childNodes[0];
|
|
180
|
+
return content?.yogaNode?.getComputedHeight() ?? domRef.current?.scrollHeight ?? 0;
|
|
181
|
+
},
|
|
182
|
+
getViewportHeight() {
|
|
183
|
+
return domRef.current?.scrollViewportHeight ?? 0;
|
|
184
|
+
},
|
|
185
|
+
getViewportTop() {
|
|
186
|
+
return domRef.current?.scrollViewportTop ?? 0;
|
|
187
|
+
},
|
|
188
|
+
isSticky() {
|
|
189
|
+
const el = domRef.current;
|
|
190
|
+
if (!el)
|
|
191
|
+
return false;
|
|
192
|
+
return el.stickyScroll ?? Boolean(el.attributes['stickyScroll']);
|
|
193
|
+
},
|
|
194
|
+
subscribe(listener) {
|
|
195
|
+
listenersRef.current.add(listener);
|
|
196
|
+
return () => listenersRef.current.delete(listener);
|
|
197
|
+
},
|
|
198
|
+
setClampBounds(min, max) {
|
|
199
|
+
const el = domRef.current;
|
|
200
|
+
if (!el)
|
|
201
|
+
return;
|
|
202
|
+
el.scrollClampMin = min;
|
|
203
|
+
el.scrollClampMax = max;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
handleRef.current = handle;
|
|
207
|
+
return handle;
|
|
208
|
+
},
|
|
138
209
|
// notify/scrollMutated are inline (no useCallback) but only close over
|
|
139
210
|
// refs + imports — stable. Empty deps avoids rebuilding the handle on
|
|
140
211
|
// every render (which re-registers the ref = churn).
|
|
141
212
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
142
213
|
[]);
|
|
214
|
+
// Position-routed wheel events (pointer over this box) scroll THIS box
|
|
215
|
+
// through the public scrollBy path — clamp bounds, sticky clearing, and
|
|
216
|
+
// subscriber notify all apply. Horizontal wheel (deltaX) has no renderer
|
|
217
|
+
// support yet (no scrollLeft in the DOM model) and is ignored.
|
|
218
|
+
const handleWheel = useCallback((e) => {
|
|
219
|
+
if (e.deltaY !== 0)
|
|
220
|
+
handleRef.current?.scrollBy(e.deltaY);
|
|
221
|
+
}, []);
|
|
143
222
|
// Structure: outer viewport (overflow:scroll, constrained height) >
|
|
144
223
|
// inner content (flexGrow:1, flexShrink:0 — fills at least the viewport
|
|
145
224
|
// but grows beyond it for tall content). flexGrow:1 lets children use
|
|
@@ -159,7 +238,7 @@ function ScrollBox({ children, ref, stickyScroll, ...style }) {
|
|
|
159
238
|
// must reach React subscribers too — see dom.ts onStickyRestore.
|
|
160
239
|
el.onStickyRestore = notify;
|
|
161
240
|
}
|
|
162
|
-
}, style: {
|
|
241
|
+
}, onWheel: handleWheel, style: {
|
|
163
242
|
flexWrap: 'nowrap',
|
|
164
243
|
flexDirection: style.flexDirection ?? 'row',
|
|
165
244
|
flexGrow: style.flexGrow ?? 0,
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
/** Shared frame interval for render throttling and animations (~60fps). */
|
|
2
2
|
export declare const FRAME_INTERVAL_MS = 16;
|
|
3
|
+
/**
|
|
4
|
+
* In-flight pty gate threshold (bytes) for scroll-drain frames — Grok
|
|
5
|
+
* Build's Presenter in_flight gate. While stdout holds more unflushed
|
|
6
|
+
* output than this, drain frames hold off instead of stacking latency
|
|
7
|
+
* into a slow ConPTY/ssh link. Sized above one full-screen diff (~4KB at
|
|
8
|
+
* 100 cols) so the gate only trips on genuine backlog, never on a single
|
|
9
|
+
* in-transit frame.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PTY_BACKLOG_BYTES = 8192;
|
|
3
12
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/ink/constants.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,KAAK,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/ink/constants.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA"}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
/** Shared frame interval for render throttling and animations (~60fps). */
|
|
2
2
|
export const FRAME_INTERVAL_MS = 16;
|
|
3
|
+
/**
|
|
4
|
+
* In-flight pty gate threshold (bytes) for scroll-drain frames — Grok
|
|
5
|
+
* Build's Presenter in_flight gate. While stdout holds more unflushed
|
|
6
|
+
* output than this, drain frames hold off instead of stacking latency
|
|
7
|
+
* into a slow ConPTY/ssh link. Sized above one full-screen diff (~4KB at
|
|
8
|
+
* 100 cols) so the gate only trips on genuine backlog, never on a single
|
|
9
|
+
* in-transit frame.
|
|
10
|
+
*/
|
|
11
|
+
export const PTY_BACKLOG_BYTES = 8192;
|
|
@@ -1,25 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PointerEvent, type PointerEventInit } from './pointer-event.js';
|
|
2
2
|
/**
|
|
3
3
|
* Mouse click event. Fired on left-button release without drag, only when
|
|
4
4
|
* mouse tracking is enabled (i.e. inside <AlternateScreen>).
|
|
5
5
|
*
|
|
6
6
|
* Bubbles from the deepest hit node up through parentNode. Call
|
|
7
7
|
* stopImmediatePropagation() to prevent ancestors' onClick from firing.
|
|
8
|
+
*
|
|
9
|
+
* Extends PointerEvent: `shift`/`alt`/`ctrl` expose the modifiers the
|
|
10
|
+
* terminal reported on the release, and `localCol`/`localRow` are recomputed
|
|
11
|
+
* per handler so containers see coordinates relative to themselves.
|
|
8
12
|
*/
|
|
9
|
-
export declare class ClickEvent extends
|
|
10
|
-
/** 0-indexed screen column of the click */
|
|
11
|
-
readonly col: number;
|
|
12
|
-
/** 0-indexed screen row of the click */
|
|
13
|
-
readonly row: number;
|
|
14
|
-
/**
|
|
15
|
-
* Click column relative to the current handler's Box (col - box.x).
|
|
16
|
-
* Recomputed by dispatchClick before each handler fires, so an onClick
|
|
17
|
-
* on a container sees coords relative to that container, not to any
|
|
18
|
-
* child the click landed on.
|
|
19
|
-
*/
|
|
20
|
-
localCol: number;
|
|
21
|
-
/** Click row relative to the current handler's Box (row - box.y). */
|
|
22
|
-
localRow: number;
|
|
13
|
+
export declare class ClickEvent extends PointerEvent {
|
|
23
14
|
/**
|
|
24
15
|
* True if the clicked cell has no visible content (unwritten in the
|
|
25
16
|
* screen buffer — both packed words are 0). Handlers can check this to
|
|
@@ -27,6 +18,6 @@ export declare class ClickEvent extends Event {
|
|
|
27
18
|
* clicks on empty terminal space don't toggle state.
|
|
28
19
|
*/
|
|
29
20
|
readonly cellIsBlank: boolean;
|
|
30
|
-
constructor(col: number, row: number, cellIsBlank: boolean);
|
|
21
|
+
constructor(col: number, row: number, cellIsBlank: boolean, init?: PointerEventInit);
|
|
31
22
|
}
|
|
32
23
|
//# sourceMappingURL=click-event.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"click-event.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/click-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"click-event.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/click-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAExE;;;;;;;;;;GAUG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;gBAG3B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,OAAO,EACpB,IAAI,CAAC,EAAE,gBAAgB;CAa1B"}
|
|
@@ -1,25 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PointerEvent } from './pointer-event.js';
|
|
2
2
|
/**
|
|
3
3
|
* Mouse click event. Fired on left-button release without drag, only when
|
|
4
4
|
* mouse tracking is enabled (i.e. inside <AlternateScreen>).
|
|
5
5
|
*
|
|
6
6
|
* Bubbles from the deepest hit node up through parentNode. Call
|
|
7
7
|
* stopImmediatePropagation() to prevent ancestors' onClick from firing.
|
|
8
|
+
*
|
|
9
|
+
* Extends PointerEvent: `shift`/`alt`/`ctrl` expose the modifiers the
|
|
10
|
+
* terminal reported on the release, and `localCol`/`localRow` are recomputed
|
|
11
|
+
* per handler so containers see coordinates relative to themselves.
|
|
8
12
|
*/
|
|
9
|
-
export class ClickEvent extends
|
|
10
|
-
/** 0-indexed screen column of the click */
|
|
11
|
-
col;
|
|
12
|
-
/** 0-indexed screen row of the click */
|
|
13
|
-
row;
|
|
14
|
-
/**
|
|
15
|
-
* Click column relative to the current handler's Box (col - box.x).
|
|
16
|
-
* Recomputed by dispatchClick before each handler fires, so an onClick
|
|
17
|
-
* on a container sees coords relative to that container, not to any
|
|
18
|
-
* child the click landed on.
|
|
19
|
-
*/
|
|
20
|
-
localCol = 0;
|
|
21
|
-
/** Click row relative to the current handler's Box (row - box.y). */
|
|
22
|
-
localRow = 0;
|
|
13
|
+
export class ClickEvent extends PointerEvent {
|
|
23
14
|
/**
|
|
24
15
|
* True if the clicked cell has no visible content (unwritten in the
|
|
25
16
|
* screen buffer — both packed words are 0). Handlers can check this to
|
|
@@ -27,10 +18,16 @@ export class ClickEvent extends Event {
|
|
|
27
18
|
* clicks on empty terminal space don't toggle state.
|
|
28
19
|
*/
|
|
29
20
|
cellIsBlank;
|
|
30
|
-
constructor(col, row, cellIsBlank) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
constructor(col, row, cellIsBlank, init) {
|
|
22
|
+
// A click is by definition a left-button release without drag. Normalize
|
|
23
|
+
// the low button bits to 0 (left) while preserving modifier bits
|
|
24
|
+
// (0x04 shift / 0x08 alt / 0x10 ctrl) from the release byte.
|
|
25
|
+
const button = init?.button ?? 0;
|
|
26
|
+
super('click', col, row, {
|
|
27
|
+
...init,
|
|
28
|
+
action: 'release',
|
|
29
|
+
button: button & ~0x03,
|
|
30
|
+
});
|
|
34
31
|
this.cellIsBlank = cellIsBlank;
|
|
35
32
|
}
|
|
36
33
|
}
|
|
@@ -2,13 +2,22 @@ import type { ClickEvent } from './click-event.js';
|
|
|
2
2
|
import type { FocusEvent } from './focus-event.js';
|
|
3
3
|
import type { KeyboardEvent } from './keyboard-event.js';
|
|
4
4
|
import type { PasteEvent } from './paste-event.js';
|
|
5
|
+
import type { PointerEvent } from './pointer-event.js';
|
|
5
6
|
import type { ResizeEvent } from './resize-event.js';
|
|
7
|
+
import type { WheelEvent } from './wheel-event.js';
|
|
6
8
|
type KeyboardEventHandler = (event: KeyboardEvent) => void;
|
|
7
9
|
type FocusEventHandler = (event: FocusEvent) => void;
|
|
8
10
|
type PasteEventHandler = (event: PasteEvent) => void;
|
|
9
11
|
type ResizeEventHandler = (event: ResizeEvent) => void;
|
|
10
12
|
type ClickEventHandler = (event: ClickEvent) => void;
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Hover handlers receive the pointer position. Existing `() => void`
|
|
15
|
+
* handlers remain assignable (a function taking fewer parameters is
|
|
16
|
+
* assignable to one taking more), so this widening is fully backwards
|
|
17
|
+
* compatible.
|
|
18
|
+
*/
|
|
19
|
+
type HoverEventHandler = (event: PointerEvent) => void;
|
|
20
|
+
type WheelEventHandler = (event: WheelEvent) => void;
|
|
12
21
|
/**
|
|
13
22
|
* Props for event handlers on Box and other host components.
|
|
14
23
|
*
|
|
@@ -29,6 +38,7 @@ export type EventHandlerProps = {
|
|
|
29
38
|
onClick?: ClickEventHandler;
|
|
30
39
|
onMouseEnter?: HoverEventHandler;
|
|
31
40
|
onMouseLeave?: HoverEventHandler;
|
|
41
|
+
onWheel?: WheelEventHandler;
|
|
32
42
|
};
|
|
33
43
|
/**
|
|
34
44
|
* Reverse lookup: event type string → handler prop names.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-handlers.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/event-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"event-handlers.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/event-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,KAAK,oBAAoB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;AAC1D,KAAK,iBAAiB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AACpD,KAAK,iBAAiB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AACpD,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;AACtD,KAAK,iBAAiB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AACpD;;;;;GAKG;AACH,KAAK,iBAAiB,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;AACtD,KAAK,iBAAiB,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;AAEpD;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,oBAAoB,CAAA;IAChC,gBAAgB,CAAC,EAAE,oBAAoB,CAAA;IAEvC,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,cAAc,CAAC,EAAE,iBAAiB,CAAA;IAClC,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,aAAa,CAAC,EAAE,iBAAiB,CAAA;IAEjC,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,cAAc,CAAC,EAAE,iBAAiB,CAAA;IAElC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAE7B,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,YAAY,CAAC,EAAE,iBAAiB,CAAA;IAChC,YAAY,CAAC,EAAE,iBAAiB,CAAA;IAChC,OAAO,CAAC,EAAE,iBAAiB,CAAA;CAC5B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,MAAM,EACN;IAAE,MAAM,CAAC,EAAE,MAAM,iBAAiB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,iBAAiB,CAAA;CAAE,CASxE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAc9B,CAAA"}
|
|
@@ -9,6 +9,7 @@ export const HANDLER_FOR_EVENT = {
|
|
|
9
9
|
paste: { bubble: 'onPaste', capture: 'onPasteCapture' },
|
|
10
10
|
resize: { bubble: 'onResize' },
|
|
11
11
|
click: { bubble: 'onClick' },
|
|
12
|
+
wheel: { bubble: 'onWheel' },
|
|
12
13
|
};
|
|
13
14
|
/**
|
|
14
15
|
* Set of all event handler prop names, for the reconciler to detect
|
|
@@ -27,4 +28,5 @@ export const EVENT_HANDLER_PROPS = new Set([
|
|
|
27
28
|
'onClick',
|
|
28
29
|
'onMouseEnter',
|
|
29
30
|
'onMouseLeave',
|
|
31
|
+
'onWheel',
|
|
30
32
|
]);
|
|
@@ -13,6 +13,8 @@ export type Key = {
|
|
|
13
13
|
pageUp: boolean;
|
|
14
14
|
wheelUp: boolean;
|
|
15
15
|
wheelDown: boolean;
|
|
16
|
+
wheelLeft: boolean;
|
|
17
|
+
wheelRight: boolean;
|
|
16
18
|
home: boolean;
|
|
17
19
|
end: boolean;
|
|
18
20
|
return: boolean;
|
|
@@ -25,6 +27,13 @@ export type Key = {
|
|
|
25
27
|
delete: boolean;
|
|
26
28
|
meta: boolean;
|
|
27
29
|
super: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Pointer column (0-indexed) when the key is a wheel event — the SGR/X10
|
|
32
|
+
* sequence carries the position. Undefined for non-wheel keys.
|
|
33
|
+
*/
|
|
34
|
+
mouseCol?: number;
|
|
35
|
+
/** Pointer row (0-indexed) when the key is a wheel event. See mouseCol. */
|
|
36
|
+
mouseRow?: number;
|
|
28
37
|
};
|
|
29
38
|
/**
|
|
30
39
|
* Event fired for each input chunk received from stdin (a typed character or
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-event.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/input-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC;;;GAGG;AACH,MAAM,MAAM,GAAG,GAAG;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,EAAE,EAAE,OAAO,CAAA;IACX,GAAG,EAAE,OAAO,CAAA;IACZ,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"input-event.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/input-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC;;;GAGG;AACH,MAAM,MAAM,GAAG,GAAG;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,EAAE,EAAE,OAAO,CAAA;IACX,GAAG,EAAE,OAAO,CAAA;IACZ,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AA2KD;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;IAE5B;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IAEjB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;wBAGoB;IACpB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;gBAEd,QAAQ,EAAE,SAAS;CAShC"}
|
|
@@ -10,6 +10,8 @@ function parseKey(keypress) {
|
|
|
10
10
|
pageUp: keypress.name === 'pageup',
|
|
11
11
|
wheelUp: keypress.name === 'wheelup',
|
|
12
12
|
wheelDown: keypress.name === 'wheeldown',
|
|
13
|
+
wheelLeft: keypress.name === 'wheelleft',
|
|
14
|
+
wheelRight: keypress.name === 'wheelright',
|
|
13
15
|
home: keypress.name === 'home',
|
|
14
16
|
end: keypress.name === 'end',
|
|
15
17
|
return: keypress.name === 'return',
|
|
@@ -29,6 +31,8 @@ function parseKey(keypress) {
|
|
|
29
31
|
// protocol CSI u sequences. Distinct from meta (Alt/Option) so
|
|
30
32
|
// bindings like cmd+c can be expressed separately from opt+c.
|
|
31
33
|
super: keypress.super,
|
|
34
|
+
mouseCol: keypress.mouseCol,
|
|
35
|
+
mouseRow: keypress.mouseRow,
|
|
32
36
|
};
|
|
33
37
|
let input = keypress.ctrl ? keypress.name : keypress.sequence;
|
|
34
38
|
// Handle undefined input case
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { TerminalEvent, type EventTarget } from './terminal-event.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pointer action reported by the terminal protocol.
|
|
4
|
+
*
|
|
5
|
+
* - `press`: a button went down (SGR `M` terminator / X10 press)
|
|
6
|
+
* - `release`: a button came up (SGR `m` terminator; X10 cannot report this)
|
|
7
|
+
* - `move`: pointer motion (SGR drag bit or mode-1003 no-button motion)
|
|
8
|
+
*/
|
|
9
|
+
export type PointerAction = 'press' | 'release' | 'move';
|
|
10
|
+
/** Optional state when constructing a {@link PointerEvent}. */
|
|
11
|
+
export type PointerEventInit = {
|
|
12
|
+
/** Raw protocol button byte (SGR bits: 0x04 shift, 0x08 alt, 0x10 ctrl). */
|
|
13
|
+
button?: number;
|
|
14
|
+
action?: PointerAction;
|
|
15
|
+
bubbles?: boolean;
|
|
16
|
+
cancelable?: boolean;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Base class for pointer-derived terminal events (click, wheel, hover).
|
|
20
|
+
*
|
|
21
|
+
* Carries the raw SGR/X10 button byte so handlers can read modifier flags
|
|
22
|
+
* (`shift`/`alt`/`ctrl`) without re-parsing the escape sequence, plus
|
|
23
|
+
* per-handler local coordinates: `_prepareForTarget` recomputes
|
|
24
|
+
* `localCol`/`localRow` from the nodeCache rect before each handler fires,
|
|
25
|
+
* so an onClick on a container sees coordinates relative to that container,
|
|
26
|
+
* not to the child the pointer actually landed on.
|
|
27
|
+
*
|
|
28
|
+
* `meta` is deliberately always false: xterm.js drops metaKey before SGR
|
|
29
|
+
* encoding (the SGR bit we call "meta" is wired to alt), so no pointer
|
|
30
|
+
* protocol can distinguish it reliably.
|
|
31
|
+
*/
|
|
32
|
+
export declare class PointerEvent extends TerminalEvent {
|
|
33
|
+
/** 0-indexed screen column of the pointer. */
|
|
34
|
+
readonly col: number;
|
|
35
|
+
/** 0-indexed screen row of the pointer. */
|
|
36
|
+
readonly row: number;
|
|
37
|
+
/** Raw protocol button byte (SGR encoding). */
|
|
38
|
+
readonly button: number;
|
|
39
|
+
/** Which pointer action produced this event. */
|
|
40
|
+
readonly action: PointerAction;
|
|
41
|
+
/** Shift held (SGR button bit 0x04). */
|
|
42
|
+
readonly shift: boolean;
|
|
43
|
+
/** Alt/Option held (SGR button bit 0x08). */
|
|
44
|
+
readonly alt: boolean;
|
|
45
|
+
/** Ctrl held (SGR button bit 0x10). */
|
|
46
|
+
readonly ctrl: boolean;
|
|
47
|
+
/** Always false — see class doc. */
|
|
48
|
+
readonly meta = false;
|
|
49
|
+
/** Column relative to the current handler's node (set during dispatch). */
|
|
50
|
+
localCol: number;
|
|
51
|
+
/** Row relative to the current handler's node (set during dispatch). */
|
|
52
|
+
localRow: number;
|
|
53
|
+
constructor(type: string, col: number, row: number, init?: PointerEventInit);
|
|
54
|
+
/**
|
|
55
|
+
* Refresh localCol/localRow for the node whose handler is about to run.
|
|
56
|
+
* Nodes without a cached rect (not rendered this frame) get 0,0 — handlers
|
|
57
|
+
* should prefer absolute col/row when that distinction matters.
|
|
58
|
+
*/
|
|
59
|
+
_prepareForTarget(target: EventTarget): void;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=pointer-event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pointer-event.d.ts","sourceRoot":"","sources":["../../../../src/ink/events/pointer-event.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAErE;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAExD,+DAA+D;AAC/D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAa,SAAQ,aAAa;IAC7C,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,SAAQ;IACrB,2EAA2E;IAC3E,QAAQ,SAAI;IACZ,wEAAwE;IACxE,QAAQ,SAAI;gBAEA,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB;IAc3E;;;;OAIG;IACM,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;CAKtD"}
|