mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-158286 LookupCellRenderer - get rid of SingleAlarm in favour of flow
GitOrigin-RevId: 8cffbdd2089d02d04bb012cb3dd579406acb2eaf
This commit is contained in:
committed by
intellij-monorepo-bot
parent
44dda124a9
commit
6372bfea0a
@@ -7902,7 +7902,6 @@ f:com.intellij.codeInsight.lookup.impl.LookupCellRenderer
|
||||
- f:refreshUi():V
|
||||
- f:scheduleUpdateLookupWidthFromVisibleItems():V
|
||||
- f:updateItemPresentation(com.intellij.codeInsight.lookup.LookupElement):V
|
||||
- f:updateLookupWidthFromVisibleItems():V
|
||||
f:com.intellij.codeInsight.lookup.impl.LookupCellRenderer$Companion
|
||||
- f:augmentIcon(com.intellij.openapi.editor.Editor,javax.swing.Icon,javax.swing.Icon):javax.swing.Icon
|
||||
- f:bodyInsets():java.awt.Insets
|
||||
|
||||
+1
-1
@@ -520,7 +520,7 @@ public final class CompletionProgressIndicator extends ProgressIndicatorBase imp
|
||||
private void addItemToLookup(CompletionResult item) {
|
||||
Ref<Boolean> stopRef = new Ref<>(Boolean.FALSE);
|
||||
DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode(() -> {
|
||||
stopRef.set(!lookup.addItem(item.getLookupElement(), item.getPrefixMatcher()));
|
||||
stopRef.set(lookup.isLookupDisposed() || !lookup.addItem(item.getLookupElement(), item.getPrefixMatcher()));
|
||||
});
|
||||
|
||||
if (stopRef.get()) {
|
||||
|
||||
@@ -7,9 +7,7 @@ import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation
|
||||
import com.intellij.codeInsight.lookup.LookupElementRenderer
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.components.ComponentManagerEx
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.util.cancelOnDispose
|
||||
import com.intellij.util.indexing.DumbModeAccessType
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
@@ -38,8 +36,11 @@ internal class AsyncRendering(private val lookup: LookupImpl) {
|
||||
synchronized(LAST_COMPUTATION) {
|
||||
cancelRendering(element)
|
||||
|
||||
@Suppress("UsagesOfObsoleteApi")
|
||||
val job = (lookup.project as ComponentManagerEx).getCoroutineScope().launch(limitedDispatcher) {
|
||||
if (lookup.isLookupDisposed) {
|
||||
return
|
||||
}
|
||||
|
||||
val job = lookup.coroutineScope.launch(limitedDispatcher) {
|
||||
val job = coroutineContext.job
|
||||
readAction {
|
||||
if (element.isValid) {
|
||||
@@ -49,7 +50,7 @@ internal class AsyncRendering(private val lookup: LookupImpl) {
|
||||
synchronized(LAST_COMPUTATION) {
|
||||
element.replace(LAST_COMPUTATION, job, null)
|
||||
}
|
||||
}.also { it.cancelOnDispose(lookup) }
|
||||
}
|
||||
element.putUserData(LAST_COMPUTATION, job)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import com.intellij.codeInsight.lookup.impl.LookupCellRenderer.Companion.bodyIns
|
||||
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer.Companion.getGrayedForeground
|
||||
import com.intellij.codeInsight.lookup.impl.LookupCellRenderer.IconDecorator
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
@@ -23,6 +25,7 @@ import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.platform.util.coroutines.flow.throttle
|
||||
import com.intellij.psi.codeStyle.NameUtil
|
||||
import com.intellij.ui.*
|
||||
import com.intellij.ui.ExperimentalUI.Companion.isNewUI
|
||||
@@ -34,7 +37,6 @@ import com.intellij.ui.scale.JBUIScale.scale
|
||||
import com.intellij.ui.speedSearch.SpeedSearchUtil
|
||||
import com.intellij.util.IconUtil.cropIcon
|
||||
import com.intellij.util.ObjectUtils
|
||||
import com.intellij.util.SingleAlarm
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.containers.FList
|
||||
import com.intellij.util.ui.EmptyIcon
|
||||
@@ -43,6 +45,11 @@ import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import com.intellij.util.ui.accessibility.AccessibleContextUtil
|
||||
import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.annotations.VisibleForTesting
|
||||
@@ -75,7 +82,7 @@ class LookupCellRenderer(lookup: LookupImpl, editorComponent: JComponent) : List
|
||||
var lookupTextWidth: Int = 50
|
||||
private set
|
||||
private val widthLock = ObjectUtils.sentinel("lookup width lock")
|
||||
private val lookupWidthUpdater: Runnable
|
||||
private val lookupWidthUpdater: () -> Unit
|
||||
private val shrinkLookup: Boolean
|
||||
|
||||
private val asyncRendering: AsyncRendering
|
||||
@@ -111,23 +118,30 @@ class LookupCellRenderer(lookup: LookupImpl, editorComponent: JComponent) : List
|
||||
panel.add(tailComponent, BorderLayout.CENTER)
|
||||
panel.add(typeLabel, BorderLayout.EAST)
|
||||
|
||||
normalMetrics = this.lookup.topLevelEditor.component.getFontMetrics(normalFont)
|
||||
boldMetrics = this.lookup.topLevelEditor.component.getFontMetrics(boldFont)
|
||||
asyncRendering = AsyncRendering(this.lookup)
|
||||
normalMetrics = lookup.topLevelEditor.component.getFontMetrics(normalFont)
|
||||
boldMetrics = lookup.topLevelEditor.component.getFontMetrics(boldFont)
|
||||
asyncRendering = AsyncRendering(lookup)
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
// avoid delay in unit tests
|
||||
lookupWidthUpdater = Runnable { ApplicationManager.getApplication().invokeLater { this.updateLookupWidthFromVisibleItems() } }
|
||||
lookupWidthUpdater = {
|
||||
ApplicationManager.getApplication().invokeLater({ updateLookupWidthFromVisibleItems() }, lookup.project.disposed)
|
||||
}
|
||||
}
|
||||
else {
|
||||
val alarm =
|
||||
SingleAlarm({ this.updateLookupWidthFromVisibleItems() }, 50, lookup, ModalityState.stateForComponent(editorComponent))
|
||||
lookupWidthUpdater = Runnable {
|
||||
synchronized(alarm) {
|
||||
if (!alarm.isDisposed) {
|
||||
alarm.request()
|
||||
val lookupWidthUpdateRequests = MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
val coroutineContext = Dispatchers.EDT + ModalityState.stateForComponent(editorComponent).asContextElement()
|
||||
lookup.coroutineScope.launch {
|
||||
lookupWidthUpdateRequests
|
||||
.throttle(50)
|
||||
.collect {
|
||||
withContext(coroutineContext) {
|
||||
updateLookupWidthFromVisibleItems()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lookupWidthUpdater = {
|
||||
check(lookupWidthUpdateRequests.tryEmit(Unit))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,7 +492,7 @@ class LookupCellRenderer(lookup: LookupImpl, editorComponent: JComponent) : List
|
||||
/**
|
||||
* Update lookup width due to visible in lookup items
|
||||
*/
|
||||
fun updateLookupWidthFromVisibleItems() {
|
||||
private fun updateLookupWidthFromVisibleItems() {
|
||||
val visibleItems = lookup.visibleItems
|
||||
|
||||
var maxWidth = if (shrinkLookup) 0 else lookupTextWidth
|
||||
@@ -505,7 +519,7 @@ class LookupCellRenderer(lookup: LookupImpl, editorComponent: JComponent) : List
|
||||
}
|
||||
|
||||
fun scheduleUpdateLookupWidthFromVisibleItems() {
|
||||
lookupWidthUpdater.run()
|
||||
lookupWidthUpdater()
|
||||
}
|
||||
|
||||
fun itemAdded(element: LookupElement, fastPresentation: LookupElementPresentation) {
|
||||
|
||||
@@ -58,6 +58,9 @@ import com.intellij.util.ui.accessibility.AccessibleContextUtil;
|
||||
import com.intellij.util.ui.accessibility.ScreenReader;
|
||||
import com.intellij.util.ui.update.Activatable;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import kotlinx.coroutines.CoroutineScope;
|
||||
import kotlinx.coroutines.CoroutineScopeKt;
|
||||
import kotlinx.coroutines.Dispatchers;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -77,6 +80,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.intellij.codeInsight.lookup.LookupElement.LOOKUP_ELEMENT_SHOW_TIMESTAMP_MILLIS;
|
||||
import static kotlinx.coroutines.SupervisorKt.SupervisorJob;
|
||||
|
||||
public class LookupImpl extends LightweightHint implements LookupEx, Disposable, LookupElementListPresenter {
|
||||
private static final Logger LOG = Logger.getInstance(LookupImpl.class);
|
||||
@@ -116,6 +120,8 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
private final EmptyLookupItem myDummyItem = new EmptyLookupItem(CommonBundle.message("tree.node.loading"), true);
|
||||
private boolean myFirstElementAdded = false;
|
||||
|
||||
final CoroutineScope coroutineScope = CoroutineScopeKt.CoroutineScope(SupervisorJob(null).plus(Dispatchers.getDefault()));
|
||||
|
||||
public LookupImpl(Project project, Editor editor, @NotNull LookupArranger arranger) {
|
||||
super(new JPanel(new BorderLayout()));
|
||||
setForceShowAsPopup(true);
|
||||
@@ -346,7 +352,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
}
|
||||
|
||||
public void fireBeforeAppendPrefix(char c) {
|
||||
myPrefixChangeListeners.forEach((listener -> listener.beforeAppend(c)));
|
||||
for (PrefixChangeListener listener : myPrefixChangeListeners) {
|
||||
listener.beforeAppend(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void appendPrefix(char c) {
|
||||
@@ -362,7 +370,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
refreshUi(false, true);
|
||||
ensureSelectionVisible(true);
|
||||
}
|
||||
myPrefixChangeListeners.forEach((listener -> listener.afterAppend(c)));
|
||||
for (PrefixChangeListener listener : myPrefixChangeListeners) {
|
||||
listener.afterAppend(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void setStartCompletionWhenNothingMatches(boolean startCompletionWhenNothingMatches) {
|
||||
@@ -419,7 +429,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
ensureSelectionVisible(true);
|
||||
}
|
||||
|
||||
myPrefixChangeListeners.forEach((listener -> listener.afterTruncate()));
|
||||
for (PrefixChangeListener listener : myPrefixChangeListeners) {
|
||||
listener.afterTruncate();
|
||||
}
|
||||
}
|
||||
|
||||
void moveToCaretPosition() {
|
||||
@@ -449,7 +461,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
|
||||
if (!myFirstElementAdded && !items.isEmpty()) {
|
||||
myFirstElementAdded = true;
|
||||
myListeners.forEach(LookupListener::firstElementShown);
|
||||
for (LookupListener listener : myListeners) {
|
||||
listener.firstElementShown();
|
||||
}
|
||||
}
|
||||
|
||||
myOffsets.checkMinPrefixLengthChanges(items, this);
|
||||
@@ -461,7 +475,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
model.removeAll();
|
||||
if (!finalItems.isEmpty()) {
|
||||
Long currentTimeMillis = System.currentTimeMillis();
|
||||
finalItems.forEach(item -> item.putUserDataIfAbsent(LOOKUP_ELEMENT_SHOW_TIMESTAMP_MILLIS, currentTimeMillis));
|
||||
for (LookupElement item : finalItems) {
|
||||
item.putUserDataIfAbsent(LOOKUP_ELEMENT_SHOW_TIMESTAMP_MILLIS, currentTimeMillis);
|
||||
}
|
||||
model.add(finalItems);
|
||||
addDummyItems(myDummyItemCount.get());
|
||||
}
|
||||
@@ -1195,6 +1211,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
CoroutineScopeKt.cancel(coroutineScope, null);
|
||||
ThreadingAssertions.assertEventDispatchThread();
|
||||
assert myHidden;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ internal class MacScrollBarAnimationBehavior(
|
||||
) : DefaultScrollBarAnimationBehavior(trackAnimator, thumbAnimator) {
|
||||
private var isTrackHovered: Boolean = false
|
||||
@Suppress("SSBasedInspection")
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default + CoroutineName("IdeRootPane"))
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||
private val hideThumbRequests = MutableSharedFlow<Boolean>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
|
||||
init {
|
||||
|
||||
@@ -60,7 +60,7 @@ class ProgressDialog(
|
||||
private var popup: DialogWrapper? = null
|
||||
|
||||
@Suppress("SSBasedInspection")
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default + CoroutineName("IdeRootPane"))
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||
|
||||
init {
|
||||
ui.progressBar.isIndeterminate = progressWindow.isIndeterminate
|
||||
|
||||
Reference in New Issue
Block a user