attachCustomKeyEventHandler inverts xterm.js's return-value contract (silently swallows all input)
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 52/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- typescript
- Lĩnh vực
- frontend
Hướng nghiên cứu
Bắt đầu tại lib/input-handler.ts#L377-L385 và tái hiện hành vi của handler bằng ví dụ xterm.js-style trong issue. Đọc hướng dẫn migration trong README, bảng tương thích và JSDoc của attachCustomKeyEventHandler trước khi xác nhận maintainers muốn contract về giá trị trả về nào. Hoàn tất nghĩa là input thông thường hoạt động, shortcut được nêu vẫn được xử lý và contract đã chọn được tài liệu hóa ở nơi người dùng có thể tìm thấy.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
attachCustomKeyEventHandler returns the opposite of what xterm.js's handler of the same name returns. Because the README's migration story is "change your import: @xterm/xterm → ghostty-web", an app that carries its existing handler across ends up with a terminal that ignores every keystroke — while connecting, rendering, scrolling and showing the shell prompt perfectly. There is no error and nothing on screen to suggest the keyboard is the problem.
The two contracts
xterm.js — the return value says let the terminal have this key:
The function returns whether the event should be processed by xterm.js.
So a handler that only wants to claim a shortcut or two returns true for everything else.
ghostty-web — the return value says I already handled it, drop it (lib/input-handler.ts#L377-L385):
// Check custom key event handler
if (this.customKeyEventHandler) {
const handled = this.customKeyEventHandler(event);
if (handled) {
// Custom handler consumed the event
event.preventDefault();
return;
}
}
That same xterm-shaped handler now returns true for every ordinary key, so every ordinary key is swallowed — and the one or two keys it deliberately claimed (returning false) are the only ones that reach the pty, inverted in both directions.
Reproduction
import { init, Terminal } from 'ghostty-web';
await init();
const term = new Terminal();
term.open(el);
term.onData(d => ws.send(d));
// Straight from an xterm.js app: claim Ctrl+F, let everything else through.
term.attachCustomKeyEventHandler((e) => {
if (e.ctrlKey && e.key === 'f') { e.preventDefault(); return false; }
return true;
});
Expected: typing works, Ctrl+F is swallowed.
Actual: nothing can be typed at all, and Ctrl+F is the only key that reaches the shell.
Removing the handler entirely makes typing work again, which is what makes this hard to attribute — the handler is usually old, unrelated code that was correct before the migration.
Versions
[email protected], and the code above is current main.
Suggestion
Either is fine from where I sit, but the ambiguity is the expensive part:
- Invert it to match xterm.js — treat a falsy return as "consumed". Most faithful to the stated API compatibility, but silently changes behaviour for anyone who already adapted, so it would want a note in the changelog.
- Keep the current meaning and document it — call it out in the README migration line and in the JSDoc on
attachCustomKeyEventHandler, since that method is the one place a reader would look. Today the JSDoc says "Returns true to prevent default handling", which is accurate but only visible if you already suspect the handler.
A line in the compatibility table would also have caught this for me before I shipped it.
Happy to send a PR for whichever direction you prefer.
- Ngôn ngữ chính
- TypeScript
- Star
- 2.9k
- Fork
- 174
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Chúng tôi chưa kiểm tra các tệp thiết lập môi trường của dự án này. Hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của coder/ghostty-web
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
coder/ghostty-web#199 ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 72/100
coder/ghostty-web#198 ·
-
A single throw inside render() permanently stops the render loop, and a consumer cannot restart itĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 65/100
coder/ghostty-web#189 ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 70/100
coder/ghostty-web#188 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 45/100
coder/ghostty-web#187 ·
Tất cả issue của coder/ghostty-web
Issue tương tự
-
priority: P2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
prime-radiant-inc/evener#3291 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
accessibility bug revealjs
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
quarto-dev/quarto-cli#14961 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
supabase/agent-skills#614 ·
-
Content
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
RunestoneInteractive/rs#1559 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày