From 44eeff4813e69053e8caa30409c5c2760b42d86c Mon Sep 17 00:00:00 2001 From: Sergei Tachenov Date: Thu, 20 Feb 2025 17:41:38 +0200 Subject: [PATCH] IJPL-178555 Remove Graphics translation from AbstractToolbarComboUI The problem with Graphics translation is that once there's a DeferredIconImpl among the icons, it can use the coordinates passed to paintIcon to schedule a repaint request. If these coordinates are not relative to the component's coordinate system, then the request will be wrong and the next repaint may be clipped incorrectly. Until this issue is fixed, we can at least temporarily fix the issue with these toolbar combos by removing the translation and basing the paint rectangle on the component's coordinate system. GitOrigin-RevId: 124b5656b2101ac2e235a2d658c793a20d9208f6 --- .../ide/ui/laf/darcula/ui/AbstractToolbarComboUI.kt | 4 ++-- .../intellij/ide/ui/laf/darcula/ui/ToolbarComboButtonUI.kt | 5 +++-- .../intellij/ide/ui/laf/darcula/ui/ToolbarSplitButtonUI.kt | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/AbstractToolbarComboUI.kt b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/AbstractToolbarComboUI.kt index 0dc5d6f1a51e..7f9e1332389e 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/AbstractToolbarComboUI.kt +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/AbstractToolbarComboUI.kt @@ -57,10 +57,10 @@ open class AbstractToolbarComboUI : ComponentUI(), PropertyChangeListener { val metrics = c.getFontMetrics(c.font) g.color = if (c.isEnabled) c.getForeground() else UIUtil.getLabelDisabledForeground() - val baseline = c.getBaseline(c.width, c.height) - c.insets.top + val baseline = c.getBaseline(c.width, c.height) val text = c.textCutStrategy.calcShownText(fullText, metrics, textRect.width, g) val strBounds = metrics.getStringBounds(text, g).getBounds() - strBounds.setLocation(max(0, (textRect.centerX - strBounds.centerX).toInt()), baseline) + strBounds.setLocation((textRect.centerX - strBounds.centerX).toInt().coerceAtLeast(textRect.x), baseline) val v = c.getClientProperty(BasicHTML.propertyKey) as? View if (v != null) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarComboButtonUI.kt b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarComboButtonUI.kt index 8be03084b3ce..c979c941ef10 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarComboButtonUI.kt +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarComboButtonUI.kt @@ -64,11 +64,12 @@ internal class ToolbarComboButtonUI: AbstractToolbarComboUI() { assert(!StringUtil.isEmpty(text) || rightIcons.isEmpty()) { "Right icons are only allowed when text is not empty" } val innerRect = SwingUtilities.calculateInnerArea(c, null) - val g2 = g.create(innerRect.x, innerRect.y, innerRect.width, innerRect.height) as Graphics2D - val paintRect = Rectangle(0, 0, innerRect.width, innerRect.height ) + val paintRect = Rectangle(innerRect) JBInsets.removeFrom(paintRect, c.margin) val maxTextWidth = calcMaxTextWidth(combo, paintRect) + val g2 = g.create() as Graphics2D try { + g2.clip(paintRect) GraphicsUtil.setupAAPainting(g2) if (!leftIcons.isEmpty()) { val iconsRect = paintIcons(leftIcons, combo, g2, paintRect) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarSplitButtonUI.kt b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarSplitButtonUI.kt index cef97a3912c3..6fee27cbe331 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarSplitButtonUI.kt +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/ToolbarSplitButtonUI.kt @@ -75,13 +75,13 @@ class ToolbarSplitButtonUI : AbstractToolbarComboUI(), PropertyChangeListener { assert(!StringUtil.isEmpty(text) || rightIcons.isEmpty()) { "Right icons are only allowed when text is not empty" } val innerRect = SwingUtilities.calculateInnerArea(c, null) - val g2 = g.create(innerRect.x, innerRect.y, innerRect.width, innerRect.height) as Graphics2D - val paintRect = Rectangle(0, 0, innerRect.width, innerRect.height ) + val paintRect = Rectangle(innerRect) JBInsets.removeFrom(paintRect, button.leftPartMargin.getTopBottom()) paintRect.cutLeft(c.leftPartMargin.left) - val maxTextWidth = calcMaxTextWidth(button, innerRect) + val g2 = g.create() as Graphics2D try { + g2.clip(paintRect) GraphicsUtil.setupAAPainting(g2) //paint left icons