From 99d94c0b3aa375b2815bc943a6c7b4bf51174dbd Mon Sep 17 00:00:00 2001 From: Jonah Graham Date: Tue, 25 Nov 2025 13:35:25 -0500 Subject: [PATCH] [GTK4] Fix custom drawing in GTK4 This involves changing the mechanism with which we do custom drawing. Previously we tried to hook into GtkWidget's snapshot, but this required messing around with the vtable of the widget to call our handler instead. This commit changes to using GtkOverlays + GtkDrawingAreas to allow custom drawing on top of the GtkWidgets. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/2819 --- .../Eclipse SWT PI/gtk/library/gtk4.c | 176 ++++++++++++++++++ .../Eclipse SWT PI/gtk/library/gtk4_stats.h | 16 ++ .../org/eclipse/swt/internal/gtk4/GTK4.java | 74 ++++++++ .../gtk/org/eclipse/swt/widgets/Button.java | 26 ++- .../gtk/org/eclipse/swt/widgets/Canvas.java | 9 +- .../gtk/org/eclipse/swt/widgets/Control.java | 15 +- .../gtk/org/eclipse/swt/widgets/Display.java | 26 +-- .../gtk/org/eclipse/swt/widgets/Widget.java | 25 +-- 8 files changed, 308 insertions(+), 59 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 5240b3c85c3..255c5b3c1df 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 @@ -1066,6 +1066,72 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1drag_1source_1set_1icon) } #endif +#ifndef NO_gtk_1drawing_1area_1get_1content_1height +JNIEXPORT jint JNICALL GTK4_NATIVE(gtk_1drawing_1area_1get_1content_1height) + (JNIEnv *env, jclass that, jlong arg0) +{ + jint rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1drawing_1area_1get_1content_1height_FUNC); + rc = (jint)gtk_drawing_area_get_content_height((GtkDrawingArea *)arg0); + GTK4_NATIVE_EXIT(env, that, gtk_1drawing_1area_1get_1content_1height_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1drawing_1area_1get_1content_1width +JNIEXPORT jint JNICALL GTK4_NATIVE(gtk_1drawing_1area_1get_1content_1width) + (JNIEnv *env, jclass that, jlong arg0) +{ + jint rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1drawing_1area_1get_1content_1width_FUNC); + rc = (jint)gtk_drawing_area_get_content_width((GtkDrawingArea *)arg0); + GTK4_NATIVE_EXIT(env, that, gtk_1drawing_1area_1get_1content_1width_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1drawing_1area_1new +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1drawing_1area_1new) + (JNIEnv *env, jclass that) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1drawing_1area_1new_FUNC); + rc = (jlong)gtk_drawing_area_new(); + GTK4_NATIVE_EXIT(env, that, gtk_1drawing_1area_1new_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1drawing_1area_1set_1content_1height +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1drawing_1area_1set_1content_1height) + (JNIEnv *env, jclass that, jlong arg0, jint arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1drawing_1area_1set_1content_1height_FUNC); + gtk_drawing_area_set_content_height((GtkDrawingArea *)arg0, (int)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1drawing_1area_1set_1content_1height_FUNC); +} +#endif + +#ifndef NO_gtk_1drawing_1area_1set_1content_1width +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1drawing_1area_1set_1content_1width) + (JNIEnv *env, jclass that, jlong arg0, jint arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1drawing_1area_1set_1content_1width_FUNC); + gtk_drawing_area_set_content_width((GtkDrawingArea *)arg0, (int)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1drawing_1area_1set_1content_1width_FUNC); +} +#endif + +#ifndef NO_gtk_1drawing_1area_1set_1draw_1func +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1drawing_1area_1set_1draw_1func) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jlong arg3) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1drawing_1area_1set_1draw_1func_FUNC); + gtk_drawing_area_set_draw_func((GtkDrawingArea *)arg0, (GtkDrawingAreaDrawFunc)arg1, (gpointer)arg2, (GDestroyNotify)arg3); + GTK4_NATIVE_EXIT(env, that, gtk_1drawing_1area_1set_1draw_1func_FUNC); +} +#endif + #ifndef NO_gtk_1drop_1target_1async_1new JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1drop_1target_1async_1new) (JNIEnv *env, jclass that, jlong arg0, jint arg1) @@ -2072,6 +2138,116 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1native_1get_1surface) } #endif +#ifndef NO_gtk_1overlay_1add_1overlay +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1overlay_1add_1overlay) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1add_1overlay_FUNC); + gtk_overlay_add_overlay((GtkOverlay *)arg0, (GtkWidget *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1add_1overlay_FUNC); +} +#endif + +#ifndef NO_gtk_1overlay_1get_1child +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1overlay_1get_1child) + (JNIEnv *env, jclass that, jlong arg0) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1get_1child_FUNC); + rc = (jlong)gtk_overlay_get_child((GtkOverlay *)arg0); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1get_1child_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1overlay_1get_1clip_1overlay +JNIEXPORT jboolean JNICALL GTK4_NATIVE(gtk_1overlay_1get_1clip_1overlay) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + jboolean rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1get_1clip_1overlay_FUNC); + rc = (jboolean)gtk_overlay_get_clip_overlay((GtkOverlay *)arg0, (GtkWidget *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1get_1clip_1overlay_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1overlay_1get_1measure_1overlay +JNIEXPORT jboolean JNICALL GTK4_NATIVE(gtk_1overlay_1get_1measure_1overlay) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + jboolean rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1get_1measure_1overlay_FUNC); + rc = (jboolean)gtk_overlay_get_measure_overlay((GtkOverlay *)arg0, (GtkWidget *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1get_1measure_1overlay_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1overlay_1get_1type +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1overlay_1get_1type) + (JNIEnv *env, jclass that) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1get_1type_FUNC); + rc = (jlong)gtk_overlay_get_type(); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1get_1type_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1overlay_1new +JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1overlay_1new) + (JNIEnv *env, jclass that) +{ + jlong rc = 0; + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1new_FUNC); + rc = (jlong)gtk_overlay_new(); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1new_FUNC); + return rc; +} +#endif + +#ifndef NO_gtk_1overlay_1remove_1overlay +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1overlay_1remove_1overlay) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1remove_1overlay_FUNC); + gtk_overlay_remove_overlay((GtkOverlay *)arg0, (GtkWidget *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1remove_1overlay_FUNC); +} +#endif + +#ifndef NO_gtk_1overlay_1set_1child +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1overlay_1set_1child) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1set_1child_FUNC); + gtk_overlay_set_child((GtkOverlay *)arg0, (GtkWidget *)arg1); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1set_1child_FUNC); +} +#endif + +#ifndef NO_gtk_1overlay_1set_1clip_1overlay +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1overlay_1set_1clip_1overlay) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jboolean arg2) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1set_1clip_1overlay_FUNC); + gtk_overlay_set_clip_overlay((GtkOverlay *)arg0, (GtkWidget *)arg1, (gboolean)arg2); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1set_1clip_1overlay_FUNC); +} +#endif + +#ifndef NO_gtk_1overlay_1set_1measure_1overlay +JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1overlay_1set_1measure_1overlay) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jboolean arg2) +{ + GTK4_NATIVE_ENTER(env, that, gtk_1overlay_1set_1measure_1overlay_FUNC); + gtk_overlay_set_measure_overlay((GtkOverlay *)arg0, (GtkWidget *)arg1, (gboolean)arg2); + GTK4_NATIVE_EXIT(env, that, gtk_1overlay_1set_1measure_1overlay_FUNC); +} +#endif + #ifndef NO_gtk_1picture_1new JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1picture_1new) (JNIEnv *env, jclass that) 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 efc66650c7d..230414885c0 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 @@ -101,6 +101,12 @@ typedef enum { gtk_1drag_1source_1new_FUNC, gtk_1drag_1source_1set_1actions_FUNC, gtk_1drag_1source_1set_1icon_FUNC, + gtk_1drawing_1area_1get_1content_1height_FUNC, + gtk_1drawing_1area_1get_1content_1width_FUNC, + gtk_1drawing_1area_1new_FUNC, + gtk_1drawing_1area_1set_1content_1height_FUNC, + gtk_1drawing_1area_1set_1content_1width_FUNC, + gtk_1drawing_1area_1set_1draw_1func_FUNC, gtk_1drop_1target_1async_1new_FUNC, gtk_1drop_1target_1async_1set_1formats_FUNC, gtk_1editable_1get_1delegate_FUNC, @@ -169,6 +175,16 @@ typedef enum { gtk_1named_1action_1new_FUNC, gtk_1native_1get_1for_1surface_FUNC, gtk_1native_1get_1surface_FUNC, + gtk_1overlay_1add_1overlay_FUNC, + gtk_1overlay_1get_1child_FUNC, + gtk_1overlay_1get_1clip_1overlay_FUNC, + gtk_1overlay_1get_1measure_1overlay_FUNC, + gtk_1overlay_1get_1type_FUNC, + gtk_1overlay_1new_FUNC, + gtk_1overlay_1remove_1overlay_FUNC, + gtk_1overlay_1set_1child_FUNC, + gtk_1overlay_1set_1clip_1overlay_FUNC, + gtk_1overlay_1set_1measure_1overlay_FUNC, gtk_1picture_1new_FUNC, gtk_1picture_1set_1can_1shrink_FUNC, gtk_1picture_1set_1paintable_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 3c03bc15386..6fd64776b05 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 @@ -1064,4 +1064,78 @@ public class GTK4 { */ public static final native long gtk_gesture_get_last_updated_sequence(long gesture); + /** + */ + public static final native long gtk_drawing_area_new(); + /** + * + * @param self cast=(GtkDrawingArea *) + * @param draw_func cast=(GtkDrawingAreaDrawFunc) + * @param user_data cast=(gpointer) + * @param destroy cast=(GDestroyNotify) + */ + public static final native void gtk_drawing_area_set_draw_func(long self, long draw_func, long user_data, long destroy); + /** + * @param self cast=(GtkDrawingArea *) + */ + public static final native int gtk_drawing_area_get_content_height (long self); + /** + * @param self cast=(GtkDrawingArea *) + */ + public static final native int gtk_drawing_area_get_content_width (long self); + /** + * @param self cast=(GtkDrawingArea *) + * @param height cast=(int) + */ + public static final native void gtk_drawing_area_set_content_height (long self, int height); + /** + * @param self cast=(GtkDrawingArea *) + * @param width cast=(int) + */ + public static final native void gtk_drawing_area_set_content_width (long self, int width); + + public static final native long gtk_overlay_get_type(); + public static final native long gtk_overlay_new(); + + /** + * @param overlay cast=(GtkOverlay *) + * @param widget cast=(GtkWidget *) + */ + public static final native void gtk_overlay_add_overlay (long overlay, long widget); + /** + * @param overlay cast=(GtkOverlay *) + * @param widget cast=(GtkWidget *) + */ + public static final native void gtk_overlay_remove_overlay (long overlay, long widget); + /** + * @param overlay cast=(GtkOverlay *) + * @param widget cast=(GtkWidget *) + */ + public static final native void gtk_overlay_set_child (long overlay, long widget); + /** + * @param overlay cast=(GtkOverlay *) + */ + public static final native long gtk_overlay_get_child (long overlay); + /** + * @param overlay cast=(GtkOverlay *) + * @param widget cast=(GtkWidget *) + */ + public static final native boolean gtk_overlay_get_measure_overlay (long overlay, long widget); + /** + * @param overlay cast=(GtkOverlay *) + * @param widget cast=(GtkWidget *) + * @param measure cast=(gboolean) + */ + public static final native void gtk_overlay_set_measure_overlay (long overlay, long widget, boolean measure); + /** + * @param overlay cast=(GtkOverlay *) + * @param widget cast=(GtkWidget *) + */ + public static final native boolean gtk_overlay_get_clip_overlay (long overlay, long widget); + /** + * @param overlay cast=(GtkOverlay *) + * @param widget cast=(GtkWidget *) + * @param clip_overlay cast=(gboolean) + */ + public static final native void gtk_overlay_set_clip_overlay (long overlay, long widget, boolean clip_overlay); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java index 885e0dbd082..0e28ff1a701 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java @@ -50,7 +50,9 @@ * @noextend This class is not intended to be subclassed by clients. */ public class Button extends Control { - long boxHandle, labelHandle, imageHandle, arrowHandle, groupHandle; + private long drawingAreaHandle; + private long overlayaHandle; + private long boxHandle, labelHandle, imageHandle, arrowHandle, groupHandle; boolean selected, grayed; /** True iff this toggle button requires special theme handling. See bug 546552.*/ boolean toggleButtonTheming; @@ -389,7 +391,16 @@ void createHandle (int index) { if (imageHandle == 0) error(SWT.ERROR_NO_HANDLES); if (GTK.GTK4) { - GTK.gtk_widget_set_parent(boxHandle, handle); + drawingAreaHandle = GTK4.gtk_drawing_area_new(); + GTK.gtk_widget_set_hexpand(drawingAreaHandle, true); + GTK.gtk_widget_set_vexpand(drawingAreaHandle, true); + GTK4.gtk_drawing_area_set_draw_func(drawingAreaHandle, display.gtk4DrawProc, handle, 0); + + overlayaHandle = GTK4.gtk_overlay_new(); + GTK4.gtk_overlay_add_overlay(overlayaHandle, drawingAreaHandle); + + GTK.gtk_widget_set_parent(overlayaHandle, handle); + GTK4.gtk_overlay_set_child(overlayaHandle, boxHandle); GTK4.gtk_box_append(boxHandle, imageHandle); GTK4.gtk_box_append(boxHandle, labelHandle); } else { @@ -454,6 +465,8 @@ void checkBackground() { @Override void deregister () { super.deregister (); + if (drawingAreaHandle != 0) display.removeWidget (drawingAreaHandle); + if (overlayaHandle != 0) display.removeWidget (overlayaHandle); if (boxHandle != 0) display.removeWidget (boxHandle); if (labelHandle != 0) display.removeWidget (labelHandle); if (imageHandle != 0) display.removeWidget (imageHandle); @@ -720,6 +733,8 @@ boolean mnemonicMatch (char key) { @Override void register () { super.register (); + if (drawingAreaHandle != 0) display.addWidget (drawingAreaHandle, this); + if (overlayaHandle != 0) display.addWidget (overlayaHandle, this); if (boxHandle != 0) display.addWidget (boxHandle, this); if (labelHandle != 0) display.addWidget (labelHandle, this); if (imageHandle != 0) display.addWidget (imageHandle, this); @@ -729,6 +744,7 @@ void register () { @Override void releaseHandle () { super.releaseHandle (); + overlayaHandle = drawingAreaHandle = 0; boxHandle = imageHandle = labelHandle = arrowHandle = 0; } @@ -737,7 +753,9 @@ void releaseWidget() { super.releaseWidget(); if (GTK.GTK4) { - if (boxHandle != 0) GTK.gtk_widget_unparent(boxHandle); + // TODO review this with the new overlay work + if (overlayaHandle != 0) GTK.gtk_widget_unparent(overlayaHandle); +// if (boxHandle != 0) GTK.gtk_widget_unparent(boxHandle); } // Release reference to hidden GtkCheckButton that allows for SWT.RADIO behavior @@ -1290,6 +1308,7 @@ public void setText (String string) { } private void updateWidgetsVisibility() { + // TODO what do I need to do on show widget for overlay/drawing area if (text.length() == 0 && image == null) { gtk_widget_hide (boxHandle); gtk_widget_hide (labelHandle); @@ -1310,6 +1329,7 @@ private void updateWidgetsVisibility() { @Override void showWidget () { super.showWidget (); + // TODO what do I need to do on show widget for overlay/drawing area if (boxHandle != 0 && ((text != null && text.length() != 0) || image != null)) gtk_widget_show (boxHandle); if (labelHandle != 0 && text != null && text.length() != 0) gtk_widget_show (labelHandle); if (arrowHandle != 0) gtk_widget_show (arrowHandle); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java index 6ca8783717e..5c7cb58a61d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java @@ -176,10 +176,11 @@ long gtk_draw (long widget, long cairo) { } @Override -void gtk4_draw (long widget, long cairo, Rectangle bounds) { - if ((state & OBSCURED) != 0) return; - super.gtk4_draw (widget, cairo, bounds); - drawCaretInFocus(widget, cairo); +void gtk4_draw (long cairo, int width, int height) { +// TODO +// if ((state & OBSCURED) != 0) return; +// super.gtk4_draw (widget, cairo, bounds); +// drawCaretInFocus(widget, cairo); } void drawCaretInFocus(long widget, long cairo) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index b193dd7be60..a0ed02292c5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -520,14 +520,7 @@ private void hookWidgetSignals(long focusHandle) { private void hookPaintSignals() { long paintHandle = paintHandle(); - if (GTK.GTK4) { - long widgetClass = GTK.GTK_WIDGET_GET_CLASS(paintHandle()); - GtkWidgetClass widgetClassStruct = new GtkWidgetClass(); - - OS.memmove(widgetClassStruct, widgetClass); - widgetClassStruct.snapshot = display.snapshotDrawProc; - OS.memmove(widgetClass, widgetClassStruct); - } else { + if (!GTK.GTK4) { int paintMask = GDK.GDK_EXPOSURE_MASK; GTK3.gtk_widget_add_events (paintHandle, paintMask); OS.g_signal_connect_closure_by_id (paintHandle, display.signalIds [DRAW], 0, display.getClosure (EXPOSE_EVENT_INVERSE), false); @@ -3834,10 +3827,8 @@ void cairoClipRegion (long cairo) { eventRegion = actualRegion; } - - @Override -void gtk4_draw(long widget, long cairo, Rectangle bounds) { +void gtk4_draw(long cairo, int width, int height) { if (!hooksPaint()) return; GCData data = new GCData(); @@ -3847,7 +3838,7 @@ void gtk4_draw(long widget, long cairo, Rectangle bounds) { Event event = new Event(); event.count = 1; event.gc = gc; - event.setBounds(bounds); + event.setBounds(new Rectangle(0, 0, width, height)); drawWidget(gc); sendEvent(SWT.Paint, event); 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 132f293b132..aee684b80cd 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 @@ -133,13 +133,13 @@ public class Display extends Device implements Executor { Callback eventCallback; long eventProc, windowProc2, windowProc3, windowProc4, windowProc5, windowProc6; long changeValueProc; - long snapshotDrawProc, keyPressReleaseProc, focusProc, windowActiveProc, enterMotionProc, leaveProc, + long gtk4DrawProc, keyPressReleaseProc, focusProc, windowActiveProc, enterMotionProc, leaveProc, scrollProc, resizeProc, activateProc, gesturePressReleaseProc; long notifyProc; long computeSizeProc; Callback windowCallback2, windowCallback3, windowCallback4, windowCallback5, windowCallback6; Callback changeValue; - Callback snapshotDraw, keyPressReleaseCallback, focusCallback, windowActiveCallback, enterMotionCallback, computeSizeCallback, + Callback gtk4Draw, keyPressReleaseCallback, focusCallback, windowActiveCallback, enterMotionCallback, computeSizeCallback, scrollCallback, leaveCallback, resizeCallback, activateCallback, gesturePressReleaseCallback; Callback notifyCallback; EventTable eventTable, filterTable; @@ -1717,16 +1717,10 @@ static long rendererClassInitProc (long g_class, long class_data) { return 0; } -void snapshotDrawProc(long handle, long snapshot) { +void gtk4DrawProc(long drawing_area, long cairo, int width, int height, long user_data) { Display display = getCurrent (); - Widget widget = display.getWidget (handle); - if (widget != null) widget.snapshotToDraw(handle, snapshot); - long child = GTK4.gtk_widget_get_first_child(handle); - // Propagate the snapshot down the widget tree - while (child != 0) { - GTK4.gtk_widget_snapshot_child(handle, child, snapshot); - child = GTK4.gtk_widget_get_next_sibling(child); - } + Widget widget = display.getWidget (user_data); + if (widget != null) widget.gtk4_draw(cairo, width, height); } static long rendererGetPreferredWidthProc (long cell, long handle, long minimun_size, long natural_size) { @@ -3565,8 +3559,8 @@ void initializeCallbacks () { windowProc2 = windowCallback2.getAddress (); if (GTK.GTK4) { - snapshotDraw = new Callback(this, "snapshotDrawProc", void.class, new Type[] {long.class, long.class}); //$NON-NLS-1$ - snapshotDrawProc = snapshotDraw.getAddress(); + gtk4Draw = new Callback(this, "gtk4DrawProc", void.class, new Type[] {long.class, long.class, int.class, int.class, long.class}); //$NON-NLS-1$ + gtk4DrawProc = gtk4Draw.getAddress(); keyPressReleaseCallback = new Callback(this, "keyPressReleaseProc", boolean.class, new Type[] { long.class, int.class, int.class, int.class, long.class}); //$NON-NLS-1$ @@ -4697,9 +4691,9 @@ void releaseDisplay () { gesturePressReleaseCallback = null; gesturePressReleaseProc = 0; - snapshotDraw.dispose(); - snapshotDraw = null; - snapshotDrawProc = 0; + gtk4Draw.dispose(); + gtk4Draw = null; + gtk4DrawProc = 0; } notifyCallback.dispose(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java index 46fabc5b44a..d48d916036b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java @@ -18,7 +18,6 @@ import org.eclipse.swt.*; import org.eclipse.swt.events.*; -import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.gtk.*; import org.eclipse.swt.internal.gtk3.*; @@ -962,7 +961,7 @@ long gtk_draw (long widget, long cairo) { return 0; } -void gtk4_draw(long widget, long cairo, Rectangle bounds) {} +void gtk4_draw(long cairo, int width, int height) {} long gtk_focus (long widget, long event) { return 0; @@ -2283,28 +2282,6 @@ long sizeRequestProc (long handle, long arg0, long user_data) { return 0; } -/** - * Converts an incoming snapshot into a gtk_draw() call, complete with - * a Cairo context. - * - * @param handle the widget receiving the snapshot - * @param snapshot the actual GtkSnapshot - */ -void snapshotToDraw (long handle, long snapshot) { - GtkAllocation allocation = new GtkAllocation(); - GTK.gtk_widget_get_allocation(handle, allocation); - long rect = Graphene.graphene_rect_alloc(); - Graphene.graphene_rect_init(rect, 0, 0, allocation.width, allocation.height); - - long cairo = GTK4.gtk_snapshot_append_cairo(snapshot, rect); - if (cairo != 0) { - Rectangle bounds = new Rectangle(0, 0, allocation.width, allocation.height); - gtk4_draw(handle, cairo, bounds); - } - - Graphene.graphene_rect_free(rect); -} - long gtk_widget_get_window (long widget){ GTK.gtk_widget_realize(widget); return GTK3.gtk_widget_get_window (widget);