[PR #765] [MERGED] fix(palette): querySpecialColors resistent to term emulators with noi… #1550

Closed
opened 2026-03-14 09:42:45 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/765
Author: @MaxDillon
Created: 3/2/2026
Status: Merged
Merged: 3/2/2026
Merged by: @kommander

Base: mainHead: main


📝 Commits (2)

  • e0ade78 fix(palette): querySpecialColors resistent to term emulators with noisy esc sequences
  • bcb4028 prettier

📊 Changes

1 file changed (+4 additions, -0 deletions)

View changed files

📝 packages/core/src/lib/terminal-palette.ts (+4 -0)

📄 Description

Issue for this PR

#705

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Opentuin getPallette function for querySpecialColors has an idleTimer meant to exit out before the explicit timeout if the terminal does not provide all of the color escape sequences 10-19. The idle timer resets if any escape sequence triggers the onData function again.

This is an issue for terminal emulators like ghostty which are very noisy with the escape sequences they send. Here we only allow the timeout to reset if a response conforming to OSC_SPECIAL_RESPONSE is read in the buffer.

This is possibly overly conservative. If we were being more aggressive, we could only reset the idle timer when an entry in results gets updated from a null value. As it stands, this improves start time of getPallette in ghostty from the max timeout to almost negligable

How did you verify your code works?

  • I tested locally with the following simple script
#!/usr/bin/env bun

import { createCliRenderer, TextRenderable } from "../index"
import { setupCommonDemoKeys } from "./lib/standalone-keys"

const startTime = Date.now()

// 1. Create renderer
const renderer = await createCliRenderer({
  exitOnCtrlC: true,
  targetFps: 60,
})

// 2. Start automatic render loop
renderer.auto()

// 3. Add trivial renderable
const text = new TextRenderable(renderer, {
  id: "placeholder",
  content: "Renderer active… (toggle stdout with `)",
  left: 0,
  top: 0,
})
renderer.root.add(text)

// 4. Hook up common demo keys (including stdout toggle)
setupCommonDemoKeys(renderer)

// 5. Request palette
const palette = await renderer.getPalette({ timeout: 5000, size: 16 })

console.log("time elapsed", Date.now() - startTime)
  • Without fix: [17:54:05] [LOG] 'time elapsed' 5014
  • With fix: [17:54:28] [LOG] 'time elapsed' 220

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

🔄 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/765 **Author:** [@MaxDillon](https://github.com/MaxDillon) **Created:** 3/2/2026 **Status:** ✅ Merged **Merged:** 3/2/2026 **Merged by:** [@kommander](https://github.com/kommander) **Base:** `main` ← **Head:** `main` --- ### 📝 Commits (2) - [`e0ade78`](https://github.com/anomalyco/opentui/commit/e0ade788df83a4e952fe62b53804b5cb24bfe997) fix(palette): querySpecialColors resistent to term emulators with noisy esc sequences - [`bcb4028`](https://github.com/anomalyco/opentui/commit/bcb402889f822f6ee0c8e05bf00f967f153fe93c) prettier ### 📊 Changes **1 file changed** (+4 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/lib/terminal-palette.ts` (+4 -0) </details> ### 📄 Description ### Issue for this PR #705 ### Type of change - [x] Bug fix - [ ] New feature - [ ] Refactor / code improvement - [ ] Documentation ### What does this PR do? Opentuin getPallette function for querySpecialColors has an idleTimer meant to exit out before the explicit timeout if the terminal does not provide all of the color escape sequences 10-19. The idle timer resets if any escape sequence triggers the onData function again. This is an issue for terminal emulators like ghostty which are very noisy with the escape sequences they send. Here we only allow the timeout to reset if a response conforming to `OSC_SPECIAL_RESPONSE` is read in the buffer. This is possibly overly conservative. If we were being more aggressive, we could only reset the idle timer when an entry in results gets updated from a null value. As it stands, this improves start time of getPallette in ghostty from the max timeout to almost negligable ### How did you verify your code works? - I tested locally with the following simple script ```js #!/usr/bin/env bun import { createCliRenderer, TextRenderable } from "../index" import { setupCommonDemoKeys } from "./lib/standalone-keys" const startTime = Date.now() // 1. Create renderer const renderer = await createCliRenderer({ exitOnCtrlC: true, targetFps: 60, }) // 2. Start automatic render loop renderer.auto() // 3. Add trivial renderable const text = new TextRenderable(renderer, { id: "placeholder", content: "Renderer active… (toggle stdout with `)", left: 0, top: 0, }) renderer.root.add(text) // 4. Hook up common demo keys (including stdout toggle) setupCommonDemoKeys(renderer) // 5. Request palette const palette = await renderer.getPalette({ timeout: 5000, size: 16 }) console.log("time elapsed", Date.now() - startTime) ``` - Without fix: `[17:54:05] [LOG] 'time elapsed' 5014` - With fix: `[17:54:28] [LOG] 'time elapsed' 220` ### Checklist - [x] I have tested my changes locally - [x] I have not included unrelated changes in this PR --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-14 09:42:45 +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#1550
No description provided.