IDEA-319836 Don't update tool window weights if editor area isn't there

Sometimes, apparently when the IDE is being initialized, some tool windows
appear before the editor area (EditorSplitters technically) is created and visible.
When that happens, ThreeComponentSplitter uses that area to extend the tool
window beyond its weight. In the worst case the Project View takes all available
space. Once its weight is updated based on its new size, it just stays like that
forever.

To fix that, we check that the middle component is present and visible. If it's not,
we don't update weights and write a log message. While this doesn't fix the original
issue, it prevents the new weight from sticking and the Project View taking all space
until manually resized.

While we're at it, add some useful logging when weights are updated or not updated.

GitOrigin-RevId: 7e03dc699b569940db1706c69f474c1f5df4caf2
This commit is contained in:
Sergei Tachenov
2023-05-18 16:44:10 +00:00
committed by intellij-monorepo-bot
parent 004bcb109a
commit 1b73198e9b
@@ -46,6 +46,7 @@ import com.intellij.openapi.project.ex.ProjectEx
import com.intellij.openapi.project.processOpenedProjects
import com.intellij.openapi.ui.FrameWrapper
import com.intellij.openapi.ui.Splitter
import com.intellij.openapi.ui.ThreeComponentsSplitter
import com.intellij.openapi.ui.popup.Balloon
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.util.*
@@ -600,6 +601,7 @@ open class ToolWindowManagerImpl @NonInjectable @TestOnly internal constructor(
if (isUnifiedToolWindowSizesEnabled()) {
info.weight = layoutState.getUnifiedAnchorWeight(info.anchor)
LOG.debug("Activated tool window: ${info.id}, using ${info.anchor} unified weight of ${info.weight}")
}
if (source != null) {
@@ -1313,9 +1315,11 @@ open class ToolWindowManagerImpl @NonInjectable @TestOnly internal constructor(
if (another != null && anchor.isUltrawideLayout()) { // split windows side-by-side, set weight of the entire splitter
weight += another.new.weight
}
LOG.debug("Setting ${item.entry.id} weight=${weight} from the saved layout")
toolWindowPane.setWeight(anchor, weight)
}
if (item.old.sideWeight != item.new.sideWeight) {
LOG.debug("Setting ${item.entry.id} side weight ${item.new.sideWeight} from the saved layout")
toolWindowPane.setSideWeight(item.entry.toolWindow, item.new.sideWeight)
}
}
@@ -2033,8 +2037,11 @@ open class ToolWindowManagerImpl @NonInjectable @TestOnly internal constructor(
}
else {
// docked and sliding windows
val dockingAreaComponent = if (source.parent is Splitter) source.parent as Splitter else source
if (!dockingAreaIsInSplitterWithVisibleEditorArea(dockingAreaComponent)) {
return
}
val anchor = info.anchor
val dockingAreaComponent: Component
if (source.parent is Splitter) {
var sizeInSplit = if (anchor.isSplitVertically) source.height else source.width
val splitter = source.parent as Splitter
@@ -2044,20 +2051,37 @@ open class ToolWindowManagerImpl @NonInjectable @TestOnly internal constructor(
info.sideWeight = getAdjustedRatio(partSize = sizeInSplit,
totalSize = if (anchor.isSplitVertically) splitter.height else splitter.width,
direction = if (splitter.secondComponent === source) -1 else 1)
dockingAreaComponent = splitter
}
else {
dockingAreaComponent = source
}
val toolWindowPane = getToolWindowPane(toolWindow)
val toolWindowWeight = getAdjustedWeight(toolWindowPane, anchor, source)
val dockingAreaWeight = getAdjustedWeight(toolWindowPane, anchor, dockingAreaComponent)
info.weight = toolWindowWeight
layoutState.setUnifiedAnchorWeight(anchor, dockingAreaWeight)
LOG.debug("Moved/resized tool window ${info.id}, updated weight=${toolWindowWeight}, docking area weight=${dockingAreaWeight}")
}
fireStateChanged(MovedOrResized, toolWindow)
}
private fun dockingAreaIsInSplitterWithVisibleEditorArea(dockingAreaComponent: Component): Boolean {
val parentSplitter = dockingAreaComponent.parent as? ThreeComponentsSplitter
if (parentSplitter == null) {
LOG.warn(Exception("InternalDecoratorImpl/Splitter is not in a ThreeComponentsSplitter, " +
"can't perform sanity checks, tool window info is not updated. " +
"Actual parent = ${dockingAreaComponent.parent}"))
return false
}
val editorComponent = parentSplitter.innerComponent
if (editorComponent == null) {
LOG.info("Editor area is null, not updating tool window weights")
return false
}
if (!editorComponent.isVisible) {
LOG.info("Editor area is not visible, not updating tool window weights")
return false
}
return true
}
private fun getAdjustedWeight(
toolWindowPane: ToolWindowPane,
anchor: ToolWindowAnchor,