fix: bell indicator stuck after returning to terminal tab
Two issues prevented the bell emoji from clearing reliably: 1. Race on tab return: clearBellState() runs on visibilitychange/focus, but the WebSocket has buffered output from while the tab was hidden. The terminal processes it immediately, onBell fires, and the bell is right back. Fixed with a 1-second suppression window after clearing — bells from buffered output are ignored. 2. Bell stays when clicking without typing: the bell only cleared on onData (keyboard input). If you clicked the terminal or just switched back without typing, the emoji persisted. Added a mousedown listener on the terminal element to clear it on any mouse interaction.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -737,7 +737,14 @@ class WebTerminal {
|
|||||||
return `webterm:bell:${this.routeKey}`;
|
return `webterm:bell:${this.routeKey}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bellSuppressUntil = 0;
|
||||||
|
|
||||||
private setBellActive(): void {
|
private setBellActive(): void {
|
||||||
|
// Suppress bells briefly after returning to the tab so that
|
||||||
|
// buffered output processed on visibility change doesn't
|
||||||
|
// immediately re-trigger the indicator we just cleared.
|
||||||
|
if (Date.now() < this.bellSuppressUntil) return;
|
||||||
|
|
||||||
if (!this.bellActive) {
|
if (!this.bellActive) {
|
||||||
this.bellActive = true;
|
this.bellActive = true;
|
||||||
document.title = `${BELL_EMOJI} ${this.baseTitle}`;
|
document.title = `${BELL_EMOJI} ${this.baseTitle}`;
|
||||||
@@ -749,6 +756,10 @@ class WebTerminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private clearBellState(): void {
|
private clearBellState(): void {
|
||||||
|
// Suppress further bells for a short window so that buffered
|
||||||
|
// output arriving right after focus doesn't re-set the indicator.
|
||||||
|
this.bellSuppressUntil = Date.now() + 1000;
|
||||||
|
|
||||||
const key = this.bellStorageKey();
|
const key = this.bellStorageKey();
|
||||||
if (key) {
|
if (key) {
|
||||||
localStorage.removeItem(key);
|
localStorage.removeItem(key);
|
||||||
@@ -846,6 +857,11 @@ class WebTerminal {
|
|||||||
this.setBellActive();
|
this.setBellActive();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Clear bell on any mouse interaction with the terminal
|
||||||
|
this.addTrackedListener(this.element, "mousedown", () => {
|
||||||
|
if (this.bellActive) this.clearBellState();
|
||||||
|
});
|
||||||
|
|
||||||
// Handle resize
|
// Handle resize
|
||||||
this.terminal.onResize((size) => {
|
this.terminal.onResize((size) => {
|
||||||
if (this.isValidSize(size.cols, size.rows)) {
|
if (this.isValidSize(size.cols, size.rows)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user