From fe6600234cafe16afb1d06a0254d2135ffb71b12 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 11 Sep 2019 04:16:31 +0200 Subject: Bug 1394 - NEWT X11Window didn't gather inset at window creation (properly) X11Window.c's 'NewtWindows_getFrameExtends(..)' retrieves the insets via XGetWindowProperty on _NET_FRAME_EXTENTS. Right after window creation this method fails as the WM did not yet provide the information as the window has not yet been mapped. Implementation needs to retry for a certain amount of time (250ms) and maximum number of attempts (96 XEvent). This issue surfaced while validating fix for Bug 1393, testing TestDisplayLifecycle02NEWT also on X11. --- src/newt/native/X11Window.c | 62 +++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 16 deletions(-) (limited to 'src/newt') diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 7ddc5d3d0..6c163ea88 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -63,6 +63,14 @@ #endif +#include + +static int64_t getCurrentMillis() { + struct timeval tv; + gettimeofday(&tv,NULL); + return (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + #define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask) static int putPtrIn32Long(unsigned long * dst, uintptr_t src) { @@ -321,31 +329,41 @@ static void NewtWindows_setCWAbove(Display *dpy, Window w) { xwc.stack_mode = Above; XConfigureWindow(dpy, w, CWStackMode, &xwc); } -static Status NewtWindows_getWindowPositionRelative2Parent (Display *dpy, Window w, int *x_return, int *y_return) { +static Bool NewtWindows_getWindowPositionRelative2Parent (Display *dpy, Window win, Window winParent, int *x_return, int *y_return) { + Window child; + return XTranslateCoordinates(dpy, win, winParent, 0, 0, x_return, y_return, &child); +} +static Status NewtWindows_getWindowTopLeftPositionRelative2Parent (Display *dpy, Window win, int *x_return, int *y_return) { Window root_return; unsigned int width_return, height_return; unsigned int border_width_return; unsigned int depth_return; - if(0 != XGetGeometry(dpy, w, &root_return, x_return, y_return, &width_return, - &height_return, &border_width_return, &depth_return)) { + if(0 != XGetGeometry(dpy, win, &root_return, x_return, y_return, &width_return, + &height_return, &border_width_return, &depth_return)) { return 1; // OK } return 0; // Error } -static Status NewtWindows_getFrameExtends(Display *dpy, JavaWindow *w, int *left, int *right, int *top, int *bottom) { +static Status NewtWindows_getFrameExtends(Display *dpy, JavaWindow *javaWin, int *left, int *right, int *top, int *bottom) { Atom actual_type = 0; int actual_format = 0; int nitems_32 = 4; // l, r, t, b unsigned char * frame_extends_data_pp = NULL; + unsigned long nitems = 0; - { - unsigned long nitems = 0; + /** Safe polling ... */ + #define TIMEOUT 250 + int64_t t0 = getCurrentMillis(); + #define MAX_ATTEMPTS 96 + int evtCount = 0; + + while( nitemswindow, w->allAtoms[_NET_FRAME_EXTENTS_IDX], 0, nitems_32, False, - AnyPropertyType, &actual_type, &actual_format, + res = XGetWindowProperty(dpy, javaWin->window, javaWin->allAtoms[_NET_FRAME_EXTENTS_IDX], + 0, nitems_32, False, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &frame_extends_data_pp); if ( Success != res ) { @@ -354,12 +372,23 @@ static Status NewtWindows_getFrameExtends(Display *dpy, JavaWindow *w, int *left } if(nitemswindow == e.xany.window)); + } else { + // timeout or max-attempts: exit + return 0; + } } } long * extends = (long*) frame_extends_data_pp; @@ -468,9 +497,9 @@ Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *righ // The following logic only works if window is top-level _and_ the WM // has 'decorated' our client window w/ another parent window _within_ the actual 'framed' window. Window parent = NewtWindows_getParent(dpy, w->window); - if(0 != NewtWindows_getWindowPositionRelative2Parent (dpy, parent, left, top)) { - *right = *left; *bottom = *top; - DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom); + if( 0 != NewtWindows_getWindowTopLeftPositionRelative2Parent (dpy, parent, left, top) ) { + *right = *left; *bottom = *left; + DBG_PRINT( "NewtWindows_updateInsets: insets relative to parent position [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom); return True; // OK } } @@ -925,8 +954,9 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind // get position from WM int dest_x, dest_y; Window child; - XTranslateCoordinates(dpy, window, windowParent, 0, 0, &dest_x, &dest_y, &child); - x = (int)dest_x; y = (int)dest_y; + if( XTranslateCoordinates(dpy, window, windowParent, 0, 0, &dest_x, &dest_y, &child) ) { + x = (int)dest_x; y = (int)dest_y; + } } DBG_PRINT("X11: [CreateWindow]: client: %d/%d %dx%d, autoPos %d\n", x, y, width, height, TST_FLAG_IS_AUTOPOSITION(flags)); -- cgit v1.2.3