From dbc129a3ebf6f3fa2d15bbce3cac666b4a7c9ec6 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 7 Dec 2018 14:38:25 +0300 Subject: [PATCH] make tool window registration in Disposer simpler to avoid double dispose (via register(d, ()->Disposer.dispose(t)) pattern) --- .../openapi/wm/impl/ToolWindowImpl.java | 7 +++- .../wm/impl/ToolWindowManagerImpl.java | 39 +++++++------------ 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java index aa20704b200f..d6fadd1f3de4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -5,6 +5,7 @@ import com.intellij.ide.UiActivity; import com.intellij.ide.UiActivityMonitor; import com.intellij.ide.impl.ContentManagerWatcher; import com.intellij.notification.EventLog; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; @@ -44,7 +45,7 @@ import java.util.ArrayList; * @author Anton Katilin * @author Vladimir Kondratyev */ -public final class ToolWindowImpl implements ToolWindowEx { +public final class ToolWindowImpl implements ToolWindowEx, Disposable { private final PropertyChangeSupport myChangeSupport = new PropertyChangeSupport(this); private final ToolWindowManagerImpl myToolWindowManager; private final String myId; @@ -81,6 +82,7 @@ public final class ToolWindowImpl implements ToolWindowEx { final ContentFactory contentFactory = ServiceManager.getService(ContentFactory.class); myContentUI = new ToolWindowContentUi(this); myContentManager = contentFactory.createContentManager(myContentUI, canCloseContent, toolWindowManager.getProject()); + Disposer.register(this, myContentManager); if (component != null) { final Content content = contentFactory.createContent(component, "", false); @@ -504,8 +506,9 @@ public final class ToolWindowImpl implements ToolWindowEx { return myContentManager.isDisposed(); } + @Override public void dispose() { - Disposer.dispose(myContentManager); + myToolWindowManager.doUnregisterToolWindow(myId); } boolean isPlaceholderMode() { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index a8ca82449dbc..f31ebb32d007 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -37,6 +37,7 @@ import com.intellij.ui.BalloonImpl; import com.intellij.ui.ColorUtil; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.*; +import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.EdtInvocationManager; import com.intellij.util.ui.PositionTracker; @@ -59,6 +60,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Predicate; @State( @@ -397,10 +399,6 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis @Override public void dispose() { - for (String id : new ArrayList<>(myId2StripeButton.keySet())) { - unregisterToolWindow(id); - } - LOG.assertTrue(myId2StripeButton.isEmpty(), myId2StripeButton); } @@ -489,7 +487,7 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis final ToolWindowFactory factory = bean.getToolWindowFactory(); ToolWindow window = registerToolWindow(bean.id, label, toolWindowAnchor, false, bean.canCloseContents, DumbService.isDumbAware(factory), factory.shouldBeAvailable(myProject)); - final ToolWindowImpl toolWindow = (ToolWindowImpl)registerDisposable(bean.id, myProject, window); + final ToolWindowImpl toolWindow = (ToolWindowImpl)window; toolWindow.setContentFactory(factory); if (bean.icon != null && toolWindow.getIcon() == null) { Icon icon = IconLoader.findIcon(bean.icon, factory.getClass()); @@ -1011,7 +1009,7 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis @NotNull ToolWindowAnchor anchor, @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean canCloseContents) { - return registerDisposable(id, parentDisposable, registerToolWindow(id, component, anchor, false, canCloseContents, canWorkInDumbMode, true)); + return registerToolWindow(id, component, anchor, false, canCloseContents, canWorkInDumbMode, true); } @NotNull @@ -1048,8 +1046,7 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean secondary) { - ToolWindow window = registerToolWindow(id, null, anchor, secondary, canCloseContent, canWorkInDumbMode, true); - return registerDisposable(id, parentDisposable, window); + return registerToolWindow(id, null, anchor, secondary, canCloseContent, canWorkInDumbMode, true); } @NotNull @@ -1080,6 +1077,7 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis // Create decorator ToolWindowImpl toolWindow = new ToolWindowImpl(this, id, canCloseContent, component); + Disposer.register(this, toolWindow); toolWindow.setAvailable(shouldBeAvailable, null); InternalDecorator decorator = new InternalDecorator(myProject, info.copy(), toolWindow, canWorkInDumbMode); ActivateToolWindowAction.ensureToolWindowActionRegistered(toolWindow); @@ -1091,6 +1089,7 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis // Create and show tool button final StripeButton button = new StripeButton(decorator, myToolWindowsPane); + Disposer.register(toolWindow, button); myId2StripeButton.put(id, button); List commandsList = new ArrayList<>(); appendAddButtonCmd(button, info, commandsList); @@ -1114,14 +1113,12 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis return toolWindow; } - @NotNull - private ToolWindow registerDisposable(@NotNull final String id, @NotNull final Disposable parentDisposable, @NotNull ToolWindow window) { - Disposer.register(parentDisposable, () -> unregisterToolWindow(id)); - return window; - } - @Override public void unregisterToolWindow(@NotNull final String id) { + Disposer.dispose((ToolWindowImpl)getToolWindow(id)); + } + + void doUnregisterToolWindow(@NotNull String id) { if (LOG.isDebugEnabled()) { LOG.debug("enter: unregisterToolWindow(" + id + ")"); } @@ -1154,8 +1151,6 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis toolWindow.removePropertyChangeListener(myToolWindowPropertyChangeListener); // Destroy stripe button - final StripeButton button = getStripeButton(id); - Disposer.dispose(button); myId2StripeButton.remove(id); // ToolWindowFocusWatcher watcher = (ToolWindowFocusWatcher)myId2FocusWatcher.remove(id); @@ -1166,8 +1161,6 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis decorator.dispose(); decorator.removeInternalDecoratorListener(myInternalDecoratorListener); myId2InternalDecorator.remove(id); - - ((ToolWindowImpl)toolWindow).dispose(); } private void applyInfo(@NotNull String id, WindowInfoImpl info, List commandsList) { @@ -1327,13 +1320,9 @@ public class ToolWindowManagerImpl extends ToolWindowManagerEx implements Persis final Balloon balloon = JBPopupFactory.getInstance() .createHtmlTextBalloonBuilder(text.replace("\n", "
"), icon, type.getTitleForeground(), type.getPopupBackground(), listenerWrapper) .setBorderColor(type.getBorderColor()).setHideOnClickOutside(false).setHideOnFrameResize(false).createBalloon(); - NotificationsManagerImpl.frameActivateBalloonListener(balloon, () -> { - final Alarm alarm = new Alarm(); - alarm.addRequest(() -> { - ((BalloonImpl)balloon).setHideOnClickOutside(true); - Disposer.dispose(alarm); - }, 100); - }); + NotificationsManagerImpl.frameActivateBalloonListener(balloon, () -> + AppExecutorUtil.getAppScheduledExecutorService().schedule(()->((BalloonImpl)balloon).setHideOnClickOutside(true), 100, TimeUnit.MILLISECONDS) + ); listenerWrapper.myBalloon = balloon; myWindow2Balloon.put(toolWindowId, balloon); Disposer.register(balloon, () -> {