mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
mem leaks: clear CWindow listeners and rootPane: unify listeners & DRY
This commit is contained in:
@@ -971,6 +971,19 @@ public abstract class DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
public static void cleanupWindowListeners(@Nullable Window window) {
|
||||
if (window == null) return;
|
||||
for (WindowListener listener : window.getWindowListeners()) {
|
||||
if (listener.getClass().getName().startsWith("com.intellij.")) {
|
||||
LOG.warn("Stale listener: " + listener);
|
||||
}
|
||||
else {
|
||||
LOG.info("Stale listener: " + listener);
|
||||
}
|
||||
window.removeWindowListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is invoked by default implementation of "Cancel" action. It just closes dialog
|
||||
|
||||
@@ -25,7 +25,6 @@ import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil;
|
||||
import com.intellij.openapi.actionSystem.impl.MouseGestureManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerAdapter;
|
||||
@@ -60,7 +59,6 @@ import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
public class FrameWrapper implements Disposable, DataProvider {
|
||||
private static final Logger LOG = Logger.getInstance(FrameWrapper.class);
|
||||
|
||||
private String myDimensionKey = null;
|
||||
private JComponent myComponent = null;
|
||||
@@ -253,10 +251,7 @@ public class FrameWrapper implements Disposable, DataProvider {
|
||||
|
||||
frame.dispose();
|
||||
|
||||
for (WindowListener listener : frame.getWindowListeners()) {
|
||||
LOG.info("Clearing stale window listener: " + listener);
|
||||
frame.removeWindowListener(listener);
|
||||
}
|
||||
DialogWrapper.cleanupWindowListeners(frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+39
-48
@@ -709,50 +709,6 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
|
||||
ScreenUtil.fitToScreen(bounds);
|
||||
setBounds(bounds);
|
||||
}
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowActivated(WindowEvent e) {
|
||||
final DialogWrapper wrapper = getDialogWrapper();
|
||||
if (wrapper != null && myFocusTrackback != null) {
|
||||
myFocusTrackback.cleanParentWindow();
|
||||
myFocusTrackback.registerFocusComponent(new FocusTrackback.ComponentQuery() {
|
||||
@Override
|
||||
public Component getComponent() {
|
||||
return wrapper.getPreferredFocusedComponent();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
if (!isModal()) {
|
||||
final Ref<IdeFocusManager> focusManager = new Ref<>(null);
|
||||
Project project = getProject();
|
||||
if (project != null && !project.isDisposed()) {
|
||||
focusManager.set(getFocusManager());
|
||||
focusManager.get().doWhenFocusSettlesDown(() -> disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get()));
|
||||
}
|
||||
else {
|
||||
disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowOpened(WindowEvent e) {
|
||||
if (!SystemInfo.isMacOSLion) return;
|
||||
Window window = e.getWindow();
|
||||
if (window instanceof Dialog) {
|
||||
ID _native = MacUtil.findWindowForTitle(((Dialog)window).getTitle());
|
||||
if (_native != null && _native.intValue() > 0) {
|
||||
// see MacMainFrameDecorator
|
||||
// NSCollectionBehaviorFullScreenAuxiliary = 1 << 8
|
||||
Foundation.invoke(_native, "setCollectionBehavior:", 1 << 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (Registry.is("actionSystem.fixLostTyping")) {
|
||||
final IdeEventQueue queue = IdeEventQueue.getInstance();
|
||||
@@ -846,10 +802,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
|
||||
myWindowListener = null;
|
||||
}
|
||||
|
||||
for (WindowListener listener : getWindowListeners()) {
|
||||
LOG.info("Clearing stale window listener: " + listener);
|
||||
removeWindowListener(listener);
|
||||
}
|
||||
DialogWrapper.cleanupWindowListeners(this);
|
||||
|
||||
if (myFocusTrackback != null && !(myFocusTrackback.isScheduledForRestore() || myFocusTrackback.isWillBeScheduledForRestore())) {
|
||||
myFocusTrackback.dispose();
|
||||
@@ -938,6 +891,17 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
|
||||
|
||||
@Override
|
||||
public void windowOpened(final WindowEvent e) {
|
||||
if (SystemInfo.isMacOSLion) {
|
||||
Window window = e.getWindow();
|
||||
if (window instanceof Dialog) {
|
||||
ID _native = MacUtil.findWindowForTitle(((Dialog)window).getTitle());
|
||||
if (_native != null && _native.intValue() > 0) {
|
||||
// see MacMainFrameDecorator
|
||||
// NSCollectionBehaviorFullScreenAuxiliary = 1 << 8
|
||||
Foundation.invoke(_native, "setCollectionBehavior:", 1 << 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
myOpened = true;
|
||||
final DialogWrapper activeWrapper = getActiveWrapper();
|
||||
@@ -953,6 +917,18 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
|
||||
|
||||
@Override
|
||||
public void windowActivated(final WindowEvent e) {
|
||||
if (myFocusTrackback != null) {
|
||||
DialogWrapper wrapper = getDialogWrapper();
|
||||
if (wrapper != null) {
|
||||
myFocusTrackback.cleanParentWindow();
|
||||
myFocusTrackback.registerFocusComponent(new FocusTrackback.ComponentQuery() {
|
||||
@Override
|
||||
public Component getComponent() {
|
||||
return wrapper.getPreferredFocusedComponent();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
final DialogWrapper wrapper = getActiveWrapper();
|
||||
if (wrapper == null && !myFocusedCallback.isProcessed()) {
|
||||
@@ -991,6 +967,21 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
if (!isModal()) {
|
||||
Ref<IdeFocusManager> focusManager = new Ref<>(null);
|
||||
Project project = getProject();
|
||||
if (project != null && !project.isDisposed()) {
|
||||
focusManager.set(getFocusManager());
|
||||
focusManager.get().doWhenFocusSettlesDown(() -> disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get()));
|
||||
}
|
||||
else {
|
||||
disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyFocused(DialogWrapper wrapper) {
|
||||
myFocusedCallback.setDone();
|
||||
final long timeout = wrapper.getTypeAheadTimeoutMs();
|
||||
|
||||
@@ -39,10 +39,8 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class FocusTrackback {
|
||||
|
||||
@@ -79,8 +77,7 @@ public class FocusTrackback {
|
||||
myMustBeShown = mustBeShown;
|
||||
|
||||
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
if (app == null || app.isHeadlessEnvironment() || wrongOS()) return;
|
||||
if (isHeadlessOrWrongOS()) return;
|
||||
|
||||
register(parent);
|
||||
|
||||
@@ -135,6 +132,11 @@ public class FocusTrackback {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isHeadlessOrWrongOS() {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
return app == null || app.isHeadlessEnvironment() || wrongOS();
|
||||
}
|
||||
|
||||
private void setLocalFocusOwner(Component component) {
|
||||
myLocalFocusOwner = new WeakReference<>(component);
|
||||
}
|
||||
@@ -171,10 +173,10 @@ public class FocusTrackback {
|
||||
}
|
||||
|
||||
private List<FocusTrackback> getCleanStackForRoot() {
|
||||
return getCleanStackForRoot(myRoot);
|
||||
return myRoot == null ? Collections.emptyList() : getCleanStackForRoot(myRoot);
|
||||
}
|
||||
|
||||
private static List<FocusTrackback> getCleanStackForRoot(final Window root) {
|
||||
private static List<FocusTrackback> getCleanStackForRoot(@NotNull Window root) {
|
||||
List<FocusTrackback> stack = getStackForRoot(root);
|
||||
|
||||
final FocusTrackback[] stackArray = stack.toArray(new FocusTrackback[stack.size()]);
|
||||
@@ -190,8 +192,7 @@ public class FocusTrackback {
|
||||
}
|
||||
|
||||
public void restoreFocus() {
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
if (app == null || wrongOS() || myConsumed || isScheduledForRestore()) return;
|
||||
if (isHeadlessOrWrongOS() || myConsumed || isScheduledForRestore()) return;
|
||||
|
||||
Project project = null;
|
||||
DataManager dataManager = DataManager.getInstance();
|
||||
|
||||
Reference in New Issue
Block a user