|
41 | 41 | import org.eclipse.core.runtime.Platform; |
42 | 42 | import org.eclipse.core.runtime.Status; |
43 | 43 | import org.eclipse.core.runtime.jobs.Job; |
| 44 | +import org.eclipse.core.runtime.IProduct; |
44 | 45 | import org.eclipse.core.runtime.preferences.ConfigurationScope; |
| 46 | +import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| 47 | +import org.eclipse.core.runtime.preferences.UserScope; |
45 | 48 | import org.eclipse.equinox.app.IApplication; |
46 | 49 | import org.eclipse.equinox.app.IApplicationContext; |
47 | 50 | import org.eclipse.jface.dialogs.IDialogConstants; |
|
52 | 55 | import org.eclipse.osgi.service.datalocation.Location; |
53 | 56 | import org.eclipse.osgi.util.NLS; |
54 | 57 | import org.eclipse.swt.SWT; |
| 58 | +import org.eclipse.swt.graphics.Color; |
55 | 59 | import org.eclipse.swt.layout.FillLayout; |
56 | 60 | import org.eclipse.swt.widgets.Composite; |
57 | 61 | import org.eclipse.swt.widgets.Control; |
@@ -94,6 +98,8 @@ public class IDEApplication implements IApplication, IExecutableExtension { |
94 | 98 |
|
95 | 99 | private static final String USER_NAME = "user.name"; //$NON-NLS-1$ |
96 | 100 |
|
| 101 | + private boolean isDark; |
| 102 | + |
97 | 103 | // Use the branding plug-in of the platform feature since this is most likely |
98 | 104 | // to change on an update of the IDE. |
99 | 105 | private static final String WORKSPACE_CHECK_REFERENCE_BUNDLE_NAME = "org.eclipse.platform"; //$NON-NLS-1$ |
@@ -145,6 +151,9 @@ public Object start(IApplicationContext appContext) throws Exception { |
145 | 151 | Job.getJobManager().suspend(); |
146 | 152 |
|
147 | 153 | Display display = createDisplay(); |
| 154 | + |
| 155 | + initializeDefaultTheme(display); |
| 156 | + |
148 | 157 | // processor must be created before we start event loop |
149 | 158 | DelayedEventsProcessor processor = new DelayedEventsProcessor(display); |
150 | 159 |
|
@@ -587,6 +596,14 @@ protected Shell getParentShell() { |
587 | 596 | return null; |
588 | 597 | } |
589 | 598 |
|
| 599 | + @Override |
| 600 | + protected Control createContents(Composite parent) { |
| 601 | + Control contents = super.createContents(parent); |
| 602 | + if (isDark) { |
| 603 | + applyDarkStyles(getShell()); |
| 604 | + } |
| 605 | + return contents; |
| 606 | + } |
590 | 607 | }.prompt(force); |
591 | 608 | } |
592 | 609 |
|
@@ -852,6 +869,61 @@ protected static Version toMajorMinorVersion(Version version) { |
852 | 869 | return new Version(version.getMajor(), version.getMinor(), 0); |
853 | 870 | } |
854 | 871 |
|
| 872 | + protected void initializeDefaultTheme(Display display) { |
| 873 | + IEclipsePreferences themeNode = UserScope.INSTANCE.getNode("org.eclipse.e4.ui.css.swt.theme"); //$NON-NLS-1$ |
| 874 | + String productOrAppId = getProductOrApplicationId(); |
| 875 | + String defaultThemeId = null; |
| 876 | + if (productOrAppId != null) { |
| 877 | + defaultThemeId = themeNode.node(productOrAppId).get("themeid", null); //$NON-NLS-1$ |
| 878 | + } |
| 879 | + if (defaultThemeId == null) { |
| 880 | + defaultThemeId = themeNode.get("themeid", null); //$NON-NLS-1$ |
| 881 | + } |
| 882 | + isDark = defaultThemeId != null && defaultThemeId.contains("dark"); //$NON-NLS-1$ |
| 883 | + if (isDark) { |
| 884 | + display.addListener(SWT.Show, event -> { |
| 885 | + if (event.widget instanceof Shell shell) { |
| 886 | + applyDarkStyles(shell); |
| 887 | + } |
| 888 | + }); |
| 889 | + } |
| 890 | + } |
| 891 | + |
| 892 | + /** |
| 893 | + * Returns the product ID if a product is configured, otherwise falls back to |
| 894 | + * the application ID from the system property. Returns {@code null} if neither |
| 895 | + * is available. |
| 896 | + */ |
| 897 | + private static String getProductOrApplicationId() { |
| 898 | + IProduct product = Platform.getProduct(); |
| 899 | + if (product != null) { |
| 900 | + return product.getId(); |
| 901 | + } |
| 902 | + return System.getProperty("eclipse.application"); //$NON-NLS-1$ |
| 903 | + } |
| 904 | + |
| 905 | + private void applyDarkStyles(Shell shell) { |
| 906 | + Color bg = new Color(shell.getDisplay(), 72, 72, 76); // #48484c |
| 907 | + Color fg = new Color(shell.getDisplay(), 238, 238, 238); // #eeeeee |
| 908 | + shell.setBackground(bg); |
| 909 | + shell.setForeground(fg); |
| 910 | + applyStylesRecursive(shell, bg, fg); |
| 911 | + shell.addDisposeListener(e -> { |
| 912 | + bg.dispose(); |
| 913 | + fg.dispose(); |
| 914 | + }); |
| 915 | + } |
| 916 | + |
| 917 | + private void applyStylesRecursive(Control control, Color bg, Color fg) { |
| 918 | + control.setBackground(bg); |
| 919 | + control.setForeground(fg); |
| 920 | + if (control instanceof Composite composite) { |
| 921 | + for (Control child : composite.getChildren()) { |
| 922 | + applyStylesRecursive(child, bg, fg); |
| 923 | + } |
| 924 | + } |
| 925 | + } |
| 926 | + |
855 | 927 | @Override |
856 | 928 | public void stop() { |
857 | 929 | final IWorkbench workbench = PlatformUI.getWorkbench(); |
|
0 commit comments