diff options
author | Eric Williams | 2019-08-07 18:54:29 +0000 |
---|---|---|
committer | Eric Williams | 2019-08-08 17:19:14 +0000 |
commit | e810121a9c756a3e2600f7eb79b5ee64527235ea (patch) | |
tree | 81ba3859b10d4c8562e0ad88a894a921775a64bd | |
parent | c25bd073db68c302b4c2ec26b608ed1856ea4e6e (diff) | |
download | eclipse.platform.swt-e810121a9c756a3e2600f7eb79b5ee64527235ea.tar.gz eclipse.platform.swt-e810121a9c756a3e2600f7eb79b5ee64527235ea.tar.xz eclipse.platform.swt-e810121a9c756a3e2600f7eb79b5ee64527235ea.zip |
Bug 549733: [GTK] [API] Query the current system setting for dark mode
Adjust the original patch such that it works with both GTK_THEME
and the system GTK theme.
Change-Id: I9e0db81274123ea054539c343a58a1d9fe221740
Signed-off-by: Eric Williams <ericwill@redhat.com>
6 files changed, 111 insertions, 20 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c index e0326b8506..81feb4b3ab 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c @@ -15483,6 +15483,23 @@ fail: } #endif +#ifndef NO__1g_1object_1get__J_3B_3ZJ +JNIEXPORT void JNICALL OS_NATIVE(_1g_1object_1get__J_3B_3ZJ) + (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jbooleanArray arg2, jlong arg3) +{ + jbyte *lparg1=NULL; + jboolean *lparg2=NULL; + OS_NATIVE_ENTER(env, that, _1g_1object_1get__J_3B_3ZJ_FUNC); + if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail; + if (arg2) if ((lparg2 = (*env)->GetBooleanArrayElements(env, arg2, NULL)) == NULL) goto fail; + g_object_get((GObject *)arg0, (const gchar *)lparg1, lparg2, (const gchar *)NULL); +fail: + if (arg2 && lparg2) (*env)->ReleaseBooleanArrayElements(env, arg2, lparg2, 0); + if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, JNI_ABORT); + OS_NATIVE_EXIT(env, that, _1g_1object_1get__J_3B_3ZJ_FUNC); +} +#endif + #ifndef NO__1g_1object_1get_1qdata JNIEXPORT jlong JNICALL OS_NATIVE(_1g_1object_1get_1qdata) (JNIEnv *env, jclass that, jlong arg0, jint arg1) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c index 3512668735..c99927c3f5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c @@ -1276,6 +1276,7 @@ char * OS_nativeFunctionNames[] = { "_1g_1object_1class_1find_1property", "_1g_1object_1get__J_3B_3IJ", "_1g_1object_1get__J_3B_3JJ", + "_1g_1object_1get__J_3B_3ZJ", "_1g_1object_1get_1qdata", "_1g_1object_1new", "_1g_1object_1notify", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h index 642bc88848..b368da0b32 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h @@ -1250,6 +1250,7 @@ typedef enum { _1g_1object_1class_1find_1property_FUNC, _1g_1object_1get__J_3B_3IJ_FUNC, _1g_1object_1get__J_3B_3JJ_FUNC, + _1g_1object_1get__J_3B_3ZJ_FUNC, _1g_1object_1get_1qdata_FUNC, _1g_1object_1new_FUNC, _1g_1object_1notify_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index b6a3080f7f..813c4b0e64 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -715,13 +715,7 @@ public class OS extends C { * A string containing the theme name supplied via the GTK_THEME * environment variable. Otherwise this will contain an empty string. */ - public static final String GTK_THEME_NAME; - /** - * True if GTK_THEME_SET is true, and if the dark variant was - * specified via the GTK_THEME environment variable. - */ - public static final boolean GTK_THEME_DARK; - + public static final String GTK_THEME_SET_NAME; /** * True if SWT is running on the GNOME desktop environment. */ @@ -768,16 +762,12 @@ public class OS extends C { String gtkThemeCheck = getEnvironmentalVariable(gtkThemeProperty); boolean gtkThemeSet = false; String gtkThemeName = ""; - boolean gtkThemeDark = false; if (gtkThemeCheck != null && !gtkThemeCheck.isEmpty()) { gtkThemeSet = true; - gtkThemeDark = gtkThemeCheck.contains(":dark") ? true : false; - String [] themeNameSplit = gtkThemeCheck.split(":"); - gtkThemeName = themeNameSplit[0]; + gtkThemeName = gtkThemeCheck; } GTK_THEME_SET = gtkThemeSet; - GTK_THEME_NAME = gtkThemeName; - GTK_THEME_DARK = gtkThemeDark; + GTK_THEME_SET_NAME = gtkThemeName; Map<String, String> env = System.getenv(); String desktopEnvironment = env.get("XDG_CURRENT_DESKTOP"); @@ -2041,6 +2031,20 @@ public static final void g_object_get(long object, byte[] first_property_name, l } /** * @param object cast=(GObject *) + * @param first_property_name cast=(const gchar *),flags=no_out + * @param terminator cast=(const gchar *),flags=sentinel + */ +public static final native void _g_object_get(long object, byte[] first_property_name, boolean[] value, long terminator); +public static final void g_object_get(long object, byte[] first_property_name, boolean[] value, long terminator) { + lock.lock(); + try { + _g_object_get(object, first_property_name, value, terminator); + } finally { + lock.unlock(); + } +} +/** + * @param object cast=(GObject *) * @param quark cast=(GQuark) */ public static final native long _g_object_get_qdata(long object, int quark); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java index 624d3ec2f8..152a7d6a7b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java @@ -330,6 +330,12 @@ public class Display extends Device { final int SWT_COLOR_LIST_SELECTION_TEXT_INACTIVE = 38; final int SWT_COLOR_LIST_SELECTION_INACTIVE = 39; + /* Theme related */ + /** The name of the current theme, including the theme named by GTK_THEME. */ + static String themeName; + /** True if the current theme is dark. This includes the theme set in GTK_THEME. */ + static boolean themeDark; + /* Popup Menus */ Menu [] popups; @@ -1070,17 +1076,43 @@ void checkIMModule () { } } +/** + * Sets the org.eclipse.swt.internal.gtk.theme value with the current + * GTK theme name. Checks if the current theme SWT is running with + * is dark or not. This includes checking the GTK_THEME environment + * variable, the theme name, and GSettings. + * + * @param themeName the full name of the current theme SWT is running with + * @return true if the current theme is dark + */ +boolean checkAndSetThemeDetails (String themeName) { + if (themeName.endsWith("-dark") || themeName.endsWith(":dark")) { + System.setProperty("org.eclipse.swt.internal.gtk.theme", themeName); + return true; + } + long settings = GTK.gtk_settings_get_default (); + boolean [] darkThemePreferred = new boolean [1]; + OS.g_object_get(settings, GTK.gtk_application_prefer_dark_theme, darkThemePreferred, 0); + if (darkThemePreferred[0]) { + /* + * When 'gtk-application-prefer-dark-theme' is set to true, GTK uses the 'dark' + * variant of the theme specified in the system settings -- see 'get_theme_name' + * in the GtkSettings source code for more context. + */ + System.setProperty("org.eclipse.swt.internal.gtk.theme", themeName.concat(":dark")); + } else { + System.setProperty("org.eclipse.swt.internal.gtk.theme", themeName); + } + return darkThemePreferred[0]; +} + void createDisplay (DeviceData data) { boolean init = GTK.GTK4 ? GTK.gtk_init_check () : GTK.gtk_init_check (new long [] {0}, null); if (!init) SWT.error (SWT.ERROR_NO_HANDLES, null, " [gtk_init_check() failed]"); //$NON-NLS-1$ checkIMModule(); //set GTK+ Theme name as property for introspection purposes - if (OS.GTK_THEME_SET) { - String themeName = OS.GTK_THEME_NAME + (OS.GTK_THEME_DARK ? ":dark" : ""); - System.setProperty("org.eclipse.swt.internal.gtk.theme", themeName); - } else { - System.setProperty("org.eclipse.swt.internal.gtk.theme", OS.getThemeName()); - } + themeName = OS.GTK_THEME_SET ? OS.GTK_THEME_SET_NAME : OS.getThemeName(); + themeDark = checkAndSetThemeDetails(themeName); if (OS.isX11()) { xDisplay = GTK.GTK4 ? 0 : GDK.gdk_x11_get_default_xdisplay(); } @@ -2442,7 +2474,7 @@ public Point [] getIconSizes () { * @since 3.112 */ public static boolean isSystemDarkTheme () { - return OS.GTK_THEME_DARK; + return themeDark; } int getLastEventTime () { diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug549733_GTKDarkAPI.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug549733_GTKDarkAPI.java new file mode 100644 index 0000000000..d95df18d66 --- /dev/null +++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug549733_GTKDarkAPI.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat and others. All rights reserved. + * The contents of this file are made available under the terms + * of the GNU Lesser General Public License (LGPL) Version 2.1 that + * accompanies this distribution (lgpl-v21.txt). The LGPL is also + * available at http://www.gnu.org/licenses/lgpl.html. If the version + * of the LGPL at http://www.gnu.org is different to the version of + * the LGPL accompanying this distribution and there is any conflict + * between the two license versions, the terms of the LGPL accompanying + * this distribution shall govern. + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.gtk.snippets; + +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class Bug549733_GTKDarkAPI { + + public static void main(String[] args) { + Display display = new Display(); + Shell shell = new Shell(display); + shell.setLayout(new FillLayout()); + shell.setSize(500, 200); + System.out.println("Display.isThemeDark(): " + Display.isSystemDarkTheme()); + System.out.println("Theme name set in SWT: " + System.getProperty("org.eclipse.swt.internal.gtk.theme")); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + } +} |