NewtCanvasSWT Linux Exception with GTK_VERSION

classic Classic list List threaded Threaded
41 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

gouessej
Administrator
Thank you for the feedback. How do you use ibus to work around the bug you mentioned?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Marcel
I think this is not a JOGL bug. It is more related to GTK. You can set the environment variable as described in my previous link.

Here is described how you start an application inside of Eclipse with a variable:

https://stackoverflow.com/questions/7048216/environment-variables-in-eclipse

(see the post from aspiring_sarge)

For me only xim worked but it is said it should'nt be used (see previous post)

In the shell something like "export GTK_IM_MODULE=ibus" should work.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Marcel
This post was updated on .
In reply to this post by gouessej
However I haven't checked the console. I got now the same Eclipse error as Wade Walker already described:

The window 0x7f3d5b37fb10 already has a drawing context. You cannot call gdk_window_begin_draw_frame() without calling gdk_window_end_draw_frame() first

Maybe that's why I get the handle exception.

Probably this error is more related to SWT because Wade Walker already described that the function gdk_window_begin_draw_frame()  is not called in JOGL?

I get the handle exception when running my application from Eclipse within the console of the running application. However beside the exception the application runs fine even when I open another JOGL window in parallel,
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
In reply to this post by Marcel
I'll works some more on this over the weekend -- I just got busy this week :)
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
In reply to this post by gouessej
Here is the patch for SWTAccessor.java. I'll make another post to explain the current state of debugging.

diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index c79ed2f67..051798e9c 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -81,7 +81,9 @@ public class SWTAccessor {
     private static final String str_internal_new_GC = "internal_new_GC";
     private static final String str_internal_dispose_GC = "internal_dispose_GC";
 
-    private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";
+    private static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";    // used by earlier versions of SWT
+    private static final String str_GTK_gtk_class = "org.eclipse.swt.internal.gtk.GTK";  // used by later versions of SWT
+    private static final String str_GDK_gtk_class = "org.eclipse.swt.internal.gtk.GDK";  // used by later versions of SWT
     public static final Class<?> OS_gtk_class;
     private static final String str_OS_gtk_version = "GTK_VERSION";
     public static final VersionNumber OS_gtk_version;
@@ -96,6 +98,7 @@ public class SWTAccessor {
     private static final Method OS_gdk_x11_drawable_get_xid;
     private static final Method OS_gdk_x11_window_get_xid;
     private static final Method OS_gdk_window_set_back_pixmap;
+    private static final Method OS_gdk_window_set_background_pattern;
 
     private static final String str_gtk_widget_realize = "gtk_widget_realize";
     private static final String str_gtk_widget_unrealize = "gtk_widget_unrealize";
@@ -107,9 +110,11 @@ public class SWTAccessor {
     private static final String str_gdk_x11_drawable_get_xid = "gdk_x11_drawable_get_xid";
     private static final String str_gdk_x11_window_get_xid = "gdk_x11_window_get_xid";
     private static final String str_gdk_window_set_back_pixmap = "gdk_window_set_back_pixmap";
+    private static final String str_gdk_window_set_background_pattern = "gdk_window_set_background_pattern";
 
     private static final VersionNumber GTK_VERSION_2_14_0 = new VersionNumber(2, 14, 0);
     private static final VersionNumber GTK_VERSION_2_24_0 = new VersionNumber(2, 24, 0);
+    private static final VersionNumber GTK_VERSION_2_90_0 = new VersionNumber(2, 90, 0);
     private static final VersionNumber GTK_VERSION_3_0_0  = new VersionNumber(3,  0, 0);
 
     private static VersionNumber GTK_VERSION(final int version) {
@@ -174,13 +179,23 @@ public class SWTAccessor {
 
         Class<?> c=null;
         VersionNumber _gtk_version = new VersionNumber(0, 0, 0);
-        Method m1=null, m2=null, m3=null, m4=null, m5=null, m6=null, m7=null, m8=null, m9=null, ma=null;
+        Method m1=null, m2=null, m3=null, m4=null, m5=null, m6=null, m7=null, m8=null, m9=null, ma=null, mb=null;
         final Class<?> handleType = swt_uses_long_handles  ? long.class : int.class ;
         if( isX11 ) {
             // mandatory
             try {
                 c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
-                final Field field_OS_gtk_version = c.getField(str_OS_gtk_version);
+                Field field_OS_gtk_version;
+                Class<?> cGDK=c;  // used for newer versions of SWT that have a org.eclipse.swt.internal.gtk.GDK object
+                try {
+                    field_OS_gtk_version = c.getField(str_OS_gtk_version);
+                } catch (NoSuchFieldException ex) {
+                       // if the GTK_VERSION field didn't exist in org.eclipse.swt.internal.gtk.OS, then look for
+                       // it in org.eclipse.swt.internal.gtk.GTK, where it was moved in later versions of SWT
+                    c = ReflectionUtil.getClass(str_GTK_gtk_class, false, SWTAccessor.class.getClassLoader());
+                    field_OS_gtk_version = c.getField(str_OS_gtk_version);
+                    cGDK = ReflectionUtil.getClass(str_GDK_gtk_class, false, SWTAccessor.class.getClassLoader());
+                }
                 _gtk_version = GTK_VERSION(field_OS_gtk_version.getInt(null));
                 m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);
                 if (_gtk_version.compareTo(GTK_VERSION_2_14_0) >= 0) {
@@ -189,17 +204,22 @@ public class SWTAccessor {
                     m3 = c.getDeclaredMethod(str_GTK_WIDGET_WINDOW, handleType);
                 }
                 if (_gtk_version.compareTo(GTK_VERSION_2_24_0) >= 0) {
-                    m6 = c.getDeclaredMethod(str_gdk_x11_display_get_xdisplay, handleType);
-                    m7 = c.getDeclaredMethod(str_gdk_window_get_display, handleType);
+                    m6 = cGDK.getDeclaredMethod(str_gdk_x11_display_get_xdisplay, handleType);
+                    m7 = cGDK.getDeclaredMethod(str_gdk_window_get_display, handleType);
                 } else {
                     m5 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xdisplay, handleType);
                 }
                 if (_gtk_version.compareTo(GTK_VERSION_3_0_0) >= 0) {
-                    m9 = c.getDeclaredMethod(str_gdk_x11_window_get_xid, handleType);
+                    m9 = cGDK.getDeclaredMethod(str_gdk_x11_window_get_xid, handleType);
                 } else {
                     m8 = c.getDeclaredMethod(str_gdk_x11_drawable_get_xid, handleType);
                 }
-                ma = c.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class);
+                
+                if (_gtk_version.compareTo(GTK_VERSION_2_90_0) >= 0) {
+                    mb = cGDK.getDeclaredMethod(str_gdk_window_set_background_pattern, handleType, handleType);
+                } else {
+                    ma = c.getDeclaredMethod(str_gdk_window_set_back_pixmap, handleType, handleType, boolean.class);
+                }
             } catch (final Exception ex) { throw new NativeWindowException(ex); }
             // optional
             try {
@@ -218,6 +238,7 @@ public class SWTAccessor {
         OS_gdk_x11_drawable_get_xid = m8;
         OS_gdk_x11_window_get_xid = m9;
         OS_gdk_window_set_back_pixmap = ma;
+        OS_gdk_window_set_background_pattern = mb;
 
         isX11GTK = isX11 && null != OS_gtk_class;
 
@@ -237,6 +258,10 @@ public class SWTAccessor {
         ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg) });
     }
 
+    private static void callStaticMethodLL2V(final Method m, final long arg0, final long arg1) {
+        ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg0), getIntOrLong(arg1) });
+    }
+
     private static void callStaticMethodLLZ2V(final Method m, final long arg0, final long arg1, final boolean arg3) {
         ReflectionUtil.callMethod(null, m, new Object[] { getIntOrLong(arg0), getIntOrLong(arg1), Boolean.valueOf(arg3) });
     }
@@ -309,7 +334,13 @@ public class SWTAccessor {
     }
 
     public static void gdk_window_set_back_pixmap(final long window, final long pixmap, final boolean parent_relative) {
-        callStaticMethodLLZ2V(OS_gdk_window_set_back_pixmap, window, pixmap, parent_relative);
+       if(OS_gdk_window_set_back_pixmap != null) {
+           callStaticMethodLLZ2V(OS_gdk_window_set_back_pixmap, window, pixmap, parent_relative);
+       }
+       // in recent GTK, can't set background to pixmap any more; this sets it relative to parent
+       else if(OS_gdk_window_set_background_pattern != null) {
+               callStaticMethodLL2V(OS_gdk_window_set_background_pattern, window, 0);
+       }
     }
 
     //
@@ -510,7 +541,7 @@ public class SWTAccessor {
     public static long createCompatibleX11ChildWindow(final AbstractGraphicsScreen screen, final Control swtControl, final int visualID, final int width, final int height) {
         final long handle = getHandle(swtControl);
         final long parentWindow = gdk_widget_get_window( handle );
-        gdk_window_set_back_pixmap (parentWindow, 0, false);
+        // gdk_window_set_back_pixmap(parentWindow, 0, false);
 
         final long x11ParentHandle = gdk_window_get_xwindow(parentWindow);
         final long x11WindowHandle = X11Lib.CreateWindow(x11ParentHandle, screen.getDevice().getHandle(), screen.getIndex(), visualID, width, height, true, true);
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
In reply to this post by Marcel
I extended the timeouts on the TestNewtCanvasSWTGLn unit test, and now I can duplicate this failure even when stepping through the test in the debugger. I put breakpoints on gdk_window_begin_draw_frame() and gdk_window_end_draw_frame() in the GDK library so I could check if any calls to these are unpaired.

But they aren't! I see six properly paired calls to begin/end, then on the seventh begin, it throws the
(SWT:15054): Gdk-CRITICAL **: 07:54:54.539: The window 0x7f073d2ec640 already has a drawing context. You cannot call gdk_window_begin_draw_frame() without calling gdk_window_end_draw_frame() first.
 The error always happens after the same number of calls, and is perfectly reproducible.

What's more, these calls to gdk_window_begin_draw_frame()/gdk_window_end_draw_frame() are always in a call stack of pure GTK/SWT code. There's no JOGL code at all being invoked during window event processing. JOGL calls Display.readAndDispatch() at the top level, but that's it. This makes me think the problem has to do with how the NewtCanvasSWT is set up in the first place, but that part of the JOGL code is pretty difficult to understand.

So in short, I think there are two bugs here. Bug #1 was that SWTAccessor didn't work with newer versions of SWT, which is fixed by the patch I posted. But bug #2 is that JOGL's NewtCanvasSWT doesn't work with GTK 3.22.30 on Ubuntu 18.04 for reasons which are still unknown.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
I added https://jogamp.org/bugzilla/show_bug.cgi?id=1362 to refer to these discussions.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
In reply to this post by Marcel
One thing I forgot to mention: you might try
export SWT_GTK3=0
 after (or instead of) your patch to SWTAccessor. It could be that GTK2 will work for you.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Marcel
Thanks for the investigation and patch.

Yes I used GTK3=0 in my previous app versions (because of embedded JavaFX GUI's. But OpenJFX now supports GTK3, too)

However SWT_GTK3=0 is no option anymore because the latest Eclipse dropped the support, see:

https://www.eclipse.org/eclipse/news/4.10/platform.php (scroll down)
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Marcel
In reply to this post by Wade Walker
@Wade Walker: Could you please file a link to a repository (Github, Gitlab, etc.) where the fixed classes could be accessed and compared.
In addition I also aplied some HighDPI fixes to the NewtCanvasSWT class to scale the canvas according to the OS settings using the DPIUtil class from SWT.

It might be that you already fixed that, too.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
@Marcel: Take a look at https://github.com/WadeWalker/gluegen/tree/java-11-fixes and https://github.com/WadeWalker/jogl/tree/java-11-fixes -- those two branches contain all the changes I've made from the base version at jogamp.com.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Marcel
Very strange. If I export my RCP for Linux everything works fine so far. I tested it on several distribution (Debian, Ubuntu, Arch).
No handle exceptions are generated.
 RCP is built upon OpenJDK 12, JOGL 2.3.2 (with patches) and Eclipse 4.11 (03.2019).
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
Do you know what version of GTK is included with Eclipse 4.11? This could be a GTK bug that's fixed now.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Marcel
In 4.11 only GTK3 is supported. They dropped GTK2 support in 4.10, see:

https://www.eclipse.org/eclipse/news/4.10/platform.php#gtk2-removal

I still get the handle error when I start the RCP from within Eclipse. Exported as a RCP product  I do not get any handle errors.
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Sven Gothel
Administrator
Thank you all for accumulating these findings.

To ensure it won't get lost,
it would be very helpful if one could
add the compilation of last findings
to Bug 1362 <https://jogamp.org/bugzilla/show_bug.cgi?id=1362>

Then either Wade or I will make sure patches will be merged
or even typing the fix ourselves ;-)

Target release is 2.4.0 (next one),
since this is a blocker.

Thank you.

On 4/3/19 2:49 PM, Marcel [via jogamp] wrote:

--
health & wealth
mailto:[hidden email] ; http://jausoft.com
land : +49 (471) 4707742 ; fax : +49 (471) 4707741
Timezone CET: PST+9, EST+6, UTC+1
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Marcel
Hello Sven,

thanks for working on this.

I already saw that you and Wade filed the bug in the bug report.

The only thing I would add would be the DPI scaling (NEWT) which I think you already described here:

http://forum.jogamp.org/JOGL-broken-with-JRE-gt-8-and-Windows-window-scaling-td4039122.html

Would it make sense to crosspost the report in the Eclipse bug database?
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Sven Gothel
Administrator
In reply to this post by Sven Gothel
I found a fix to the issue while I was creating
two clean unit tests, see comment 18 and the previous one.

https://jogamp.org/bugzilla/show_bug.cgi?id=1362#c18

Commit
https://jogamp.org/git/?p=jogl.git;a=commit;h=a2f09981ee7d590204bf865314c2cdf802c4ed77

+++
commit a2f09981ee7d590204bf865314c2cdf802c4ed77:
TestSWTAccessor02NewtGLWindow demonstrates a fix by letting the Canvas PAINT!

This commit shows the very little change set required to allow working on SWT
>= 4.10 + GTK3,
i.e. adding the PAINT listener to Canvas and letting it paint.

Almost too ridiculous? I stumbled over it by creating this test in the first place
when copying the 01 test -> 02 and adding the native parenting.

Possible explanation: The parent Canvas may need to paint once at least due to
some
lazy initialization within SWT or GTK3?!

+++

Successfull triage, next step: Fine tuning (paint only once?) and
adding to NewtCanvasSWT and our GLCanvas implementation.

Therefor, this might be a SWT issue and our patch a workaround.

+++

On 4/3/19 6:42 PM, Sven Gothel [via jogamp] wrote:

> Thank you all for accumulating these findings.
>
> To ensure it won't get lost,
> it would be very helpful if one could
> add the compilation of last findings
> to Bug 1362 <https://jogamp.org/bugzilla/show_bug.cgi?id=1362>
>
> Then either Wade or I will make sure patches will be merged
> or even typing the fix ourselves ;-)
>
> Target release is 2.4.0 (next one),
> since this is a blocker.
>
> Thank you.
>
> On 4/3/19 2:49 PM, Marcel [via jogamp] wrote:
>
>> In 4.11 only GTK3 is supported. The dropped GTK2 support
>>
>> ------------------------------------------------------------------------------
>> If you reply to this email, your message will be added to the discussion below:
>>
> http://forum.jogamp.org/NewtCanvasSWT-Linux-Exception-with-GTK-VERSION-tp4039442p4039664.html
>>
>> To start a new topic under jogl, email [hidden email]
>> To unsubscribe from jogl, click here
>> <
>> NAML
>>
> <http://forum.jogamp.org/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>
>>
>
>
> --
> health & wealth
> mailto:[hidden email] ; http://jausoft.com
> land : +49 (471) 4707742 ; fax : +49 (471) 4707741
> Timezone CET: PST+9, EST+6, UTC+1
>
>
> ------------------------------------------------------------------------------
> If you reply to this email, your message will be added to the discussion below:
> http://forum.jogamp.org/NewtCanvasSWT-Linux-Exception-with-GTK-VERSION-tp4039442p4039666.html
>
> To start a new topic under jogl, email [hidden email]
> To unsubscribe from jogl, click here
> <
> NAML
> <
http://forum.jogamp.org/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>

Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

gouessej
Administrator
Great job Sven, I wouldn't have thought about trying that :)
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Sven Gothel
Administrator
Thank you.

It was quite an interesting experience indeed.

As I debated w/ Wade in the bugzilla comments,
I advised testing the native window handle first.
So I did and it was good using a proper little SWT app.

So the next step was to 'find the difference',
knowing that we didn't do anything w/ the parent's
SWT GTK/GDK object but attach our NEWT child to it.

Hence I added the little whole parenting code in the copied
test case 02. And it worked!

Now I created a third copy 03 (not checked in)
and removed the difference to the NewtCanvasSWT test case,
i.e. the proper SWT canvas rendering.
Voila, the bug got reproduced.

Hence the issue was something added in 01,
the SWT canvas rendering.
And finally it turned out to be just the background setting.

~Sven

On 4/9/19 11:19 PM, gouessej [via jogamp] wrote:

> Great job Sven, I wouldn't have thought about trying that :)
> Julien Gouesse | Personal blog <http://gouessej.wordpress.com> | Website
> <http://tuer.sourceforge.net>
>
>
> ------------------------------------------------------------------------------
> If you reply to this email, your message will be added to the discussion below:
> http://forum.jogamp.org/NewtCanvasSWT-Linux-Exception-with-GTK-VERSION-tp4039442p4039684.html
>
> To start a new topic under jogl, email [hidden email]
> To unsubscribe from jogl, click here
> <
> NAML
> <
http://forum.jogamp.org/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>

Reply | Threaded
Open this post in threaded view
|

Re: NewtCanvasSWT Linux Exception with GTK_VERSION

Wade Walker
Administrator
I'm very glad you found this -- the next thing I was going to try was setting breakpoints on the native gdk_window_begin_draw_frame()/gdk_window_end_draw_frame() to see who initiated it the unmatched call, but it would have been difficult to see which method in the native code was responsible, and then figure out what to do about it. Your way was smarter and easier :)
123