Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2019-08-07 18:54:29 +0000
committerEric Williams2019-08-08 17:19:14 +0000
commite810121a9c756a3e2600f7eb79b5ee64527235ea (patch)
tree81ba3859b10d4c8562e0ad88a894a921775a64bd
parentc25bd073db68c302b4c2ec26b608ed1856ea4e6e (diff)
downloadeclipse.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>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c17
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java30
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java46
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug549733_GTKDarkAPI.java36
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();
+ }
+ }
+}

Back to the top