mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
IJPL-191565 Search Everywhere for RD: fix getting popupInstance
(cherry picked from commit 91f3e83e30ae1fe26ceb339066db2f213942522d) GitOrigin-RevId: 8481bc056e2c93673d33c993f44a9c64ed43dcc6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
dbe65d77f5
commit
9703ddf2a2
@@ -33,6 +33,7 @@ import com.intellij.platform.util.coroutines.childScope
|
||||
import com.intellij.platform.util.coroutines.sync.OverflowSemaphore
|
||||
import com.intellij.ui.ScreenUtil
|
||||
import com.intellij.ui.awt.RelativePoint
|
||||
import com.intellij.util.ui.EDT
|
||||
import com.intellij.util.ui.StartupUiUtil
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import fleet.kernel.DurableRef
|
||||
@@ -43,6 +44,8 @@ import kotlinx.coroutines.channels.BufferOverflow
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.awt.KeyboardFocusManager
|
||||
import java.awt.Point
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
@@ -55,7 +58,11 @@ class SeFrontendService(val project: Project?, private val coroutineScope: Corou
|
||||
private val popupSemaphore = OverflowSemaphore(1, overflow = BufferOverflow.DROP_LATEST)
|
||||
|
||||
@Volatile
|
||||
private var popupInstance: SePopupInstance? = null
|
||||
private var popupInstanceFuture: CompletableFuture<SePopupInstance>? = null
|
||||
private val popupInstance: SePopupInstance?
|
||||
get() = if (EDT.isCurrentThreadEdt()) popupInstanceFuture?.getNow(null)
|
||||
else runCatching { popupInstanceFuture?.get(2, TimeUnit.SECONDS) }.getOrNull()
|
||||
|
||||
|
||||
@Volatile
|
||||
var localProvidersHolder: SeProvidersHolder? = null
|
||||
@@ -66,6 +73,9 @@ class SeFrontendService(val project: Project?, private val coroutineScope: Corou
|
||||
val removeSessionRef: AtomicBoolean = AtomicBoolean(true)
|
||||
|
||||
override fun show(tabId: String, searchText: String?, initEvent: AnActionEvent) {
|
||||
val popupFuture = CompletableFuture<SePopupInstance>()
|
||||
popupInstanceFuture = popupFuture
|
||||
|
||||
coroutineScope.launch {
|
||||
val popupScope = coroutineScope.childScope("SearchEverywhereFrontendService popup scope")
|
||||
val sessionRef = SeSessionEntity.createRef()
|
||||
@@ -73,12 +83,12 @@ class SeFrontendService(val project: Project?, private val coroutineScope: Corou
|
||||
try {
|
||||
popupSemaphore.withPermit {
|
||||
localProvidersHolder = SeProvidersHolder.initialize(initEvent, project, sessionRef, "Frontend")
|
||||
val completable = doShowPopup(tabId, searchText, initEvent, popupScope, sessionRef)
|
||||
val completable = doShowPopup(popupFuture, tabId, searchText, initEvent, popupScope, sessionRef)
|
||||
completable.await()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
popupInstance = null
|
||||
popupInstanceFuture = null
|
||||
localProvidersHolder?.let { Disposer.dispose(it) }
|
||||
localProvidersHolder = null
|
||||
|
||||
@@ -97,6 +107,7 @@ class SeFrontendService(val project: Project?, private val coroutineScope: Corou
|
||||
}
|
||||
|
||||
private suspend fun doShowPopup(
|
||||
popupFuture: CompletableFuture<SePopupInstance>,
|
||||
tabId: String,
|
||||
searchText: String?,
|
||||
initEvent: AnActionEvent,
|
||||
@@ -180,7 +191,7 @@ class SeFrontendService(val project: Project?, private val coroutineScope: Corou
|
||||
calcPopupPositionAndShow(popup, contentPane)
|
||||
}
|
||||
|
||||
popupInstance = SePopupInstance(popupVm, contentPane, searchStatePublisher)
|
||||
popupFuture.complete(SePopupInstance(popupVm, contentPane, searchStatePublisher))
|
||||
|
||||
val endTime = System.currentTimeMillis()
|
||||
SeLog.log { "Search Everywhere popup opened in ${endTime - startTime} ms" }
|
||||
|
||||
@@ -91,40 +91,18 @@ public class SearchEverywhereCommand extends AbstractCommand {
|
||||
Ref<String> tabId = computeTabId(tab);
|
||||
|
||||
int numberOfPermits = getNumberOfPermits(insertText);
|
||||
var manager = SearchEverywhereManager.getInstance(project);
|
||||
boolean isNewSe = !(manager instanceof SearchEverywhereManagerImpl);
|
||||
Semaphore typingSemaphore = new Semaphore(numberOfPermits);
|
||||
|
||||
TraceKt.use(PerformanceTestSpan.getTracer(warmup).spanBuilder("searchEverywhere"), globalSpan -> {
|
||||
ApplicationManager.getApplication().invokeAndWait(Context.current().wrap(() -> {
|
||||
try {
|
||||
TypingTarget target = findTarget(context);
|
||||
Component component;
|
||||
if (!(target instanceof EditorComponentImpl)) {
|
||||
LOG.info("Editor is not opened, focus owner will be used.");
|
||||
component = IdeFocusManager.getInstance(project).getFocusOwner();
|
||||
}
|
||||
else {
|
||||
component = (EditorComponentImpl)target;
|
||||
}
|
||||
DataContext dataContext = CustomizedDataContext.withSnapshot(
|
||||
DataManager.getInstance().getDataContext(component),
|
||||
sink -> sink.set(CommonDataKeys.PROJECT, context.getProject()));
|
||||
DataContext wrappedDataContext = wrapDataContextWithActionStartData(dataContext);
|
||||
IdeEventQueue.getInstance().getPopupManager().closeAllPopups(false);
|
||||
TraceKt.use(PerformanceTestSpan.getTracer(warmup).spanBuilder("searchEverywhere_dialog_shown"), dialogSpan -> {
|
||||
var manager = SearchEverywhereManager.getInstance(project);
|
||||
AnActionEvent event = AnActionEvent.createEvent(
|
||||
wrappedDataContext, null, ActionPlaces.EDITOR_POPUP, ActionUiKind.POPUP, null);
|
||||
manager.show(tabId.get(), "", event);
|
||||
SearchEverywherePopupInstance popupInstance = manager.getCurrentlyShownPopupInstance();
|
||||
assert (popupInstance != null);
|
||||
attachSearchListeners(popupInstance);
|
||||
return null;
|
||||
});
|
||||
typeOrInsertText(context, insertText, typingSemaphore, warmup);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}));
|
||||
if (isNewSe) {
|
||||
showPopupInEdtWaitForPopupAndTypeText(manager, project, context, tabId, insertText, typingSemaphore, warmup);
|
||||
}
|
||||
else {
|
||||
showPopupAndTypeTextAllInEDT(manager, project, context, tabId, insertText, typingSemaphore, warmup);
|
||||
}
|
||||
|
||||
try {
|
||||
typingSemaphore.acquire();
|
||||
SearchEverywherePopupInstance popupInstance = SearchEverywhereManager.getInstance(project).getCurrentlyShownPopupInstance();
|
||||
@@ -151,6 +129,82 @@ public class SearchEverywhereCommand extends AbstractCommand {
|
||||
return Promises.toPromise(actionCallback);
|
||||
}
|
||||
|
||||
private void showPopupAndTypeTextAllInEDT(SearchEverywhereManager manager, Project project, @NotNull PlaybackContext context, Ref<String> tabId, String insertText, Semaphore typingSemaphore, boolean warmup) {
|
||||
ApplicationManager.getApplication().invokeAndWait(Context.current().wrap(() -> {
|
||||
try {
|
||||
DataContext wrappedDataContext = createDataContext(context, project);
|
||||
IdeEventQueue.getInstance().getPopupManager().closeAllPopups(false);
|
||||
TraceKt.use(PerformanceTestSpan.getTracer(warmup).spanBuilder("searchEverywhere_dialog_shown"), dialogSpan -> {
|
||||
showPopup(manager, wrappedDataContext, tabId);
|
||||
SearchEverywherePopupInstance popupInstance = manager.getCurrentlyShownPopupInstance();
|
||||
assert (popupInstance != null);
|
||||
attachSearchListeners(popupInstance);
|
||||
return null;
|
||||
});
|
||||
typeOrInsertText(context, insertText, typingSemaphore, warmup);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void showPopupInEdtWaitForPopupAndTypeText(SearchEverywhereManager manager, Project project, @NotNull PlaybackContext context, Ref<String> tabId, String insertText, Semaphore typingSemaphore, boolean warmup) {
|
||||
ApplicationManager.getApplication().invokeAndWait(Context.current().wrap(() -> {
|
||||
try {
|
||||
DataContext wrappedDataContext = createDataContext(context, project);
|
||||
IdeEventQueue.getInstance().getPopupManager().closeAllPopups(false);
|
||||
TraceKt.use(PerformanceTestSpan.getTracer(warmup).spanBuilder("searchEverywhere_dialog_shown"), dialogSpan -> {
|
||||
showPopup(manager, wrappedDataContext, tabId);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}));
|
||||
|
||||
// Get the popup instance outside if EDT
|
||||
SearchEverywherePopupInstance popupInstance = manager.getCurrentlyShownPopupInstance();
|
||||
|
||||
ApplicationManager.getApplication().invokeAndWait(Context.current().wrap(() -> {
|
||||
try {
|
||||
attachListenersToPopup(popupInstance);
|
||||
typeOrInsertText(context, insertText, typingSemaphore, warmup);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private static DataContext createDataContext(@NotNull PlaybackContext context, @NotNull Project project) {
|
||||
TypingTarget target = findTarget(context);
|
||||
Component component;
|
||||
if (!(target instanceof EditorComponentImpl)) {
|
||||
LOG.info("Editor is not opened, focus owner will be used.");
|
||||
component = IdeFocusManager.getInstance(project).getFocusOwner();
|
||||
}
|
||||
else {
|
||||
component = (EditorComponentImpl)target;
|
||||
}
|
||||
DataContext dataContext = CustomizedDataContext.withSnapshot(
|
||||
DataManager.getInstance().getDataContext(component),
|
||||
sink -> sink.set(CommonDataKeys.PROJECT, context.getProject()));
|
||||
return wrapDataContextWithActionStartData(dataContext);
|
||||
}
|
||||
|
||||
private static void showPopup(SearchEverywhereManager manager, DataContext dataContext, Ref<String> tabId) {
|
||||
AnActionEvent event = AnActionEvent.createEvent(
|
||||
dataContext, null, ActionPlaces.EDITOR_POPUP, ActionUiKind.POPUP, null);
|
||||
manager.show(tabId.get(), "", event);
|
||||
}
|
||||
|
||||
private void attachListenersToPopup(SearchEverywherePopupInstance popupInstance) {
|
||||
assert (popupInstance != null);
|
||||
attachSearchListeners(popupInstance);
|
||||
}
|
||||
|
||||
private static @NotNull Ref<String> computeTabId(String tab) {
|
||||
Ref<String> tabId = new Ref<>();
|
||||
switch (tab) {
|
||||
|
||||
Reference in New Issue
Block a user