Skip to content

Commit 0b528bf

Browse files
Highlighting problem when using the dark theme on Windows eclipse-platform/eclipse.platform.swt#811
JFace viewer are using OS selection color to highlight the selected item. On some OS this is not accessible. With this change, the selection color can be changed via color preference in the settings of eclipse. Fixes eclipse-platform/eclipse.platform.swt#811
1 parent 6dcd646 commit 0b528bf

File tree

9 files changed

+167
-20
lines changed

9 files changed

+167
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package org.eclipse.jface.viewers;
2+
3+
import org.eclipse.jface.resource.ColorRegistry;
4+
import org.eclipse.jface.resource.JFaceResources;
5+
import org.eclipse.swt.SWT;
6+
import org.eclipse.swt.graphics.GC;
7+
import org.eclipse.swt.widgets.Control;
8+
import org.eclipse.swt.widgets.Event;
9+
import org.eclipse.swt.widgets.Listener;
10+
import org.eclipse.swt.widgets.Scrollable;
11+
12+
/**
13+
* EraseItem event listener that takes care of coloring the selection color of
14+
* column viewers. The coloring is only applied if no other erase item listener
15+
* is registered for the viewer. If other erase item listeners are registers,
16+
* most probably a other customer coloring is applied and should not be
17+
* overwritten.
18+
*
19+
* @since 3.4
20+
* @see FocusCellOwnerDrawHighlighter
21+
*/
22+
public class ColumnViewerSelectionColorListener implements Listener {
23+
24+
/**
25+
* Registers an erase item event listener that takes care of coloring the
26+
* selection color of the given viewer.
27+
*
28+
* @param viewer The viewer that should be colored
29+
*/
30+
public static void addListenerToViewer(StructuredViewer viewer) {
31+
viewer.getControl().addListener(SWT.EraseItem, new ColumnViewerSelectionColorListener());
32+
}
33+
34+
@Override
35+
public void handleEvent(Event event) {
36+
if ((event.detail & SWT.SELECTED) == 0) {
37+
return; /* item not selected */
38+
}
39+
40+
Listener[] eraseItemListeners = event.widget.getListeners(SWT.EraseItem);
41+
if (eraseItemListeners.length != 1) {
42+
return; /* other eraseItemListener exists, do not apply coloring */
43+
}
44+
45+
GC gc = event.gc;
46+
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
47+
if (event.widget instanceof Control control && control.isFocusControl()) {
48+
gc.setBackground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND")); //$NON-NLS-1$
49+
gc.setForeground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND")); //$NON-NLS-1$
50+
} else {
51+
gc.setBackground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND_NO_FOCUS")); //$NON-NLS-1$
52+
gc.setForeground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND_NO_FOCUS")); //$NON-NLS-1$
53+
}
54+
55+
int width = event.width;
56+
if (event.widget instanceof Scrollable scrollable) {
57+
width = scrollable.getClientArea().width;
58+
}
59+
60+
gc.fillRectangle(0, event.y, width, event.height);
61+
62+
event.detail &= ~SWT.SELECTED;
63+
}
64+
65+
}

bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import org.eclipse.core.runtime.Assert;
2020
import org.eclipse.jface.util.Util;
21+
import org.eclipse.jface.resource.ColorRegistry;
22+
import org.eclipse.jface.resource.JFaceResources;
2123
import org.eclipse.swt.SWT;
2224
import org.eclipse.swt.graphics.Color;
2325
import org.eclipse.swt.graphics.GC;
@@ -151,8 +153,8 @@ private void hookListener(final ColumnViewer viewer) {
151153
* @return the color or <code>null</code> to use the default
152154
*/
153155
protected Color getSelectedCellBackgroundColor(ViewerCell cell) {
154-
return removeNonFocusedSelectionInformation ? null
155-
: cell.getItem().getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
156+
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
157+
return colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND"); //$NON-NLS-1$
156158
}
157159

158160
/**
@@ -164,7 +166,8 @@ protected Color getSelectedCellBackgroundColor(ViewerCell cell) {
164166
* @return the color or <code>null</code> to use the default
165167
*/
166168
protected Color getSelectedCellForegroundColor(ViewerCell cell) {
167-
return null;
169+
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
170+
return colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND"); //$NON-NLS-1$
168171
}
169172

170173
/**
@@ -178,7 +181,8 @@ protected Color getSelectedCellForegroundColor(ViewerCell cell) {
178181
* @since 3.4
179182
*/
180183
protected Color getSelectedCellForegroundColorNoFocus(ViewerCell cell) {
181-
return null;
184+
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
185+
return colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND_NO_FOCUS"); //$NON-NLS-1$
182186
}
183187

184188
/**
@@ -192,7 +196,8 @@ protected Color getSelectedCellForegroundColorNoFocus(ViewerCell cell) {
192196
* @since 3.4
193197
*/
194198
protected Color getSelectedCellBackgroundColorNoFocus(ViewerCell cell) {
195-
return null;
199+
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
200+
return colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND_NO_FOCUS"); //$NON-NLS-1$
196201
}
197202

198203
/**

bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.java

+18-15
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import java.util.HashSet;
1818
import java.util.Set;
1919

20+
import org.eclipse.jface.resource.ColorRegistry;
21+
import org.eclipse.jface.resource.JFaceResources;
2022
import org.eclipse.swt.SWT;
2123
import org.eclipse.swt.graphics.Color;
2224
import org.eclipse.swt.graphics.Rectangle;
@@ -166,20 +168,16 @@ public void update(ViewerCell cell) {
166168
}
167169

168170
/**
169-
* Handle the erase event. The default implementation colors the background
170-
* of selected areas with {@link SWT#COLOR_LIST_SELECTION} and foregrounds
171-
* with {@link SWT#COLOR_LIST_SELECTION_TEXT}. Note that this
172-
* implementation causes non-native behavior on some platforms. Subclasses
173-
* should override this method and <b>not</b> call the super
171+
* Handle the erase event. The default implementation colors the background of
172+
* selected areas with "org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND" and
173+
* foregrounds with "org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND". Note
174+
* that this implementation causes non-native behavior on some platforms.
175+
* Subclasses should override this method and <b>not</b> call the super
174176
* implementation.
175177
*
176-
* @param event
177-
* the erase event
178-
* @param element
179-
* the model object
178+
* @param event the erase event
179+
* @param element the model object
180180
* @see SWT#EraseItem
181-
* @see SWT#COLOR_LIST_SELECTION
182-
* @see SWT#COLOR_LIST_SELECTION_TEXT
183181
*/
184182
protected void erase(Event event, Object element) {
185183

@@ -189,11 +187,16 @@ protected void erase(Event event, Object element) {
189187
Color oldForeground = event.gc.getForeground();
190188
Color oldBackground = event.gc.getBackground();
191189

192-
event.gc.setBackground(event.item.getDisplay().getSystemColor(
193-
SWT.COLOR_LIST_SELECTION));
194-
event.gc.setForeground(event.item.getDisplay().getSystemColor(
195-
SWT.COLOR_LIST_SELECTION_TEXT));
190+
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
191+
if (event.widget instanceof Control control && control.isFocusControl()) {
192+
event.gc.setBackground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND")); //$NON-NLS-1$
193+
event.gc.setForeground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND")); //$NON-NLS-1$
194+
} else {
195+
event.gc.setBackground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND_NO_FOCUS")); //$NON-NLS-1$
196+
event.gc.setForeground(colorRegistry.get("org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND_NO_FOCUS")); //$NON-NLS-1$
197+
}
196198
event.gc.fillRectangle(bounds);
199+
197200
/* restore the old GC colors */
198201
event.gc.setForeground(oldForeground);
199202
event.gc.setBackground(oldBackground);

bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/StyledCellLabelProvider.java

+1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ protected void erase(Event event, Object element) {
263263
// info has been set by 'update': announce that we paint ourselves
264264
event.detail &= ~SWT.FOREGROUND;
265265
}
266+
super.erase(event, element);
266267
}
267268

268269
@Override

bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/TableViewer.java

+10
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ public TableViewer(Composite parent, int style) {
119119
public TableViewer(Table table) {
120120
this.table = table;
121121
hookControl(table);
122+
overwriteSelectionColor();
122123
}
123124

124125
@Override
@@ -507,4 +508,13 @@ void handleExpandableNodeClicked(Widget w) {
507508
}
508509
}
509510

511+
/**
512+
* The color of the selected item is drawn by the OS. On some OS the color might
513+
* be not accessible. To fix this issue the background color for selected items
514+
* is drawn in a custom method.
515+
*/
516+
private void overwriteSelectionColor() {
517+
ColumnViewerSelectionColorListener.addListenerToViewer(this);
518+
}
519+
510520
}

bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/TreeViewer.java

+10
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public TreeViewer(Tree tree) {
137137
super();
138138
this.tree = tree;
139139
hookControl(tree);
140+
overwriteSelectionColor();
140141
}
141142

142143
@Override
@@ -1188,4 +1189,13 @@ Object getLastElement(Widget parent) {
11881189
}
11891190
return items[length - 1].getData();
11901191
}
1192+
1193+
/**
1194+
* The color of the selected item is drawn by the OS. On some OS the color might
1195+
* be not accessible. To fix this issue the background color for selected items
1196+
* is drawn in a custom method.
1197+
*/
1198+
private void overwriteSelectionColor() {
1199+
ColumnViewerSelectionColorListener.addListenerToViewer(this);
1200+
}
11911201
}

bundles/org.eclipse.ui.themes/css/dark/e4-dark_preferencestyle.css

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ IEclipsePreferences#org-eclipse-ui-workbench:org-eclipse-ui-themes { /* pseudo a
6565
'org.eclipse.ui.workbench.FORM_HEADING_ERROR_COLOR=255,110,110'
6666
'org.eclipse.ui.workbench.FORM_HEADING_WARNING_COLOR=255,200,0'
6767
'org.eclipse.ui.workbench.FORM_HEADING_INFO_COLOR=170,170,170'
68+
'org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND=255,255,255'
69+
'org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND=0,90,210'
70+
'org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND_NO_FOCUS=227,227,227'
71+
'org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND_NO_FOCUS=70,70,70'
6872
'ERROR_COLOR=247,68,117'
6973
'HYPERLINK_COLOR=111,197,238'
7074
'INCOMING_COLOR=31,179,235'

bundles/org.eclipse.ui/plugin.properties

+9
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,15 @@ Color.showKeysForegroundDesc=Color for foreground of the control to visualize pr
374374
Color.showKeysBackground=Keys background color
375375
Color.showKeysBackgroundDesc=Color for background of the control to visualize pressed keys
376376

377+
Color.selectedCellForeground=Selection foreground color for cell viewer
378+
Color.selectedCellForegroundDesc=The selection foreground color of a cell viewer
379+
Color.selectedCellBackground=Selection background color for cell viewer
380+
Color.selectedCellBackgroundDesc=The selection background color of a cell viewer
381+
Color.selectedCellForegroundNoFocus=Selection foreground color for cell viewer without focus
382+
Color.selectedCellForegroundNoFocusDesc=The selection foreground color of a cell viewer without focus
383+
Color.selectedCellBackgroundNoFocus=Selection background color for cell viewer without focus
384+
Color.selectedCellBackgroundNoFocusDesc=The selection background color of a cell viewer without focus
385+
377386
ThemeName.SystemDefault = Reduced Palette
378387
HighContrast.ThemeDescription = A theme that takes all of its values from the system settings.
379388

bundles/org.eclipse.ui/plugin.xml

+40
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,46 @@
20542054
%Color.showKeysBackgroundDesc
20552055
</description>
20562056
</colorDefinition>
2057+
<colorDefinition
2058+
id="org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND"
2059+
isEditable="true"
2060+
categoryId="org.eclipse.ui.workbenchMisc"
2061+
label="%Color.selectedCellForeground"
2062+
value="255,255,255">
2063+
<description>
2064+
%Color.selectedCellForegroundDesc
2065+
</description>
2066+
</colorDefinition>
2067+
<colorDefinition
2068+
id="org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND"
2069+
isEditable="true"
2070+
categoryId="org.eclipse.ui.workbenchMisc"
2071+
label="%Color.selectedCellBackground"
2072+
value="0,90,210">
2073+
<description>
2074+
%Color.selectedCellBackgroundDesc
2075+
</description>
2076+
</colorDefinition>
2077+
<colorDefinition
2078+
id="org.eclipse.ui.workbench.SELECTED_CELL_FOREGROUND_NO_FOCUS"
2079+
isEditable="true"
2080+
categoryId="org.eclipse.ui.workbenchMisc"
2081+
label="%Color.selectedCellForegroundNoFocus"
2082+
value="0,0,0">
2083+
<description>
2084+
%Color.selectedCellForegroundNoFocusDesc
2085+
</description>
2086+
</colorDefinition>
2087+
<colorDefinition
2088+
id="org.eclipse.ui.workbench.SELECTED_CELL_BACKGROUND_NO_FOCUS"
2089+
isEditable="true"
2090+
categoryId="org.eclipse.ui.workbenchMisc"
2091+
label="%Color.selectedCellBackgroundNoFocus"
2092+
value="220,220,220">
2093+
<description>
2094+
%Color.selectedCellBackgroundNoFocusDesc
2095+
</description>
2096+
</colorDefinition>
20572097
</extension>
20582098
<extension
20592099
point="org.eclipse.core.runtime.preferences">

0 commit comments

Comments
 (0)