From 3ceb953657e7b4dba654e51800facba09f11e10d Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Thu, 16 Jul 2015 23:25:45 +0300 Subject: [PATCH] IDEA-142728 Slow actions update --- .../ApplicationActivationListener.java | 4 +-- .../src/com/intellij/ide/IdeEventQueue.java | 28 +++++++-------- .../application/impl/ApplicationImpl.java | 34 +++++++++++-------- .../openapi/wm/impl/FocusManagerImpl.java | 2 +- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/application/ApplicationActivationListener.java b/platform/platform-api/src/com/intellij/openapi/application/ApplicationActivationListener.java index 5ad5f6e569e8..5d7cb9dbe377 100644 --- a/platform/platform-api/src/com/intellij/openapi/application/ApplicationActivationListener.java +++ b/platform/platform-api/src/com/intellij/openapi/application/ApplicationActivationListener.java @@ -42,7 +42,7 @@ public interface ApplicationActivationListener { * The shortcoming of the method is that a notification is delivered * with a delay. See {code app.deactivation.timeout} key in the registry */ - void delayedApplicationDeactivated(IdeFrame ideFrame); + void applicationDeactivating(IdeFrame ideFrame); abstract class Adapter implements ApplicationActivationListener { @Override @@ -52,6 +52,6 @@ public interface ApplicationActivationListener { public void applicationDeactivated(IdeFrame ideFrame) { } @Override - public void delayedApplicationDeactivated(IdeFrame ideFrame) { } + public void applicationDeactivating(IdeFrame ideFrame) { } } } diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index 716c5267a459..f6abdda0ef56 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -812,32 +812,30 @@ public class IdeEventQueue extends EventQueue { //if () { // getPopupManager().closeAllPopups(); //} - appImpl.myCancelDeactivation = true; - if (!appImpl.isActive()) { - appImpl.tryToApplyActivationState(eventWindow, true, false); - } + appImpl.tryToApplyActivationState(eventWindow, true, true); } else if (we.getID() == WindowEvent.WINDOW_DEACTIVATED) { requestToDeactivateTime.getAndSet(System.currentTimeMillis()); - // For stuff that cannot wait we notify about deactivation immediately - appImpl.tryToApplyActivationState(eventWindow, false, true); + // For stuff that cannot wait we notify about upcoming deactivation + appImpl.tryToApplyActivationState(eventWindow, false, false); // We do not know for sure that application is going to be inactive, // we could just be showing a popup or another transient window. // So let's postpone the application deactivation for a while - appImpl.myCancelDeactivation = false; + if (appImpl.isActive() && !appImpl.isDeactivating()) { - Timer timer = new Timer(Registry.intValue("app.deactivation.timeout"), new ActionListener() { - public void actionPerformed(ActionEvent evt) { - if (appImpl.isActiveDelayed() && !appImpl.isDeactivationCanceled()) { - appImpl.tryToApplyActivationState(eventWindow, false, false); + Timer timer = new Timer(Registry.intValue("app.deactivation.timeout"), new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (!appImpl.isDeactivationCancelled()) { + appImpl.tryToApplyActivationState(eventWindow, false, true); + } } - } - }); + }); - timer.setRepeats(false); - timer.start(); + timer.setRepeats(false); + timer.start(); + } } if (we.getID() == WindowEvent.WINDOW_DEACTIVATED || we.getID() == WindowEvent.WINDOW_LOST_FOCUS) { diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 8cd1e30cbf33..d875089860a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -125,15 +125,15 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private boolean myLoaded; private static final String WAS_EVER_SHOWN = "was.ever.shown"; - private volatile boolean myActive; - private volatile boolean myActiveDelayed; - public volatile boolean myCancelDeactivation; + private volatile Boolean myActive; + private volatile boolean myDeactivating; + public volatile boolean myDeactivationCancelled; private static final int IS_EDT_FLAG = 1<<30; // we don't mess with sign bit since we want to do arithmetic private static final int IS_READ_LOCK_ACQUIRED_FLAG = 1<<29; - public boolean isActiveDelayed() { - return myActiveDelayed; + public boolean isDeactivating() { + return myDeactivating; } private static class Status { @@ -1177,8 +1177,8 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App return true; } - public boolean isDeactivationCanceled() { - return myCancelDeactivation; + public boolean isDeactivationCancelled() { + return myDeactivationCancelled; } /** @@ -1199,13 +1199,14 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App public boolean tryToApplyActivationState(Window window, boolean activation, boolean immediate) { return activation ? applyActivation(window) : immediate ? applyDeactivation(window) - : applyDelayedDeactivation(window); + : applyDeactivating(window); } private boolean applyActivation(Window window) { if (!isActive()) { + myDeactivationCancelled = true; myActive = true; - myActiveDelayed = true; + myDeactivating = false; IdeFrame ideFrame = getIdeFrameFromWindow(window); if (ideFrame != null) { getMessageBus().syncPublisher(ApplicationActivationListener.TOPIC).applicationActivated(ideFrame); @@ -1226,12 +1227,13 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App return false; } - private boolean applyDelayedDeactivation(Window window) { - if (isActiveDelayed()) { - myActiveDelayed = false; + private boolean applyDeactivating(Window window) { + if (isActive() && !myDeactivating) { + myDeactivationCancelled = false; + myDeactivating = true; IdeFrame ideFrame = getIdeFrameFromWindow(window); if (ideFrame != null) { - getMessageBus().syncPublisher(ApplicationActivationListener.TOPIC).delayedApplicationDeactivated(ideFrame); + getMessageBus().syncPublisher(ApplicationActivationListener.TOPIC).applicationDeactivating(ideFrame); return true; } } @@ -1246,8 +1248,10 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App @Override public boolean isActive() { if (isUnitTestMode()) return true; - - return KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow() != null || myActive; + if (myActive == null) {//Here we get initial state that's been unknown before + myActive = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow() != null; + } + return myActive; } @NotNull 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 874786db021e..7269997487e8 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 @@ -1085,7 +1085,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } @Override - public void delayedApplicationDeactivated(IdeFrame ideFrame) { + public void applicationDeactivating(IdeFrame ideFrame) { final Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); Component parent = UIUtil.findUltimateParent(owner);