From b8ed790d83d9b62b346c757e36fe0109edb401e4 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Wed, 22 Oct 2025 18:15:56 +0200 Subject: [PATCH] Allow to ignore explicitly defined disabled icons The algorithm for generating disabled icons on-the-fly has recently been enhanced. Most explicit disabled icons that have been embedded into bundles conform to what now can be generated on-the-fly. In addition, the algorithm is interchangeable, allowing custom stylings of disabled icons. However, when there are still bundles, such as extensions out of own control, that still explicitly define disabled icons, exchanging the algorithm for disabled icons will lead to inconsistent appearance as only the on-the-fly generated icons will adhere to that. This change allows to ignore explicitly defined disabled icons, such that even if some bundles defined disabled icons, they will be ignored and on-the-fly generated disabled icons according to the selected algorithm will be used instead. An according preference that can be configured via the appearance tab is added. --- .../swt/AbstractContributionItem.java | 4 +++ .../org.eclipse.jface/META-INF/MANIFEST.MF | 2 +- .../jface/action/ActionContributionItem.java | 32 ++++++++++++++++++- .../ui/IWorkbenchPreferenceConstants.java | 11 +++++++ .../ui/internal/WorkbenchMessages.java | 3 ++ .../internal/dialogs/ViewsPreferencePage.java | 19 ++++++++++- .../eclipse/ui/internal/messages.properties | 3 ++ .../ui/menus/CommandContributionItem.java | 5 ++- .../src/org/eclipse/ui/internal/UIPlugin.java | 11 +++++++ .../ui/internal/UIPreferenceInitializer.java | 1 + .../tests/action/ToolBarManagerTest.java | 6 ++++ 11 files changed, 93 insertions(+), 4 deletions(-) diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/AbstractContributionItem.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/AbstractContributionItem.java index 020601182d7..3b9f6d2c581 100644 --- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/AbstractContributionItem.java +++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/AbstractContributionItem.java @@ -38,6 +38,7 @@ import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.swt.util.ISWTResourceUtilities; import org.eclipse.emf.common.util.URI; +import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.ContributionItem; import org.eclipse.jface.action.IContributionManager; import org.eclipse.jface.action.IMenuCreator; @@ -211,6 +212,9 @@ protected void updateIcons() { } private String getDisabledIconURI(MItem toolItem) { + if (ActionContributionItem.getIgnoreDisabledIcons()) { + return ""; //$NON-NLS-1$ + } Object obj = toolItem.getTransientData().get(IPresentationEngine.DISABLED_ICON_IMAGE_KEY); return obj instanceof String s ? s : ""; //$NON-NLS-1$ } diff --git a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF index a28edbfee32..a627f5c1706 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, diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java index 7cc82c7d5db..c9a1cf664b3 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java @@ -96,6 +96,33 @@ public static void setUseColorIconsInToolbars(boolean useColorIcons) { USE_COLOR_ICONS = useColorIcons; } + private static boolean IGNORE_DISABLED_ICONS = true; + + /** + * Returns whether explicitly defined disabled icons should be ignored, such + * that all disabled icons are generated on-the-fly. + * + * @return true if disabled icons set to tool items should be + * ignored, false otherwise + * @since 3.40 + */ + public static boolean getIgnoreDisabledIcons() { + return IGNORE_DISABLED_ICONS; + } + + /** + * Sets whether explicitly defined disabled icons should be ignored, such that + * all disabled icons are generated on-the-fly. + * + * @param ignoreDisabledIcons true if disabled icons set to tool + * items should be ignored, false + * otherwise + * @since 3.40 + */ + public static void setIgnoreDisabledIcons(boolean ignoreDisabledIcons) { + IGNORE_DISABLED_ICONS = ignoreDisabledIcons; + } + /** * The presentation mode. */ @@ -988,7 +1015,10 @@ private boolean updateImages(boolean forceImage) { if (widget instanceof ToolItem) { ImageDescriptor image = action.getImageDescriptor(); ImageDescriptor hoverImage = action.getHoverImageDescriptor(); - ImageDescriptor disabledImage = action.getDisabledImageDescriptor(); + ImageDescriptor disabledImage = null; + if (!getIgnoreDisabledIcons()) { + disabledImage = action.getDisabledImageDescriptor(); + } // Make sure there is a valid image in case images are forced. if (image == null && forceImage) { image = ImageDescriptor.getMissingImageDescriptor(); diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/IWorkbenchPreferenceConstants.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/IWorkbenchPreferenceConstants.java index 79a643440fa..ad9c22d87dc 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/IWorkbenchPreferenceConstants.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/IWorkbenchPreferenceConstants.java @@ -721,4 +721,15 @@ public interface IWorkbenchPreferenceConstants { * @since 3.134 */ String RESCALING_AT_RUNTIME = "monitorSpecificScaling"; //$NON-NLS-1$ + + /** + *

+ * Whether explicitly defined disabled icons shall be ignored in favor of using + * on-the-fly generated disabled icons. + *

+ * + * @since 3.139 + */ + String IGNORE_DISABLED_ICONS = "ignoreDisabledIcons"; //$NON-NLS-1$ + } diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java index cdc17e28774..d52637d96d7 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/WorkbenchMessages.java @@ -491,6 +491,9 @@ public class WorkbenchMessages extends NLS { public static String ViewsPreference_hideIconsForViewTabs; public static String ViewsPreference_viewTabs_dirty_indicator_label; public static String ViewsPreference_showDirtyIndicatorForTabs; + public static String ViewsPreference_disabledIcons_description; + public static String ViewsPreference_ignoreDisabledIcons; + public static String ViewsPreference_ignoreDisabledIcons_tooltip; public static String ToggleFullScreenMode_ActivationPopup_Description; public static String ToggleFullScreenMode_ActivationPopup_Description_NoKeybinding; public static String ToggleFullScreenMode_ActivationPopup_DoNotShowAgain; diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java index 806407d8338..b082c709d00 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/dialogs/ViewsPreferencePage.java @@ -117,6 +117,7 @@ public class ViewsPreferencePage extends PreferencePage implements IWorkbenchPre private Button themingEnabled; private Button rescaleAtRuntime; + private Button ignoreDisabledIcons; private Button hideIconsForViewTabs; private Button showFullTextForViewTabs; @@ -144,6 +145,7 @@ protected Control createContents(Composite parent) { layout.horizontalSpacing = 10; comp.setLayout(layout); createThemeIndependentComposits(comp); + createDisabledIconsButtons(comp); createRescaleAtRuntimeCheckButton(comp); return comp; } @@ -201,7 +203,7 @@ protected Control createContents(Composite parent) { createDependency(showFullTextForViewTabs, hideIconsForViewTabs); createShowDirtyIndicatorForTabs(comp); - + createDisabledIconsButtons(comp); createRescaleAtRuntimeCheckButton(comp); if (currentTheme != null) { @@ -253,6 +255,17 @@ private void createRescaleAtRuntimeCheckButton(Composite parent) { } } + private void createDisabledIconsButtons(Composite parent) { + createLabel(parent, ""); //$NON-NLS-1$ + createLabel(parent, WorkbenchMessages.ViewsPreference_disabledIcons_description); + + boolean initialStateIgnoreDisabledIcons = PrefUtil.getAPIPreferenceStore() + .getBoolean(IWorkbenchPreferenceConstants.IGNORE_DISABLED_ICONS); + ignoreDisabledIcons = createCheckButton(parent, WorkbenchMessages.ViewsPreference_ignoreDisabledIcons, + initialStateIgnoreDisabledIcons); + ignoreDisabledIcons.setToolTipText(WorkbenchMessages.ViewsPreference_ignoreDisabledIcons_tooltip); + } + private void createThemeIndependentComposits(Composite comp) { createColoredLabelsPref(comp); createEnableMruPref(comp); @@ -483,6 +496,8 @@ public boolean performOk() { .getSelection(); prefs.putBoolean(PartRenderingEngine.ENABLED_THEME_KEY, themingEnabled.getSelection()); } + PrefUtil.getAPIPreferenceStore().setValue(IWorkbenchPreferenceConstants.IGNORE_DISABLED_ICONS, + ignoreDisabledIcons.getSelection()); boolean isRescaleAtRuntimeChanged = false; if (rescaleAtRuntime != null) { @@ -624,6 +639,8 @@ protected void performDefaults() { } IPreferenceStore apiStore = PrefUtil.getAPIPreferenceStore(); useColoredLabels.setSelection(apiStore.getDefaultBoolean(IWorkbenchPreferenceConstants.USE_COLORED_LABELS)); + ignoreDisabledIcons + .setSelection(apiStore.getDefaultBoolean(IWorkbenchPreferenceConstants.IGNORE_DISABLED_ICONS)); enableMru.setSelection(defaultPrefs.getBoolean(StackRenderer.MRU_KEY_DEFAULT, StackRenderer.MRU_DEFAULT)); super.performDefaults(); diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties index 0fc6557edeb..f72ca4a9cb1 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/messages.properties @@ -436,6 +436,9 @@ ViewsPreference_hideIconsForViewTabs = Hide icons ViewsPreference_viewTabs_icons_and_titles_label = Tab icons and titles in view areas: ViewsPreference_viewTabs_dirty_indicator_label = Indicator for unsaved changes in view and editor tabs: ViewsPreference_showDirtyIndicatorForTabs = Indicate unsaved changes by overlaying the close button +ViewsPreference_disabledIcons_description = Icons for disabled actions: +ViewsPreference_ignoreDisabledIcons = Ignore pre-generated disabled icons +ViewsPreference_ignoreDisabledIcons_tooltip = When enabled ignores pre-generated disabled icons in favor of generating consistently styled disabled icons on the fly ToggleFullScreenMode_ActivationPopup_Description=You have gone full screen. Use the Toggle Full Screen command ({0}) to deactivate. ToggleFullScreenMode_ActivationPopup_Description_NoKeybinding=You have gone full screen. Use the Toggle Full Screen command to deactivate. ToggleFullScreenMode_ActivationPopup_DoNotShowAgain=Do not show again diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/menus/CommandContributionItem.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/menus/CommandContributionItem.java index 5fdbaa986e8..dc2ea80c631 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/menus/CommandContributionItem.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/menus/CommandContributionItem.java @@ -28,6 +28,7 @@ import org.eclipse.core.commands.common.NotDefinedException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.ContributionItem; import org.eclipse.jface.action.IContributionManager; import org.eclipse.jface.action.IMenuListener2; @@ -892,7 +893,9 @@ private void updateIcons() { localResourceManager = m; } else if (widget instanceof ToolItem item) { LocalResourceManager m = new LocalResourceManager(JFaceResources.getResources()); - item.setDisabledImage(disabledIcon == null ? null : m.create(disabledIcon)); + if (!ActionContributionItem.getIgnoreDisabledIcons()) { + item.setDisabledImage(disabledIcon == null ? null : m.create(disabledIcon)); + } item.setHotImage(hoverIcon == null ? null : m.create(hoverIcon)); item.setImage(icon == null ? null : m.create(icon)); disposeOldImages(); diff --git a/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPlugin.java b/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPlugin.java index 5c0962634a1..31f4974e665 100644 --- a/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPlugin.java +++ b/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPlugin.java @@ -14,8 +14,10 @@ package org.eclipse.ui.internal; import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.internal.util.PrefUtil; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -98,5 +100,14 @@ public void savePreferences() { UIPlugin.this.savePluginPreferences(); } }); + initializeIconConfigurations(); } + + private void initializeIconConfigurations() { + // configure disabled icons appearance + boolean ignoreDisabledIcons = PrefUtil.getAPIPreferenceStore() + .getBoolean(IWorkbenchPreferenceConstants.IGNORE_DISABLED_ICONS); + ActionContributionItem.setIgnoreDisabledIcons(ignoreDisabledIcons); + } + } diff --git a/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPreferenceInitializer.java b/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPreferenceInitializer.java index 864731c2f6f..3def0f40b03 100644 --- a/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPreferenceInitializer.java +++ b/bundles/org.eclipse.ui/src/org/eclipse/ui/internal/UIPreferenceInitializer.java @@ -62,6 +62,7 @@ public void initializeDefaultPreferences() { false); node.putBoolean(IWorkbenchPreferenceConstants.USE_COLORED_LABELS, true); + node.putBoolean(IWorkbenchPreferenceConstants.IGNORE_DISABLED_ICONS, true); node.putBoolean( IWorkbenchPreferenceConstants.SHOW_TEXT_ON_PERSPECTIVE_BAR, false); diff --git a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/action/ToolBarManagerTest.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/action/ToolBarManagerTest.java index 889b98522b4..aa33c15bf95 100644 --- a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/action/ToolBarManagerTest.java +++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/action/ToolBarManagerTest.java @@ -141,8 +141,10 @@ protected Control createControl(Composite parent) { @Test public void testDefaultImageIsGray() { boolean oldState = ActionContributionItem.getUseColorIconsInToolbars(); + boolean oldStateIgnoreDisabled = ActionContributionItem.getIgnoreDisabledIcons(); try { ActionContributionItem.setUseColorIconsInToolbars(false); + ActionContributionItem.setIgnoreDisabledIcons(false); ToolBarManager manager = new ToolBarManager(); Action action = new Action("Button with Hover") { }; @@ -165,14 +167,17 @@ public void testDefaultImageIsGray() { assertImageEqualsDescriptor(ImageDescriptor.createWithFlags(descriptor, SWT.IMAGE_GRAY), item.getImage()); } finally { ActionContributionItem.setUseColorIconsInToolbars(oldState); + ActionContributionItem.setIgnoreDisabledIcons(oldStateIgnoreDisabled); } } @Test public void testActionImagesAreSet() { boolean oldState = ActionContributionItem.getUseColorIconsInToolbars(); + boolean oldStateIgnoreDisabled = ActionContributionItem.getIgnoreDisabledIcons(); try { ActionContributionItem.setUseColorIconsInToolbars(true); + ActionContributionItem.setIgnoreDisabledIcons(false); ToolBarManager manager = new ToolBarManager(); Action action = new Action("Button with Hover") { }; @@ -195,6 +200,7 @@ public void testActionImagesAreSet() { assertImageEqualsDescriptor(disabledDescriptor, item.getDisabledImage()); } finally { ActionContributionItem.setUseColorIconsInToolbars(oldState); + ActionContributionItem.setIgnoreDisabledIcons(oldStateIgnoreDisabled); } }