[PR #739] [MERGED] fix crash on mouse hover of a destroyed renderable #748

Closed
opened 2026-03-02 23:47:57 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/739
Author: @justfortheloveof
Created: 2/24/2026
Status: Merged
Merged: 3/1/2026
Merged by: @simonklee

Base: mainHead: fix-mouse-over


📝 Commits (3)

  • 3ecdba4 fix crash on mouse hover of a destroyed renderable
  • 3ed532c add regression test for mouse out fired on destroyed renderable
  • 608d777 fix destroyed renderable crash in handleMouseData mouse out path

📊 Changes

2 files changed (+77 additions, -2 deletions)

View changed files

📝 packages/core/src/renderer.ts (+6 -2)
📝 packages/core/src/tests/renderer.mouse.test.ts (+71 -0)

📄 Description

Fixes #738

Tested in my TUI, see the line with // HACK: where I added:

if (this.isDestroyed) return;

Without this guard, we crash in the scenario described in #738 . With the guard, we don't.

import { useTheme } from '../../theme/index.ts';
import { ICONS } from '../../utils/icons.ts';
import { openInBrowser } from '../../utils/shell.ts';

type Props = {
	text: string;
	url: string;
};

export function Link(props: Props) {
	const theme = useTheme();
	return (
		<text
			onMouseUp={() => openInBrowser(props.url)}
			onMouseDown={function () {
				this.fg = theme.text;
			}}
			onMouseOver={function () {
				this.fg = theme.accent;
			}}
			onMouseOut={function () {
				if (this.isDestroyed) return; // HACK:
				this.fg = theme.text;
			}}
			fg={theme.text}
			wrapMode='none'
		>
			<span>{props.text}</span>
			<span style={{ fg: theme.accent }}>{ICONS.urlHint}</span>
		</text>
	);
}

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/anomalyco/opentui/pull/739 **Author:** [@justfortheloveof](https://github.com/justfortheloveof) **Created:** 2/24/2026 **Status:** ✅ Merged **Merged:** 3/1/2026 **Merged by:** [@simonklee](https://github.com/simonklee) **Base:** `main` ← **Head:** `fix-mouse-over` --- ### 📝 Commits (3) - [`3ecdba4`](https://github.com/anomalyco/opentui/commit/3ecdba48295d146f9de274b25b67112c89cb8869) fix crash on mouse hover of a destroyed renderable - [`3ed532c`](https://github.com/anomalyco/opentui/commit/3ed532c2893905e0dab4d49fd6e32f8965140cc9) add regression test for mouse out fired on destroyed renderable - [`608d777`](https://github.com/anomalyco/opentui/commit/608d777a11d8c1a264ec91f4039e2a9d4a92b81e) fix destroyed renderable crash in handleMouseData mouse out path ### 📊 Changes **2 files changed** (+77 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/renderer.ts` (+6 -2) 📝 `packages/core/src/tests/renderer.mouse.test.ts` (+71 -0) </details> ### 📄 Description Fixes #738 Tested in my TUI, see the line with `// HACK:` where I added: ```typescript if (this.isDestroyed) return; ``` Without this guard, we crash in the scenario described in #738 . With the guard, we don't. ```typescript import { useTheme } from '../../theme/index.ts'; import { ICONS } from '../../utils/icons.ts'; import { openInBrowser } from '../../utils/shell.ts'; type Props = { text: string; url: string; }; export function Link(props: Props) { const theme = useTheme(); return ( <text onMouseUp={() => openInBrowser(props.url)} onMouseDown={function () { this.fg = theme.text; }} onMouseOver={function () { this.fg = theme.accent; }} onMouseOut={function () { if (this.isDestroyed) return; // HACK: this.fg = theme.text; }} fg={theme.text} wrapMode='none' > <span>{props.text}</span> <span style={{ fg: theme.accent }}>{ICONS.urlHint}</span> </text> ); } ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-02 23:47:57 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#748
No description provided.