From ab860568928542a93c21e5f421a2106ce2da5f76 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 7 Dec 2011 18:38:24 +0300 Subject: [PATCH] [nika] focus fix for intentions popus (ex.: spellchecker intention in the commit dialog returned focus to the commit tree) --- .../src/com/intellij/ide/IdeEventQueue.java | 5 +++- .../openapi/wm/impl/FocusManagerImpl.java | 27 +++++++++++++------ .../com/intellij/ui/popup/AbstractPopup.java | 5 +--- .../com/intellij/ui/popup/PopupComponent.java | 27 ++++++++++++------- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index 0a3d2786a186..a52461998d74 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -585,8 +585,11 @@ public class IdeEventQueue extends EventQueue { if (focusOwner == null || !focusOwner.isShowing() || focusOwner instanceof JFrame || focusOwner instanceof JDialog) { boolean mouseEventsAhead = isMouseEventAhead(e); + boolean focusTransferred = IdeFocusManager.getGlobalInstance().isFocusBeingTransferred(); - if (!mouseEventsAhead) { + boolean okToFixFocus = !mouseEventsAhead && (!focusTransferred || !Registry.is("actionSystem.fixLostTyping")); + + if (okToFixFocus) { Window showingWindow = mgr.getActiveWindow(); if (showingWindow == null) { Method getNativeFocusOwner = ReflectionUtil.getDeclaredMethod(KeyboardFocusManager.class, "getNativeFocusOwner"); 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 91c3465066e3..1c24a21f184d 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 @@ -734,32 +734,43 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } private int getCurrentModalityCount() { - int modalDialogs = 0; + int modalityCount = 0; Window[] windows = Window.getWindows(); for (Window each : windows) { + if (!each.isShowing()) continue; + if (each instanceof Dialog) { Dialog eachDialog = (Dialog)each; - if (eachDialog.isModal() && eachDialog.isShowing()) { - modalDialogs++; + if (eachDialog.isModal()) { + modalityCount++; + } else if (each instanceof JDialog) { + if (isModalContextPopup(((JDialog)each).getRootPane())) { + modalityCount++; + } } } else if (each instanceof JWindow) { - final JBPopup popup = (JBPopup)((JWindow)each).getRootPane().getClientProperty(JBPopup.KEY); - if (popup != null && popup.isModalContext()) { - modalDialogs++; + JRootPane rootPane = ((JWindow)each).getRootPane(); + if (isModalContextPopup(rootPane)) { + modalityCount++; } } } Iterator modalityCounts = myModalityCount2FlushCount.keySet().iterator(); while (modalityCounts.hasNext()) { Integer eachModalityCount = modalityCounts.next(); - if (eachModalityCount > modalDialogs) { + if (eachModalityCount > modalityCount) { modalityCounts.remove(); } } - return modalDialogs; + return modalityCount; } + private boolean isModalContextPopup(JRootPane rootPane) { + final JBPopup popup = (JBPopup)rootPane.getClientProperty(JBPopup.KEY); + return popup != null && popup.isModalContext(); + } + public void suspendKeyProcessingUntil(@NotNull final ActionCallback done) { typeAheadUntil(done); } 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 0726090febb8..46eb4bcc4a1c 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -696,7 +696,7 @@ public class AbstractPopup implements JBPopup { PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog); myNativePopup = factory.isNativePopup(); - myPopup = factory.getPopup(myOwner, myContent, targetBounds.x, targetBounds.y); + myPopup = factory.getPopup(myOwner, myContent, targetBounds.x, targetBounds.y, this); if (myResizable) { final JRootPane root = myContent.getRootPane(); @@ -751,9 +751,6 @@ public class AbstractPopup implements JBPopup { myWindow = updateMaskAndAlpha(window); - if (myWindow instanceof JWindow) { - ((JWindow)myWindow).getRootPane().putClientProperty(KEY, this); - } if (myWindow != null) { // dialogwrapper-based popups do this internally through peer, diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java index 86d63554f72c..fb4d29d1b814 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java @@ -16,6 +16,7 @@ package com.intellij.ui.popup; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.util.PopupUtil; import com.intellij.openapi.util.SystemInfo; import com.intellij.util.ReflectionUtil; @@ -38,15 +39,15 @@ public interface PopupComponent { boolean isPopupWindow(Window window); interface Factory { - PopupComponent getPopup(Component owner, Component content, int x, int y); + PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup); boolean isNativePopup(); class AwtDefault implements Factory { - public PopupComponent getPopup(Component owner, Component content, int x, int y) { + public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) { final PopupFactory factory = PopupFactory.getSharedInstance(); final Popup popup = factory.getPopup(owner, content, x, y); - return new AwtPopupWrapper(popup); + return new AwtPopupWrapper(popup, jbPopup); } public boolean isNativePopup() { @@ -55,7 +56,7 @@ public interface PopupComponent { } class AwtHeavyweight implements Factory { - public PopupComponent getPopup(Component owner, Component content, int x, int y) { + public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) { final PopupFactory factory = PopupFactory.getSharedInstance(); final int oldType = PopupUtil.getPopupType(factory); @@ -63,7 +64,7 @@ public interface PopupComponent { final Popup popup = factory.getPopup(owner, content, x, y); if (oldType >= 0) PopupUtil.setPopupType(factory, oldType); - return new AwtPopupWrapper(popup); + return new AwtPopupWrapper(popup, jbPopup); } public boolean isNativePopup() { @@ -72,8 +73,8 @@ public interface PopupComponent { } class Dialog implements Factory { - public PopupComponent getPopup(Component owner, Component content, int x, int y) { - return new DialogPopupWrapper(owner, content, x, y); + public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) { + return new DialogPopupWrapper(owner, content, x, y, jbPopup); } public boolean isNativePopup() { @@ -95,7 +96,7 @@ public interface PopupComponent { return myDialog != null && myDialog == window; } - public DialogPopupWrapper(Component owner, Component content, int x, int y) { + public DialogPopupWrapper(Component owner, Component content, int x, int y, JBPopup jbPopup) { if (!owner.isShowing()) { throw new IllegalArgumentException("Popup owner must be showing"); } @@ -109,6 +110,7 @@ public interface PopupComponent { myDialog.getContentPane().setLayout(new BorderLayout()); myDialog.getContentPane().add(content, BorderLayout.CENTER); + myDialog.getRootPane().putClientProperty(JBPopup.KEY, jbPopup); myDialog.setUndecorated(true); myDialog.pack(); @@ -123,6 +125,7 @@ public interface PopupComponent { myDialog.setVisible(false); if (dispose) { myDialog.dispose(); + myDialog.getRootPane().putClientProperty(JBPopup.KEY, null); } } @@ -142,9 +145,11 @@ public interface PopupComponent { class AwtPopupWrapper implements PopupComponent { private final Popup myPopup; + private JBPopup myJBPopup; - public AwtPopupWrapper(Popup popup) { + public AwtPopupWrapper(Popup popup, JBPopup jbPopup) { myPopup = popup; + myJBPopup = jbPopup; if (SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel()) { final Component c = (Component)ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component"); @@ -176,6 +181,10 @@ public interface PopupComponent { public void show() { myPopup.show(); + Window wnd = getWindow(); + if (wnd instanceof JWindow) { + ((JWindow)wnd).getRootPane().putClientProperty(JBPopup.KEY, myJBPopup); + } } public Window getWindow() {