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
This commit is contained in:
Sergei Tachenov
2025-02-20 18:23:55 +00:00
committed by intellij-monorepo-bot
parent 06e74902d4
commit 44eeff4813
3 changed files with 8 additions and 7 deletions
@@ -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) {
@@ -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)
@@ -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