mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -84,7 +84,6 @@
|
||||
<orderEntry type="module" module-name="github" />
|
||||
<orderEntry type="module" module-name="hg4idea" />
|
||||
<orderEntry type="module" module-name="relaxng" />
|
||||
<orderEntry type="module" module-name="gradle" />
|
||||
<orderEntry type="module" module-name="remote-servers-impl" />
|
||||
<orderEntry type="module" module-name="dom-tests" />
|
||||
<orderEntry type="module" module-name="colorSchemes" />
|
||||
|
||||
@@ -31,6 +31,8 @@ com.android.tools.idea.rendering.RenderErrorPanelTest
|
||||
com.android.tools.idea.sdk.VersionCheckTest
|
||||
org.jetbrains.android.sdk.AndroidSdkUtilsTest
|
||||
org.jetbrains.android.sdk.AndroidSdkDataTest
|
||||
com.android.tools.idea.gradle.AndroidGradleModelTest
|
||||
com.android.tools.idea.gradle.InternalAndroidModelViewTest
|
||||
com.android.tools.idea.gradle.project.GradleProjectImporterTest
|
||||
com.android.tools.idea.gradle.compiler.AndroidGradleBuildProcessParametersProviderTest
|
||||
com.android.tools.idea.sdk.JdksTest
|
||||
|
||||
@@ -59,7 +59,8 @@ public class ManualRangeMarker {
|
||||
if (mySurviveOnExternalChange && PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, myRange)) {
|
||||
PersistentRangeMarker.LinesCols linesCols = myLinesCols != null ? myLinesCols
|
||||
: PersistentRangeMarker.storeLinesAndCols(myRange, documentBefore);
|
||||
Pair<ProperTextRange, PersistentRangeMarker.LinesCols> pair = PersistentRangeMarker.translateViaDiff((DocumentEventImpl)event, linesCols);
|
||||
Pair<ProperTextRange, PersistentRangeMarker.LinesCols> pair =
|
||||
linesCols == null ? null : PersistentRangeMarker.translateViaDiff((DocumentEventImpl)event, linesCols);
|
||||
if (pair != null) {
|
||||
return new ManualRangeMarker(pair.first, myGreedyLeft, myGreedyRight, true, pair.second);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ class PersistentRangeMarker extends RangeMarkerImpl {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Pair<ProperTextRange, LinesCols> translateViaDiff(final DocumentEventImpl event, LinesCols linesCols) {
|
||||
static Pair<ProperTextRange, LinesCols> translateViaDiff(@NotNull final DocumentEventImpl event, @NotNull LinesCols linesCols) {
|
||||
try {
|
||||
int myStartLine = event.translateLineViaDiffStrict(linesCols.myStartLine);
|
||||
Document document = event.getDocument();
|
||||
|
||||
+8
-1
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.VisualPosition;
|
||||
import com.intellij.openapi.editor.event.*;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -202,7 +203,13 @@ public class QuickDocOnMouseOverManager {
|
||||
return;
|
||||
}
|
||||
|
||||
VisualPosition visualPosition = editor.xyToVisualPosition(e.getMouseEvent().getPoint());
|
||||
Point point = e.getMouseEvent().getPoint();
|
||||
if (editor instanceof EditorEx && ((EditorEx)editor).getFoldingModel().getFoldingPlaceholderAt(point) != null) {
|
||||
closeQuickDocIfPossible();
|
||||
return;
|
||||
}
|
||||
|
||||
VisualPosition visualPosition = editor.xyToVisualPosition(point);
|
||||
if (editor.getSoftWrapModel().isInsideOrBeforeSoftWrap(visualPosition)) {
|
||||
closeQuickDocIfPossible();
|
||||
return;
|
||||
|
||||
@@ -28,7 +28,8 @@ import java.util.List;
|
||||
* @author dslomov
|
||||
*/
|
||||
public abstract class PluggableFileWatcher {
|
||||
public static final ExtensionPointName<PluggableFileWatcher> EP_NAME = ExtensionPointName.create("com.intellij.vfs.local.pluggableFileWatcher");
|
||||
public static final ExtensionPointName<PluggableFileWatcher> EP_NAME =
|
||||
ExtensionPointName.create("com.intellij.vfs.local.pluggableFileWatcher");
|
||||
|
||||
public abstract void initialize(@NotNull ManagingFS managingFS, @NotNull FileWatcherNotificationSink notificationSink);
|
||||
|
||||
@@ -45,11 +46,11 @@ public abstract class PluggableFileWatcher {
|
||||
|
||||
public abstract boolean isWatched(@NotNull VirtualFile file);
|
||||
|
||||
public abstract void resetChangedPaths();
|
||||
public void resetChangedPaths() { }
|
||||
|
||||
@TestOnly
|
||||
public abstract void startup() throws IOException;
|
||||
|
||||
@TestOnly
|
||||
public abstract void shutdown() throws InterruptedException;
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -277,7 +278,7 @@ public class StartupManagerImpl extends StartupManagerEx {
|
||||
if (!(fs instanceof LocalFileSystemImpl)) return;
|
||||
FileWatcher watcher = ((LocalFileSystemImpl)fs).getFileWatcher();
|
||||
if (!watcher.isOperational()) return;
|
||||
List<String> manualWatchRoots = watcher.getManualWatchRoots();
|
||||
Collection<String> manualWatchRoots = watcher.getManualWatchRoots();
|
||||
if (manualWatchRoots.isEmpty()) return;
|
||||
VirtualFile[] roots = ProjectRootManager.getInstance(myProject).getContentRoots();
|
||||
if (roots.length == 0) return;
|
||||
|
||||
+4
-9
@@ -53,6 +53,7 @@ import com.intellij.openapi.util.ScalableIcon;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.impl.IdeBackgroundUtil;
|
||||
import com.intellij.openapi.wm.impl.IdeGlassPaneImpl;
|
||||
import com.intellij.ui.HintHint;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
@@ -1362,26 +1363,24 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
}
|
||||
|
||||
void validateMousePointer(@NotNull MouseEvent e) {
|
||||
Cursor cursor = getCursor();//Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
|
||||
if (IdeGlassPaneImpl.hasPreProcessedCursor(this)) return;
|
||||
|
||||
Cursor cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
|
||||
FoldRegion foldingAtCursor = findFoldingAnchorAt(e.getX(), e.getY());
|
||||
setActiveFoldRegion(foldingAtCursor);
|
||||
boolean updated = false;
|
||||
if (foldingAtCursor != null) {
|
||||
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
|
||||
updated = true;
|
||||
}
|
||||
GutterIconRenderer renderer = getGutterRenderer(e);
|
||||
if (renderer != null) {
|
||||
if (renderer.isNavigateAction()) {
|
||||
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ActiveGutterRenderer lineRenderer = getActiveRendererByMouseEvent(e);
|
||||
if (lineRenderer != null) {
|
||||
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
|
||||
updated = true;
|
||||
}
|
||||
else {
|
||||
TextAnnotationGutterProvider provider = getProviderAtPoint(e.getPoint());
|
||||
@@ -1391,15 +1390,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
if (action != null) {
|
||||
int line = getLineNumAtPoint(e.getPoint());
|
||||
cursor = action.getCursor(line);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!updated && cursor == Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) {
|
||||
cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
|
||||
}
|
||||
setCursor(cursor);
|
||||
}
|
||||
|
||||
|
||||
+14
-9
@@ -119,7 +119,7 @@ public final class UpdateChecker {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(project, IdeBundle.message("updates.checking.progress"), true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
doUpdateAndShowResult(getProject(), !fromSettings, true, settings, indicator, null);
|
||||
doUpdateAndShowResult(getProject(), fromSettings, true, settings, indicator, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,7 +135,7 @@ public final class UpdateChecker {
|
||||
}
|
||||
|
||||
private static void doUpdateAndShowResult(@Nullable final Project project,
|
||||
final boolean enableLink,
|
||||
final boolean fromSettings,
|
||||
final boolean manualCheck,
|
||||
@NotNull final UpdateSettings updateSettings,
|
||||
@Nullable ProgressIndicator indicator,
|
||||
@@ -186,7 +186,13 @@ public final class UpdateChecker {
|
||||
}
|
||||
|
||||
incompatiblePlugins = buildNumber != null ? new HashSet<IdeaPluginDescriptor>() : null;
|
||||
updatedPlugins = checkPluginsUpdate(manualCheck, updateSettings, indicator, incompatiblePlugins, buildNumber);
|
||||
try {
|
||||
updatedPlugins = checkPluginsUpdate(updateSettings, indicator, incompatiblePlugins, buildNumber);
|
||||
}
|
||||
catch (IOException e) {
|
||||
showErrorMessage(manualCheck, IdeBundle.message("updates.error.connection.failed", e.getMessage()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// show result
|
||||
@@ -194,12 +200,12 @@ public final class UpdateChecker {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showUpdateResult(project, result, updateSettings, updatedPlugins, incompatiblePlugins, enableLink, manualCheck);
|
||||
showUpdateResult(project, result, updateSettings, updatedPlugins, incompatiblePlugins, !fromSettings, manualCheck);
|
||||
if (callback != null) {
|
||||
callback.setDone();
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
}, fromSettings ? ModalityState.any() : ModalityState.NON_MODAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -244,11 +250,10 @@ public final class UpdateChecker {
|
||||
return strategy.checkForUpdates();
|
||||
}
|
||||
|
||||
private static Collection<PluginDownloader> checkPluginsUpdate(boolean manualCheck,
|
||||
@NotNull UpdateSettings updateSettings,
|
||||
private static Collection<PluginDownloader> checkPluginsUpdate(@NotNull UpdateSettings updateSettings,
|
||||
@Nullable ProgressIndicator indicator,
|
||||
@Nullable Collection<IdeaPluginDescriptor> incompatiblePlugins,
|
||||
@Nullable BuildNumber buildNumber) {
|
||||
@Nullable BuildNumber buildNumber) throws IOException {
|
||||
// collect installed plugins and plugins imported from a previous installation
|
||||
Map<PluginId, IdeaPluginDescriptor> updateable = ContainerUtil.newTroveMap();
|
||||
|
||||
@@ -309,7 +314,7 @@ public final class UpdateChecker {
|
||||
LOG.info("failed to load plugin descriptions from " + host + ": " + e.getMessage());
|
||||
}
|
||||
else {
|
||||
showErrorMessage(manualCheck, IdeBundle.message("updates.error.connection.failed", e.getMessage()));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static com.intellij.util.containers.ContainerUtil.emptyList;
|
||||
import static com.intellij.util.containers.ContainerUtil.newArrayList;
|
||||
|
||||
/**
|
||||
@@ -54,9 +54,6 @@ public class FileWatcher {
|
||||
}
|
||||
};
|
||||
|
||||
private final Object myLock = new Object();
|
||||
private final PluggableFileWatcher[] myWatchers;
|
||||
|
||||
public static class DirtyPaths {
|
||||
public final List<String> dirtyPaths = newArrayList();
|
||||
public final List<String> dirtyPathsRecursive = newArrayList();
|
||||
@@ -69,14 +66,15 @@ public class FileWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
private DirtyPaths myDirtyPaths = new DirtyPaths();
|
||||
private final AtomicBoolean myFailureShownToTheUser = new AtomicBoolean(false);
|
||||
private final MyFileWatcherNotificationSink myNotificationSink;
|
||||
private final PluggableFileWatcher[] myWatchers;
|
||||
private final AtomicBoolean myFailureShown = new AtomicBoolean(false);
|
||||
|
||||
FileWatcher(@NotNull ManagingFS managingFS) {
|
||||
MyFileWatcherNotificationSink notificationSink = new MyFileWatcherNotificationSink();
|
||||
myNotificationSink = new MyFileWatcherNotificationSink();
|
||||
myWatchers = PluggableFileWatcher.EP_NAME.getExtensions();
|
||||
for (PluggableFileWatcher watcher : myWatchers) {
|
||||
watcher.initialize(managingFS, notificationSink);
|
||||
watcher.initialize(managingFS, myNotificationSink);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,37 +100,29 @@ public class FileWatcher {
|
||||
|
||||
@NotNull
|
||||
public DirtyPaths getDirtyPaths() {
|
||||
synchronized (myLock) {
|
||||
if (!myDirtyPaths.isEmpty()) {
|
||||
DirtyPaths dirtyPaths = myDirtyPaths;
|
||||
myDirtyPaths = new DirtyPaths();
|
||||
for (PluggableFileWatcher watcher : myWatchers) {
|
||||
watcher.resetChangedPaths();
|
||||
}
|
||||
return dirtyPaths;
|
||||
}
|
||||
else {
|
||||
return DirtyPaths.EMPTY;
|
||||
}
|
||||
}
|
||||
return myNotificationSink.getDirtyPaths();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getManualWatchRoots() {
|
||||
public Collection<String> getManualWatchRoots() {
|
||||
if (myWatchers.length == 1) {
|
||||
return myWatchers[0].getManualWatchRoots();
|
||||
}
|
||||
HashSet<String> result = null;
|
||||
|
||||
Set<String> result = null;
|
||||
for (PluggableFileWatcher watcher : myWatchers) {
|
||||
List<String> roots = watcher.getManualWatchRoots();
|
||||
if (result == null) {
|
||||
result = new HashSet<String>(roots);
|
||||
} else {
|
||||
result.retainAll(roots);
|
||||
Collection<String> roots = watcher.getManualWatchRoots();
|
||||
if (!roots.isEmpty()) {
|
||||
if (result == null) {
|
||||
result = new HashSet<String>(roots);
|
||||
}
|
||||
else {
|
||||
result.retainAll(roots);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result == null) return emptyList();
|
||||
return Collections.list(Collections.enumeration(result));
|
||||
|
||||
return result != null ? result : Collections.<String>emptyList();
|
||||
}
|
||||
|
||||
public void setWatchRoots(@NotNull List<String> recursive, @NotNull List<String> flat) {
|
||||
@@ -151,16 +141,37 @@ public class FileWatcher {
|
||||
public void notifyOnFailure(final String cause, @Nullable final NotificationListener listener) {
|
||||
LOG.warn(cause);
|
||||
|
||||
if (myFailureShownToTheUser.compareAndSet(false, true)) ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String title = ApplicationBundle.message("watcher.slow.sync");
|
||||
Notifications.Bus.notify(NOTIFICATION_GROUP.getValue().createNotification(title, cause, NotificationType.WARNING, listener));
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
if (myFailureShown.compareAndSet(false, true)) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String title = ApplicationBundle.message("watcher.slow.sync");
|
||||
Notifications.Bus.notify(NOTIFICATION_GROUP.getValue().createNotification(title, cause, NotificationType.WARNING, listener));
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyFileWatcherNotificationSink implements FileWatcherNotificationSink {
|
||||
private final Object myLock = new Object();
|
||||
private DirtyPaths myDirtyPaths = new DirtyPaths();
|
||||
|
||||
private DirtyPaths getDirtyPaths() {
|
||||
synchronized (myLock) {
|
||||
if (!myDirtyPaths.isEmpty()) {
|
||||
DirtyPaths dirtyPaths = myDirtyPaths;
|
||||
myDirtyPaths = new DirtyPaths();
|
||||
for (PluggableFileWatcher watcher : myWatchers) {
|
||||
watcher.resetChangedPaths();
|
||||
}
|
||||
return dirtyPaths;
|
||||
}
|
||||
else {
|
||||
return DirtyPaths.EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDirtyPaths(Collection<String> paths) {
|
||||
synchronized (myLock) {
|
||||
|
||||
+32
-22
@@ -32,6 +32,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ShutDownTracker;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.local.FileWatcherNotificationSink;
|
||||
@@ -66,13 +67,13 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
|
||||
private static final int MAX_PROCESS_LAUNCH_ATTEMPT_COUNT = 10;
|
||||
|
||||
private ManagingFS myManagingFS;
|
||||
private FileWatcherNotificationSink myNotificationSink;
|
||||
private File myExecutable;
|
||||
|
||||
private volatile MyProcessHandler myProcessHandler;
|
||||
private volatile int myStartAttemptCount = 0;
|
||||
private volatile boolean myIsShuttingDown = false;
|
||||
private final AtomicInteger mySettingRoots = new AtomicInteger(0);
|
||||
private final Object myLock = new Object();
|
||||
private FileWatcherNotificationSink myNotificationSink;
|
||||
|
||||
private volatile List<String> myRecursiveWatchRoots = emptyList();
|
||||
private volatile List<String> myFlatWatchRoots = emptyList();
|
||||
@@ -280,7 +281,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
|
||||
|
||||
@Override
|
||||
public void resetChangedPaths() {
|
||||
synchronized (myLock) {
|
||||
synchronized (myLastChangedPaths) {
|
||||
myLastChangedPathIndex = 0;
|
||||
for (int i = 0; i < myLastChangedPaths.length; ++i) myLastChangedPaths[i] = null;
|
||||
}
|
||||
@@ -375,7 +376,8 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
|
||||
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
LOG.warn("Watcher terminated with exit code " + event.getExitCode());
|
||||
String message = "Watcher terminated with exit code " + event.getExitCode();
|
||||
if (myIsShuttingDown) LOG.info(message); else LOG.warn(message);
|
||||
|
||||
myProcessHandler = null;
|
||||
|
||||
@@ -444,7 +446,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
|
||||
}
|
||||
}
|
||||
else {
|
||||
String path = line.replace('\0', '\n'); // unescape
|
||||
String path = StringUtil.trimEnd(line.replace('\0', '\n'), File.separator); // unescape
|
||||
processChange(path, myLastOp);
|
||||
myLastOp = null;
|
||||
}
|
||||
@@ -482,7 +484,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
|
||||
}
|
||||
|
||||
private void processChange(String path, WatcherOp op) {
|
||||
if (SystemInfo.isWindows && op == WatcherOp.RECDIRTY && path.length() == 3 && Character.isLetter(path.charAt(0))) {
|
||||
if (SystemInfo.isWindows && op == WatcherOp.RECDIRTY) {
|
||||
VirtualFile root = LocalFileSystem.getInstance().findFileByPath(path);
|
||||
if (root != null) {
|
||||
myNotificationSink.notifyPathsRecursive(list(root.getPresentableUrl()));
|
||||
@@ -491,25 +493,13 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
|
||||
return;
|
||||
}
|
||||
|
||||
if (op == WatcherOp.CHANGE) {
|
||||
// collapse subsequent change file change notifications that happen once we copy large file,
|
||||
// this allows reduction of path checks at least 20% for Windows
|
||||
synchronized (myLock) {
|
||||
for (int i = 0; i < myLastChangedPaths.length; ++i) {
|
||||
int last = myLastChangedPathIndex - i - 1;
|
||||
if (last < 0) last += myLastChangedPaths.length;
|
||||
String lastChangedPath = myLastChangedPaths[last];
|
||||
if (lastChangedPath != null && lastChangedPath.equals(path)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
myLastChangedPaths[myLastChangedPathIndex++] = path;
|
||||
if (myLastChangedPathIndex == myLastChangedPaths.length) myLastChangedPathIndex = 0;
|
||||
if ((op == WatcherOp.CHANGE || op == WatcherOp.STATS) && isRepetition(path)) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Repetition: " + path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int length = path.length();
|
||||
if (length > 1 && path.charAt(length - 1) == '/') path = path.substring(0, length - 1);
|
||||
boolean exactPath = op != WatcherOp.DIRTY && op != WatcherOp.RECDIRTY;
|
||||
Collection<String> paths = checkWatchable(path, exactPath, false);
|
||||
|
||||
@@ -547,6 +537,26 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRepetition(String path) {
|
||||
// collapse subsequent change file change notifications that happen once we copy large file,
|
||||
// this allows reduction of path checks at least 20% for Windows
|
||||
synchronized (myLastChangedPaths) {
|
||||
for (int i = 0; i < myLastChangedPaths.length; ++i) {
|
||||
int last = myLastChangedPathIndex - i - 1;
|
||||
if (last < 0) last += myLastChangedPaths.length;
|
||||
String lastChangedPath = myLastChangedPaths[last];
|
||||
if (lastChangedPath != null && lastChangedPath.equals(path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
myLastChangedPaths[myLastChangedPathIndex++] = path;
|
||||
if (myLastChangedPathIndex == myLastChangedPaths.length) myLastChangedPathIndex = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("TestOnlyProblems")
|
||||
private void notifyOnAnyEvent() {
|
||||
myNotificationSink.notifyOnAnyEvent();
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.util.List;
|
||||
public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEventQueue.EventDispatcher {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.IdeGlassPaneImpl");
|
||||
private static final String PREPROCESSED_CURSOR_KEY = "SuperCursor";
|
||||
|
||||
private final List<EventListener> myMouseListeners = new ArrayList<EventListener>();
|
||||
private final Set<EventListener> mySortedMouseListeners = new TreeSet<EventListener>(new Comparator<EventListener>() {
|
||||
@@ -345,6 +346,9 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
|
||||
}
|
||||
|
||||
if (cursor != null && !cursor.equals(target.getCursor())) {
|
||||
if (target instanceof JComponent) {
|
||||
((JComponent)target).putClientProperty(PREPROCESSED_CURSOR_KEY, Boolean.TRUE);
|
||||
}
|
||||
target.setCursor(cursor);
|
||||
}
|
||||
}
|
||||
@@ -393,9 +397,15 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
|
||||
private void restoreLastComponent(Component newC) {
|
||||
if (myLastCursorComponent != null && myLastCursorComponent != newC) {
|
||||
myLastCursorComponent.setCursor(myLastOriginalCursor);
|
||||
if (myLastCursorComponent instanceof JComponent) {
|
||||
((JComponent)myLastCursorComponent).putClientProperty(PREPROCESSED_CURSOR_KEY, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasPreProcessedCursor(@NotNull JComponent component) {
|
||||
return component.getClientProperty(PREPROCESSED_CURSOR_KEY) != null;
|
||||
}
|
||||
|
||||
public void setCursor(Cursor cursor, @NotNull Object requestor) {
|
||||
if (cursor == null) {
|
||||
|
||||
@@ -123,6 +123,8 @@ format.file.size.bytes={0}b
|
||||
format.file.size.kbytes={0}Kb
|
||||
format.file.size.mbytes={0}Mb
|
||||
|
||||
profiling.capture.snapshot.progress=Capturing Memory Snapshot
|
||||
profiling.compress.snapshot.progress=Compressing Memory Snapshot
|
||||
profiling.capture.snapshot.success=Captured snapshot ''{0}'' is placed in user home directory. <a href="{1}">Show in {2}</a>.
|
||||
profiling.capture.snapshot.error=Failed to capture snapshot: {0}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user