Skip to content

Commit d420530

Browse files
committed
[Gtk4] Implement Control.print
Implementation of this method had no port to Gtk 4 api and was causing troubles by calling into no-longer existing 3.x APIs
1 parent 35d3f4d commit d420530

4 files changed

Lines changed: 148 additions & 12 deletions

File tree

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,16 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1content_1serializer_1set_1task_1data)
601601
}
602602
#endif
603603

604+
#ifndef NO_gdk_1paintable_1snapshot
605+
JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1paintable_1snapshot)
606+
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2, jint arg3)
607+
{
608+
GTK4_NATIVE_ENTER(env, that, gdk_1paintable_1snapshot_FUNC);
609+
gdk_paintable_snapshot((GdkPaintable *)arg0, (GdkSnapshot *)arg1, (double)arg2, (double)arg3);
610+
GTK4_NATIVE_EXIT(env, that, gdk_1paintable_1snapshot_FUNC);
611+
}
612+
#endif
613+
604614
#ifndef NO_gdk_1toplevel_1focus
605615
JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1toplevel_1focus)
606616
(JNIEnv *env, jclass that, jlong arg0, jint arg1)
@@ -682,6 +692,26 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gdk_1toplevel_1size_1set_1size)
682692
}
683693
#endif
684694

695+
#ifndef NO_gsk_1render_1node_1draw
696+
JNIEXPORT void JNICALL GTK4_NATIVE(gsk_1render_1node_1draw)
697+
(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
698+
{
699+
GTK4_NATIVE_ENTER(env, that, gsk_1render_1node_1draw_FUNC);
700+
gsk_render_node_draw((GskRenderNode *)arg0, (cairo_t *)arg1);
701+
GTK4_NATIVE_EXIT(env, that, gsk_1render_1node_1draw_FUNC);
702+
}
703+
#endif
704+
705+
#ifndef NO_gsk_1render_1node_1unref
706+
JNIEXPORT void JNICALL GTK4_NATIVE(gsk_1render_1node_1unref)
707+
(JNIEnv *env, jclass that, jlong arg0)
708+
{
709+
GTK4_NATIVE_ENTER(env, that, gsk_1render_1node_1unref_FUNC);
710+
gsk_render_node_unref((GskRenderNode *)arg0);
711+
GTK4_NATIVE_EXIT(env, that, gsk_1render_1node_1unref_FUNC);
712+
}
713+
#endif
714+
685715
#ifndef NO_gtk_1box_1append
686716
JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1box_1append)
687717
(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
@@ -2322,6 +2352,30 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1snapshot_1append_1cairo)
23222352
}
23232353
#endif
23242354

2355+
#ifndef NO_gtk_1snapshot_1free_1to_1node
2356+
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1snapshot_1free_1to_1node)
2357+
(JNIEnv *env, jclass that, jlong arg0)
2358+
{
2359+
jlong rc = 0;
2360+
GTK4_NATIVE_ENTER(env, that, gtk_1snapshot_1free_1to_1node_FUNC);
2361+
rc = (jlong)gtk_snapshot_free_to_node((GtkSnapshot *)arg0);
2362+
GTK4_NATIVE_EXIT(env, that, gtk_1snapshot_1free_1to_1node_FUNC);
2363+
return rc;
2364+
}
2365+
#endif
2366+
2367+
#ifndef NO_gtk_1snapshot_1new
2368+
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1snapshot_1new)
2369+
(JNIEnv *env, jclass that)
2370+
{
2371+
jlong rc = 0;
2372+
GTK4_NATIVE_ENTER(env, that, gtk_1snapshot_1new_FUNC);
2373+
rc = (jlong)gtk_snapshot_new();
2374+
GTK4_NATIVE_EXIT(env, that, gtk_1snapshot_1new_FUNC);
2375+
return rc;
2376+
}
2377+
#endif
2378+
23252379
#ifndef NO_gtk_1style_1context_1add_1provider_1for_1display
23262380
JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1style_1context_1add_1provider_1for_1display)
23272381
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2)
@@ -2697,6 +2751,18 @@ JNIEXPORT void JNICALL GTK4_NATIVE(gtk_1widget_1measure)
26972751
}
26982752
#endif
26992753

2754+
#ifndef NO_gtk_1widget_1paintable_1new
2755+
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1widget_1paintable_1new)
2756+
(JNIEnv *env, jclass that, jlong arg0)
2757+
{
2758+
jlong rc = 0;
2759+
GTK4_NATIVE_ENTER(env, that, gtk_1widget_1paintable_1new_FUNC);
2760+
rc = (jlong)gtk_widget_paintable_new((GtkWidget *)arg0);
2761+
GTK4_NATIVE_EXIT(env, that, gtk_1widget_1paintable_1new_FUNC);
2762+
return rc;
2763+
}
2764+
#endif
2765+
27002766
#ifndef NO_gtk_1widget_1pick
27012767
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1widget_1pick)
27022768
(JNIEnv *env, jclass that, jlong arg0, jdouble arg1, jdouble arg2, jint arg3)

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,16 @@ typedef enum {
6666
gdk_1content_1serializer_1return_1error_FUNC,
6767
gdk_1content_1serializer_1return_1success_FUNC,
6868
gdk_1content_1serializer_1set_1task_1data_FUNC,
69+
gdk_1paintable_1snapshot_FUNC,
6970
gdk_1toplevel_1focus_FUNC,
7071
gdk_1toplevel_1get_1state_FUNC,
7172
gdk_1toplevel_1lower_FUNC,
7273
gdk_1toplevel_1set_1icon_1list_FUNC,
7374
gdk_1toplevel_1size_1get_1bounds_FUNC,
7475
gdk_1toplevel_1size_1set_1min_1size_FUNC,
7576
gdk_1toplevel_1size_1set_1size_FUNC,
77+
gsk_1render_1node_1draw_FUNC,
78+
gsk_1render_1node_1unref_FUNC,
7679
gtk_1box_1append_FUNC,
7780
gtk_1box_1insert_1child_1after_FUNC,
7881
gtk_1box_1prepend_FUNC,
@@ -190,6 +193,8 @@ typedef enum {
190193
gtk_1shortcut_1controller_1set_1scope_FUNC,
191194
gtk_1shortcut_1new_FUNC,
192195
gtk_1snapshot_1append_1cairo_FUNC,
196+
gtk_1snapshot_1free_1to_1node_FUNC,
197+
gtk_1snapshot_1new_FUNC,
193198
gtk_1style_1context_1add_1provider_1for_1display_FUNC,
194199
gtk_1style_1context_1get_1border_FUNC,
195200
gtk_1style_1context_1get_1color_FUNC,
@@ -218,6 +223,7 @@ typedef enum {
218223
gtk_1widget_1insert_1after_FUNC,
219224
gtk_1widget_1insert_1before_FUNC,
220225
gtk_1widget_1measure_FUNC,
226+
gtk_1widget_1paintable_1new_FUNC,
221227
gtk_1widget_1pick_FUNC,
222228
gtk_1widget_1set_1cursor_FUNC,
223229
gtk_1widget_1set_1focusable_FUNC,

bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ public class GTK4 {
172172
/** @param surface cast=(GdkToplevel *) */
173173
public static final native void gdk_toplevel_focus(long surface, int timestamp);
174174

175+
175176
/* GtkDragSource */
176177
public static final native long gtk_drag_source_new();
177178
/**
@@ -725,6 +726,10 @@ public class GTK4 {
725726
* @param next_sibling cast=(GtkWidget *)
726727
*/
727728
public static final native void gtk_widget_insert_before(long widget, long parent, long next_sibling);
729+
/**
730+
* @param widget cast=(GtkWidget *)
731+
*/
732+
public static final native long gtk_widget_paintable_new(long widget);
728733
/**
729734
* @param widget cast=(GtkWidget *)
730735
* @param x cast=(double)
@@ -738,12 +743,19 @@ public class GTK4 {
738743
public static final native long gtk_combo_box_get_child(long combo_box);
739744

740745
/* GtkSnapshot */
746+
747+
public static final native long gtk_snapshot_new();
741748
/**
742749
* @param snapshot cast=(GtkSnapshot *)
743750
* @param rect cast=(const graphene_rect_t *)
744751
*/
745752
public static final native long gtk_snapshot_append_cairo(long snapshot, long rect);
746753

754+
/**
755+
* @param snapshot cast=(GtkSnapshot *)
756+
*/
757+
public static final native long gtk_snapshot_free_to_node(long snapshot);
758+
747759
/* GtkImage */
748760
/**
749761
* @param image cast=(GtkImage *)
@@ -1087,5 +1099,21 @@ public class GTK4 {
10871099
public static final native int gtk_widget_get_height(long widget);
10881100

10891101
public static final native long gtk_header_bar_new();
1102+
/**
1103+
* @param paintable cast=(GdkPaintable *)
1104+
* @param snapshot cast=(GdkSnapshot *)
1105+
* @param width cast=(double)
1106+
* @param height cast=(double)
1107+
*/
1108+
public static final native void gdk_paintable_snapshot(long paintable, long snapshot, int width, int height);
10901109

1110+
/**
1111+
* @param renderNode cast=(GskRenderNode *)
1112+
* @param cr cast=(cairo_t *)
1113+
*/
1114+
public static final native void gsk_render_node_draw(long renderNode, long cr);
1115+
/**
1116+
* @param renderNode cast=(GskRenderNode *)
1117+
*/
1118+
public static final native void gsk_render_node_unref(long renderNode);
10911119
}

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -626,18 +626,54 @@ public boolean print (GC gc) {
626626
if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
627627
long topHandle = topHandle ();
628628
GTK.gtk_widget_realize (topHandle);
629-
/*
630-
* Feature in GTK: gtk_widget_draw() will only draw if the
631-
* widget's priv->alloc_needed field is set to TRUE. Since
632-
* this field is private and inaccessible, get and set the
633-
* allocation to trigger it to be TRUE. See bug 530969.
634-
*/
635-
GtkAllocation allocation = new GtkAllocation ();
636-
GTK.gtk_widget_get_allocation(topHandle, allocation);
637-
// Prevent allocation warnings
638-
GTK.gtk_widget_get_preferred_size(topHandle, null, null);
639-
GTK3.gtk_widget_size_allocate(topHandle, allocation);
640-
GTK3.gtk_widget_draw(topHandle, gc.handle);
629+
630+
if (GTK.GTK4) {
631+
/*
632+
* In GTK4 gtk_widget_draw() has been removed. Rendering is now
633+
* done via GtkSnapshot and the GskRenderNode pipeline. Snapshot the widget,
634+
* extract the render node, then draw it onto the GC's Cairo context using
635+
* gsk_render_node_draw().
636+
*/
637+
638+
long widgetPaintable = GTK4.gtk_widget_paintable_new(topHandle);
639+
if (widgetPaintable == 0) return false;
640+
try {
641+
int width = GTK4.gtk_widget_get_width(topHandle);
642+
int height = GTK4.gtk_widget_get_height(topHandle);
643+
644+
long snapshot = GTK4.gtk_snapshot_new();
645+
if (snapshot == 0) return false;
646+
647+
try {
648+
GTK4.gdk_paintable_snapshot(widgetPaintable, snapshot, width, height);
649+
650+
long renderNode = GTK4.gtk_snapshot_free_to_node(snapshot);
651+
snapshot = 0; // freed by gtk_snapshot_free_to_node
652+
653+
if (renderNode == 0) return false;
654+
655+
GTK4.gsk_render_node_draw(renderNode, gc.handle);
656+
GTK4.gsk_render_node_unref(renderNode);
657+
} finally {
658+
if (snapshot != 0) OS.g_object_unref(snapshot);
659+
}
660+
} finally {
661+
OS.g_object_unref(widgetPaintable);
662+
}
663+
} else {
664+
/*
665+
* In GTK 3 gtk_widget_draw() will only draw if the
666+
* widget's priv->alloc_needed field is set to TRUE. Since
667+
* this field is private and inaccessible, get and set the
668+
* allocation to trigger it to be TRUE. See bug 530969.
669+
*/
670+
GtkAllocation allocation = new GtkAllocation ();
671+
GTK.gtk_widget_get_allocation(topHandle, allocation);
672+
// Prevent allocation warnings
673+
GTK.gtk_widget_get_preferred_size(topHandle, null, null);
674+
GTK3.gtk_widget_size_allocate(topHandle, allocation);
675+
GTK3.gtk_widget_draw(topHandle, gc.handle);
676+
}
641677
return true;
642678
}
643679

0 commit comments

Comments
 (0)