IJPL-183770 Fix excessive toolbar iterations

Do not iterate components:
1. On paint
2. When adding a new toolbar


(cherry picked from commit 0e387c189d60107a09ea950c53c184b900733a27)

IJ-CR-161198

GitOrigin-RevId: a74da26116dc32a9aaf5c57eb9e2ff7e30513981
This commit is contained in:
Gregory.Shrago
2025-04-24 22:44:42 +04:00
committed by intellij-monorepo-bot
parent 42bfd78282
commit e766f48c75
4 changed files with 41 additions and 31 deletions

View File

@@ -2956,7 +2956,6 @@ f:com.intellij.ide.actions.ToggleToolbarAction
- s:createToggleToolbarGroup(com.intellij.openapi.project.Project,com.intellij.openapi.wm.ToolWindow):com.intellij.openapi.actionSystem.DefaultActionGroup
- s:createToolWindowAction(com.intellij.openapi.wm.ToolWindow,com.intellij.ide.util.PropertiesComponent):com.intellij.ide.actions.ToggleToolbarAction
- getActionUpdateThread():com.intellij.openapi.actionSystem.ActionUpdateThread
- s:hasVisibleToolwindowToolbars(com.intellij.openapi.wm.ToolWindow):Z
- isSelected(com.intellij.openapi.actionSystem.AnActionEvent):Z
- s:isToolbarVisible(com.intellij.openapi.wm.ToolWindow):Z
- s:isToolbarVisible(com.intellij.openapi.wm.ToolWindow,com.intellij.ide.util.PropertiesComponent):Z
@@ -2969,7 +2968,7 @@ f:com.intellij.ide.actions.ToggleToolbarAction
- s:setToolbarVisible(java.lang.Iterable,Z):V
- s:setToolbarVisible(java.lang.String,com.intellij.ide.util.PropertiesComponent,java.lang.Iterable,java.lang.Boolean):V
- update(com.intellij.openapi.actionSystem.AnActionEvent):V
- s:updateToolbarsVisibility(com.intellij.openapi.wm.ToolWindow,com.intellij.ide.util.PropertiesComponent):V
- s:updateToolbarVisibility(com.intellij.openapi.wm.ToolWindow,com.intellij.openapi.actionSystem.ActionToolbar,com.intellij.ide.util.PropertiesComponent):V
f:com.intellij.ide.actions.ToggleZenModeAction
- com.intellij.openapi.project.DumbAwareAction
- sf:Companion:com.intellij.ide.actions.ToggleZenModeAction$Companion

View File

@@ -27,7 +27,6 @@ import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.function.Supplier;
@@ -46,7 +45,8 @@ public final class ToggleToolbarAction extends ToggleAction implements DumbAware
return new ToggleToolbarAction(properties, getShowToolbarProperty(id), components);
}
public static @NotNull ToggleToolbarAction createToolWindowAction(@NotNull ToolWindow toolWindow, @NotNull PropertiesComponent properties) {
public static @NotNull ToggleToolbarAction createToolWindowAction(@NotNull ToolWindow toolWindow,
@NotNull PropertiesComponent properties) {
updateToolbarsVisibility(toolWindow, properties);
toolWindow.addContentManagerListener(new ContentManagerListener() {
@Override
@@ -74,10 +74,16 @@ public final class ToggleToolbarAction extends ToggleAction implements DumbAware
});
}
public static void updateToolbarsVisibility(@NotNull ToolWindow toolWindow, @NotNull PropertiesComponent properties) {
if (toolWindow.getContentManagerIfCreated() != null) {
setToolbarVisible(Collections.singletonList(toolWindow.getComponent()), isToolbarVisible(toolWindow, properties));
}
private static void updateToolbarsVisibility(@NotNull ToolWindow toolWindow,
@NotNull PropertiesComponent properties) {
if (toolWindow.getContentManagerIfCreated() == null) return;
setToolbarVisible(Collections.singletonList(toolWindow.getComponent()), isToolbarVisible(toolWindow, properties));
}
public static void updateToolbarVisibility(@NotNull ToolWindow toolWindow,
@NotNull ActionToolbar toolbar,
@NotNull PropertiesComponent properties) {
setToolbarVisible(toolbar, isToolbarVisible(toolWindow, properties));
}
public static void setToolbarVisible(@NotNull ToolWindow toolWindow,
@@ -95,14 +101,19 @@ public final class ToggleToolbarAction extends ToggleAction implements DumbAware
setToolbarVisibleImpl(getShowToolbarProperty(id), properties, components, state);
}
public static void setToolbarVisible(@NotNull Iterable<? extends JComponent> roots, boolean state) {
public static void setToolbarVisible(@NotNull Iterable<? extends JComponent> roots,
boolean state) {
for (ActionToolbar toolbar : iterateToolbars(roots)) {
JComponent c = toolbar.getComponent();
c.setVisible(state);
Container parent = c.getParent();
if (parent instanceof EditorHeaderComponent) {
parent.setVisible(state);
}
setToolbarVisible(toolbar, state);
}
}
private static void setToolbarVisible(ActionToolbar toolbar, boolean state) {
JComponent c = toolbar.getComponent();
c.setVisible(state);
Container parent = c.getParent();
if (parent instanceof EditorHeaderComponent) {
parent.setVisible(state);
}
}
@@ -155,11 +166,6 @@ public final class ToggleToolbarAction extends ToggleAction implements DumbAware
return ActionUpdateThread.EDT;
}
public static boolean hasVisibleToolwindowToolbars(@NotNull ToolWindow toolWindow) {
Iterator<ActionToolbar> iterator = iterateToolbars(Collections.singletonList(toolWindow.getContentManager().getComponent())).iterator();
return iterator.hasNext() && iterator.next().getComponent().isVisible();
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
return isSelected();
@@ -199,8 +205,8 @@ public final class ToggleToolbarAction extends ToggleAction implements DumbAware
.filter(ActionToolbar.class)
.filter(toolbar -> {
var c = toolbar.getComponent();
return !Boolean.TRUE.equals(c.getClientProperty(ActionToolbarImpl.IMPORTANT_TOOLBAR_KEY))
&& !(c instanceof FloatingToolbarComponent);
return !Boolean.TRUE.equals(c.getClientProperty(ActionToolbarImpl.IMPORTANT_TOOLBAR_KEY)) &&
!(c instanceof FloatingToolbarComponent);
});
}

View File

@@ -177,7 +177,7 @@ internal class ToolWindowImpl(
return decorator!!
}
fun createCellDecorator() : InternalDecoratorImpl {
fun createCellDecorator(): InternalDecoratorImpl {
val cellContentManager = ContentManagerImpl(canCloseContent, toolWindowManager.project, parentDisposable, ContentManagerImpl.ContentUiProducer { contentManager, componentGetter ->
ToolWindowContentUi(this, contentManager, componentGetter.get())
})
@@ -221,10 +221,11 @@ internal class ToolWindowImpl(
})
object : ComponentTreeWatcher(ArrayUtil.EMPTY_CLASS_ARRAY) {
override fun processComponent(component: Component) {
if (component is ActionToolbar) {
updateToolbarsVisibility()
}
if (component !is ActionToolbar) return
ToggleToolbarAction.updateToolbarVisibility(
this@ToolWindowImpl, component, PropertiesComponent.getInstance(project))
}
override fun unprocessComponent(component: Component) = Unit
}.register(decorator)
if (ExperimentalUI.isNewUI()) {
@@ -251,8 +252,13 @@ internal class ToolWindowImpl(
return contentManager
}
private fun updateToolbarsVisibility() {
ToggleToolbarAction.updateToolbarsVisibility(this, PropertiesComponent.getInstance(project))
internal fun hasTopToolbar(): Boolean {
val decorator = decorator ?: return false
val header = decorator.header
val headerBounds = SwingUtilities.convertRectangle(header.parent, header.bounds, decorator)
val component = UIUtil.getDeepestComponentAt(
decorator, headerBounds.width/2, headerBounds.height * 3 / 2)
return UIUtil.getParentOfType(ActionToolbar::class.java, component) != null
}
private fun updateScrolledState() {
@@ -363,7 +369,7 @@ internal class ToolWindowImpl(
toolWindowFocusWatcher?.setFocusedComponentImpl(component)
}
fun getLastFocusedContent() : Content? {
fun getLastFocusedContent(): Content? {
val lastFocusedComponent = toolWindowFocusWatcher?.focusedComponent
if (lastFocusedComponent is JComponent) {
if (!lastFocusedComponent.isShowing) return null

View File

@@ -3,7 +3,6 @@ package com.intellij.toolWindow
import com.intellij.icons.AllIcons
import com.intellij.ide.IdeBundle
import com.intellij.ide.actions.ToggleToolbarAction
import com.intellij.ide.actions.ToolwindowFusEventFields
import com.intellij.ide.ui.UISettings.Companion.setupAntialiasing
import com.intellij.internal.statistic.eventLog.events.EventPair
@@ -302,7 +301,7 @@ abstract class ToolWindowHeader internal constructor(
val contentCount = (nearestDecorator?.contentManager ?: toolWindow.contentManager).contentCount
drawBottomLine = (toolWindow.anchor == ToolWindowAnchor.BOTTOM
|| (toolWindow.windowInfo.contentUiType == ToolWindowContentUiType.TABBED && contentCount > 1)
|| ToggleToolbarAction.hasVisibleToolwindowToolbars(toolWindow)
|| toolWindow.hasTopToolbar()
|| scrolled)
}