mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 10:36:35 +00:00
fix(chat): stop placeholder ghosting in chat composer (#65)
`TextEditor`'s NSTextView surfaces a typed glyph one frame before the SwiftUI binding propagates, so the bare `if text.isEmpty` overlay rendered the translucent placeholder text directly on top of the just-typed character — the "behind or around" ghost the reporter described. Two mitigations: - Pin an opaque `ScarfColor.backgroundSecondary` rect behind the placeholder Text. During any single-frame binding lag the user now sees a clean placeholder rather than layered glyphs. - Switch the conditional to `.opacity(text.isEmpty ? 1 : 0)` so the view tree stays stable per keystroke. Pairs with the composer perf fix from #67. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -108,7 +108,23 @@ struct RichChatInputBar: View {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.overlay(alignment: .topLeading) {
|
.overlay(alignment: .topLeading) {
|
||||||
if text.isEmpty {
|
// Placeholder ghosting (#65): TextEditor's
|
||||||
|
// NSTextView updates the visible glyphs a frame
|
||||||
|
// before the SwiftUI binding propagates, so a
|
||||||
|
// bare `if text.isEmpty` overlay renders the
|
||||||
|
// translucent placeholder text on top of the
|
||||||
|
// just-typed character — visible as a "behind
|
||||||
|
// or around" ghost. Two mitigations:
|
||||||
|
//
|
||||||
|
// 1. Pin an opaque rectangle behind the
|
||||||
|
// placeholder text. During any single-
|
||||||
|
// frame lag the user sees a clean
|
||||||
|
// placeholder, never layered glyphs.
|
||||||
|
// 2. Use `.opacity(...)` instead of an `if`.
|
||||||
|
// Keeps the view tree stable per
|
||||||
|
// keystroke (removes the per-keystroke
|
||||||
|
// view-mutation churn the composer was
|
||||||
|
// already paying for).
|
||||||
Text(supportsImagePrompts
|
Text(supportsImagePrompts
|
||||||
? "Message Hermes… / for commands · drag images to attach"
|
? "Message Hermes… / for commands · drag images to attach"
|
||||||
: "Message Hermes… / for commands")
|
: "Message Hermes… / for commands")
|
||||||
@@ -116,9 +132,10 @@ struct RichChatInputBar: View {
|
|||||||
.foregroundStyle(ScarfColor.foregroundFaint)
|
.foregroundStyle(ScarfColor.foregroundFaint)
|
||||||
.padding(.horizontal, 14)
|
.padding(.horizontal, 14)
|
||||||
.padding(.vertical, 10)
|
.padding(.vertical, 10)
|
||||||
|
.background(ScarfColor.backgroundSecondary)
|
||||||
|
.opacity(text.isEmpty ? 1 : 0)
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Drag-drop image attachments. Receives both file URLs
|
// Drag-drop image attachments. Receives both file URLs
|
||||||
// (from Finder) and raw image bitmap data (from
|
// (from Finder) and raw image bitmap data (from
|
||||||
// screenshot tools that drop tiff/png directly).
|
// screenshot tools that drop tiff/png directly).
|
||||||
|
|||||||
Reference in New Issue
Block a user