fix popups: heavy/medium: restore state of factory after popup creation + delegate setPopupType to the original factory

This commit is contained in:
Alexey Pegov
2010-08-10 20:31:16 +04:00
parent 2adcf97d35
commit 81be032ebc
4 changed files with 44 additions and 21 deletions
@@ -15,13 +15,17 @@
*/
package com.intellij.openapi.ui.popup.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.popup.JBPopup;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Method;
public class PopupUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.ui.popup.util.PopupUtil");
private PopupUtil() {
}
@@ -46,4 +50,29 @@ public class PopupUtil {
}
}
public static void setPopupType(@NotNull final PopupFactory factory, final int type) {
try {
final Method method = PopupFactory.class.getDeclaredMethod("setPopupType", int.class);
method.setAccessible(true);
method.invoke(factory, type);
}
catch (Throwable e) {
LOG.error(e);
}
}
public static int getPopupType(@NotNull final PopupFactory factory) {
try {
final Method method = PopupFactory.class.getDeclaredMethod("getPopupType");
method.setAccessible(true);
final Object result = method.invoke(factory);
return result instanceof Integer ? (Integer) result : -1;
}
catch (Throwable e) {
LOG.error(e);
}
return -1;
}
}
@@ -21,6 +21,7 @@ import com.intellij.idea.StartupUtil;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
@@ -308,10 +309,8 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
}
popupWeight = popupWeight.trim();
final boolean heavyWeighPopup = HEAVY_WEIGHT_POPUP.equals(popupWeight);
PopupFactory popupFactory;
final PopupFactory oldFactory = PopupFactory.getSharedInstance();
if (!(oldFactory instanceof OurPopupFactory)) {
popupFactory = new OurPopupFactory() {
@@ -322,20 +321,17 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
int y
) throws IllegalArgumentException {
final Point point = fixPopupLocation(contents, x, y);
try {
final Method method = PopupFactory.class.getDeclaredMethod("setPopupType", int.class);
method.setAccessible(true);
method.invoke(oldFactory, heavyWeighPopup ? 2 : 1);
}
catch (Throwable e) {
LOG.error(e);
final int popupType = PopupUtil.getPopupType(this);
if (popupType >= 0) {
PopupUtil.setPopupType(oldFactory, popupType);
}
return oldFactory.getPopup(owner, contents, point.x, point.y);
}
};
PopupUtil.setPopupType(popupFactory, HEAVY_WEIGHT_POPUP.equals(popupWeight) ? 2 : 1);
PopupFactory.setSharedInstance(popupFactory);
}
@@ -710,7 +710,10 @@ public class AbstractPopup implements JBPopup {
}
if (myWindow != null) {
if (!myMayBeParent) {
// dialogwrapper-based popups do this internally through peer,
// for other popups like jdialog-based we should exclude them manually, but
// we still have to be able to use IdeFrame as parent
if (!myMayBeParent && !(myWindow instanceof Frame)) {
WindowManager.getInstance().doNotSuggestAsParent(myWindow);
}
}
@@ -16,11 +16,11 @@
package com.intellij.ui.popup;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.util.ReflectionUtil;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Method;
public interface PopupComponent {
@@ -53,17 +53,12 @@ public interface PopupComponent {
public PopupComponent getPopup(Component owner, Component content, int x, int y) {
final PopupFactory factory = PopupFactory.getSharedInstance();
try {
final Method method = PopupFactory.class.getDeclaredMethod("setPopupType", int.class);
method.setAccessible(true);
method.invoke(factory, 2);
final int oldType = PopupUtil.getPopupType(factory);
PopupUtil.setPopupType(factory, 2);
final Popup popup = factory.getPopup(owner, content, x, y);
if (oldType >= 0) PopupUtil.setPopupType(factory, oldType);
}
catch (Throwable e) {
LOG.error(e);
}
return new AwtPopupWrapper(factory.getPopup(owner, content, x, y));
return new AwtPopupWrapper(popup);
}
public boolean isNativePopup() {