mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[git] Fix blinking temporary notifications about "unregistered Git roots" IDEA-83015, IDEA-85606
PROBLEM CAUSE: Notifications blinked because 2 events were arriving from different threads almost simultaneously: creating .git, and registering the mapping. The first event initiated rescan => notification was shown. The second event initiated another rescan => notification was hidden. FIX: Queue scan requests instead of immediate scanning, and add a delay before beginning the scan. Use an Alarm (1s delay, pooled thread) instead of self-made state-aware handler. Don't queue requests: only one (the latest) is needed, because consecutive scan won't add more information.
This commit is contained in:
@@ -17,7 +17,6 @@ package git4idea.roots;
|
||||
|
||||
import com.intellij.ProjectTopics;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.DumbAwareRunnable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootEvent;
|
||||
@@ -28,12 +27,13 @@ import com.intellij.openapi.vcs.VcsListener;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import git4idea.GitUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
@@ -45,11 +45,13 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
|
||||
private volatile boolean myProjectIsInitialized;
|
||||
private volatile boolean myMappingsAreReady;
|
||||
private volatile boolean myScanning;
|
||||
@NotNull private final Object SCAN_LOCK = new Object();
|
||||
|
||||
@NotNull private final Alarm myAlarm;
|
||||
private static final long WAIT_BEFORE_SCAN = TimeUnit.SECONDS.toMillis(1);
|
||||
|
||||
public GitRootScanner(@NotNull Project project, @NotNull Runnable executeAfterScan) {
|
||||
myExecuteAfterScan = executeAfterScan;
|
||||
myRootProblemNotifier = GitRootProblemNotifier.getInstance(project);
|
||||
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(new DumbAwareRunnable() {
|
||||
@Override
|
||||
@@ -64,7 +66,7 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, this);
|
||||
messageBus.connect().subscribe(ProjectTopics.PROJECT_ROOTS, this);
|
||||
|
||||
myRootProblemNotifier = GitRootProblemNotifier.getInstance(project);
|
||||
myAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD, project);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,40 +104,7 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
|
||||
private void scanIfReady() {
|
||||
if (readyToScan()) {
|
||||
scan();
|
||||
}
|
||||
}
|
||||
|
||||
private void scan() {
|
||||
if (myScanning) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
public void run() {
|
||||
scanWithLock();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
scanWithLock();
|
||||
}
|
||||
}
|
||||
|
||||
private void scanWithLock() {
|
||||
synchronized (SCAN_LOCK) {
|
||||
if (myScanning) {
|
||||
return;
|
||||
}
|
||||
myScanning = true;
|
||||
try {
|
||||
myRootProblemNotifier.rescanAndNotifyIfNeeded();
|
||||
myExecuteAfterScan.run();
|
||||
}
|
||||
finally {
|
||||
myScanning = false;
|
||||
}
|
||||
scheduleScan();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,4 +112,15 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis
|
||||
return myMappingsAreReady && myProjectIsInitialized;
|
||||
}
|
||||
|
||||
private void scheduleScan() {
|
||||
myAlarm.cancelAllRequests(); // one scan is enough, no need to queue, they all do the same
|
||||
myAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myRootProblemNotifier.rescanAndNotifyIfNeeded();
|
||||
myExecuteAfterScan.run();
|
||||
}
|
||||
}, WAIT_BEFORE_SCAN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user