diff options
author | Sven Gothel <[email protected]> | 2011-09-06 02:56:07 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-09-06 02:56:07 +0200 |
commit | 4faa65ee907a78649e118717574c96031dc9e79b (patch) | |
tree | ed5e034e796c4174a60de38b64382433a24bf473 /src/newt/native | |
parent | 7ea8aa31e055ba95a062c87ec4d606f73c2504fa (diff) |
NEWT/Window/Insets: Implement proper Inset usage ; Cleanup WindowImpl::reconfigureWindowImpl
Implement proper Inset usage (window decoration size)
- Insets are either polled (updateInsets()) or event driven (insetsChanged())
- Insets are used for size/pos calculations from Java side
- Natural size/pos in NEWT is client-area, ie w/o Insets
- Adding setTopLevelPosition()/setTopLevelSize() for top-level values,
ie including insets
WindowImpl::reconfigureWindowImpl
- Use flags to pass down the requested action to the native implementation
- Impl. all native actions: visible, decoration, reparent, resize, fullscreen
- Always use size/pos in client-area space, impl. shall use Insets to tranform them
- Remove double-setting of (reparent/fullscreen), which where introduced due to buggy impl. code
- Fix return from fullscreen position: Was overwritten with FS position (0/0)
- Fix decoration change: Remove visible toggle - not required, and actually disturbing
X11Windows/WindowsWindow: Added/Fixed Insets impl.
Tests (manual):
- TestSharedContextVBOES2NEWT utilizies proper window layout using Insets
- TestParenting03bAWT uses window layout for reparenting
Diffstat (limited to 'src/newt/native')
-rw-r--r-- | src/newt/native/Window.h | 24 | ||||
-rw-r--r-- | src/newt/native/WindowsWindow.c | 141 | ||||
-rw-r--r-- | src/newt/native/X11Window.c | 221 |
3 files changed, 220 insertions, 166 deletions
diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h new file mode 100644 index 000000000..f46d9fbe9 --- /dev/null +++ b/src/newt/native/Window.h @@ -0,0 +1,24 @@ + +#ifndef _WINDOW_H_ +#define _WINDOW_H_ + +#define FLAG_CHANGE_PARENTING ( 1 << 0 ) +#define FLAG_CHANGE_DECORATION ( 1 << 1 ) +#define FLAG_CHANGE_FULLSCREEN ( 1 << 2 ) +#define FLAG_CHANGE_VISIBILITY ( 1 << 3 ) +#define FLAG_HAS_PARENT ( 1 << 4 ) +#define FLAG_IS_UNDECORATED ( 1 << 5 ) +#define FLAG_IS_FULLSCREEN ( 1 << 6 ) +#define FLAG_IS_VISIBLE ( 1 << 7 ) + +#define TST_FLAG_CHANGE_PARENTING(f) ( 0 != ( (f) & FLAG_CHANGE_PARENTING ) ) +#define TST_FLAG_CHANGE_DECORATION(f) ( 0 != ( (f) & FLAG_CHANGE_DECORATION ) ) +#define TST_FLAG_CHANGE_FULLSCREEN(f) ( 0 != ( (f) & FLAG_CHANGE_FULLSCREEN ) ) +#define TST_FLAG_CHANGE_VISIBILITY(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY ) ) + +#define TST_FLAG_HAS_PARENT(f) ( 0 != ( (f) & FLAG_HAS_PARENT ) ) +#define TST_FLAG_IS_UNDECORATED(f) ( 0 != ( (f) & FLAG_IS_UNDECORATED ) ) +#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) ) +#define TST_FLAG_IS_VISIBLE(f) ( 0 != ( (f) & FLAG_IS_VISIBLE ) ) + +#endif diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 0dd1b6260..2ae50f550 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -85,6 +85,7 @@ #include "jogamp_newt_driver_windows_WindowsScreen.h" #include "jogamp_newt_driver_windows_WindowsWindow.h" +#include "Window.h" #include "MouseEvent.h" #include "InputEvent.h" #include "KeyEvent.h" @@ -666,8 +667,8 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd) (int)(m_insets.right-m_insets.left), (int)(m_insets.top-m_insets.bottom)); (*env)->CallVoidMethod(env, window, insetsChangedID, - m_insets.left, m_insets.top, - m_insets.right, m_insets.bottom); + m_insets.left, m_insets.right, + m_insets.top, m_insets.bottom); return &m_insets; } @@ -703,7 +704,6 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd) m_insets.right < 0 || m_insets.bottom < 0) { LONG style = GetWindowLong(hwnd, GWL_STYLE); - // TODO: TDV: better undecorated checking needed BOOL bIsUndecorated = (style & (WS_CHILD|WS_POPUP|WS_SYSMENU)) != 0; if (!bIsUndecorated) { @@ -728,12 +728,12 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd) } } - DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, %d/%d %dx%d\n", - (void*)hwnd, (int)m_insets.left, (int)m_insets.top, (int)(m_insets.right-m_insets.left), (int)(m_insets.top-m_insets.bottom)); + DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, [l %d, r %d - t %d, b %d - %dx%d]\n", + (void*)hwnd, (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom, + (int) ( m_insets.left + m_insets.right ), (int) (m_insets.top + m_insets.bottom)); - (*env)->CallVoidMethod(env, window, insetsChangedID, - m_insets.left, m_insets.top, - m_insets.right, m_insets.bottom); + (*env)->CallVoidMethod(env, window, insetsChangedID, + (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom); return &m_insets; } @@ -745,19 +745,19 @@ static void WmSize(JNIEnv *env, jobject window, HWND wnd, UINT type) int w, h; BOOL isVisible = IsWindowVisible(wnd); - // make sure insets are up to date - (void)UpdateInsets(env, window, wnd); - if (type == SIZE_MINIMIZED) { // TODO: deal with minimized window sizing return; } + // make sure insets are up to date + (void)UpdateInsets(env, window, wnd); + GetClientRect(wnd, &rc); // we report back the dimensions of the client area - w = rc.right - rc.left; - h = rc.bottom - rc.top; + w = (int) ( rc.right - rc.left ); + h = (int) ( rc.bottom - rc.top ); DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d, visible %d\n", (void*)wnd, w, h, isVisible); @@ -1351,8 +1351,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind #else SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud); #endif - - UpdateInsets(env, obj, window); + (void)UpdateInsets(env, wud->jinstance, window); } #ifdef UNICODE @@ -1381,80 +1380,26 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_MonitorFro #endif } -/*** - * returns bits: 1: size change, 2: pos change - */ -int NewtWindow_setVisiblePosSize(JNIEnv *env, jobject obj, HWND hwnd, jboolean top, jboolean visible, - int x, int y, int width, int height) +void NewtWindow_setVisiblePosSize(JNIEnv *env, jobject obj, HWND hwnd, + BOOL top, BOOL undecorated, BOOL visible, + int x, int y, int width, int height) { UINT flags; - HWND hWndInsertAfter; BOOL bRes; - int iRes=0; - int wwidth = width; // final window width - int wheight = height; // final window height - DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, top %d, visible %d\n", - x, y, width, height, (int)top, (int)visible); + DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, top %d, undecorated %d, visible %d\n", + x, y, width, height, top, undecorated, visible); - if(JNI_TRUE == visible) { + if(visible) { flags = SWP_SHOWWINDOW; } else { flags = SWP_NOACTIVATE | SWP_NOZORDER; } - if(0>x || 0>y ) { - flags |= SWP_NOMOVE; - } else { - iRes |= 2; - } - if(0>=width || 0>=height ) { - flags |= SWP_NOSIZE; - } else { - iRes |= 1; - } - - if(JNI_TRUE == top) { - hWndInsertAfter = HWND_TOPMOST; - if ( 0 == ( flags & SWP_NOSIZE ) ) { - - // since width, height are the size of the client area, we need to add insets - RECT *pInsets = UpdateInsets(env, obj, hwnd); - - wwidth += pInsets->left + pInsets->right; - wheight += pInsets->top + pInsets->bottom; - } - DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize top size w/ insets: %d/%d %dx%d\n", x, y, wwidth, wheight); - } else { - hWndInsertAfter = HWND_TOP; - DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize client size: %d/%d %dx%d\n", x, y, wwidth, wheight); - } - - SetWindowPos(hwnd, hWndInsertAfter, x, y, wwidth, wheight, flags); + SetWindowPos(hwnd, top ? HWND_TOPMOST : HWND_TOP, x, y, width, height, flags); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); - - return iRes; -} - -/* - * Class: jogamp_newt_driver_windows_WindowsWindow - * Method: setVisible0 - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setVisible0 - (JNIEnv *env, jobject obj, jlong window, jboolean visible, jboolean top, jint x, jint y, jint width, jint height) -{ - HWND hwnd = (HWND) (intptr_t) window; - DBG_PRINT("*** WindowsWindow: setVisible window %p, visible: %d, top %d, %d/%d %dx%d\n", - hwnd, (int)visible, (int)top, x, y, width, height); - if (visible) { - NewtWindow_setVisiblePosSize(env, obj, hwnd, top, visible, x, y, width, height); - ShowWindow(hwnd, SW_SHOW); - } else { - ShowWindow(hwnd, SW_HIDE); - } } static jboolean NewtWindows_setFullScreen(jboolean fullscreen) @@ -1478,21 +1423,23 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen) /* * Class: jogamp_newt_driver_windows_WindowsWindow * Method: reconfigureWindow0 - * Signature: (JIIIIZZII)V + * Signature: (JJIIIII)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigureWindow0 - (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, - jboolean visible, jboolean parentChange, jint fullScreenChange, jint decorationChange) + (JNIEnv *env, jobject obj, jlong parent, jlong window, + jint x, jint y, jint width, jint height, jint flags) { HWND hwndP = (HWND) (intptr_t) parent; HWND hwnd = (HWND) (intptr_t) window; DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN ; - BOOL styleChange = ( 0 != decorationChange || 0 != fullScreenChange || JNI_TRUE == parentChange ) ? TRUE : FALSE ; - UINT flags = SWP_SHOWWINDOW; - HWND hWndInsertAfter; + BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ; - DBG_PRINT("*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, fullScreenChange %d, visible %d, decorationChange %d -> styleChange %d\n", - parent, window, x, y, width, height, parentChange, fullScreenChange, visible, decorationChange, styleChange); + DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, visibleChange %d, visible %d -> styleChange %d\n", + parent, window, x, y, width, height, + TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_HAS_PARENT(flags), + TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags), + TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), + TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange); if (!IsWindow(hwnd)) { DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd); @@ -1504,12 +1451,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure return; } - if(JNI_TRUE == visible) { + if(TST_FLAG_IS_VISIBLE(flags)) { windowStyle |= WS_VISIBLE ; } - if(fullScreenChange < 0) - { + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off NewtWindows_setFullScreen(JNI_FALSE); } @@ -1517,19 +1463,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure // TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP] // CHILD: Set WS_CHILD [, Clear WS_POPUP]; SetParent(.., PARENT) // - if ( JNI_TRUE == parentChange && NULL == hwndP ) { + if( TST_FLAG_CHANGE_PARENTING(flags) && NULL == hwndP ) { SetParent(hwnd, NULL); } - if(fullScreenChange > 0) - { + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on NewtWindows_setFullScreen(JNI_TRUE); } if ( styleChange ) { if(NULL!=hwndP) { windowStyle |= WS_CHILD ; - } else if ( decorationChange < 0 || 0 < fullScreenChange ) { + } else if ( TST_FLAG_IS_UNDECORATED(flags) ) { windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; } else { windowStyle |= WS_OVERLAPPEDWINDOW; @@ -1538,12 +1483,20 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); } - if ( JNI_TRUE == parentChange && NULL != hwndP ) { + if ( TST_FLAG_CHANGE_PARENTING(flags) && NULL != hwndP ) { SetParent(hwnd, hwndP ); } - NewtWindow_setVisiblePosSize(env, obj, hwnd, (NULL == hwndP) ? JNI_TRUE : JNI_FALSE /* top */, visible, - x, y, width, height); + NewtWindow_setVisiblePosSize(env, obj, hwnd, (NULL == hwndP) ? JNI_TRUE : JNI_FALSE /* top */, + TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_VISIBLE(flags), x, y, width, height); + + if( TST_FLAG_CHANGE_VISIBILITY(flags) ) { + if( TST_FLAG_IS_VISIBLE(flags) ) { + ShowWindow(hwnd, SW_SHOW); + } else { + ShowWindow(hwnd, SW_HIDE); + } + } DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X\n"); } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index a18efbdb8..43ff6b3bc 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -52,6 +52,7 @@ #include "jogamp_newt_driver_x11_X11Display.h" #include "jogamp_newt_driver_x11_X11Window.h" +#include "Window.h" #include "MouseEvent.h" #include "InputEvent.h" #include "KeyEvent.h" @@ -164,6 +165,7 @@ static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window"; static jclass newtWindowClz=NULL; +static jmethodID insetsChangedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; @@ -380,34 +382,34 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon } static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) { - Atom actual_type_return; - int actual_format_return; + Atom actual_type; + int actual_format; int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ; unsigned char * jogl_java_object_data_pp = NULL; jobject jwindow; { - unsigned long nitems_return = 0; - unsigned long bytes_after_return = 0; + unsigned long nitems= 0; + unsigned long bytes_after= 0; jobject jwindow = NULL; int res; res = XGetWindowProperty(dpy, window, (Atom)javaObjectAtom, 0, nitems_32, False, - (Atom)javaObjectAtom, &actual_type_return, &actual_format_return, - &nitems_return, &bytes_after_return, &jogl_java_object_data_pp); + (Atom)javaObjectAtom, &actual_type, &actual_format, + &nitems, &bytes_after, &jogl_java_object_data_pp); if ( Success != res ) { if(True==showWarning) { - fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom NEWT_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, result 0!\n", res, nitems_return, bytes_after_return); + fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom NEWT_JAVA_OBJECT window property (res %d) nitems %ld, bytes_after %ld, result 0!\n", res, nitems, bytes_after); } return NULL; } - if(actual_type_return!=(Atom)javaObjectAtom || nitems_return<nitems_32 || NULL==jogl_java_object_data_pp) { + if(actual_type!=(Atom)javaObjectAtom || nitems<nitems_32 || NULL==jogl_java_object_data_pp) { XFree(jogl_java_object_data_pp); if(True==showWarning) { - fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom NEWT_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, actual_type_return %ld, NEWT_JAVA_OBJECT %ld, result 0!\n", - res, nitems_return, bytes_after_return, (long)actual_type_return, javaObjectAtom); + fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom NEWT_JAVA_OBJECT window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, NEWT_JAVA_OBJECT %ld, result 0!\n", + res, nitems, bytes_after, (long)actual_type, javaObjectAtom); } return NULL; } @@ -433,7 +435,7 @@ static Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * roo if(NULL!=children_return) { XFree(children_return); } - return res; + return res; // 0 == res -> Error } static Window NewtWindows_getRoot (Display *dpy, Window w) { Window root_return; @@ -441,7 +443,7 @@ static Window NewtWindows_getRoot (Display *dpy, Window w) { if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) { return root_return; } - return 0; + return 0; // Error } static Window NewtWindows_getParent (Display *dpy, Window w) { Window root_return; @@ -449,26 +451,100 @@ static Window NewtWindows_getParent (Display *dpy, Window w) { if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) { return parent_return; } - return 0; + return 0; // Error } +static Status NewtWindows_getParentPosition (Display *dpy, Window w, int *x_return, int *y_return) { + Window root_return; + unsigned int width_return, height_return; + unsigned int border_width_return; + unsigned int depth_return; + Window parent = NewtWindows_getParent(dpy, w); + if(0 != parent) { + XGetGeometry(dpy, parent, &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, Window window, int *left, int *right, int *top, int *bottom) { + Atom actual_type; + int actual_format; + int nitems_32 = 4; // l, r, t, b + unsigned char * frame_extends_data_pp = NULL; + + { + Atom _NET_FRAME_EXTENTS = XInternAtom( dpy, "_NET_FRAME_EXTENTS", False ); + unsigned long nitems = 0; + unsigned long bytes_after = 0; + int res; + + res = XGetWindowProperty(dpy, window, _NET_FRAME_EXTENTS, 0, nitems_32, False, + AnyPropertyType, &actual_type, &actual_format, + &nitems, &bytes_after, &frame_extends_data_pp); + + if ( Success != res ) { + fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom _NET_FRAME_EXTENTS window property (res %d) nitems %ld, bytes_after %ld, result 0!\n", res, nitems, bytes_after); + return 0; // Error + } + + if(nitems<nitems_32 || NULL==frame_extends_data_pp) { + XFree(frame_extends_data_pp); + fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom _NET_FRAME_EXTENTS window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, actual_format %d, _NET_FRAME_EXTENTS %ld, result 0!\n", + res, nitems, bytes_after, (long)actual_type, actual_format, _NET_FRAME_EXTENTS); + return 0; // Error + } + } + long * extends = (long*) frame_extends_data_pp; + *left = (int) *(extends + 0); + *right = (int) *(extends + 1); + *top = (int) *(extends + 2); + *bottom = (int) *(extends + 3); + + DBG_PRINT( "X11: _NET_FRAME_EXTENTS: window %p insets [ l %d, r %d, t %d, b %d ]\n", + (void*)window, *left, *right, *top, *bottom); + + XFree(frame_extends_data_pp); + + return 1; // Ok +} +static Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) { + if(0 != NewtWindows_getFrameExtends(dpy, window, left, right, top, bottom)) { + DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n", + *left, *right, *top, *bottom); + (*env)->CallVoidMethod(env, jwindow, insetsChangedID, *left, *right, *top, *bottom); + return 1; // OK + } else if(0 != NewtWindows_getParentPosition (dpy, window, left, top)) { + *right = *left; *bottom = *left; + DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n", + *left, *right, *top, *bottom); + (*env)->CallVoidMethod(env, jwindow, insetsChangedID, *left, *right, *top, *bottom); + return 1; // OK + } + return 0; // Error +} static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) { XWindowAttributes xwa; Window focus_return; int revert_to_return; + DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d\n", dpy, (void*)w, force); + XGetInputFocus(dpy, &focus_return, &revert_to_return); if( JNI_TRUE==force || focus_return!=w) { if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) { + DBG_PRINT( "X11: XRaiseWindow dpy %p,win %pd\n", dpy, (void*)w); XRaiseWindow(dpy, w); // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable XGetWindowAttributes(dpy, w, &xwa); if(xwa.map_state == IsViewable) { + DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w); XSetInputFocus(dpy, w, RevertToParent, CurrentTime); } } } + DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force); XSync(dpy, False); } @@ -583,7 +659,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 return ; } - DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type); + // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type); displayDispatchErrorHandlerEnable(1, env); @@ -707,6 +783,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event); if ( evt.xconfigure.window == evt.xconfigure.event ) { // ignore child window change notification + { + // update insets + int left, right, top, bottom; + NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom); + } (*env)->CallVoidMethod(env, jwindow, sizeChangedID, (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE); (*env)->CallVoidMethod(env, jwindow, positionChangedID, @@ -749,6 +830,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 evt.xmap.event!=evt.xmap.window); if( evt.xmap.event == evt.xmap.window ) { // ignore child window notification + { + // update insets + int left, right, top, bottom; + NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom); + } (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); } break; @@ -786,7 +872,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 parentResult = (jlong) (intptr_t) evt.xreparent.parent; } #ifdef VERBOSE_ON - DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", + DBG_PRINT( "X11: event . ReparentNotify: call %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", + evt.xreparent.x, evt.xreparent.y, (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent, (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent, (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent); @@ -1256,6 +1343,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0 (JNIEnv *env, jclass clazz) { + insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V"); positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); @@ -1270,7 +1358,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0 enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V"); focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z"); - if (sizeChangedID == NULL || + if (insetsChangedID == NULL || + sizeChangedID == NULL || positionChangedID == NULL || focusChangedID == NULL || visibleChangedID == NULL || @@ -1305,6 +1394,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 int scrn_idx = (int)screen_index; Window windowParent = (Window) parent; Window window = 0; + jobject jwindow = 0; XVisualInfo visualTemplate; XVisualInfo *pVisualQuery = NULL; @@ -1401,11 +1491,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 } XSetWMProtocols(dpy, window, &wm_delete_atom, 1); // windowDeleteAtom - setJavaWindowProperty(env, dpy, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj)); + jwindow = (*env)->NewGlobalRef(env, obj); + setJavaWindowProperty(env, dpy, window, javaObjectAtom, jwindow); NewtWindows_setDecorations(dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); XSync(dpy, False); + // since native creation happens at setVisible(true) .. + // we can pre-map the window here to be able to gather the insets. + XMapWindow(dpy, window); + XSync(dpy, False); + { + // update insets + int left, right, top, bottom; + NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom); + } + DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", (void*)window, dpy); return (jlong) window; } @@ -1454,57 +1555,31 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 DBG_PRINT( "X11: CloseWindow END\n"); } -static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) +static void NewtWindows_setPosSize(Display *dpy, int screen_index, Window w, jint x, jint y, jint width, jint height, Bool undecorated) { if(width>0 && height>0 || x>=0 && y>=0) { // resize/position if requested XWindowChanges xwc; - unsigned int mod_flags = ( (x>=0)?CWX:0 ) | ( (y>=0)?CWY:0 ) | - ( (width>0)?CWWidth:0 ) | ( (height>0)?CWHeight:0 ) ; - DBG_PRINT( "X11: reconfigureWindow0 %d/%d %dx%d, mod: 0x%X\n", x, y, width, height, mod_flags); + + DBG_PRINT( "X11: reconfigureWindow0 %d/%d %dx%d\n", x, y, width, height); + memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; xwc.y=y; xwc.width=width; xwc.height=height; - XConfigureWindow(dpy, w, mod_flags, &xwc); + XConfigureWindow(dpy, w, (CWX | CWY | CWWidth | CWHeight), &xwc); XSync(dpy, False); } } /* * Class: jogamp_newt_driver_x11_X11Window - * Method: setVisible0 - * Signature: (JJZIIII)V - */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setVisible0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean visible, jint x, jint y, jint width, jint height) -{ - Display * dpy = (Display *) (intptr_t) display; - Window w = (Window)window; - DBG_PRINT( "X11: setVisible0 vis %d - %d/%d %dx%d\n", visible, x, y, width, height); - - if(dpy==NULL) { - NewtCommon_FatalError(env, "invalid display connection.."); - } - - if(visible==JNI_TRUE) { - XMapRaised(dpy, w); - } else { - XUnmapWindow(dpy, w); - } - XSync(dpy, False); - - NewtWindows_setPosSize(dpy, w, x, y, width, height); -} - -/* - * Class: jogamp_newt_driver_x11_X11Window * Method: reconfigureWindow0 - * Signature: (JIJJIIIIZZII)V + * Signature: (JIJJIIIII)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index, jlong jparent, jlong jwindow, - jint x, jint y, jint width, jint height, jboolean isVisible, jboolean parentChange, jint fullscreenChange, jint decorationChange) + jint x, jint y, jint width, jint height, jint flags) { Display * dpy = (Display *) (intptr_t) jdisplay; Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index); @@ -1513,54 +1588,56 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 Window parent = (0!=jparent)?(Window)jparent:root; Window topParentParent; Window topParentWindow; - Bool moveIntoParent = False; displayDispatchErrorHandlerEnable(1, env); topParentParent = NewtWindows_getParent (dpy, parent); topParentWindow = NewtWindows_getParent (dpy, w); - DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d/%p, parent %p/%p (top %p), win %p (top %p), %d/%d %dx%d visible %d, parentChange %d, fullscreenChange %d, decorationChange %d\n", + DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d/%p, parent %p/%p (top %p), win %p (top %p), %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, visibleChange %d, visible %d\n", (void*)dpy, screen_index, (void*)scrn, (void*) jparent, (void*)parent, (void*) topParentParent, (void*)w, (void*)topParentWindow, - x, y, width, height, isVisible, parentChange, fullscreenChange, decorationChange); + x, y, width, height, + TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_HAS_PARENT(flags), + TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags), + TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), + TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags)); - if(JNI_TRUE == isVisible) { // unmap window if visible, reduce X11 internal signaling (WM unmap) - XUnmapWindow(dpy, w); + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off + NewtWindows_setFullscreen(dpy, root, w, False ); XSync(dpy, False); } - if(0 > fullscreenChange ) { // FS off - NewtWindows_setFullscreen(dpy, root, w, False ); + if( TST_FLAG_CHANGE_DECORATION(flags) && TST_FLAG_IS_UNDECORATED(flags) ) { + NewtWindows_setDecorations (dpy, w, False); XSync(dpy, False); } - if(parentChange) { - if(0 != jparent) { // move into parent .. - moveIntoParent = True; - NewtWindows_setDecorations (dpy, w, False); - XSync(dpy, False); - } + if( TST_FLAG_CHANGE_PARENTING(flags) ) { XReparentWindow( dpy, w, parent, x, y ); // actual reparent call XSync(dpy, False); } - if(!moveIntoParent && 0!=decorationChange) { - NewtWindows_setDecorations (dpy, w, (0 < decorationChange) ? True : False); + if( TST_FLAG_CHANGE_DECORATION(flags) && !TST_FLAG_IS_UNDECORATED(flags) ) { + NewtWindows_setDecorations (dpy, w, True); + XSync(dpy, False); + } + + if( TST_FLAG_CHANGE_VISIBILITY(flags) ) { + if( TST_FLAG_IS_VISIBLE(flags) ) { + XMapRaised(dpy, w); + } else { + XUnmapWindow(dpy, w); + } XSync(dpy, False); } - NewtWindows_setPosSize(dpy, w, x, y, width, height); + NewtWindows_setPosSize(dpy, screen_index, w, x, y, width, height, TST_FLAG_IS_UNDECORATED(flags) ? True : False); - if(0 < fullscreenChange ) { // FS on + if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on NewtWindows_setFullscreen(dpy, root, w, True ); XSync(dpy, False); } - if(JNI_TRUE == isVisible) { // map window - XMapRaised(dpy, w); - XSync(dpy, False); - } - displayDispatchErrorHandlerEnable(0, env); DBG_PRINT( "X11: reconfigureWindow0 X\n"); |