summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java')
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java68
1 files changed, 61 insertions, 7 deletions
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
index 78802ccdf6bb..e50403abef45 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
@@ -162,6 +162,25 @@ public class AbstractPopup implements JBPopup {
private UiActivity myActivityKey;
private Disposable myProjectDisposable;
+ private volatile State myState = State.NEW;
+
+ private enum State {NEW, INIT, SHOWING, SHOWN, CANCEL, DISPOSE}
+
+ private void debugState(String message, State... states) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(hashCode() + " - " + message);
+ if (!ApplicationManager.getApplication().isDispatchThread()) {
+ LOG.debug("unexpected thread");
+ }
+ for (State state : states) {
+ if (state == myState) {
+ return;
+ }
+ }
+ LOG.debug(new IllegalStateException("myState=" + myState));
+ }
+ }
+
AbstractPopup() { }
AbstractPopup init(Project project,
@@ -302,6 +321,8 @@ public class AbstractPopup implements JBPopup {
}
myKeyEventHandler = keyEventHandler;
+ debugState("popup initialized", State.NEW);
+ myState = State.INIT;
return this;
}
@@ -582,10 +603,18 @@ public class AbstractPopup implements JBPopup {
@Override
public void cancel(InputEvent e) {
+ if (myState == State.CANCEL || myState == State.DISPOSE) {
+ return;
+ }
+ debugState("cancel popup", State.SHOWN);
+ myState = State.CANCEL;
+
if (isDisposed()) return;
if (myPopup != null) {
if (!canClose()) {
+ debugState("cannot cancel popup", State.CANCEL);
+ myState = State.SHOWN;
return;
}
storeDimensionSize(myContent.getSize());
@@ -610,8 +639,13 @@ public class AbstractPopup implements JBPopup {
}
if (myInStack) {
- myFocusTrackback.setForcedRestore(!myOk && myFocusable);
- myFocusTrackback.restoreFocus();
+ if (myFocusTrackback != null) {
+ myFocusTrackback.setForcedRestore(!myOk && myFocusable);
+ myFocusTrackback.restoreFocus();
+ }
+ else if (LOG.isDebugEnabled()) {
+ LOG.debug("cancel before show @ " + Thread.currentThread());
+ }
}
@@ -664,6 +698,9 @@ public class AbstractPopup implements JBPopup {
assert ApplicationManager.getApplication().isDispatchThread();
+ debugState("show popup", State.INIT);
+ myState = State.SHOWING;
+
installWindowHook(this);
installProjectDisposer();
addActivity();
@@ -673,6 +710,8 @@ public class AbstractPopup implements JBPopup {
final boolean shouldShow = beforeShow();
if (!shouldShow) {
removeActivity();
+ debugState("rejected to show popup", State.SHOWING);
+ myState = State.INIT;
return;
}
@@ -758,10 +797,11 @@ public class AbstractPopup implements JBPopup {
PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog);
myNativePopup = factory.isNativePopup();
Component popupOwner = myOwner;
- if (popupOwner instanceof RootPaneContainer) {
+ if (popupOwner instanceof RootPaneContainer && !(popupOwner instanceof IdeFrame && !Registry.is("popup.fix.ide.frame.owner"))) {
// JDK uses cached heavyweight popup for a window ancestor
RootPaneContainer root = (RootPaneContainer)popupOwner;
popupOwner = root.getRootPane();
+ LOG.debug("popup owner fixed for JDK cache");
}
if (LOG.isDebugEnabled()) {
LOG.debug("expected preferred size: " + myContent.getPreferredSize());
@@ -957,6 +997,8 @@ public class AbstractPopup implements JBPopup {
}
});
}
+ debugState("popup shown", State.SHOWING);
+ myState = State.SHOWN;
}
public void focusPreferredComponent() {
@@ -1232,6 +1274,16 @@ public class AbstractPopup implements JBPopup {
@Override
public void dispose() {
+ if (myState == State.SHOWN) {
+ LOG.debug("shown popup must be cancelled");
+ cancel();
+ }
+ if (myState == State.DISPOSE) {
+ return;
+ }
+ debugState("dispose popup", State.INIT, State.CANCEL);
+ myState = State.DISPOSE;
+
if (myDisposed) {
return;
}
@@ -1480,8 +1532,8 @@ public class AbstractPopup implements JBPopup {
@Override
public Dimension getSize() {
if (myPopup != null) {
- final Window popupWindow = SwingUtilities.windowForComponent(myContent);
- return popupWindow.getSize();
+ final Window popupWindow = getContentWindow(myContent);
+ return (popupWindow == null) ? myForcedSize : popupWindow.getSize();
} else {
return myForcedSize;
}
@@ -1491,7 +1543,8 @@ public class AbstractPopup implements JBPopup {
public void moveToFitScreen() {
if (myPopup == null) return;
- final Window popupWindow = SwingUtilities.windowForComponent(myContent);
+ final Window popupWindow = getContentWindow(myContent);
+ if (popupWindow == null) return;
Rectangle bounds = popupWindow.getBounds();
ScreenUtil.moveRectangleToFitTheScreen(bounds);
@@ -1501,7 +1554,8 @@ public class AbstractPopup implements JBPopup {
public static Window setSize(JComponent content, final Dimension size) {
- final Window popupWindow = SwingUtilities.windowForComponent(content);
+ final Window popupWindow = getContentWindow(content);
+ if (popupWindow == null) return null;
Insets insets = content.getInsets();
if (insets != null) {
size.width += insets.left + insets.right;