[editor] IJPL-233406 add smooth caret blinking to settings

GitOrigin-RevId: d4a4591949241b3a0650104363316fc39d14b3d8
This commit is contained in:
Stanislav Alekseev
2026-02-06 11:21:05 +00:00
committed by intellij-monorepo-bot
parent 6971721ea9
commit a46470eb3d
11 changed files with 51 additions and 4 deletions
@@ -143,6 +143,8 @@ f:com.intellij.openapi.actionSystem.Presentation
com.intellij.openapi.editor.EditorSettings
- *a:getCaretEasing():com.intellij.openapi.editor.EditorSettings$CaretEasing
- *a:isAnimatedCaret():Z
- *a:isSmoothCaretBlinking():Z
- *a:setSmoothCaretBlinking(Z):V
*e:com.intellij.openapi.editor.EditorSettings$CaretEasing
- java.lang.Enum
- sf:EASE:com.intellij.openapi.editor.EditorSettings$CaretEasing
@@ -126,6 +126,11 @@ public interface EditorSettings {
int getCaretBlinkPeriod();
void setCaretBlinkPeriod(int blinkPeriod);
@ApiStatus.Experimental
boolean isSmoothCaretBlinking();
@ApiStatus.Experimental
void setSmoothCaretBlinking(boolean smoothCaretBlinking);
boolean isBlockCursor();
void setBlockCursor(boolean blockCursor);
@@ -6,14 +6,18 @@ c:com.intellij.openapi.editor.ex.EditorSettingsExternalizable
- com.intellij.openapi.components.PersistentStateComponent
- *:getCaretEasing():com.intellij.openapi.editor.EditorSettings$CaretEasing
- *:isAnimatedCaret():Z
- *:isSmoothBlinkCaret():Z
- *:setAnimatedCaret(Z):V
- *:setCaretEasing(com.intellij.openapi.editor.EditorSettings$CaretEasing):V
- *:setSmoothBlinkCaret(Z):V
f:com.intellij.openapi.editor.ex.EditorSettingsExternalizable$OptionSet
- *:CARET_EASING:com.intellij.openapi.editor.EditorSettings$CaretEasing
- *:IS_ANIMATED_CARET:Z
- *:IS_SMOOTH_CARET_BLINKING:Z
f:com.intellij.openapi.editor.ex.EditorSettingsExternalizable$PropNames
- *sf:PROP_CARET_EASING:java.lang.String
- *sf:PROP_IS_ANIMATED_CARET:java.lang.String
- *sf:PROP_IS_SMOOTH_CARET_BLINKING:java.lang.String
com.intellij.openapi.fileEditor.impl.EditorTabColorProvider
- com.intellij.openapi.project.PossiblyDumbAware
- *:getEditorTabForegroundColor(com.intellij.openapi.project.Project,com.intellij.openapi.vfs.VirtualFile):com.intellij.openapi.editor.colors.ColorKey
@@ -75,6 +75,7 @@ public class EditorSettingsExternalizable implements PersistentStateComponent<Ed
public boolean SHOW_INTENTION_BULB = true;
public boolean IS_CARET_BLINKING = true;
public int CARET_BLINKING_PERIOD = BLINKING_RANGE.initial;
@ApiStatus.Experimental public boolean IS_SMOOTH_CARET_BLINKING = false;
public boolean IS_RIGHT_MARGIN_SHOWN = true;
public boolean ARE_LINE_NUMBERS_SHOWN = true;
public @NotNull EditorSettings.LineNumerationType LINE_NUMERATION = EditorSettings.LineNumerationType.ABSOLUTE;
@@ -746,6 +747,18 @@ public class EditorSettingsExternalizable implements PersistentStateComponent<Ed
myPropertyChangeSupport.firePropertyChange(PropNames.PROP_CARET_BLINKING_PERIOD, old, newValue);
}
@ApiStatus.Experimental
public boolean isSmoothBlinkCaret() {
return myOptions.IS_SMOOTH_CARET_BLINKING;
}
@ApiStatus.Experimental
public void setSmoothBlinkCaret(boolean smoothBlinkCaret) {
boolean old = myOptions.IS_SMOOTH_CARET_BLINKING;
if (old == smoothBlinkCaret) return;
myOptions.IS_SMOOTH_CARET_BLINKING = smoothBlinkCaret;
myPropertyChangeSupport.firePropertyChange(PropNames.PROP_IS_SMOOTH_CARET_BLINKING, old, smoothBlinkCaret);
}
public boolean isEnsureNewLineAtEOF() {
return myOptions.IS_ENSURE_NEWLINE_AT_EOF;
@@ -1166,6 +1179,7 @@ public class EditorSettingsExternalizable implements PersistentStateComponent<Ed
public static final @NonNls String PROP_SHOW_INTENTION_BULB = "showIntentionBulb";
public static final @NonNls String PROP_IS_CARET_BLINKING = "isCaretBlinking";
public static final @NonNls String PROP_CARET_BLINKING_PERIOD = "caretBlinkingPeriod";
@ApiStatus.Experimental public static final @NonNls String PROP_IS_SMOOTH_CARET_BLINKING = "isSmoothCaretBlinking";
public static final @NonNls String PROP_IS_RIGHT_MARGIN_SHOWN = "isRightMarginShown";
public static final @NonNls String PROP_ARE_LINE_NUMBERS_SHOWN = "areLineNumbersShown";
public static final @NonNls String PROP_ARE_LINE_NUMBERS_AFTER_ICONS = "areLineNumbersAfterIcons";
@@ -284,6 +284,7 @@ checkbox.use.animated.caret=Use smooth caret movement
checkbox.use.full.line.height.caret=Use full line height caret
checkbox.highlight.selection.occurrences=Highlight occurrences of selected text
checkbox.caret.blinking.ms=Caret blinking (ms):
checkbox.smooth.caret.blinking=Use smooth caret blinking
checkbox.mark.modified.tabs=Mark modified
checkbox.mark.modified.tabs.with.asterisk=Mark modified (*)
checkbox.show.tabs.tooltips=Show full path on mouse hover
@@ -38,6 +38,7 @@ private val model:EditorSettingsExternalizable
get() = EditorSettingsExternalizable.getInstance()
private val myCbBlinkCaret get() = CheckboxDescriptor(ApplicationBundle.message("checkbox.caret.blinking.ms"), model::isBlinkCaret, model::setBlinkCaret)
private val myCbSmoothBlinkCaret get() = CheckboxDescriptor(ApplicationBundle.message("checkbox.smooth.caret.blinking"), model::isSmoothBlinkCaret, model::setSmoothBlinkCaret)
private val myCbBlockCursor get() = CheckboxDescriptor(ApplicationBundle.message("checkbox.use.block.caret"), model::isBlockCursor, model::setBlockCursor)
private val myCbFullLineHeightCursor get() = CheckboxDescriptor(ApplicationBundle.message("checkbox.use.full.line.height.caret"), model::isFullLineHeightCursor, model::setFullLineHeightCursor)
private val myCbAnimatedCaret get() = CheckboxDescriptor(ApplicationBundle.message("checkbox.use.animated.caret"), model::isAnimatedCaret, model::setAnimatedCaret)
@@ -76,6 +77,9 @@ class EditorAppearanceConfigurable : BoundCompositeSearchableConfigurable<Unname
.columns(5)
.enabledIf(cbBlinkCaret.selected)
}
row {
checkBox(myCbSmoothBlinkCaret)
}
row {
checkBox(myCbBlockCursor)
}
@@ -75,7 +75,7 @@ internal class EditorCaretRepaintService(coroutineScope: CoroutineScope) {
}
private suspend fun blink(editor: EditorImpl) {
if (Registry.`is`("editor.smooth.caret.blinking")) {
if (editor.settings.isSmoothCaretBlinking) {
blinkSmooth(editor)
} else {
blinkNormal(editor)
@@ -3182,6 +3182,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myCurrentDragIsSubstantial = true;
}
void restartCaretBlinking() {
synchronized (caretRepaintService) {
caretRepaintService.restart();
}
}
void updateCaretCursor() {
myUpdateCursor = true;
if (myCaretCursor.myIsShown) {
@@ -150,6 +150,7 @@ class EditorSettingsState(private val editor: EditorImpl?,
CustomOutValueModifier { if (editor != null && editor.isColumnMode) true else it })
var myIsCaretBlinking: Boolean by property { EditorSettingsExternalizable.getInstance().isBlinkCaret }
var myCaretBlinkingPeriod: Int by property { EditorSettingsExternalizable.getInstance().blinkPeriod }
var myIsSmoothCaretBlinking: Boolean by property { EditorSettingsExternalizable.getInstance().isSmoothBlinkCaret }
var myIsRightMarginShown: Boolean by property(EditorSettingsExternalizable.getInstance().isRightMarginShown) {
if (editor != null && rightMargin == CodeStyleConstraints.MAX_RIGHT_MARGIN) false
else EditorSettingsExternalizable.getInstance().isRightMarginShown
@@ -253,6 +254,7 @@ class EditorSettingsState(private val editor: EditorImpl?,
EditorSettingsExternalizable.PropNames.PROP_IS_CARET_INSIDE_TABS -> refresh(::myIsCaretInsideTabs)
EditorSettingsExternalizable.PropNames.PROP_IS_CARET_BLINKING -> refresh(::myIsCaretBlinking)
EditorSettingsExternalizable.PropNames.PROP_CARET_BLINKING_PERIOD -> refresh(::myCaretBlinkingPeriod)
EditorSettingsExternalizable.PropNames.PROP_IS_SMOOTH_CARET_BLINKING -> refresh(::myIsSmoothCaretBlinking)
EditorSettingsExternalizable.PropNames.PROP_IS_RIGHT_MARGIN_SHOWN -> refresh(::myIsRightMarginShown)
EditorSettingsExternalizable.PropNames.PROP_VERTICAL_SCROLL_OFFSET -> refresh(::myVerticalScrollOffset)
@@ -144,6 +144,10 @@ class SettingsImpl internal constructor(private val editor: EditorImpl?, kind: E
editor?.contentComponent?.repaint()
}
if (propertyName == state::myIsSmoothCaretBlinking.name) {
editor?.restartCaretBlinking()
}
if (propertyName == state::myStickyLinesShownForLanguage.name) {
editor?.stickyLinesForLangChanged(event)
}
@@ -524,6 +528,14 @@ class SettingsImpl internal constructor(private val editor: EditorImpl?, kind: E
state.myCaretBlinkingPeriod = blinkPeriod
}
override fun isSmoothCaretBlinking(): Boolean {
return state.myIsSmoothCaretBlinking
}
override fun setSmoothCaretBlinking(`val`: Boolean) {
state.myIsSmoothCaretBlinking = `val`
}
override fun isDndEnabled(): Boolean {
return state.myIsDndEnabled
}
@@ -1317,9 +1317,6 @@ editor.smooth.caret.curve.parametric.factor.description=Parametric f(t) = 1 - (1
editor.smooth.caret.duration=120
editor.smooth.caret.duration.description=Duration of caret blinking animation in milliseconds
editor.smooth.caret.blinking=false
editor.smooth.caret.blinking.description=Enable smooth caret blinking animation
editor.zero.latency.rendering=true
editor.zero.latency.rendering.description=Enables zero-latency rendering mode in editor