Skip to content

Commit

Permalink
fix: light TM themes don't have light background in Eclipse dark mode
Browse files Browse the repository at this point in the history
  • Loading branch information
sebthom committed Feb 10, 2024
1 parent 4d7d253 commit 5c780dc
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ void systemDefaultEditorColorTest() throws IOException, PartInitException {
assertNull(theme.getEditorSelectionBackground(), "System default selection background should be null");
assertNull(theme.getEditorSelectionForeground(), "System default selection foreground should be null");

final Color lineHighlight = ColorManager.getInstance().getPreferenceEditorColor(EDITOR_CURRENTLINE_HIGHLIGHT);
assertNotNull(theme.getEditorCurrentLineHighlight(), "Highlight shouldn't be a null");
assertNotEquals(lineHighlight, theme.getEditorCurrentLineHighlight(), "Default Line highlight should be from TM theme");
final Color eclipseLineHighlight = ColorManager.getInstance().getPreferenceEditorColor(EDITOR_CURRENTLINE_HIGHLIGHT);
final Color themeLineHighlight = theme.getEditorCurrentLineHighlight();
assertNotNull(themeLineHighlight, "Highlight shouldn't be a null");
assertNotEquals(eclipseLineHighlight, themeLineHighlight, "Default Line highlight should be from TM theme");
}

@Test
Expand Down
1 change: 1 addition & 0 deletions org.eclipse.tm4e.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Require-Bundle: org.eclipse.core.expressions,
org.eclipse.core.runtime,
org.eclipse.jface.text,
org.eclipse.ui,
org.eclipse.ui.editors,
org.eclipse.ui.ide;resolution:=optional,
org.eclipse.ui.trace;resolution:=optional,
org.eclipse.ui.workbench.texteditor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.eclipse.tm4e.core.grammar.IGrammar;
import org.eclipse.tm4e.registry.ITMScope;
import org.eclipse.tm4e.ui.TMUIPlugin;
import org.eclipse.tm4e.ui.internal.utils.PreferenceUtils;
import org.eclipse.tm4e.ui.internal.utils.UI;
import org.eclipse.tm4e.ui.text.TMPresentationReconciler;
import org.eclipse.tm4e.ui.themes.ITheme;
import org.eclipse.tm4e.ui.themes.IThemeManager;
Expand Down Expand Up @@ -59,7 +59,7 @@ protected IContributionItem[] getContributionItems() {
final IGrammar grammar = presentationReconciler.getGrammar();
if (grammar != null) {
final IThemeManager manager = TMUIPlugin.getThemeManager();
final boolean dark = PreferenceUtils.isDarkEclipseTheme();
final boolean dark = UI.isDarkEclipseTheme();
final String scopeName = ITMScope.parse(grammar.getScopeName()).getName();
final ITheme selectedTheme = manager.getThemeForScope(scopeName, dark);
for (final ITheme theme : manager.getThemes()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ public final class PreferenceConstants {

public static final String THEME_ASSOCIATIONS = "org.eclipse.tm4e.ui.themeAssociations";

public static final String E4_THEME_ID = "themeid";

public static final String DEFAULT_DARK_THEME = "org.eclipse.tm4e.ui.themes.defaultDarkTheme";
public static final String DEFAULT_LIGHT_THEME = "org.eclipse.tm4e.ui.themes.defaultLightTheme";

public static final String EDITOR_CURRENTLINE_HIGHLIGHT = "currentLineColor";

private PreferenceConstants() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.tm4e.registry.ITMScope;
import org.eclipse.tm4e.ui.internal.utils.PreferenceUtils;
import org.eclipse.tm4e.ui.internal.utils.UI;
import org.eclipse.tm4e.ui.themes.ITheme;
import org.eclipse.tm4e.ui.themes.IThemeAssociation;
import org.eclipse.tm4e.ui.themes.IThemeManager;
Expand Down Expand Up @@ -54,7 +54,7 @@ public ITheme[] getThemes() {

@Override
public ITheme getDefaultTheme() {
return getDefaultTheme(PreferenceUtils.isDarkEclipseTheme());
return getDefaultTheme(UI.isDarkEclipseTheme());
}

@Override
Expand Down Expand Up @@ -87,7 +87,7 @@ public ITheme[] getThemes(final boolean dark) {

@Override
public ITheme getThemeForScope(final String scopeName) {
return getThemeForScope(scopeName, PreferenceUtils.isDarkEclipseTheme());
return getThemeForScope(scopeName, UI.isDarkEclipseTheme());
}

@Override
Expand All @@ -109,9 +109,7 @@ public ITheme getThemeForScope(String scopeName, final boolean dark) {

@Override
public ITheme getThemeForScope(final String scopeName, final RGB background) {
return getThemeForScope(scopeName, 0.299 * background.red
+ 0.587 * background.green
+ 0.114 * background.blue < 128);
return getThemeForScope(scopeName, UI.isDarkColor(background));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static ThemeManager getInstance() {
*/
public static void addPreferenceChangeListener(final IPreferenceChangeListener themeChangeListener) {
// Observe change of Eclipse E4 Theme
var prefs = PreferenceUtils.getE4PreferenceStore();
var prefs = PreferenceUtils.getE4ThemesPreferenceStore();
if (prefs != null) {
prefs.addPreferenceChangeListener(themeChangeListener);
}
Expand All @@ -84,7 +84,7 @@ public static void addPreferenceChangeListener(final IPreferenceChangeListener t
*/
public static void removePreferenceChangeListener(final IPreferenceChangeListener themeChangeListener) {
// Observe change of Eclipse E4 Theme
var prefs = PreferenceUtils.getE4PreferenceStore();
var prefs = PreferenceUtils.getE4ThemesPreferenceStore();
if (prefs != null) {
prefs.removePreferenceChangeListener(themeChangeListener);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,21 @@
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tm4e.ui.TMUIPlugin;
import org.eclipse.tm4e.ui.internal.preferences.PreferenceConstants;
import org.eclipse.ui.editors.text.EditorsUI;

public final class PreferenceUtils {

/** see {@link org.eclipse.e4.ui.css.swt.internal.theme.ThemeEngine#THEMEID_KEY} */
@SuppressWarnings({ "restriction", "javadoc" })
public static final String E4_THEME_ID = "themeid";

/** see {@link org.eclipse.e4.ui.css.swt.internal.theme.ThemeEngine#THEME_PLUGIN_ID} */
@SuppressWarnings({ "restriction" })
private static final String E4_CSS_PREFERENCE_NAME = "org.eclipse.e4.ui.css.swt.theme";
private static final String EDITORS_PREFERENCE_NAME = "org.eclipse.ui.editors";

private static @Nullable Boolean isDebugGenerateTest;
private static @Nullable Boolean isDebugThrowError;

/**
* @return if Eclipse is currently using a dark UI theme
*/
public static boolean isDarkEclipseTheme() {
final IEclipsePreferences prefs = getE4PreferenceStore();
final String eclipseThemeId = prefs == null ? null : prefs.get(PreferenceConstants.E4_THEME_ID, null);
return eclipseThemeId != null && eclipseThemeId.toLowerCase().contains("dark");
}

public static boolean isDebugGenerateTest() {
var isDebugGenerateTest = PreferenceUtils.isDebugGenerateTest;
if (isDebugGenerateTest == null)
Expand All @@ -52,12 +48,12 @@ public static boolean isDebugThrowError() {
}

/**
* Get e4 preferences store
* Get e4 themes preferences store
*
* @return preferences store
*/
@Nullable
public static IEclipsePreferences getE4PreferenceStore() {
public static IEclipsePreferences getE4ThemesPreferenceStore() {
return InstanceScope.INSTANCE.getNode(E4_CSS_PREFERENCE_NAME);
}

Expand All @@ -68,7 +64,7 @@ public static IEclipsePreferences getE4PreferenceStore() {
*/
@Nullable
public static IEclipsePreferences getEditorsPreferenceStore() {
return InstanceScope.INSTANCE.getNode(EDITORS_PREFERENCE_NAME);
return InstanceScope.INSTANCE.getNode(EditorsUI.PLUGIN_ID);
}

private PreferenceUtils() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
Expand Down Expand Up @@ -151,6 +153,29 @@ public static int getTextWidth(final String string) {
}
}

/**
* @return 0-255
*/
private static int getBrightness(final int red, final int green, final int blue) {
// https://www.w3.org/TR/AERT/#color-contrast
return (int) (0.299 * red + 0.587 * green + 0.114 * blue);
}

public static boolean isDarkColor(final RGB color) {
return getBrightness(color.red, color.green, color.blue) < 128;
}

public static boolean isDarkColor(final Color color) {
return getBrightness(color.getRed(), color.getGreen(), color.getBlue()) < 128;
}

public static boolean isDarkEclipseTheme() {
final var shell = getActiveShell();
if (shell == null)
throw new IllegalStateException("No active shell found!");
return isDarkColor(shell.getBackground());
}

private UI() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public class TMPresentationReconciler implements IPresentationReconciler {
return;

switch (event.getKey()) {
case PreferenceConstants.E4_THEME_ID, //
case PreferenceUtils.E4_THEME_ID, //
PreferenceConstants.THEME_ASSOCIATIONS, //
PreferenceConstants.DEFAULT_DARK_THEME, //
PreferenceConstants.DEFAULT_LIGHT_THEME:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@
import org.eclipse.tm4e.registry.TMResource;
import org.eclipse.tm4e.registry.XMLConstants;
import org.eclipse.tm4e.ui.TMUIPlugin;
import org.eclipse.tm4e.ui.internal.preferences.PreferenceConstants;
import org.eclipse.tm4e.ui.internal.utils.UI;
import org.eclipse.tm4e.ui.themes.css.CSSTokenProvider;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;

/**
* {@link ITheme} implementation.
Expand Down Expand Up @@ -87,40 +88,47 @@ public IToken getToken(final String type) {
return provider == null ? ITokenProvider.DEFAULT_TOKEN : provider.getToken(type);
}

private @Nullable Color getPriorityColor(final @Nullable Color themeColor, final String prefStoreKey) {
// if the theme is light but Eclipse is in dark mode (or vice versa) we cannot use the pref settings and always use the theme colors
return UI.isDarkEclipseTheme() == isDark()
? ColorManager.getInstance().getPriorityColor(themeColor, prefStoreKey)
: themeColor;
}

@Nullable
@Override
public Color getEditorForeground() {
final ITokenProvider provider = getTokenProvider();
final Color themeColor = provider != null ? provider.getEditorForeground() : null;
return ColorManager.getInstance()
.getPriorityColor(themeColor, AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND);
return getPriorityColor(
provider != null ? provider.getEditorForeground() : null,
AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND);
}

@Nullable
@Override
public Color getEditorBackground() {
final ITokenProvider provider = getTokenProvider();
final Color themeColor = provider != null ? provider.getEditorBackground() : null;
return ColorManager.getInstance()
.getPriorityColor(themeColor, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
return getPriorityColor(
provider != null ? provider.getEditorBackground() : null,
AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND);
}

@Nullable
@Override
public Color getEditorSelectionForeground() {
final ITokenProvider provider = getTokenProvider();
final Color themeColor = provider != null ? provider.getEditorSelectionForeground() : null;
return ColorManager.getInstance()
.getPriorityColor(themeColor, AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND);
return getPriorityColor(
provider != null ? provider.getEditorSelectionForeground() : null,
AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND);
}

@Nullable
@Override
public Color getEditorSelectionBackground() {
final ITokenProvider provider = getTokenProvider();
final Color themeColor = provider != null ? provider.getEditorSelectionBackground() : null;
return ColorManager.getInstance()
.getPriorityColor(themeColor, AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND);
return getPriorityColor(
provider != null ? provider.getEditorSelectionBackground() : null,
AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND);
}

@Nullable
Expand All @@ -130,7 +138,7 @@ public Color getEditorCurrentLineHighlight() {
final Color themeColor = provider != null ? provider.getEditorCurrentLineHighlight() : null;
final ColorManager manager = ColorManager.getInstance();
return manager.isColorUserDefined(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND)
? manager.getPreferenceEditorColor(PreferenceConstants.EDITOR_CURRENTLINE_HIGHLIGHT)
? manager.getPreferenceEditorColor(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR)
: themeColor;
}

Expand Down

0 comments on commit 5c780dc

Please sign in to comment.