diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 3d15040d4cf4..35437e27eae3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -52,7 +52,6 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private final ArrayList myFocusRequests = new ArrayList(); private final ArrayList myToDispatchOnDone = new ArrayList(); - private int myFlushingIdleRequestsEntryCount = 0; private WeakReference myLastForcedRequest = new WeakReference(null); @@ -91,6 +90,9 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private DataContext myRunContext; + private Map myModalityCount2FlushCount = new HashMap(); + private Integer myCurrentModalityCount; + public FocusManagerImpl(WindowManager wm) { myApp = ApplicationManager.getApplication(); myQueue = IdeEventQueue.getInstance(); @@ -114,13 +116,17 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { myLastFocused.put((IdeFrame)parent, new WeakReference(c)); } } else if (e instanceof WindowEvent) { + Window wnd = ((WindowEvent)e).getWindow(); if (e.getID() == WindowEvent.WINDOW_CLOSED) { - Window wnd = ((WindowEvent)e).getWindow(); if (wnd instanceof IdeFrame) { myLastFocused.remove((IdeFrame)wnd); myLastFocusedAtDeactivation.remove((IdeFrame)wnd); } } + + if (wnd instanceof Dialog) { + myCurrentModalityCount = null; + } } return false; @@ -379,7 +385,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private void flushIdleRequests() { try { - myFlushingIdleRequestsEntryCount++; + incFlushingRequests(1); final KeyEvent[] events = myToDispatchOnDone.toArray(new KeyEvent[myToDispatchOnDone.size()]); if (events.length > 0) { @@ -427,14 +433,14 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { myFlushWasDelayedToFixFocus = true; } - if (canFlushIdleRequests() && myFlushingIdleRequestsEntryCount <= 1 && (focusOk || !myFlushWasDelayedToFixFocus)) { + if (canFlushIdleRequests() && getFlushingIdleRequests() <= 1 && (focusOk || !myFlushWasDelayedToFixFocus)) { myFlushWasDelayedToFixFocus = false; flushNow(); } } } finally { - myFlushingIdleRequestsEntryCount--; + incFlushingRequests(-1); if (!isIdleQueueEmpty()) { restartIdleAlarm(); } @@ -514,7 +520,51 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } private boolean isFlushingIdleRequests() { - return myFlushingIdleRequestsEntryCount > 0; + return getFlushingIdleRequests() > 0; + } + + private int getFlushingIdleRequests() { + int currentModalityCount = getCurrentModalityCount(); + if (myModalityCount2FlushCount.containsKey(currentModalityCount)) { + return myModalityCount2FlushCount.get(currentModalityCount); + } else { + return 0; + } + } + + private void incFlushingRequests(int delta) { + int currentModalityCount = getCurrentModalityCount(); + if (myModalityCount2FlushCount.containsKey(currentModalityCount)) { + Integer requests = myModalityCount2FlushCount.get(currentModalityCount); + myModalityCount2FlushCount.put(currentModalityCount, requests + delta); + } else { + myModalityCount2FlushCount.put(currentModalityCount, Integer.valueOf(delta)); + } + } + + private int getCurrentModalityCount() { + if (myCurrentModalityCount == null) { + int modalDialogs = 0; + Window[] windows = Frame.getWindows(); + for (Window each : windows) { + if (each instanceof Dialog) { + Dialog eachDialog = (Dialog)each; + if (eachDialog.isModal() && eachDialog.isShowing()) { + modalDialogs++; + } + } + } + myCurrentModalityCount = modalDialogs; + Iterator modalityCounts = myModalityCount2FlushCount.keySet().iterator(); + while (modalityCounts.hasNext()) { + Integer eachModalityCount = modalityCounts.next(); + if (eachModalityCount > myCurrentModalityCount) { + modalityCounts.remove(); + } + } + } + + return myCurrentModalityCount; } public void suspendKeyProcessingUntil(@NotNull final ActionCallback done) {