diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 820769f9..4fbd384c 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -144,6 +144,8 @@ final class LinuxDisplay implements DisplayImplementation { private boolean resizable; private boolean resized; + private int window_x; + private int window_y; private int window_width; private int window_height; @@ -516,6 +518,8 @@ final class LinuxDisplay implements DisplayImplementation { private static native long nGetInputFocus(long display) throws LWJGLException; private static native void nSetInputFocus(long display, long window, long time); private static native void nSetWindowSize(long display, long window, int width, int height, boolean resizable); + private static native int nGetX(long display, long window); + private static native int nGetY(long display, long window); private static native int nGetWidth(long display, long window); private static native int nGetHeight(long display, long window); @@ -840,10 +844,17 @@ final class LinuxDisplay implements DisplayImplementation { break; case LinuxEvent.Expose: dirty = true; + break; + case LinuxEvent.ConfigureNotify: + int x = nGetX(getDisplay(), getWindow()); + int y = nGetY(getDisplay(), getWindow()); int width = nGetWidth(getDisplay(), getWindow()); int height = nGetHeight(getDisplay(), getWindow()); + window_x = x; + window_y = y; + if (window_width != width || window_height != height) { resized = true; window_width = width; diff --git a/src/java/org/lwjgl/opengl/LinuxEvent.java b/src/java/org/lwjgl/opengl/LinuxEvent.java index fb8e9827..e8fbe90e 100644 --- a/src/java/org/lwjgl/opengl/LinuxEvent.java +++ b/src/java/org/lwjgl/opengl/LinuxEvent.java @@ -53,6 +53,7 @@ final class LinuxEvent { public static final int UnmapNotify = 18; public static final int MapNotify = 19; public static final int Expose = 12; + public static final int ConfigureNotify = 22; public static final int ClientMessage = 33; private final ByteBuffer event_buffer; diff --git a/src/native/linux/opengl/org_lwjgl_opengl_Display.c b/src/native/linux/opengl/org_lwjgl_opengl_Display.c index 4758549a..b5209284 100644 --- a/src/native/linux/opengl/org_lwjgl_opengl_Display.c +++ b/src/native/linux/opengl/org_lwjgl_opengl_Display.c @@ -283,6 +283,49 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getRootWindow(JNIEnv return RootWindow(disp, screen); } +static Window getCurrentWindow(JNIEnv *env, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + + Window parent = (Window)window_ptr; + Window win, root; + + Window *children; + unsigned int nchildren; + + do { + win = parent; + + if (XQueryTree(disp, win, &root, &parent, &children, &nchildren) == 0) { + throwException(env, "XQueryTree failed"); + return 0; + } + + if (children != NULL) XFree(children); + } while (parent != root); + + return win; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetX(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = getCurrentWindow(env, display_ptr, window_ptr); + + XWindowAttributes win_attribs; + XGetWindowAttributes(disp, win, &win_attribs); + + return win_attribs.x; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetY(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = getCurrentWindow(env, display_ptr, window_ptr); + + XWindowAttributes win_attribs; + XGetWindowAttributes(disp, win, &win_attribs); + + return win_attribs.y; +} + JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetWidth(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { Display *disp = (Display *)(intptr_t)display_ptr; Window win = (Window)window_ptr; @@ -381,7 +424,7 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m setDecorations(disp, win, 0); } - if (RootWindow(disp, screen) == parent_handle) { // on set hints when Display.setParent isn't used + if (RootWindow(disp, screen) == parent_handle) { // only set hints when Display.setParent isn't used updateWindowBounds(disp, win, x, y, width, height, JNI_TRUE, resizable); updateWindowHints(env, disp, win); } diff --git a/src/native/linux/opengles/org_lwjgl_opengl_Display.c b/src/native/linux/opengles/org_lwjgl_opengl_Display.c index 2470354f..29e4ba7d 100644 --- a/src/native/linux/opengles/org_lwjgl_opengl_Display.c +++ b/src/native/linux/opengles/org_lwjgl_opengl_Display.c @@ -273,6 +273,49 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getRootWindow(JNIEnv return RootWindow(disp, screen); } +static Window getCurrentWindow(JNIEnv *env, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + + Window parent = (Window)window_ptr; + Window win, root; + + Window *children; + unsigned int nchildren; + + do { + win = parent; + + if (XQueryTree(disp, win, &root, &parent, &children, &nchildren) == 0) { + throwException(env, "XQueryTree failed"); + return 0; + } + + if (children != NULL) XFree(children); + } while (parent != root); + + return win; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetX(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = getCurrentWindow(env, display_ptr, window_ptr); + + XWindowAttributes win_attribs; + XGetWindowAttributes(disp, win, &win_attribs); + + return win_attribs.x; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetY(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { + Display *disp = (Display *)(intptr_t)display_ptr; + Window win = getCurrentWindow(env, display_ptr, window_ptr); + + XWindowAttributes win_attribs; + XGetWindowAttributes(disp, win, &win_attribs); + + return win_attribs.y; +} + JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetWidth(JNIEnv *env, jclass unused, jlong display_ptr, jlong window_ptr) { Display *disp = (Display *)(intptr_t)display_ptr; Window win = (Window)window_ptr; @@ -375,7 +418,7 @@ static Window createWindow(JNIEnv* env, Display *disp, int screen, jint window_m setDecorations(disp, win, 0); } - if (RootWindow(disp, screen) == parent_handle) { // on set hints when Display.setParent isn't used + if (RootWindow(disp, screen) == parent_handle) { // only set hints when Display.setParent isn't used updateWindowBounds(disp, win, x, y, width, height, JNI_TRUE, resizable); updateWindowHints(env, disp, win); }