summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-01-18 23:12:36 +0100
committerSven Gothel <[email protected]>2012-01-18 23:12:36 +0100
commitab3c5678527ba2e4f092b7426527b8053d12e790 (patch)
tree8ed88607f29c642137aa4b4eb43204d480aec6c0 /src
parent319fdccb670743daa6c27e247591baf1f254e5ac (diff)
NEWT/X11: Fix Insets determination for undecorated / child window.
Due to latest changes, a bug is disposed where the native 'updateInsets' attempts to determine the window insets by it's parent window (fall-back). The latter works only in case of a top-level window. Adding query to the WM whether the window is decorated (top-level) or not. Attempt to use the fall-back parent window method in case of a decorated window. This whole inset code based on the parent window is probably completly redundant, nevertheless we keep it alive until further notice.
Diffstat (limited to 'src')
-rw-r--r--src/newt/native/X11Window.c139
1 files changed, 86 insertions, 53 deletions
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 10ce8945b..6953140c0 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -169,16 +169,21 @@ static Window NewtWindows_getParent (Display *dpy, Window w) {
}
return 0; // Error
}
-static Status NewtWindows_getParentPosition (Display *dpy, Window w, int *x_return, int *y_return) {
+static void NewtWindows_setCWAbove(Display *dpy, Window w) {
+ XWindowChanges xwc;
+ memset(&xwc, 0, sizeof(XWindowChanges));
+ xwc.stack_mode = Above;
+ XConfigureWindow(dpy, w, CWStackMode, &xwc);
+ XSync(dpy, False);
+}
+static Status NewtWindows_getWindowPositionRelative2Parent (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);
+ if(0 != XGetGeometry(dpy, w, &root_return, x_return, y_return, &width_return,
+ &height_return, &border_width_return, &depth_return)) {
return 1; // OK
}
return 0; // Error
@@ -224,53 +229,6 @@ static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left
return 1; // Ok
}
-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, JNI_FALSE, *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, JNI_FALSE, *left, *right, *top, *bottom);
- return 1; // OK
- }
- return 0; // Error
-}
-
-static void NewtWindows_setCWAbove(Display *dpy, Window w) {
- XWindowChanges xwc;
- memset(&xwc, 0, sizeof(XWindowChanges));
- xwc.stack_mode = Above;
- XConfigureWindow(dpy, w, CWStackMode, &xwc);
- XSync(dpy, False);
-}
-
-static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) {
- XWindowAttributes xwa;
- Window focus_return;
- int revert_to_return;
-
- XSync(dpy, False);
- XGetInputFocus(dpy, &focus_return, &revert_to_return);
- DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w);
-
- if( JNI_TRUE==force || focus_return!=w) {
- DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
- XRaiseWindow(dpy, w);
- NewtWindows_setCWAbove(dpy, w);
- // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
- XGetWindowAttributes(dpy, w, &xwa);
- DBG_PRINT( "X11: XSetInputFocus dpy %p,win %p, isViewable %d\n", dpy, (void*)w, (xwa.map_state == IsViewable));
- if(xwa.map_state == IsViewable) {
- XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
- }
- }
- DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force);
- XSync(dpy, False);
-}
#define DECOR_USE_MWM 1 // works for known WMs
// #define DECOR_USE_EWMH 1 // haven't seen this to work (NORMAL->POPUP, never gets undecorated)
@@ -308,6 +266,29 @@ static void NewtWindows_setDecorations (Display *dpy, Window w, Bool decorated)
XSync(dpy, False);
}
+static Bool NewtWindows_hasDecorations (Display *dpy, Window w) {
+ Bool decor = False;
+
+#ifdef DECOR_USE_MWM
+ Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False );
+ unsigned char *wm_data;
+ Atom wm_type;
+ int wm_format;
+ unsigned long wm_nitems, wm_bytes_after;
+
+ if( Success == XGetWindowProperty(dpy, w, _MOTIF_WM_HINTS, 0, PROP_MWM_HINTS_ELEMENTS, False, AnyPropertyType,
+ &wm_type, &wm_format, &wm_nitems, &wm_bytes_after, &wm_data) ) {
+ if(wm_type != None) {
+ // unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status
+ unsigned long *hints = (unsigned long *) wm_data;
+ decor = ( 0 != (hints[0] & MWM_HINTS_DECORATIONS) ) && ( 0 != hints[2] );
+ }
+ }
+#endif
+
+ return decor;
+}
+
static void NewtWindows_setNormalWindowEWMH (Display *dpy, Window w) {
Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False );
Atom types[1]={0};
@@ -431,6 +412,56 @@ static Bool NewtWindows_setFullscreenEWMH (Display *dpy, Window root, Window w,
return res;
}
+
+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, JNI_FALSE, *left, *right, *top, *bottom);
+ return 1; // OK
+ }
+
+ Bool hasDecor = NewtWindows_hasDecorations (dpy, window);
+ if(hasDecor) {
+ // 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, 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);
+ (*env)->CallVoidMethod(env, jwindow, insetsChangedID, JNI_FALSE, *left, *right, *top, *bottom);
+ return 1; // OK
+ }
+ }
+ DBG_PRINT( "NewtWindows_updateInsets: cannot determine insets - hasDecor %d\n", hasDecor);
+ 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;
+
+ XSync(dpy, False);
+ XGetInputFocus(dpy, &focus_return, &revert_to_return);
+ DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w);
+
+ if( JNI_TRUE==force || focus_return!=w) {
+ DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
+ XRaiseWindow(dpy, w);
+ NewtWindows_setCWAbove(dpy, w);
+ // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
+ XGetWindowAttributes(dpy, w, &xwa);
+ DBG_PRINT( "X11: XSetInputFocus dpy %p,win %p, isViewable %d\n", dpy, (void*)w, (xwa.map_state == IsViewable));
+ if(xwa.map_state == IsViewable) {
+ XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
+ }
+ }
+ DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force);
+ XSync(dpy, False);
+}
+
/**
* Window
*/
@@ -602,11 +633,13 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
// we can pre-map the window here to be able to gather the insets and position.
{
XEvent event;
- int left, right, top, bottom;
+ int left=0, right=0, top=0, bottom=0;
XMapWindow(dpy, window);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values
+ XSync(dpy, False);
+
// send insets before visibility, allowing java code a proper sync point!
NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom);
(*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);