From 0b14784dbe52c95d57ac39481bce18d3793e3ec9 Mon Sep 17 00:00:00 2001 From: taylor steil Date: Thu, 19 Mar 2026 14:00:14 -0700 Subject: [PATCH 1/2] Fix bold text flickering on every click/interaction applyNewTheme(_:andFontSize:) was calling highlightr.setTheme(to:) on every SwiftUI view update even when the theme and font size hadn't changed. This caused the entire text storage to be re-highlighted, momentarily stripping and reapplying bold attributes and causing visible flicker. Add an early return when both the resolved theme name matches the current theme and the font size is unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) --- Sources/CodeEditor/UXCodeTextView.swift | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Sources/CodeEditor/UXCodeTextView.swift b/Sources/CodeEditor/UXCodeTextView.swift index 7c680ae..b69549b 100644 --- a/Sources/CodeEditor/UXCodeTextView.swift +++ b/Sources/CodeEditor/UXCodeTextView.swift @@ -256,13 +256,22 @@ final class UXCodeTextView: UXTextView { func applyNewTheme(_ newTheme: CodeEditor.ThemeName? = nil, andFontSize newSize: CGFloat) -> Bool { + let resolvedTheme = newTheme ?? themeName + + // Skip expensive setTheme reload when neither theme nor font size changed. + if resolvedTheme == themeName, + let existingFont = highlightr?.theme?.codeFont, + existingFont.pointSize == newSize { + return true + } + // Setting the theme reloads it (i.e. makes a "copy"). guard let highlightr = highlightr, - highlightr.setTheme(to: (newTheme ?? themeName).rawValue), + highlightr.setTheme(to: resolvedTheme.rawValue), let theme = highlightr.theme else { return false } - + guard theme.codeFont?.pointSize != newSize else { return true } - + theme.codeFont = theme.codeFont? .withSize(newSize) theme.boldCodeFont = theme.boldCodeFont? .withSize(newSize) theme.italicCodeFont = theme.italicCodeFont?.withSize(newSize) From 275681ea16667df4ad67bd2eabe5643d4b177699 Mon Sep 17 00:00:00 2001 From: taylor steil Date: Thu, 19 Mar 2026 14:07:56 -0700 Subject: [PATCH 2/2] Fix theme not updating and track themeName correctly - applyNewTheme methods now update themeName after applying, so the early-return guard can correctly detect when theme hasn't changed - didSet on themeName guards against redundant re-application when the value hasn't actually changed - Fixes issue where switching themes in settings wouldn't always apply Co-Authored-By: Claude Opus 4.6 (1M context) --- Sources/CodeEditor/UXCodeTextView.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/CodeEditor/UXCodeTextView.swift b/Sources/CodeEditor/UXCodeTextView.swift index b69549b..58cb2d2 100644 --- a/Sources/CodeEditor/UXCodeTextView.swift +++ b/Sources/CodeEditor/UXCodeTextView.swift @@ -58,6 +58,7 @@ final class UXCodeTextView: UXTextView { } private(set) var themeName = CodeEditor.ThemeName.default { didSet { + guard themeName != oldValue else { return } highlightr?.setTheme(to: themeName.rawValue) if let font = highlightr?.theme?.codeFont { self.font = font } } @@ -247,6 +248,7 @@ final class UXCodeTextView: UXTextView { guard let highlightr = highlightr, highlightr.setTheme(to: newTheme.rawValue), let theme = highlightr.theme else { return false } + themeName = newTheme self.backgroundColor = customBackgroundColor ?? theme.themeBackgroundColor if let font = theme.codeFont, font !== self.font { self.font = font } return true @@ -257,9 +259,10 @@ final class UXCodeTextView: UXTextView { andFontSize newSize: CGFloat) -> Bool { let resolvedTheme = newTheme ?? themeName + let themeChanged = resolvedTheme != themeName // Skip expensive setTheme reload when neither theme nor font size changed. - if resolvedTheme == themeName, + if !themeChanged, let existingFont = highlightr?.theme?.codeFont, existingFont.pointSize == newSize { return true @@ -270,6 +273,8 @@ final class UXCodeTextView: UXTextView { highlightr.setTheme(to: resolvedTheme.rawValue), let theme = highlightr.theme else { return false } + if themeChanged { themeName = resolvedTheme } + guard theme.codeFont?.pointSize != newSize else { return true } theme.codeFont = theme.codeFont? .withSize(newSize)