From 92aa3081f771b109d3e60aa53e714b92103d78e3 Mon Sep 17 00:00:00 2001 From: "Klare, Heiko" Date: Fri, 9 Jan 2026 16:14:07 +0100 Subject: [PATCH] Improve CTabFolder highlight appearance on higher zooms The highlight of CTabFolders implemented in CTabRendering does not properly deal with higher zooms on Windows. The outline of the tabs is drawn with a width of one pixel whereas the highlight has an offset of one point, producing a gap at higher zooms. In addition, the highlight for rounded tabs exceeds the intended bounds. This change adapts the rendering as follows: - When the highlight is drawn rounded at the top, the shape of the outline is taken and adapted to the intended highlight height to draw the highlight. - In all other cases the highlight is drawn as a simple line of according width with an offset of half the line width with respect to its bounds. To compensate for the 1px border that is drawn on top of the highlight when it is placed at the top of a tab, another line of according size is drawn next to the highlight to make its height fit again. --- .../renderers/swt/CTabRendering.java | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java index ddbdc3461058..9e27ea7da5e7 100644 --- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java +++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java @@ -18,6 +18,7 @@ package org.eclipse.e4.ui.workbench.renderers.swt; import java.lang.reflect.Field; +import java.util.Arrays; import java.util.Objects; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IEclipsePreferences; @@ -621,17 +622,41 @@ void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds) { } if (selectedTabHighlightColor != null) { + gc.setForeground(selectedTabHighlightColor); gc.setBackground(selectedTabHighlightColor); - boolean highlightOnTop = drawTabHighlightOnTop; - if (onBottom) { - highlightOnTop = !highlightOnTop; - } int highlightHeight = 2; - int verticalOffset = highlightOnTop ? 0 : bounds.height - (highlightHeight - 1); - int horizontalOffset = itemIndex == 0 || cornerSize == SQUARE_CORNER ? 0 : 1; - int widthAdjustment = cornerSize == SQUARE_CORNER ? 0 : 1; - gc.fillRectangle(bounds.x + horizontalOffset, bounds.y + verticalOffset, bounds.width - widthAdjustment, - highlightHeight); + int originalLineWidth = gc.getLineWidth(); + if (drawTabHighlightOnTop && cornerSize != SQUARE_CORNER) { + // When using round tabs, extract the part of the outline that covers the + // highlight and draw it with adapted height + int[] highlightShape = Arrays.copyOfRange(tabOutlinePoints, 14, tabOutlinePoints.length - 14); + int yEnd = onBottom ? outlineBoundsForOutline.y + outlineBoundsForOutline.height - highlightHeight + 1 + : highlightHeight; + highlightShape[1] = highlightShape[highlightShape.length - 1] = yEnd; + boolean gcAdvanced = gc.getAdvanced(); + gc.setAdvanced(false); + gc.fillPolygon(highlightShape); + gc.setAdvanced(gcAdvanced); + } else { + // When using square tab or drawing the highlight at the bottom, simply draw + // a line + int xStart = tabOutlinePoints[2]; + int xEnd = tabOutlinePoints[tabOutlinePoints.length - 4]; + int yTop = drawTabHighlightOnTop ? tabOutlinePoints[5] : tabOutlinePoints[3]; + if (onBottom == drawTabHighlightOnTop) { + yTop -= highlightHeight; + } + gc.setLineWidth(highlightHeight); + gc.drawLine(xStart, yTop + highlightHeight / 2, xEnd, yTop + highlightHeight / 2); + if (drawTabHighlightOnTop) { + // Compensate for the outline being draw on top of the filled region by + // extending the highlight with an equally wide line next to the filled region + gc.setLineWidth(0); + int yAdditionalLine = onBottom ? yTop : yTop + highlightHeight; + gc.drawLine(xStart, yAdditionalLine, xEnd, yAdditionalLine); + } + } + gc.setLineWidth(originalLineWidth); } if (backgroundPattern != null) {