From 51e12aea9e1dc46476a16b146e2dd3cb4174d1b7 Mon Sep 17 00:00:00 2001 From: Sergei Tachenov Date: Wed, 16 Jul 2025 11:42:04 +0300 Subject: [PATCH] IJPL-197188 Fix Switcher hint popup update PSI_ELEMENT.getData returns an outdated PSI element if called in-place in the same EDT event the selection changes. Fix by postponing the update using a state flow. GitOrigin-RevId: e8568cdadbb2ee1332a2aedfd60a20c072840537 --- .../platform/recentFiles/frontend/Switcher.kt | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/platform/recentFiles/frontend/src/com/intellij/platform/recentFiles/frontend/Switcher.kt b/platform/recentFiles/frontend/src/com/intellij/platform/recentFiles/frontend/Switcher.kt index a314c158cadf..647e023b11f3 100644 --- a/platform/recentFiles/frontend/src/com/intellij/platform/recentFiles/frontend/Switcher.kt +++ b/platform/recentFiles/frontend/src/com/intellij/platform/recentFiles/frontend/Switcher.kt @@ -14,6 +14,10 @@ import com.intellij.openapi.actionSystem.ex.ActionUtil import com.intellij.openapi.actionSystem.remoting.ActionRemoteBehaviorSpecification import com.intellij.openapi.application.EDT import com.intellij.openapi.application.ModalityState +import com.intellij.openapi.application.UiDispatcherKind +import com.intellij.openapi.application.WriteIntentReadAction +import com.intellij.openapi.application.ui +import com.intellij.openapi.application.writeIntentReadAction import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.fileLogger import com.intellij.openapi.fileEditor.FileEditorManager @@ -55,6 +59,8 @@ import com.intellij.util.ui.SwingTextTrimmer import com.intellij.util.ui.accessibility.ScreenReader import com.intellij.util.ui.components.BorderLayoutPanel import kotlinx.coroutines.* +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.collectLatest import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.Nls import org.jetbrains.annotations.NonNls @@ -323,6 +329,7 @@ object Switcher : BaseSwitcherAction(null), ActionRemoteBehaviorSpecification.Fr files = JBListWithOpenInRightSplit.createListWithOpenInRightSplitter(maybeSearchableModel, null) files.visibleRowCount = files.itemsCount + val selectedValueFlow = MutableStateFlow(null) val filesSelectionListener = object : ListSelectionListener { override fun valueChanged(e: ListSelectionEvent) { LOG.debug("Switcher value changed: $e") @@ -332,9 +339,20 @@ object Switcher : BaseSwitcherAction(null), ActionRemoteBehaviorSpecification.Fr } updatePathLabel() - val hint = hint - val popupUpdater = if (hint == null || !hint.isVisible) null else hint.getUserData(PopupUpdateProcessorBase::class.java) - popupUpdater?.updatePopup(CommonDataKeys.PSI_ELEMENT.getData(DataManager.getInstance().getDataContext(this@SwitcherPanel))) + selectedValueFlow.value = selectedList?.selectedValue + } + } + uiUpdateScope.launch(CoroutineName("Switcher hint popup updater")) { + selectedValueFlow.collectLatest { selectedValue -> + withContext(Dispatchers.ui(UiDispatcherKind.RELAX)) { // can't use STRICT because updatePopup needs a WIRA + val hint = hint + val popupUpdater = if (hint == null || !hint.isVisible) null else hint.getUserData(PopupUpdateProcessorBase::class.java) + if (selectedValue != null && popupUpdater != null) { + writeIntentReadAction { + popupUpdater.updatePopup(CommonDataKeys.PSI_ELEMENT.getData(DataManager.getInstance().getDataContext(this@SwitcherPanel))) + } + } + } } } toolWindows.selectionModel.addListSelectionListener(filesSelectionListener)