[PyCharm] Jupyter (fix): Fixed exception on updating gutter icons in wrong thread. #PY-85363 Ready For Merge

(cherry picked from commit 6479c288eca69e8de3eb4b01c85736966da7cc06)

IJ-CR-181604

GitOrigin-RevId: a2680fb2a6ccd128837fd84de849f112dbd0ebe8
This commit is contained in:
Nikita Pavlenko
2025-11-07 00:23:03 +00:00
committed by intellij-monorepo-bot
parent 4b9840799c
commit d7fe932bda
2 changed files with 31 additions and 24 deletions
@@ -24,10 +24,10 @@ fun EditorEx.addComponentInlay(
showWhenFolded: Boolean = true,
priority: Int,
offset: Int,
rendererFactory: RendererFactory? = null
rendererFactory: RendererFactory? = null,
): Inlay<*> {
// see DS-5614
val fullWidthArg: Boolean = this.editorKind != EditorKind.DIFF
val fullWidthArg: Boolean = editorKind != EditorKind.DIFF
val inlay = EditorEmbeddedComponentManager.getInstance().addComponent(
this,
component,
@@ -111,39 +111,42 @@ fun registerEditorSizeWatcher(
}
val EditorEx.textEditingAreaWidth: Int
get() = scrollingModel.visibleArea.width - scrollPane.verticalScrollBar.width
get() = contentComponent.visibleRect.width
fun EditorEx.getFirstFullyVisibleLogicalLine(): Int? {
val visibleArea = this.scrollingModel.visibleArea
private fun EditorEx.getFirstFullyVisibleLogicalLine(): Int? {
val visibleArea = contentComponent.visibleRect
val startY = visibleArea.y
val endY = visibleArea.y + visibleArea.height
val firstVisibleLine = this.xyToLogicalPosition(Point(0, startY)).line
val lastVisibleLine = this.xyToLogicalPosition(Point(0, endY)).line
val visibleLine = xyToLogicalPosition(Point(0, startY)).line
val lineStartY = logicalPositionToXY(LogicalPosition(visibleLine, 0)).y
for (line in firstVisibleLine..lastVisibleLine) {
val lineStartY = this.logicalPositionToXY(LogicalPosition(line, 0)).y
val lineEndY = lineStartY + this.lineHeight
if (lineStartY >= startY && lineEndY <= endY) {
return line
}
return if (lineStartY >= startY && lineStartY + lineHeight <= endY) {
visibleLine
}
else if (lineStartY + lineHeight >= startY && lineStartY + lineHeight * 2 <= endY) {
visibleLine + 1
}
else {
null
}
return null
}
fun NotebookCellLines.Interval.computeFirstLineForHighlighter(
editor: EditorEx, gutterIconStickToFirstVisibleLine: Boolean = true
editor: EditorEx, gutterIconStickToFirstVisibleLine: Boolean = true,
): Int {
return if (gutterIconStickToFirstVisibleLine) {
val firstFullyVisibleLine = editor.getFirstFullyVisibleLogicalLine()
val startLine = if (firstFullyVisibleLine != null && firstFullyVisibleLine in this.lines) {
val startLine = if (firstFullyVisibleLine != null && firstFullyVisibleLine in lines) {
firstFullyVisibleLine
} else {
this.lines.first
}
val fullyVisibleCell = firstFullyVisibleLine == this.lines.first
if (fullyVisibleCell) this.lines.first else startLine
} else {
this.lines.first
else {
lines.first
}
val fullyVisibleCell = firstFullyVisibleLine == lines.first
if (fullyVisibleCell) lines.first else startLine
}
else {
lines.first
}
}
@@ -9,6 +9,7 @@ import com.intellij.notebooks.visualization.ui.EditorCell
import com.intellij.notebooks.visualization.ui.ProgressStatus
import com.intellij.notebooks.visualization.ui.notebook
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.DumbAwareAction.SimpleDumbAwareAction
@@ -52,7 +53,7 @@ class EditorCellRunGutterController(
override fun checkAndRebuildInlays() {}
private fun updateGutterAction() {
//For markdown, it will set up in markdown component
//For Markdown, it will set up in a Markdown component
if (cell.type == CellType.MARKDOWN)
return
@@ -63,7 +64,10 @@ class EditorCellRunGutterController(
return
}
cell.gutterAction.set(newAction)
// This should be called on EDT only, because inside we are accessing EditorEx.xyToLogicalPosition().
runInEdt {
cell.gutterAction.set(newAction)
}
}
private fun calculateAction(): DumbAwareAction? {