From 0fde631fdbecfce23f9d2aebbf1ea50d6130bfaf Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Mon, 3 Feb 2025 20:37:43 +0100 Subject: [PATCH] [GTK4] Migrate deprecated ColorChooser to ColorDialog The Color Chooser has been moved to the GTK3 class and all references inside the GTK4 blocks have been updated to use the new API. Note that the GTK4 API doesn't provide the means to set a custom palette, meaning that the colors specified with setRGBS(RGB[]) are effectively ignored. --- .../Eclipse SWT PI/gtk/library/gtk4.c | 166 ++++++++++++++++++ .../Eclipse SWT PI/gtk/library/gtk4_stats.h | 8 + .../org/eclipse/swt/internal/gtk4/GTK4.java | 48 +++++ .../org/eclipse/swt/widgets/ColorDialog.java | 101 ++++++++--- 4 files changed, 298 insertions(+), 25 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c index 0a45de52506..a06ab26f27f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c @@ -436,6 +436,172 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1check_1button_1set_1use_1underline) } #endif +#ifndef NO_gtk_1color_1dialog_1choose_1rgba +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1color_1dialog_1choose_1rgba) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jobject arg2, jlong arg3, jlong arg4, jlong arg5) +{ + GdkRGBA _arg2, *lparg2=NULL; + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1choose_1rgba_FUNC); + if (arg2) if ((lparg2 = getGdkRGBAFields(env, arg2, &_arg2)) == NULL) goto fail; +/* + gtk_color_dialog_choose_rgba(arg0, (GtkWindow *)arg1, (GdkRGBA *)lparg2, (GCancellable *)arg3, (GAsyncReadyCallback)arg4, (gpointer)arg5); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_choose_rgba) + if (fp) { + ((void (CALLING_CONVENTION*)(jlong, GtkWindow *, GdkRGBA *, GCancellable *, GAsyncReadyCallback, gpointer))fp)(arg0, (GtkWindow *)arg1, (GdkRGBA *)lparg2, (GCancellable *)arg3, (GAsyncReadyCallback)arg4, (gpointer)arg5); + } + } +fail: + if (arg2 && lparg2) setGdkRGBAFields(env, arg2, lparg2); + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1choose_1rgba_FUNC); +} +#endif + +#ifndef NO_gtk_1color_1dialog_1choose_1rgba_1finish +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1color_1dialog_1choose_1rgba_1finish) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2) +{ + jlong *lparg2=NULL; + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1choose_1rgba_1finish_FUNC); + if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail; +/* + rc = (jlong)gtk_color_dialog_choose_rgba_finish(arg0, (GAsyncResult *)arg1, (GError **)lparg2); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_choose_rgba_finish) + if (fp) { + rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong, GAsyncResult *, GError **))fp)(arg0, (GAsyncResult *)arg1, (GError **)lparg2); + } + } +fail: + if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0); + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1choose_1rgba_1finish_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1color_1dialog_1get_1modal +JNIEXPORT jboolean JNICALL GTK4_NATIVE(gtk_1color_1dialog_1get_1modal) + (JNIEnv *env, jclass that, jlong arg0) +{ + jboolean rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1get_1modal_FUNC); +/* + rc = (jboolean)gtk_color_dialog_get_modal(arg0); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_get_modal) + if (fp) { + rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jlong))fp)(arg0); + } + } + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1get_1modal_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1color_1dialog_1get_1with_1alpha +JNIEXPORT jboolean JNICALL GTK4_NATIVE(gtk_1color_1dialog_1get_1with_1alpha) + (JNIEnv *env, jclass that, jlong arg0) +{ + jboolean rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1get_1with_1alpha_FUNC); +/* + rc = (jboolean)gtk_color_dialog_get_with_alpha(arg0); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_get_with_alpha) + if (fp) { + rc = (jboolean)((jboolean (CALLING_CONVENTION*)(jlong))fp)(arg0); + } + } + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1get_1with_1alpha_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1color_1dialog_1new +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1color_1dialog_1new) + (JNIEnv *env, jclass that) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1new_FUNC); +/* + rc = (jlong)gtk_color_dialog_new(); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_new) + if (fp) { + rc = (jlong)((jlong (CALLING_CONVENTION*)())fp)(); + } + } + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1new_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1color_1dialog_1set_1modal +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1color_1dialog_1set_1modal) + (JNIEnv *env, jclass that, jlong arg0, jboolean arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1set_1modal_FUNC); +/* + gtk_color_dialog_set_modal(arg0, (gboolean)arg1); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_set_modal) + if (fp) { + ((void (CALLING_CONVENTION*)(jlong, gboolean))fp)(arg0, (gboolean)arg1); + } + } + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1set_1modal_FUNC); +} +#endif + +#ifndef NO_gtk_1color_1dialog_1set_1title +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1color_1dialog_1set_1title) + (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1) +{ + jbyte *lparg1=NULL; + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1set_1title_FUNC); + if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail; +/* + rc = (jlong)gtk_color_dialog_set_title(arg0, (char *)lparg1); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_set_title) + if (fp) { + rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong, char *))fp)(arg0, (char *)lparg1); + } + } +fail: + if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0); + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1set_1title_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1color_1dialog_1set_1with_1alpha +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1color_1dialog_1set_1with_1alpha) + (JNIEnv *env, jclass that, jlong arg0, jboolean arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1color_1dialog_1set_1with_1alpha_FUNC); +/* + gtk_color_dialog_set_with_alpha(arg0, (gboolean)arg1); +*/ + { + GTK4_LOAD_FUNCTION(fp, gtk_color_dialog_set_with_alpha) + if (fp) { + ((void (CALLING_CONVENTION*)(jlong, gboolean))fp)(arg0, (gboolean)arg1); + } + } + GTK4_NATIVE_EXIT(env, that, gtk_1color_1dialog_1set_1with_1alpha_FUNC); +} +#endif + #ifndef NO_gtk_1combo_1box_1get_1child JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1combo_1box_1get_1child) (JNIEnv *env, jclass that, jlong arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h index ff782a84205..9273b0a03c9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h @@ -58,6 +58,14 @@ typedef enum { gtk_1check_1button_1set_1group_FUNC, gtk_1check_1button_1set_1inconsistent_FUNC, gtk_1check_1button_1set_1use_1underline_FUNC, + gtk_1color_1dialog_1choose_1rgba_FUNC, + gtk_1color_1dialog_1choose_1rgba_1finish_FUNC, + gtk_1color_1dialog_1get_1modal_FUNC, + gtk_1color_1dialog_1get_1with_1alpha_FUNC, + gtk_1color_1dialog_1new_FUNC, + gtk_1color_1dialog_1set_1modal_FUNC, + gtk_1color_1dialog_1set_1title_FUNC, + gtk_1color_1dialog_1set_1with_1alpha_FUNC, gtk_1combo_1box_1get_1child_FUNC, gtk_1css_1provider_1load_1from_1data_FUNC, gtk_1drag_1source_1new_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java index 56965eda008..5f8cb6fd426 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java @@ -318,6 +318,54 @@ public class GTK4 { */ public static final native long gtk_font_dialog_set_title(long self, byte[] title); + /* GtkColorDialog */ + /** + * @method flags=dynamic + */ + public static final native long gtk_color_dialog_new(); + /** + * @method flags=dynamic + * + * @param title cast=(char *) + */ + public static final native long gtk_color_dialog_set_title(long self, byte[] title); + /** + * @method flags=dynamic + * + * @param with_alpha cast=(gboolean) + */ + public static final native void gtk_color_dialog_set_with_alpha(long self, boolean with_alpha); + /** + * @method flags=dynamic + */ + public static final native boolean gtk_color_dialog_get_with_alpha(long self); + /** + * @method flags=dynamic + * + * @param modal cast=(gboolean) + */ + public static final native void gtk_color_dialog_set_modal(long self, boolean modal); + /** + * @method flags=dynamic + */ + public static final native boolean gtk_color_dialog_get_modal(long self); + /** + * @method flags=dynamic + * + * @param parent cast=(GtkWindow *) + * @param initial_color cast=(GdkRGBA *) + * @param cancellable cast=(GCancellable *) + * @param callback cast=(GAsyncReadyCallback) + * @param user_data cast=(gpointer) + */ + public static final native void gtk_color_dialog_choose_rgba(long self, long parent, GdkRGBA initial_color, long cancellable, long callback, long user_data); + /** + * @method flags=dynamic + * + * @param result cast=(GAsyncResult *) + * @param error cast=(GError **) + */ + public static final native long gtk_color_dialog_choose_rgba_finish(long self, long result, long[] error); /* GtkScrolledWindow */ public static final native long gtk_scrolled_window_new(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ColorDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ColorDialog.java index cd0a73e4126..cd31c163d17 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ColorDialog.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ColorDialog.java @@ -131,7 +131,18 @@ public RGB[] getRGBs() { */ public RGB open () { byte[] buffer = Converter.javaStringToCString(title); - long handle = GTK.gtk_color_chooser_dialog_new(buffer, parent.topHandle()); + long handle; + if (GTK.GTK_VERSION >= OS.VERSION(4, 10, 0)) { + handle = GTK4.gtk_color_dialog_new(); + } else { + handle = GTK.gtk_color_chooser_dialog_new(buffer, parent.topHandle()); + } + if (handle == 0) error (SWT.ERROR_NO_HANDLES); + if (GTK.GTK_VERSION >= OS.VERSION(4, 10, 0)) { + GTK4.gtk_color_dialog_set_modal(handle, true); + GTK4.gtk_color_dialog_set_title(handle, buffer); + } + Display display = parent != null ? parent.getDisplay(): Display.getCurrent(); GdkRGBA rgba = new GdkRGBA(); @@ -141,34 +152,46 @@ public RGB open () { rgba.blue = (double) rgb.blue / 255; rgba.alpha = 1; } - GTK.gtk_color_chooser_set_rgba (handle, rgba); - if (rgbs != null) { - int colorsPerRow = 9; - long gdkRGBAS = OS.g_malloc(GdkRGBA.sizeof * rgbs.length); - rgba = new GdkRGBA (); - for (int i=0; i= OS.VERSION(4, 10, 0)) { + // TODO The ColorDialog API doesn't support setting a custom palette + // See https://gitlab.gnome.org/GNOME/gtk/-/issues/5936 + // > The new GtkColorDialog api doesn't have this feature atm. We might + // > want to bring it back, but judging from application use of color + // > choosers, setting custom palettes is not very popular. + if (GTK4.gtk_color_dialog_get_with_alpha(handle)) { + GTK4.gtk_color_dialog_set_with_alpha(handle, false); } - GTK.gtk_color_chooser_add_palette(handle, GTK.GTK_ORIENTATION_HORIZONTAL, colorsPerRow, - rgbs.length, gdkRGBAS); + } else { GTK.gtk_color_chooser_set_rgba (handle, rgba); + if (rgbs != null) { + int colorsPerRow = 9; + long gdkRGBAS = OS.g_malloc(GdkRGBA.sizeof * rgbs.length); + rgba = new GdkRGBA (); + for (int i=0; i= OS.VERSION(4, 10, 0)) ? GTK4.gtk_color_dialog_get_modal(handle) : GTK.gtk_window_get_modal(handle)) { oldModal = display.getModalDialog(); display.setModalDialog(this); } @@ -181,7 +204,31 @@ public RGB open () { int response; if (GTK.GTK4) { - response = SyncDialogUtil.run(display, handle, false); + if (GTK.GTK_VERSION >= OS.VERSION(4, 10, 0)) { + long shellHandle = parent != null ? parent.topHandle() : 0; + GdkRGBA initialColor = rgba; + long gdkRGBA = SyncDialogUtil.run(display, new AsyncReadyCallback() { + @Override + public void async(long callback) { + GTK4.gtk_color_dialog_choose_rgba(handle, shellHandle, initialColor, 0, callback, 0); + } + + @Override + public long await(long result) { + return GTK4.gtk_color_dialog_choose_rgba_finish(handle, result, null); + } + }); + + if (gdkRGBA != 0) { + OS.memmove(rgba, gdkRGBA, GdkRGBA.sizeof); + GDK.gdk_rgba_free(gdkRGBA); + response = GTK.GTK_RESPONSE_OK; + } else { + response = GTK.GTK_RESPONSE_CANCEL; + } + } else { + response = SyncDialogUtil.run(display, handle, false); + } } else { display.externalEventLoop = true; display.sendPreExternalEventDispatchEvent(); @@ -193,7 +240,7 @@ public RGB open () { if ((style & SWT.RIGHT_TO_LEFT) != 0) { OS.g_signal_remove_emission_hook(signalId, hookId); } - if (GTK.gtk_window_get_modal (handle)) { + if ((GTK.GTK_VERSION >= OS.VERSION(4, 10, 0)) ? GTK4.gtk_color_dialog_get_modal(handle) : GTK.gtk_window_get_modal(handle)) { display.setModalDialog(oldModal); } boolean success = response == GTK.GTK_RESPONSE_OK; @@ -201,8 +248,10 @@ public RGB open () { int red = 0; int green = 0; int blue = 0; - rgba = new GdkRGBA(); - GTK.gtk_color_chooser_get_rgba(handle, rgba); + if (GTK.GTK_VERSION < OS.VERSION(4, 10, 0)) { + rgba = new GdkRGBA(); + GTK.gtk_color_chooser_get_rgba(handle, rgba); + } red = (int) (rgba.red * 255); green = (int) (rgba.green * 255); blue = (int) (rgba.blue * 255); @@ -213,7 +262,9 @@ public RGB open () { display.removeIdleProc(); if (GTK.GTK4) { - GTK4.gtk_window_destroy(handle); + if (GTK.GTK_VERSION < OS.VERSION(4, 10, 0)) { + GTK4.gtk_window_destroy(handle); + } } else { GTK3.gtk_widget_destroy(handle); }