From 314a04593325b0bdd92159b25012a7c21e969d3e Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Mon, 12 Jan 2026 08:07:38 +0000 Subject: [PATCH 01/26] Version bump(s) for 4.39 stream --- bundles/org.eclipse.ui.themes/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.ui.themes/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.themes/META-INF/MANIFEST.MF index a1a0eafd8698..f9d231a3844e 100644 --- a/bundles/org.eclipse.ui.themes/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.themes/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Plugin.name Bundle-SymbolicName: org.eclipse.ui.themes;singleton:=true -Bundle-Version: 1.2.2900.qualifier +Bundle-Version: 1.2.3000.qualifier Bundle-Vendor: %Plugin.providerName Bundle-Localization: plugin Require-Bundle: org.eclipse.e4.ui.css.swt.theme From c2654d17566ef82ac01783d2c6b7bd15c9fda556 Mon Sep 17 00:00:00 2001 From: Christopher Hermann Date: Fri, 9 Jan 2026 17:47:51 +0100 Subject: [PATCH 02/26] Handle viewer selection color --- .../internal/text/TableOwnerDrawSupport.java | 8 +- .../ColumnViewerSelectionColorListener.java | 199 ++++++++++++++++++ .../jface/viewers/StructuredViewer.java | 1 + .../css/dark/e4-dark_preferencestyle.css | 2 + .../ColumnViewerSelectionColorFactory.java | 67 ++++++ bundles/org.eclipse.ui/plugin.properties | 9 + bundles/org.eclipse.ui/plugin.xml | 66 ++++++ 7 files changed, 350 insertions(+), 2 deletions(-) create mode 100644 bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java create mode 100644 bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java index 7f4e72a346df..a4b1ffd4257e 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java @@ -25,6 +25,8 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; +import org.eclipse.jface.viewers.ColumnViewerSelectionColorListener; + /** * Adds owner draw support for tables. @@ -83,7 +85,7 @@ public void handleEvent(Event event) { measureItem(event); break; case SWT.EraseItem: - event.detail &= ~SWT.FOREGROUND; + event.detail&= ~SWT.FOREGROUND; break; case SWT.PaintItem: performPaint(event); @@ -147,7 +149,9 @@ private void performPaint(Event event) { Color oldForeground= gc.getForeground(); Color oldBackground= gc.getBackground(); - if (!isSelected) { + if (isSelected) { + ColumnViewerSelectionColorListener.drawSelection(event); + } else { Color foreground= item.getForeground(index); gc.setForeground(foreground); diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java new file mode 100644 index 000000000000..e09bc381fffa --- /dev/null +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2024 SAP SE. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.viewers; + +import java.util.Arrays; + +import org.eclipse.jface.resource.ColorRegistry; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Scrollable; + +/** + * EraseItem event listener that provides custom selection coloring for JFace + * viewers. This listener only activates when no custom owner draw label + * provider is registered, ensuring it doesn't conflict with existing custom + * drawing implementations. + *

+ * The listener provides different colors for: + *

+ *

+ * + * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider + * @see org.eclipse.jface.viewers.StyledCellLabelProvider + * @see org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter + * @since 3.39 + */ +public class ColumnViewerSelectionColorListener implements Listener { + + private static final String LISTENER_KEY = "org.eclipse.jface.viewers.selection_color_listener"; //$NON-NLS-1$ + private static final String OWNER_DRAW_LISTENER_KEY = "owner_draw_label_provider_listener"; //$NON-NLS-1$ + + private static final String COLOR_SELECTION_BG_FOCUS = "org.eclipse.jface.SELECTION_BACKGROUND_FOCUSED"; //$NON-NLS-1$ + private static final String COLOR_SELECTION_FG_FOCUS = "org.eclipse.jface.SELECTION_FOREGROUND_FOCUSED"; //$NON-NLS-1$ + private static final String COLOR_SELECTION_BG_NO_FOCUS = "org.eclipse.jface.SELECTION_BACKGROUND_NO_FOCUS"; //$NON-NLS-1$ + private static final String COLOR_SELECTION_FG_NO_FOCUS = "org.eclipse.jface.SELECTION_FOREGROUND_NO_FOCUS"; //$NON-NLS-1$ + + /** + * Registers the selection color listener on the given viewer. + *

+ * This method is idempotent - calling it multiple times on the same viewer has + * no additional effect. + *

+ * + * @param viewer the viewer to which the listener should be added + */ + public static void addListenerToViewer(StructuredViewer viewer) { + if ("gtk".equals(SWT.getPlatform())) { //$NON-NLS-1$ + return; // Skip on Linux + } + + Control control = viewer.getControl(); + if (control.isDisposed() || isListenerRegistered(control)) { + return; // Already registered or disposed + } + + ColumnViewerSelectionColorListener listener = new ColumnViewerSelectionColorListener(); + control.setData(LISTENER_KEY, listener); + control.addListener(SWT.EraseItem, listener); + } + + private static boolean isListenerRegistered(Control control) { + return control.getData(LISTENER_KEY) != null; + } + + @Override + public void handleEvent(Event event) { + if ((event.detail & SWT.SELECTED) == 0) { + return; // Not selected + } + + if (event.widget instanceof Control control && !control.isEnabled()) { + return; // Disabled control + } + + if (hasAdditionalEraseItemListeners(event)) { + return; // Let other listeners handle selection + } + + drawSelection(event); + } + + /** + * Checks if additional EraseItem listeners were registered after this listener + * that are NOT the OwnerDrawListener. This allows user code to override the + * selection coloring by adding their own EraseItem listener, while still + * allowing StyledCellLabelProvider to work (which uses OwnerDrawListener but + * doesn't draw selection). + * + * @param event the erase event + * @return true if other custom listeners are present that should + * handle selection, false otherwise + */ + private boolean hasAdditionalEraseItemListeners(Event event) { + if (!(event.widget instanceof Control control)) { + return false; + } + + Listener[] listeners = control.getListeners(SWT.EraseItem); + Object ownerDrawListener = control.getData(OWNER_DRAW_LISTENER_KEY); + return Arrays.stream(listeners).anyMatch(l -> l != this && l != ownerDrawListener); + } + + /** + * Draws custom selection coloring for the given event. + *

+ * This method provides consistent selection rendering across different viewers + * and owner draw implementations. It handles both focused and unfocused + * selection states using themed colors from the ColorRegistry with appropriate + * fallbacks. + *

+ * + * @param event the erase event containing the widget, GC, and coordinates + * @since 3.32 + */ + public static void drawSelection(Event event) { + if ("gtk".equals(SWT.getPlatform())) { //$NON-NLS-1$ + return; // Skip on Linux + } + + Control control = (Control) event.widget; + GC gc = event.gc; + + Color backgroundColor; + Color foregroundColor; + + if (control.isFocusControl()) { + backgroundColor = getSelectionColor(COLOR_SELECTION_BG_FOCUS, event.display); + foregroundColor = getSelectionColor(COLOR_SELECTION_FG_FOCUS, event.display); + } else { + backgroundColor = getSelectionColor(COLOR_SELECTION_BG_NO_FOCUS, event.display); + foregroundColor = getSelectionColor(COLOR_SELECTION_FG_NO_FOCUS, event.display); + } + + gc.setBackground(backgroundColor); + gc.setForeground(foregroundColor); + + int width = event.width; + if (event.widget instanceof Scrollable scrollable) { + width = scrollable.getClientArea().width; + } + + gc.fillRectangle(0, event.y, width, event.height); + + // Remove SELECTED and BACKGROUND flags to prevent native drawing from + // overwriting our custom colors + event.detail &= ~(SWT.SELECTED | SWT.BACKGROUND); + } + + private static Color getSelectionColor(String key, org.eclipse.swt.graphics.Device device) { + ColorRegistry registry = JFaceResources.getColorRegistry(); + + if (registry.hasValueFor(key)) { + return registry.get(key); + } + + RGB systemColor; + switch (key) { + case COLOR_SELECTION_BG_FOCUS: + systemColor = device.getSystemColor(SWT.COLOR_TITLE_BACKGROUND).getRGB(); + break; + case COLOR_SELECTION_FG_FOCUS: + systemColor = device.getSystemColor(SWT.COLOR_WHITE).getRGB(); + break; + case COLOR_SELECTION_BG_NO_FOCUS: + systemColor = device.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND).getRGB(); + break; + case COLOR_SELECTION_FG_NO_FOCUS: + systemColor = device.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND).getRGB(); + break; + default: + systemColor = device.getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(); + break; + } + + registry.put(key, systemColor); + return registry.get(key); + } + +} diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java index 5b1ab4432d31..08dc398839e3 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java @@ -1210,6 +1210,7 @@ public void widgetDefaultSelected(SelectionEvent e) { }); handler.addPostSelectionListener(widgetSelectedAdapter(this::handlePostSelect)); handler.addOpenListener(StructuredViewer.this::handleOpen); + ColumnViewerSelectionColorListener.addListenerToViewer(this); } /** diff --git a/bundles/org.eclipse.ui.themes/css/dark/e4-dark_preferencestyle.css b/bundles/org.eclipse.ui.themes/css/dark/e4-dark_preferencestyle.css index 6e74b61901a1..8267a89fd83e 100644 --- a/bundles/org.eclipse.ui.themes/css/dark/e4-dark_preferencestyle.css +++ b/bundles/org.eclipse.ui.themes/css/dark/e4-dark_preferencestyle.css @@ -76,4 +76,6 @@ IEclipsePreferences#org-eclipse-ui-workbench:org-eclipse-ui-themes { /* pseudo a 'org.eclipse.ui.editors.rangeIndicatorColor=27,118,153' 'org.eclipse.jface.REVISION_NEWEST_COLOR=75,44,3' 'org.eclipse.jface.REVISION_OLDEST_COLOR=154,113,61' + 'org.eclipse.jface.SELECTION_FOREGROUND_NO_FOCUS=240,240,240' + 'org.eclipse.jface.SELECTION_BACKGROUND_NO_FOCUS=95,95,95' } diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java new file mode 100644 index 000000000000..e45464be95b6 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2024 SAP SE. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.internal.themes; + +import java.util.Hashtable; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.themes.IColorFactory; + +/** + * Color factory for viewer selection colors that adapts to the OS/desktop + * theme. Provides default colors based on system colors for focused and + * unfocused selections. + *

+ * The default colors are based on system title bar colors which automatically + * adapt to light/dark themes and high contrast modes. Themes can override these + * defaults to provide custom styling. + *

+ * + * @since 3.39 + */ +public class ColumnViewerSelectionColorFactory implements IColorFactory, IExecutableExtension { + + private String color = null; + + @Override + public RGB createColor() { + Display display = Display.getDefault(); + + if ("SELECTED_CELL_BACKGROUND".equals(color)) { //$NON-NLS-1$ + return display.getSystemColor(SWT.COLOR_TITLE_BACKGROUND).getRGB(); + + } else if ("SELECTED_CELL_FOREGROUND".equals(color)) { //$NON-NLS-1$ + return display.getSystemColor(SWT.COLOR_WHITE).getRGB(); + + } else if ("SELECTED_CELL_BACKGROUND_NO_FOCUS".equals(color)) { //$NON-NLS-1$ + return display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND).getRGB(); + + } else if ("SELECTED_CELL_FOREGROUND_NO_FOCUS".equals(color)) { //$NON-NLS-1$ + return display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND).getRGB(); + + } else { + return new RGB(0, 0, 0); + } + } + + @Override + public void setInitializationData(IConfigurationElement config, String propertyName, Object data) { + if (data instanceof Hashtable table) { + this.color = (String) table.get("color"); //$NON-NLS-1$ + } + } +} diff --git a/bundles/org.eclipse.ui/plugin.properties b/bundles/org.eclipse.ui/plugin.properties index 27e4672696c8..3fe7bac81114 100644 --- a/bundles/org.eclipse.ui/plugin.properties +++ b/bundles/org.eclipse.ui/plugin.properties @@ -371,6 +371,15 @@ Color.revisionNewestDesc=Background color for the newest revision shown in a tex Color.revisionOldest=Oldest revision background color Color.revisionOldestDesc=Background color for the oldest revision shown in a text editor's ruler. Together with the newest revision background color this defines a gradient used for all revision from newest to oldest. +Color.viewerSelectionBackgroundFocused=Viewer selection background (focused) +Color.viewerSelectionBackgroundFocusedDesc=Background color for selected items in viewers when the control has focus. Defaults to system highlight color. (No effect on Linux) +Color.viewerSelectionForegroundFocused=Viewer selection foreground (focused) +Color.viewerSelectionForegroundFocusedDesc=Foreground color for selected items in viewers when the control has focus. (No effect on Linux) +Color.viewerSelectionBackgroundNoFocus=Viewer selection background (no focus) +Color.viewerSelectionBackgroundNoFocusDesc=Background color for selected items in viewers when the control does not have focus. (No effect on Linux) +Color.viewerSelectionForegroundNoFocus=Viewer selection foreground (no focus) +Color.viewerSelectionForegroundNoFocusDesc=Foreground color for selected items in viewers when the control does not have focus. (No effect on Linux) + Color.showKeysForeground=Keys foreground color Color.showKeysForegroundDesc=Color for foreground of the control to visualize pressed keys Color.showKeysBackground=Keys background color diff --git a/bundles/org.eclipse.ui/plugin.xml b/bundles/org.eclipse.ui/plugin.xml index 127f5dc07ef7..ccddfd5116ed 100644 --- a/bundles/org.eclipse.ui/plugin.xml +++ b/bundles/org.eclipse.ui/plugin.xml @@ -1741,6 +1741,72 @@ + + + + + + + + %Color.viewerSelectionBackgroundFocusedDesc + + + + + + + + + %Color.viewerSelectionForegroundFocusedDesc + + + + + + + + + %Color.viewerSelectionBackgroundNoFocusDesc + + + + + + + + + %Color.viewerSelectionForegroundNoFocusDesc + + + From abe68b142c58c3a5b13212ceab623b7f93fe279e Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Wed, 25 Feb 2026 16:06:04 +0100 Subject: [PATCH 03/26] Refactor a bit, make the code more compact --- .../ColumnViewerSelectionColorListener.java | 57 ++++++------------- .../ColumnViewerSelectionColorFactory.java | 26 ++++----- 2 files changed, 27 insertions(+), 56 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index e09bc381fffa..1179761e1f07 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -64,10 +64,6 @@ public class ColumnViewerSelectionColorListener implements Listener { * @param viewer the viewer to which the listener should be added */ public static void addListenerToViewer(StructuredViewer viewer) { - if ("gtk".equals(SWT.getPlatform())) { //$NON-NLS-1$ - return; // Skip on Linux - } - Control control = viewer.getControl(); if (control.isDisposed() || isListenerRegistered(control)) { return; // Already registered or disposed @@ -133,23 +129,13 @@ private boolean hasAdditionalEraseItemListeners(Event event) { * @since 3.32 */ public static void drawSelection(Event event) { - if ("gtk".equals(SWT.getPlatform())) { //$NON-NLS-1$ - return; // Skip on Linux - } - Control control = (Control) event.widget; GC gc = event.gc; - Color backgroundColor; - Color foregroundColor; - - if (control.isFocusControl()) { - backgroundColor = getSelectionColor(COLOR_SELECTION_BG_FOCUS, event.display); - foregroundColor = getSelectionColor(COLOR_SELECTION_FG_FOCUS, event.display); - } else { - backgroundColor = getSelectionColor(COLOR_SELECTION_BG_NO_FOCUS, event.display); - foregroundColor = getSelectionColor(COLOR_SELECTION_FG_NO_FOCUS, event.display); - } + final Color backgroundColor = getSelectionColor( + control.isFocusControl() ? COLOR_SELECTION_BG_FOCUS : COLOR_SELECTION_BG_NO_FOCUS, event.display); + final Color foregroundColor = getSelectionColor( + control.isFocusControl() ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS, event.display); gc.setBackground(backgroundColor); gc.setForeground(foregroundColor); @@ -169,31 +155,22 @@ public static void drawSelection(Event event) { private static Color getSelectionColor(String key, org.eclipse.swt.graphics.Device device) { ColorRegistry registry = JFaceResources.getColorRegistry(); - if (registry.hasValueFor(key)) { - return registry.get(key); - } - - RGB systemColor; - switch (key) { - case COLOR_SELECTION_BG_FOCUS: - systemColor = device.getSystemColor(SWT.COLOR_TITLE_BACKGROUND).getRGB(); - break; - case COLOR_SELECTION_FG_FOCUS: - systemColor = device.getSystemColor(SWT.COLOR_WHITE).getRGB(); - break; - case COLOR_SELECTION_BG_NO_FOCUS: - systemColor = device.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND).getRGB(); - break; - case COLOR_SELECTION_FG_NO_FOCUS: - systemColor = device.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND).getRGB(); - break; - default: - systemColor = device.getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(); - break; + if (!registry.hasValueFor(key)) { + RGB systemColor = device.getSystemColor(idToColor(key)).getRGB(); + registry.put(key, systemColor); } - registry.put(key, systemColor); return registry.get(key); } + private static int idToColor(String id) { + return switch (id) { + case COLOR_SELECTION_BG_FOCUS -> SWT.COLOR_TITLE_BACKGROUND; + case COLOR_SELECTION_FG_FOCUS -> SWT.COLOR_WHITE; + case COLOR_SELECTION_BG_NO_FOCUS -> SWT.COLOR_TITLE_INACTIVE_BACKGROUND; + case COLOR_SELECTION_FG_NO_FOCUS -> SWT.COLOR_TITLE_INACTIVE_FOREGROUND; + default -> SWT.COLOR_LIST_SELECTION; + }; + } + } diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java index e45464be95b6..5b9875d0172f 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java @@ -39,23 +39,17 @@ public class ColumnViewerSelectionColorFactory implements IColorFactory, IExecut @Override public RGB createColor() { - Display display = Display.getDefault(); - - if ("SELECTED_CELL_BACKGROUND".equals(color)) { //$NON-NLS-1$ - return display.getSystemColor(SWT.COLOR_TITLE_BACKGROUND).getRGB(); - - } else if ("SELECTED_CELL_FOREGROUND".equals(color)) { //$NON-NLS-1$ - return display.getSystemColor(SWT.COLOR_WHITE).getRGB(); - - } else if ("SELECTED_CELL_BACKGROUND_NO_FOCUS".equals(color)) { //$NON-NLS-1$ - return display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND).getRGB(); - - } else if ("SELECTED_CELL_FOREGROUND_NO_FOCUS".equals(color)) { //$NON-NLS-1$ - return display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND).getRGB(); + return Display.getDefault().getSystemColor(idToColor(color)).getRGB(); + } - } else { - return new RGB(0, 0, 0); - } + private int idToColor(String id) { + return switch (id) { + case "SELECTED_CELL_BACKGROUND" -> SWT.COLOR_TITLE_BACKGROUND; //$NON-NLS-1$ + case "SELECTED_CELL_FOREGROUND" -> SWT.COLOR_WHITE; //$NON-NLS-1$ + case "SELECTED_CELL_BACKGROUND_NO_FOCUS" -> SWT.COLOR_TITLE_INACTIVE_BACKGROUND; //$NON-NLS-1$ + case "SELECTED_CELL_FOREGROUND_NO_FOCUS" -> SWT.COLOR_TITLE_INACTIVE_FOREGROUND; //$NON-NLS-1$ + default -> SWT.COLOR_BLACK; + }; } @Override From 339d07c59a256f2dea5a399e22d416be5d55a691 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Wed, 25 Feb 2026 16:07:34 +0100 Subject: [PATCH 04/26] Fix hasAdditionalEraseItemListeners: let it skip previous listeners --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 1179761e1f07..881acd1d3a90 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -113,7 +113,9 @@ private boolean hasAdditionalEraseItemListeners(Event event) { Listener[] listeners = control.getListeners(SWT.EraseItem); Object ownerDrawListener = control.getData(OWNER_DRAW_LISTENER_KEY); - return Arrays.stream(listeners).anyMatch(l -> l != this && l != ownerDrawListener); + return Arrays.stream(listeners).dropWhile(l -> l != this) // ignore listeners before "this" + .dropWhile(l -> l == this) // also ignore "this" + .anyMatch(l -> l != ownerDrawListener); } /** From 27abb7c51b89f1029fb6933f9aa4ff33648468c0 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Wed, 25 Feb 2026 16:43:52 +0100 Subject: [PATCH 05/26] Fill only part of the rectangle to help debugging --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 881acd1d3a90..4834cd2c04a3 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -147,7 +147,7 @@ public static void drawSelection(Event event) { width = scrollable.getClientArea().width; } - gc.fillRectangle(0, event.y, width, event.height); + gc.fillRectangle(15, event.y, width, event.height); // Remove SELECTED and BACKGROUND flags to prevent native drawing from // overwriting our custom colors From 9b24f711e73f77d92590c0f33dc0afa38ad7a24e Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Thu, 26 Feb 2026 13:23:30 +0100 Subject: [PATCH 06/26] Repaint the image manually (fix for Linux) --- .../ColumnViewerSelectionColorListener.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 4834cd2c04a3..01c8012de8ee 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -20,11 +20,14 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Scrollable; +import org.eclipse.swt.widgets.TableItem; /** * EraseItem event listener that provides custom selection coloring for JFace @@ -152,6 +155,22 @@ public static void drawSelection(Event event) { // Remove SELECTED and BACKGROUND flags to prevent native drawing from // overwriting our custom colors event.detail &= ~(SWT.SELECTED | SWT.BACKGROUND); + + // GTK paints over the image so we need to redraw explicitly + if (!(event.item instanceof TableItem item)) + return; + + int index = event.index; + Image image = item.getImage(index); + + if (image == null) + return; + + Rectangle imageBounds = item.getImageBounds(index); + Rectangle bounds = image.getBounds(); + int x = imageBounds.x + Math.max(0, (imageBounds.width - bounds.width) / 2); + int y = imageBounds.y + Math.max(0, (imageBounds.height - bounds.height) / 2); + gc.drawImage(image, x, y); } private static Color getSelectionColor(String key, org.eclipse.swt.graphics.Device device) { From d688d342b501876886de89b9de2dcaab19b5f427 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Thu, 26 Feb 2026 13:24:04 +0100 Subject: [PATCH 07/26] Make constructor private --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 01c8012de8ee..ceac09ba4671 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -57,6 +57,13 @@ public class ColumnViewerSelectionColorListener implements Listener { private static final String COLOR_SELECTION_BG_NO_FOCUS = "org.eclipse.jface.SELECTION_BACKGROUND_NO_FOCUS"; //$NON-NLS-1$ private static final String COLOR_SELECTION_FG_NO_FOCUS = "org.eclipse.jface.SELECTION_FOREGROUND_NO_FOCUS"; //$NON-NLS-1$ + /** + * This class shouldn't be instantiated directly. Attach this listener to a + * viewer via {@link #addListenerToViewer(StructuredViewer)} instead. + */ + private ColumnViewerSelectionColorListener() { + } + /** * Registers the selection color listener on the given viewer. *

From bc866ce15048667fd7bcb05895decb103088dbaa Mon Sep 17 00:00:00 2001 From: Christopher Hermann Date: Wed, 12 Feb 2025 10:34:14 +0100 Subject: [PATCH 08/26] Draw completion proposals always as focused When opening the completion proposals via the keyboard, the focus will stay in the editor to be able to accept further user input. This is causing the completion proposal to be drawn in non focus colors. This colors can lead to UX problems, especially in dark theme. With this fix, the completion proposals are always drawn in focused colors. Fixes #1688 --- .../internal/text/TableOwnerDrawSupport.java | 2 +- .../CompletionProposalDrawSupport.java | 63 +++++++++++++++++++ .../CompletionProposalPopup2.java | 3 +- .../CompletionProposalPopup.java | 3 +- 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java index a4b1ffd4257e..7e7ffe909c0d 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java @@ -72,7 +72,7 @@ private static StyleRange[] getStyledRanges(TableItem item, int column) { return (StyleRange[])item.getData(STYLED_RANGES_KEY + column); } - private TableOwnerDrawSupport(Table table) { + public TableOwnerDrawSupport(Table table) { int orientation= table.getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT); fSharedLayout= new TextLayout(table.getDisplay()); fSharedLayout.setOrientation(orientation); diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java new file mode 100644 index 000000000000..d6fd283cae72 --- /dev/null +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.jface.internal.text.contentassist; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; + +import org.eclipse.jface.internal.text.TableOwnerDrawSupport; + +/** + * Provides custom drawing support for completion proposals. This class ensures that completion + * proposals are always rendered with a focused appearance. + * + *

+ * This drawing behavior addresses the particular situation where the code completion is triggered + * via keyboard shortcut, leaving the editor focused. In such cases, without this custom drawing + * support, the completion proposal would appear unfocused, leading to a suboptimal coloring. + *

+ */ +public class CompletionProposalDrawSupport implements Listener { + + private final TableOwnerDrawSupport fTableOwnerDrawSupport; + + private CompletionProposalDrawSupport(Table table) { + fTableOwnerDrawSupport= new TableOwnerDrawSupport(table); + } + + public static void install(Table table) { + CompletionProposalDrawSupport listener= new CompletionProposalDrawSupport(table); + table.addListener(SWT.Dispose, listener); + table.addListener(SWT.MeasureItem, listener); + table.addListener(SWT.EraseItem, listener); + table.addListener(SWT.PaintItem, listener); + } + + @Override + public void handleEvent(Event event) { + if (event.widget instanceof Control control && !control.isFocusControl() && (event.type == SWT.EraseItem || event.type == SWT.PaintItem) && event.gc != null) { + Color background= event.widget.getDisplay().getSystemColor(SWT.COLOR_TITLE_BACKGROUND); + Color foreground= event.widget.getDisplay().getSystemColor(SWT.COLOR_WHITE); + event.gc.setBackground(background); + event.gc.setForeground(foreground); + } + + fTableOwnerDrawSupport.handleEvent(event); + } + +} diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java index d4450c2eacce..35306f2d4303 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java @@ -40,6 +40,7 @@ import org.eclipse.swt.widgets.TableItem; import org.eclipse.jface.internal.text.TableOwnerDrawSupport; +import org.eclipse.jface.internal.text.contentassist.CompletionProposalDrawSupport; import org.eclipse.jface.preference.JFacePreferences; import org.eclipse.jface.resource.ColorRegistry; import org.eclipse.jface.resource.JFaceColors; @@ -274,7 +275,7 @@ private void createProposalSelector() { fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled(); if (fIsColoredLabelsSupportEnabled) { - TableOwnerDrawSupport.install(fProposalTable); + CompletionProposalDrawSupport.install(fProposalTable); } fProposalTable.setLocation(0, 0); diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java index 3333fe01085e..661228369bd9 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java @@ -79,6 +79,7 @@ import org.eclipse.jface.contentassist.IContentAssistSubjectControl; import org.eclipse.jface.internal.text.InformationControlReplacer; import org.eclipse.jface.internal.text.TableOwnerDrawSupport; +import org.eclipse.jface.internal.text.contentassist.CompletionProposalDrawSupport; import org.eclipse.jface.preference.JFacePreferences; import org.eclipse.jface.resource.JFaceColors; import org.eclipse.jface.resource.JFaceResources; @@ -628,7 +629,7 @@ void createProposalSelector() { fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled(); if (fIsColoredLabelsSupportEnabled) { - TableOwnerDrawSupport.install(fProposalTable); + CompletionProposalDrawSupport.install(fProposalTable); } fProposalTable.setLocation(0, 0); From 095c9869f9b037f1b4e91df90cdc78bd87163699 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 09:31:17 +0100 Subject: [PATCH 09/26] Undo some changes in TableOwnerDrawSupport They will be handled via the CompletionProposalDrawSupport --- .../jface/internal/text/TableOwnerDrawSupport.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java index 7e7ffe909c0d..343f17864e81 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java @@ -25,8 +25,6 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; -import org.eclipse.jface.viewers.ColumnViewerSelectionColorListener; - /** * Adds owner draw support for tables. @@ -85,7 +83,7 @@ public void handleEvent(Event event) { measureItem(event); break; case SWT.EraseItem: - event.detail&= ~SWT.FOREGROUND; + event.detail &= ~SWT.FOREGROUND; break; case SWT.PaintItem: performPaint(event); @@ -149,9 +147,7 @@ private void performPaint(Event event) { Color oldForeground= gc.getForeground(); Color oldBackground= gc.getBackground(); - if (isSelected) { - ColumnViewerSelectionColorListener.drawSelection(event); - } else { + if (!isSelected) { Color foreground= item.getForeground(index); gc.setForeground(foreground); From ada2dc8ea302973b09efc06bae134747d525aee2 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 14:47:39 +0100 Subject: [PATCH 10/26] Move stuff around --- .../CompletionProposalDrawSupport.java | 36 ++- .../ColumnViewerSelectionColorListener.java | 224 +++++++++++------- 2 files changed, 166 insertions(+), 94 deletions(-) diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java index d6fd283cae72..de11a5792cd3 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java @@ -18,9 +18,11 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.Table; import org.eclipse.jface.internal.text.TableOwnerDrawSupport; +import org.eclipse.jface.viewers.ColumnViewerSelectionColorListener; /** * Provides custom drawing support for completion proposals. This class ensures that completion @@ -50,14 +52,36 @@ public static void install(Table table) { @Override public void handleEvent(Event event) { - if (event.widget instanceof Control control && !control.isFocusControl() && (event.type == SWT.EraseItem || event.type == SWT.PaintItem) && event.gc != null) { - Color background= event.widget.getDisplay().getSystemColor(SWT.COLOR_TITLE_BACKGROUND); - Color foreground= event.widget.getDisplay().getSystemColor(SWT.COLOR_WHITE); - event.gc.setBackground(background); - event.gc.setForeground(foreground); + + if (event.widget instanceof Control && event.gc != null) { + + boolean isSelected= (event.detail & SWT.SELECTED) != 0; + + if (event.type == SWT.EraseItem && isSelected) { + + final Color backgroundColor= ColumnViewerSelectionColorListener.getBackgroundColor(isSelected, event.display); + event.gc.setBackground(backgroundColor); + + final int width= (event.widget instanceof Scrollable s) ? s.getClientArea().width : event.width; + event.gc.fillRectangle(0, event.y, width, event.height); + + // Prevent native selection drawing + // Do NOT clear SWT.BACKGROUND here unless you really want to suppress SWT + // background painting. + // (You *can* clear SWT.BACKGROUND if you see it overwriting your fill on a + // platform, + // but try without first.) + event.detail&= ~SWT.SELECTED; + + } else if (event.type == SWT.PaintItem) { + + final Color foregroundColor= ColumnViewerSelectionColorListener.getForegroundColor(isSelected, event.display); + event.gc.setForeground(foregroundColor); + +// event.detail&= ~SWT.FOREGROUND; + } } fTableOwnerDrawSupport.handleEvent(event); } - } diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index ceac09ba4671..693cf21fac89 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -19,11 +19,13 @@ import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Scrollable; @@ -49,6 +51,23 @@ */ public class ColumnViewerSelectionColorListener implements Listener { + /** + * Contains the values of the color definitions from the + * plugin.xml.
+ * + * @implNote If some value doesn't match the exact name (String) inside the + * plugin.xml or if some string from the xml is not + * present here then + * {@link ColumnViewerSelectionColorFactory#getSystemColorForId(ColorId)} + * will not return what you expect. + * @since 3.5 + * + */ +// private static enum ColorId { +// SELECTED_CELL_BACKGROUND, SELECTED_CELL_FOREGROUND, SELECTED_CELL_BACKGROUND_NO_FOCUS, +// SELECTED_CELL_FOREGROUND_NO_FOCUS +// } + private static final String LISTENER_KEY = "org.eclipse.jface.viewers.selection_color_listener"; //$NON-NLS-1$ private static final String OWNER_DRAW_LISTENER_KEY = "owner_draw_label_provider_listener"; //$NON-NLS-1$ @@ -64,47 +83,10 @@ public class ColumnViewerSelectionColorListener implements Listener { private ColumnViewerSelectionColorListener() { } - /** - * Registers the selection color listener on the given viewer. - *

- * This method is idempotent - calling it multiple times on the same viewer has - * no additional effect. - *

- * - * @param viewer the viewer to which the listener should be added - */ - public static void addListenerToViewer(StructuredViewer viewer) { - Control control = viewer.getControl(); - if (control.isDisposed() || isListenerRegistered(control)) { - return; // Already registered or disposed - } - - ColumnViewerSelectionColorListener listener = new ColumnViewerSelectionColorListener(); - control.setData(LISTENER_KEY, listener); - control.addListener(SWT.EraseItem, listener); - } - private static boolean isListenerRegistered(Control control) { return control.getData(LISTENER_KEY) != null; } - @Override - public void handleEvent(Event event) { - if ((event.detail & SWT.SELECTED) == 0) { - return; // Not selected - } - - if (event.widget instanceof Control control && !control.isEnabled()) { - return; // Disabled control - } - - if (hasAdditionalEraseItemListeners(event)) { - return; // Let other listeners handle selection - } - - drawSelection(event); - } - /** * Checks if additional EraseItem listeners were registered after this listener * that are NOT the OwnerDrawListener. This allows user code to override the @@ -128,69 +110,39 @@ private boolean hasAdditionalEraseItemListeners(Event event) { .anyMatch(l -> l != ownerDrawListener); } - /** - * Draws custom selection coloring for the given event. - *

- * This method provides consistent selection rendering across different viewers - * and owner draw implementations. It handles both focused and unfocused - * selection states using themed colors from the ColorRegistry with appropriate - * fallbacks. - *

- * - * @param event the erase event containing the widget, GC, and coordinates - * @since 3.32 - */ - public static void drawSelection(Event event) { - Control control = (Control) event.widget; - GC gc = event.gc; - - final Color backgroundColor = getSelectionColor( - control.isFocusControl() ? COLOR_SELECTION_BG_FOCUS : COLOR_SELECTION_BG_NO_FOCUS, event.display); - final Color foregroundColor = getSelectionColor( - control.isFocusControl() ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS, event.display); - - gc.setBackground(backgroundColor); - gc.setForeground(foregroundColor); - - int width = event.width; - if (event.widget instanceof Scrollable scrollable) { - width = scrollable.getClientArea().width; - } - - gc.fillRectangle(15, event.y, width, event.height); - - // Remove SELECTED and BACKGROUND flags to prevent native drawing from - // overwriting our custom colors - event.detail &= ~(SWT.SELECTED | SWT.BACKGROUND); - - // GTK paints over the image so we need to redraw explicitly - if (!(event.item instanceof TableItem item)) - return; - - int index = event.index; - Image image = item.getImage(index); - - if (image == null) - return; + public static Color getForegroundColor(boolean focused, Device device) { + return getSelectionColor(focused ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS, device); + } - Rectangle imageBounds = item.getImageBounds(index); - Rectangle bounds = image.getBounds(); - int x = imageBounds.x + Math.max(0, (imageBounds.width - bounds.width) / 2); - int y = imageBounds.y + Math.max(0, (imageBounds.height - bounds.height) / 2); - gc.drawImage(image, x, y); + public static Color getBackgroundColor(boolean focused, Device device) { + return getSelectionColor(focused ? COLOR_SELECTION_BG_FOCUS : COLOR_SELECTION_BG_NO_FOCUS, device); } - private static Color getSelectionColor(String key, org.eclipse.swt.graphics.Device device) { + public static Color getSelectionColor(String key, Device device) { ColorRegistry registry = JFaceResources.getColorRegistry(); if (!registry.hasValueFor(key)) { + RGB systemColor = device.getSystemColor(idToColor(key)).getRGB(); +// RGB systemColor2 = getSystemColorForId(device, key); +// +// if (!systemColor.equals(systemColor2)) +// throw new RuntimeException("Something's fishy"); //$NON-NLS-1$ + registry.put(key, systemColor); } return registry.get(key); } + public static RGB getSystemColorForId(String id) { + return getSystemColorForId(Display.getDefault(), id); + } + + private static RGB getSystemColorForId(Device device, String id) { + return device.getSystemColor(idToColor(id)).getRGB(); + } + private static int idToColor(String id) { return switch (id) { case COLOR_SELECTION_BG_FOCUS -> SWT.COLOR_TITLE_BACKGROUND; @@ -201,4 +153,100 @@ private static int idToColor(String id) { }; } -} + public static void addListenerToViewer(StructuredViewer viewer) { + Control control = viewer.getControl(); + if (control.isDisposed() || isListenerRegistered(control)) { + return; + } + + ColumnViewerSelectionColorListener listener = new ColumnViewerSelectionColorListener(); + control.setData(LISTENER_KEY, listener); + + // We need both phases + control.addListener(SWT.EraseItem, listener); + control.addListener(SWT.PaintItem, listener); + } + + @Override + public void handleEvent(Event event) { + if (event.type == SWT.EraseItem) { + handleEraseItem(event); + } else if (event.type == SWT.PaintItem) { + handlePaintItem(event); + } + } + + private void handleEraseItem(Event event) { + if ((event.detail & SWT.SELECTED) == 0) + return; + if (event.widget instanceof Control c && !c.isEnabled()) + return; + + // Your "other listeners" logic still applies, but note: + // TableOwnerDrawSupport is a different listener and will still run. + if (hasAdditionalEraseItemListeners(event)) + return; + + Control control = (Control) event.widget; + GC gc = event.gc; + + Color bg = getBackgroundColor(control.isFocusControl(), event.display); + Color fg = getForegroundColor(control.isFocusControl(), event.display); + + gc.setBackground(bg); + gc.setForeground(fg); + + // (A) full-row + int rowWidth = (event.widget instanceof Scrollable s) ? s.getClientArea().width : event.width; + gc.fillRectangle(0, event.y, rowWidth, event.height); + + // Prevent native selection drawing + // Do NOT clear SWT.BACKGROUND here unless you really want to suppress SWT + // background painting. + // (You *can* clear SWT.BACKGROUND if you see it overwriting your fill on a + // platform, + // but try without first.) + event.detail &= ~SWT.SELECTED; + + } + + public static void handlePaintItem(Event event) { + // We must not rely on event.detail & SWT.SELECTED because we cleared it above. + // Instead compute selection state from the widget. + if (!(event.widget instanceof org.eclipse.swt.widgets.Table table)) + return; + if (!(event.item instanceof TableItem item)) + return; + + boolean isSelected = table.isSelected(table.indexOf(item)); + if (!isSelected) + return; // only adjust painting for selected rows, otherwise leave default owner draw + + GC gc = event.gc; + + // Set the foreground color for selected text/icon painting, if needed + Color fg = getSelectionColor(table.isFocusControl() ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS, + event.display); + gc.setForeground(fg); + + // Paint the image explicitly (like TableOwnerDrawSupport does) + int column = event.index; + Image image = item.getImage(column); + if (image != null) { + Rectangle imageBounds = item.getImageBounds(column); + Rectangle src = image.getBounds(); + + int x = imageBounds.x + Math.max(0, (imageBounds.width - src.width) / 2); + int y = imageBounds.y + Math.max(0, (imageBounds.height - src.height) / 2); + + gc.drawImage(image, x, y); + } + + // Text painting: + // If TableOwnerDrawSupport is installed, it will paint the text itself. + // If you find text color is wrong on selected rows, you have two choices: + // 1) Adjust TableOwnerDrawSupport to respect gc foreground, or + // 2) Paint the text yourself here (requires computing text bounds and applying + // styles). + } +} \ No newline at end of file From b921c1a39e51ead8ad699fcd29424b9dc01f5169 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 19:33:23 +0100 Subject: [PATCH 11/26] Use the id the match the colors in the color factory No need for parameters --- .../CompletionProposalDrawSupport.java | 4 +- .../ColumnViewerSelectionColorListener.java | 43 +++++-------------- .../ColumnViewerSelectionColorFactory.java | 20 ++------- bundles/org.eclipse.ui/plugin.xml | 16 ------- 4 files changed, 16 insertions(+), 67 deletions(-) diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java index de11a5792cd3..dc8a9ba575d8 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java @@ -59,7 +59,7 @@ public void handleEvent(Event event) { if (event.type == SWT.EraseItem && isSelected) { - final Color backgroundColor= ColumnViewerSelectionColorListener.getBackgroundColor(isSelected, event.display); + final Color backgroundColor= ColumnViewerSelectionColorListener.getBackgroundColor(event.display, isSelected); event.gc.setBackground(backgroundColor); final int width= (event.widget instanceof Scrollable s) ? s.getClientArea().width : event.width; @@ -75,7 +75,7 @@ public void handleEvent(Event event) { } else if (event.type == SWT.PaintItem) { - final Color foregroundColor= ColumnViewerSelectionColorListener.getForegroundColor(isSelected, event.display); + final Color foregroundColor= ColumnViewerSelectionColorListener.getForegroundColor(event.display, isSelected); event.gc.setForeground(foregroundColor); // event.detail&= ~SWT.FOREGROUND; diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 693cf21fac89..1790df0de6fc 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -51,23 +51,6 @@ */ public class ColumnViewerSelectionColorListener implements Listener { - /** - * Contains the values of the color definitions from the - * plugin.xml.
- * - * @implNote If some value doesn't match the exact name (String) inside the - * plugin.xml or if some string from the xml is not - * present here then - * {@link ColumnViewerSelectionColorFactory#getSystemColorForId(ColorId)} - * will not return what you expect. - * @since 3.5 - * - */ -// private static enum ColorId { -// SELECTED_CELL_BACKGROUND, SELECTED_CELL_FOREGROUND, SELECTED_CELL_BACKGROUND_NO_FOCUS, -// SELECTED_CELL_FOREGROUND_NO_FOCUS -// } - private static final String LISTENER_KEY = "org.eclipse.jface.viewers.selection_color_listener"; //$NON-NLS-1$ private static final String OWNER_DRAW_LISTENER_KEY = "owner_draw_label_provider_listener"; //$NON-NLS-1$ @@ -110,25 +93,19 @@ private boolean hasAdditionalEraseItemListeners(Event event) { .anyMatch(l -> l != ownerDrawListener); } - public static Color getForegroundColor(boolean focused, Device device) { - return getSelectionColor(focused ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS, device); + public static Color getForegroundColor(Device device, boolean focused) { + return getSelectionColor(device, focused ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS); } - public static Color getBackgroundColor(boolean focused, Device device) { - return getSelectionColor(focused ? COLOR_SELECTION_BG_FOCUS : COLOR_SELECTION_BG_NO_FOCUS, device); + public static Color getBackgroundColor(Device device, boolean focused) { + return getSelectionColor(device, focused ? COLOR_SELECTION_BG_FOCUS : COLOR_SELECTION_BG_NO_FOCUS); } - public static Color getSelectionColor(String key, Device device) { + private static Color getSelectionColor(Device device, String key) { ColorRegistry registry = JFaceResources.getColorRegistry(); if (!registry.hasValueFor(key)) { - RGB systemColor = device.getSystemColor(idToColor(key)).getRGB(); -// RGB systemColor2 = getSystemColorForId(device, key); -// -// if (!systemColor.equals(systemColor2)) -// throw new RuntimeException("Something's fishy"); //$NON-NLS-1$ - registry.put(key, systemColor); } @@ -190,8 +167,8 @@ private void handleEraseItem(Event event) { Control control = (Control) event.widget; GC gc = event.gc; - Color bg = getBackgroundColor(control.isFocusControl(), event.display); - Color fg = getForegroundColor(control.isFocusControl(), event.display); + Color bg = getBackgroundColor(event.display, control.isFocusControl()); + Color fg = getForegroundColor(event.display, control.isFocusControl()); gc.setBackground(bg); gc.setForeground(fg); @@ -210,7 +187,7 @@ private void handleEraseItem(Event event) { } - public static void handlePaintItem(Event event) { + private void handlePaintItem(Event event) { // We must not rely on event.detail & SWT.SELECTED because we cleared it above. // Instead compute selection state from the widget. if (!(event.widget instanceof org.eclipse.swt.widgets.Table table)) @@ -225,8 +202,8 @@ public static void handlePaintItem(Event event) { GC gc = event.gc; // Set the foreground color for selected text/icon painting, if needed - Color fg = getSelectionColor(table.isFocusControl() ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS, - event.display); + Color fg = getSelectionColor(event.display, + table.isFocusControl() ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS); gc.setForeground(fg); // Paint the image explicitly (like TableOwnerDrawSupport does) diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java index 5b9875d0172f..f987cf7eafab 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/themes/ColumnViewerSelectionColorFactory.java @@ -13,12 +13,10 @@ *******************************************************************************/ package org.eclipse.ui.internal.themes; -import java.util.Hashtable; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; -import org.eclipse.swt.SWT; +import org.eclipse.jface.viewers.ColumnViewerSelectionColorListener; import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; import org.eclipse.ui.themes.IColorFactory; /** @@ -39,23 +37,13 @@ public class ColumnViewerSelectionColorFactory implements IColorFactory, IExecut @Override public RGB createColor() { - return Display.getDefault().getSystemColor(idToColor(color)).getRGB(); - } - - private int idToColor(String id) { - return switch (id) { - case "SELECTED_CELL_BACKGROUND" -> SWT.COLOR_TITLE_BACKGROUND; //$NON-NLS-1$ - case "SELECTED_CELL_FOREGROUND" -> SWT.COLOR_WHITE; //$NON-NLS-1$ - case "SELECTED_CELL_BACKGROUND_NO_FOCUS" -> SWT.COLOR_TITLE_INACTIVE_BACKGROUND; //$NON-NLS-1$ - case "SELECTED_CELL_FOREGROUND_NO_FOCUS" -> SWT.COLOR_TITLE_INACTIVE_FOREGROUND; //$NON-NLS-1$ - default -> SWT.COLOR_BLACK; - }; + return ColumnViewerSelectionColorListener.getSystemColorForId(color); } @Override public void setInitializationData(IConfigurationElement config, String propertyName, Object data) { - if (data instanceof Hashtable table) { - this.color = (String) table.get("color"); //$NON-NLS-1$ + if ("colorDefinition".equals(config.getName())) { //$NON-NLS-1$ + this.color = config.getAttribute("id"); //$NON-NLS-1$ } } } diff --git a/bundles/org.eclipse.ui/plugin.xml b/bundles/org.eclipse.ui/plugin.xml index ccddfd5116ed..6911af10c291 100644 --- a/bundles/org.eclipse.ui/plugin.xml +++ b/bundles/org.eclipse.ui/plugin.xml @@ -1749,10 +1749,6 @@ - - %Color.viewerSelectionBackgroundFocusedDesc @@ -1765,10 +1761,6 @@ - - %Color.viewerSelectionForegroundFocusedDesc @@ -1781,10 +1773,6 @@ - - %Color.viewerSelectionBackgroundNoFocusDesc @@ -1797,10 +1785,6 @@ - - %Color.viewerSelectionForegroundNoFocusDesc From 1ca6ba68736b10f8dfd0474313cac0f58ae6c1c2 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 19:58:13 +0100 Subject: [PATCH 12/26] Adapt some comments and remove FQN (use import) --- .../CompletionProposalDrawSupport.java | 15 +++++++-------- .../ColumnViewerSelectionColorListener.java | 13 ++++--------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java index dc8a9ba575d8..91bc9f500df0 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java @@ -36,6 +36,9 @@ */ public class CompletionProposalDrawSupport implements Listener { + /** + * Delegate + */ private final TableOwnerDrawSupport fTableOwnerDrawSupport; private CompletionProposalDrawSupport(Table table) { @@ -44,6 +47,10 @@ private CompletionProposalDrawSupport(Table table) { public static void install(Table table) { CompletionProposalDrawSupport listener= new CompletionProposalDrawSupport(table); + + // Since this listener delegates to TableOwnerDrawSupport right after doing + // its own stuff, we need to make sure to listen for all kind of events so + // that the delegation happens even after a No-Op. table.addListener(SWT.Dispose, listener); table.addListener(SWT.MeasureItem, listener); table.addListener(SWT.EraseItem, listener); @@ -66,19 +73,11 @@ public void handleEvent(Event event) { event.gc.fillRectangle(0, event.y, width, event.height); // Prevent native selection drawing - // Do NOT clear SWT.BACKGROUND here unless you really want to suppress SWT - // background painting. - // (You *can* clear SWT.BACKGROUND if you see it overwriting your fill on a - // platform, - // but try without first.) event.detail&= ~SWT.SELECTED; } else if (event.type == SWT.PaintItem) { - final Color foregroundColor= ColumnViewerSelectionColorListener.getForegroundColor(event.display, isSelected); event.gc.setForeground(foregroundColor); - -// event.detail&= ~SWT.FOREGROUND; } } diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 1790df0de6fc..3bc7cbc8019e 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -29,6 +29,7 @@ import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Scrollable; +import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; /** @@ -159,8 +160,8 @@ private void handleEraseItem(Event event) { if (event.widget instanceof Control c && !c.isEnabled()) return; - // Your "other listeners" logic still applies, but note: - // TableOwnerDrawSupport is a different listener and will still run. + // No need to process if there are more processors (other than + // TableOwnerDrawSupport) after this one. if (hasAdditionalEraseItemListeners(event)) return; @@ -173,16 +174,10 @@ private void handleEraseItem(Event event) { gc.setBackground(bg); gc.setForeground(fg); - // (A) full-row int rowWidth = (event.widget instanceof Scrollable s) ? s.getClientArea().width : event.width; gc.fillRectangle(0, event.y, rowWidth, event.height); // Prevent native selection drawing - // Do NOT clear SWT.BACKGROUND here unless you really want to suppress SWT - // background painting. - // (You *can* clear SWT.BACKGROUND if you see it overwriting your fill on a - // platform, - // but try without first.) event.detail &= ~SWT.SELECTED; } @@ -190,7 +185,7 @@ private void handleEraseItem(Event event) { private void handlePaintItem(Event event) { // We must not rely on event.detail & SWT.SELECTED because we cleared it above. // Instead compute selection state from the widget. - if (!(event.widget instanceof org.eclipse.swt.widgets.Table table)) + if (!(event.widget instanceof Table table)) return; if (!(event.item instanceof TableItem item)) return; From b2683738e910c46936ab927962a56c7c02a7824a Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 20:00:08 +0100 Subject: [PATCH 13/26] Rename method to "install" to match similar methods in other listeners --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 4 ++-- .../src/org/eclipse/jface/viewers/StructuredViewer.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 3bc7cbc8019e..56019a6afe1e 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -62,7 +62,7 @@ public class ColumnViewerSelectionColorListener implements Listener { /** * This class shouldn't be instantiated directly. Attach this listener to a - * viewer via {@link #addListenerToViewer(StructuredViewer)} instead. + * viewer via {@link #install(StructuredViewer)} instead. */ private ColumnViewerSelectionColorListener() { } @@ -131,7 +131,7 @@ private static int idToColor(String id) { }; } - public static void addListenerToViewer(StructuredViewer viewer) { + public static void install(StructuredViewer viewer) { Control control = viewer.getControl(); if (control.isDisposed() || isListenerRegistered(control)) { return; diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java index 08dc398839e3..2f4774bfd3f6 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StructuredViewer.java @@ -1210,7 +1210,7 @@ public void widgetDefaultSelected(SelectionEvent e) { }); handler.addPostSelectionListener(widgetSelectedAdapter(this::handlePostSelect)); handler.addOpenListener(StructuredViewer.this::handleOpen); - ColumnViewerSelectionColorListener.addListenerToViewer(this); + ColumnViewerSelectionColorListener.install(this); } /** From 81f9cd0878d7f79c2340a580aea06e8dfcdde739 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 20:01:20 +0100 Subject: [PATCH 14/26] Move method up --- .../ColumnViewerSelectionColorListener.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 56019a6afe1e..4bb5fc1aba68 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -67,6 +67,20 @@ public class ColumnViewerSelectionColorListener implements Listener { private ColumnViewerSelectionColorListener() { } + public static void install(StructuredViewer viewer) { + Control control = viewer.getControl(); + if (control.isDisposed() || isListenerRegistered(control)) { + return; + } + + ColumnViewerSelectionColorListener listener = new ColumnViewerSelectionColorListener(); + control.setData(LISTENER_KEY, listener); + + // We need both phases + control.addListener(SWT.EraseItem, listener); + control.addListener(SWT.PaintItem, listener); + } + private static boolean isListenerRegistered(Control control) { return control.getData(LISTENER_KEY) != null; } @@ -131,20 +145,6 @@ private static int idToColor(String id) { }; } - public static void install(StructuredViewer viewer) { - Control control = viewer.getControl(); - if (control.isDisposed() || isListenerRegistered(control)) { - return; - } - - ColumnViewerSelectionColorListener listener = new ColumnViewerSelectionColorListener(); - control.setData(LISTENER_KEY, listener); - - // We need both phases - control.addListener(SWT.EraseItem, listener); - control.addListener(SWT.PaintItem, listener); - } - @Override public void handleEvent(Event event) { if (event.type == SWT.EraseItem) { From 0838f15858e9e45d781cc838eddec877a46030f0 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 20:02:46 +0100 Subject: [PATCH 15/26] Extract private method --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 4bb5fc1aba68..c5b249cffb33 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -74,7 +74,7 @@ public static void install(StructuredViewer viewer) { } ColumnViewerSelectionColorListener listener = new ColumnViewerSelectionColorListener(); - control.setData(LISTENER_KEY, listener); + registerListener(control, listener); // We need both phases control.addListener(SWT.EraseItem, listener); @@ -85,6 +85,10 @@ private static boolean isListenerRegistered(Control control) { return control.getData(LISTENER_KEY) != null; } + private static void registerListener(Control control, ColumnViewerSelectionColorListener listener) { + control.setData(LISTENER_KEY, listener); + } + /** * Checks if additional EraseItem listeners were registered after this listener * that are NOT the OwnerDrawListener. This allows user code to override the From 172eb01c7758daa9b9a662ba12d00d0d0a52d6fc Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 20:29:01 +0100 Subject: [PATCH 16/26] Use private method in ColumnViewerSelectionColorListener In order to avoid code duplication. Also add small JavaDoc --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index c5b249cffb33..40adac1cbf94 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -120,11 +120,15 @@ public static Color getBackgroundColor(Device device, boolean focused) { return getSelectionColor(device, focused ? COLOR_SELECTION_BG_FOCUS : COLOR_SELECTION_BG_NO_FOCUS); } + /** + * @return either a color set via preferences or the system color for the given + * key. + */ private static Color getSelectionColor(Device device, String key) { ColorRegistry registry = JFaceResources.getColorRegistry(); if (!registry.hasValueFor(key)) { - RGB systemColor = device.getSystemColor(idToColor(key)).getRGB(); + RGB systemColor = getSystemColorForId(device, key); registry.put(key, systemColor); } From 28563b5969ff70be238b88092423e39f3339407f Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 20:34:23 +0100 Subject: [PATCH 17/26] Move CompletionDrawSupport to parent package. This way I can reduce the visibility of the constructor in TableOwnerDrawSupport to default and avoid exposing more (internal) API surface than strictly necessary. --- .../{contentassist => }/CompletionProposalDrawSupport.java | 3 +-- .../org/eclipse/jface/internal/text/TableOwnerDrawSupport.java | 2 +- .../text/link/contentassist/CompletionProposalPopup2.java | 2 +- .../jface/text/contentassist/CompletionProposalPopup.java | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) rename bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/{contentassist => }/CompletionProposalDrawSupport.java (96%) diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/CompletionProposalDrawSupport.java similarity index 96% rename from bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java rename to bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/CompletionProposalDrawSupport.java index 91bc9f500df0..d6c4fb9a939e 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/contentassist/CompletionProposalDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/CompletionProposalDrawSupport.java @@ -11,7 +11,7 @@ * Contributors: * SAP SE - initial API and implementation *******************************************************************************/ -package org.eclipse.jface.internal.text.contentassist; +package org.eclipse.jface.internal.text; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; @@ -21,7 +21,6 @@ import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.Table; -import org.eclipse.jface.internal.text.TableOwnerDrawSupport; import org.eclipse.jface.viewers.ColumnViewerSelectionColorListener; /** diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java index 343f17864e81..166a6c7d7a46 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java @@ -70,7 +70,7 @@ private static StyleRange[] getStyledRanges(TableItem item, int column) { return (StyleRange[])item.getData(STYLED_RANGES_KEY + column); } - public TableOwnerDrawSupport(Table table) { + TableOwnerDrawSupport(Table table) { int orientation= table.getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT); fSharedLayout= new TextLayout(table.getDisplay()); fSharedLayout.setOrientation(orientation); diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java index 35306f2d4303..6316dcd60514 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/CompletionProposalPopup2.java @@ -39,8 +39,8 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; +import org.eclipse.jface.internal.text.CompletionProposalDrawSupport; import org.eclipse.jface.internal.text.TableOwnerDrawSupport; -import org.eclipse.jface.internal.text.contentassist.CompletionProposalDrawSupport; import org.eclipse.jface.preference.JFacePreferences; import org.eclipse.jface.resource.ColorRegistry; import org.eclipse.jface.resource.JFaceColors; diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java index 661228369bd9..af29dcbba625 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java @@ -77,9 +77,9 @@ import org.eclipse.jface.bindings.keys.KeySequence; import org.eclipse.jface.bindings.keys.SWTKeySupport; import org.eclipse.jface.contentassist.IContentAssistSubjectControl; +import org.eclipse.jface.internal.text.CompletionProposalDrawSupport; import org.eclipse.jface.internal.text.InformationControlReplacer; import org.eclipse.jface.internal.text.TableOwnerDrawSupport; -import org.eclipse.jface.internal.text.contentassist.CompletionProposalDrawSupport; import org.eclipse.jface.preference.JFacePreferences; import org.eclipse.jface.resource.JFaceColors; import org.eclipse.jface.resource.JFaceResources; From 521271e7f783b1cafb1a3a9f3bcc2a77b65555aa Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 20:38:42 +0100 Subject: [PATCH 18/26] Remove the install method from TableOwnerDrawSupport The method is not used anymore and the listener has been replaced by CompletionProposalDrawSupport, which adds its own functionality and then delegates to TableOwnerDrawSupport. --- .../jface/internal/text/TableOwnerDrawSupport.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java index 166a6c7d7a46..219d080a3909 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/TableOwnerDrawSupport.java @@ -27,7 +27,9 @@ /** - * Adds owner draw support for tables. + * Adds owner draw support for tables.
+ *
+ * It has been replaced by {@link CompletionProposalDrawSupport} in 2026-06. * * @since 3.4 */ @@ -40,14 +42,6 @@ public class TableOwnerDrawSupport implements Listener { private int fDeltaOfLastMeasure; - public static void install(Table table) { - TableOwnerDrawSupport listener= new TableOwnerDrawSupport(table); - table.addListener(SWT.Dispose, listener); - table.addListener(SWT.MeasureItem, listener); - table.addListener(SWT.EraseItem, listener); - table.addListener(SWT.PaintItem, listener); - } - /** * Stores the styled ranges in the given table item. * From ef799cc1c75899a5ce9bff0837de94eb265d3711 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 20:49:50 +0100 Subject: [PATCH 19/26] Rename public methods in ColumnViewerSelectionColorListener And also add JavaDocs to them instead of documenting the private method. --- .../text/CompletionProposalDrawSupport.java | 4 +-- .../ColumnViewerSelectionColorListener.java | 30 ++++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/CompletionProposalDrawSupport.java b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/CompletionProposalDrawSupport.java index d6c4fb9a939e..3ac82ef07dd9 100644 --- a/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/CompletionProposalDrawSupport.java +++ b/bundles/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/CompletionProposalDrawSupport.java @@ -65,7 +65,7 @@ public void handleEvent(Event event) { if (event.type == SWT.EraseItem && isSelected) { - final Color backgroundColor= ColumnViewerSelectionColorListener.getBackgroundColor(event.display, isSelected); + final Color backgroundColor= ColumnViewerSelectionColorListener.getSelectionBackgroundColor(event.display, isSelected); event.gc.setBackground(backgroundColor); final int width= (event.widget instanceof Scrollable s) ? s.getClientArea().width : event.width; @@ -75,7 +75,7 @@ public void handleEvent(Event event) { event.detail&= ~SWT.SELECTED; } else if (event.type == SWT.PaintItem) { - final Color foregroundColor= ColumnViewerSelectionColorListener.getForegroundColor(event.display, isSelected); + final Color foregroundColor= ColumnViewerSelectionColorListener.getSelectionForegroundColor(event.display, isSelected); event.gc.setForeground(foregroundColor); } } diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 40adac1cbf94..2f3e9980a922 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -112,18 +112,32 @@ private boolean hasAdditionalEraseItemListeners(Event event) { .anyMatch(l -> l != ownerDrawListener); } - public static Color getForegroundColor(Device device, boolean focused) { + /** + * Gets the foreground color for a selected cell or item in a viewer. + * + * @param device The device to get the system color from (in case there is no + * color set in the preferences) + * @param focused Whether or not the control that contains the cell or item is + * currently focused. + * @return either a color set via preferences or the default system color. + */ + public static Color getSelectionForegroundColor(Device device, boolean focused) { return getSelectionColor(device, focused ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS); } - public static Color getBackgroundColor(Device device, boolean focused) { + /** + * Gets the background color for a selected cell or item in a viewer. + * + * @param device The device to get the system color from (in case there is no + * color set in the preferences) + * @param focused Whether or not the control that contains the cell or item is + * currently focused. + * @return either a color set via preferences or the default system color. + */ + public static Color getSelectionBackgroundColor(Device device, boolean focused) { return getSelectionColor(device, focused ? COLOR_SELECTION_BG_FOCUS : COLOR_SELECTION_BG_NO_FOCUS); } - /** - * @return either a color set via preferences or the system color for the given - * key. - */ private static Color getSelectionColor(Device device, String key) { ColorRegistry registry = JFaceResources.getColorRegistry(); @@ -176,8 +190,8 @@ private void handleEraseItem(Event event) { Control control = (Control) event.widget; GC gc = event.gc; - Color bg = getBackgroundColor(event.display, control.isFocusControl()); - Color fg = getForegroundColor(event.display, control.isFocusControl()); + Color bg = getSelectionBackgroundColor(event.display, control.isFocusControl()); + Color fg = getSelectionForegroundColor(event.display, control.isFocusControl()); gc.setBackground(bg); gc.setForeground(fg); From 632a2018a26ce43ec29a654e4af0dd9b706000fb Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 21:05:39 +0100 Subject: [PATCH 20/26] Make constant in OwnerDrawLabelProvider more visible and use it Use it in ColumnViewerSelectionColorListener instead of duplicating it. --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 3 +-- .../src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 2f3e9980a922..010c50900cbb 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -53,7 +53,6 @@ public class ColumnViewerSelectionColorListener implements Listener { private static final String LISTENER_KEY = "org.eclipse.jface.viewers.selection_color_listener"; //$NON-NLS-1$ - private static final String OWNER_DRAW_LISTENER_KEY = "owner_draw_label_provider_listener"; //$NON-NLS-1$ private static final String COLOR_SELECTION_BG_FOCUS = "org.eclipse.jface.SELECTION_BACKGROUND_FOCUSED"; //$NON-NLS-1$ private static final String COLOR_SELECTION_FG_FOCUS = "org.eclipse.jface.SELECTION_FOREGROUND_FOCUSED"; //$NON-NLS-1$ @@ -106,7 +105,7 @@ private boolean hasAdditionalEraseItemListeners(Event event) { } Listener[] listeners = control.getListeners(SWT.EraseItem); - Object ownerDrawListener = control.getData(OWNER_DRAW_LISTENER_KEY); + Object ownerDrawListener = control.getData(OwnerDrawLabelProvider.OWNER_DRAW_LABEL_PROVIDER_LISTENER); return Arrays.stream(listeners).dropWhile(l -> l != this) // ignore listeners before "this" .dropWhile(l -> l == this) // also ignore "this" .anyMatch(l -> l != ownerDrawListener); diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.java index e240ab7393df..5a7eebbcb091 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.java @@ -68,7 +68,7 @@ public void handleEvent(Event event) { } } - private static final String OWNER_DRAW_LABEL_PROVIDER_LISTENER = "owner_draw_label_provider_listener"; //$NON-NLS-1$ + static final String OWNER_DRAW_LABEL_PROVIDER_LISTENER = "owner_draw_label_provider_listener"; //$NON-NLS-1$ /** * Set up the owner draw callbacks for the viewer. From 0ec8982f9324a972623d9e6f773c83d6fe93cd2b Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 21:13:50 +0100 Subject: [PATCH 21/26] Rename private method in ColumnViewerSelectionColorListener --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 010c50900cbb..f7b07fa93d1d 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -153,10 +153,10 @@ public static RGB getSystemColorForId(String id) { } private static RGB getSystemColorForId(Device device, String id) { - return device.getSystemColor(idToColor(id)).getRGB(); + return device.getSystemColor(idToDefaultSWTSystemColor(id)).getRGB(); } - private static int idToColor(String id) { + private static int idToDefaultSWTSystemColor(String id) { return switch (id) { case COLOR_SELECTION_BG_FOCUS -> SWT.COLOR_TITLE_BACKGROUND; case COLOR_SELECTION_FG_FOCUS -> SWT.COLOR_WHITE; From d409d11bd3326d563ee164dc5b27f49777ed568d Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 21:17:07 +0100 Subject: [PATCH 22/26] Use method getSelectionForegroundColor to avoid code duplication --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index f7b07fa93d1d..b9bb5db41a03 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -218,8 +218,7 @@ private void handlePaintItem(Event event) { GC gc = event.gc; // Set the foreground color for selected text/icon painting, if needed - Color fg = getSelectionColor(event.display, - table.isFocusControl() ? COLOR_SELECTION_FG_FOCUS : COLOR_SELECTION_FG_NO_FOCUS); + Color fg = getSelectionForegroundColor(event.display, table.isFocusControl()); gc.setForeground(fg); // Paint the image explicitly (like TableOwnerDrawSupport does) From 10907785c15c978766c11cee1cf3efa158471881 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 21:21:56 +0100 Subject: [PATCH 23/26] Do not set the foreground color in handleEraseItem. Erasing only needs to prepare the background so the foreground color has nothing to do with it. It is during the painting phase that the text (and also the icons) are drawn so setting the foreground color needs to be done only in the method handlePaintItem. --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index b9bb5db41a03..24e531705354 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -190,17 +190,14 @@ private void handleEraseItem(Event event) { GC gc = event.gc; Color bg = getSelectionBackgroundColor(event.display, control.isFocusControl()); - Color fg = getSelectionForegroundColor(event.display, control.isFocusControl()); gc.setBackground(bg); - gc.setForeground(fg); int rowWidth = (event.widget instanceof Scrollable s) ? s.getClientArea().width : event.width; gc.fillRectangle(0, event.y, rowWidth, event.height); // Prevent native selection drawing event.detail &= ~SWT.SELECTED; - } private void handlePaintItem(Event event) { From 27357b4cdfab1657e2a2555d9ed40d5becbe4ce2 Mon Sep 17 00:00:00 2001 From: Eclipse Platform Bot Date: Fri, 27 Feb 2026 20:32:13 +0000 Subject: [PATCH 24/26] Version bump(s) for 4.40 stream --- bundles/org.eclipse.jface.text/META-INF/MANIFEST.MF | 2 +- bundles/org.eclipse.jface/META-INF/MANIFEST.MF | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.jface.text/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface.text/META-INF/MANIFEST.MF index 585219082466..74f698f50f07 100644 --- a/bundles/org.eclipse.jface.text/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.jface.text/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jface.text -Bundle-Version: 3.30.0.qualifier +Bundle-Version: 3.30.100.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: diff --git a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF index 0a2620fd7113..a28edbfee326 100644 --- a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jface;singleton:=true -Bundle-Version: 3.39.0.qualifier +Bundle-Version: 3.39.100.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.jface, From da2d6fda6a0496ed795689c48493a984165a3971 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 22:07:54 +0100 Subject: [PATCH 25/26] Bump minor version of org.eclipse.jface --- bundles/org.eclipse.jface/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF index a28edbfee326..a627f5c17061 100644 --- a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jface;singleton:=true -Bundle-Version: 3.39.100.qualifier +Bundle-Version: 3.40.0.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.jface, From 8763def0ae0125b923f50bd41d52eac48a0f5f18 Mon Sep 17 00:00:00 2001 From: Federico Jeanne Date: Fri, 27 Feb 2026 22:20:22 +0100 Subject: [PATCH 26/26] Bump version in @since --- .../jface/viewers/ColumnViewerSelectionColorListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java index 24e531705354..19acd0fc8cc8 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/ColumnViewerSelectionColorListener.java @@ -48,7 +48,7 @@ * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider * @see org.eclipse.jface.viewers.StyledCellLabelProvider * @see org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter - * @since 3.39 + * @since 3.40 */ public class ColumnViewerSelectionColorListener implements Listener {