Fixed Rect/RECT conversion and added a workaround that resets the OpenGL client area when we toggle resizable after window creation.
This commit is contained in:
parent
1703b62ed5
commit
66c987f9c2
|
@ -43,6 +43,8 @@ import java.awt.event.FocusAdapter;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.lwjgl.LWJGLException;
|
import org.lwjgl.LWJGLException;
|
||||||
|
@ -196,7 +198,6 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
private boolean inAppActivate;
|
private boolean inAppActivate;
|
||||||
private boolean resized;
|
private boolean resized;
|
||||||
private boolean resizable;
|
private boolean resizable;
|
||||||
private boolean maximized;
|
|
||||||
private int x;
|
private int x;
|
||||||
private int y;
|
private int y;
|
||||||
private int width;
|
private int width;
|
||||||
|
@ -213,6 +214,8 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
private boolean trackingMouse;
|
private boolean trackingMouse;
|
||||||
private boolean mouseInside;
|
private boolean mouseInside;
|
||||||
|
|
||||||
|
private List<Runnable> deferredActions = new ArrayList<Runnable>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
Method windowProc = WindowsDisplay.class.getDeclaredMethod("handleMessage", long.class, int.class, long.class, long.class, long.class);
|
Method windowProc = WindowsDisplay.class.getDeclaredMethod("handleMessage", long.class, int.class, long.class, long.class, long.class);
|
||||||
|
@ -232,12 +235,14 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
isMinimized = false;
|
isMinimized = false;
|
||||||
isFocused = false;
|
isFocused = false;
|
||||||
redoMakeContextCurrent = false;
|
redoMakeContextCurrent = false;
|
||||||
maximized = false;
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
hasParent = parent != null;
|
hasParent = parent != null;
|
||||||
parent_hwnd = parent != null ? getHwnd(parent) : 0;
|
parent_hwnd = parent != null ? getHwnd(parent) : 0;
|
||||||
this.hwnd = nCreateWindow(x, y, mode.getWidth(), mode.getHeight(), Display.isFullscreen() || isUndecorated(), parent != null, parent_hwnd);
|
this.hwnd = nCreateWindow(x, y, mode.getWidth(), mode.getHeight(), Display.isFullscreen() || isUndecorated(), parent != null, parent_hwnd);
|
||||||
this.resizable=false;
|
if ( Display.isResizable() && parent == null ) {
|
||||||
|
setResizable(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (hwnd == 0) {
|
if (hwnd == 0) {
|
||||||
throw new LWJGLException("Failed to create window");
|
throw new LWJGLException("Failed to create window");
|
||||||
}
|
}
|
||||||
|
@ -261,9 +266,6 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
updateWidthAndHeight();
|
updateWidthAndHeight();
|
||||||
|
|
||||||
if ( parent == null ) {
|
if ( parent == null ) {
|
||||||
if(Display.isResizable()) {
|
|
||||||
setResizable(true);
|
|
||||||
}
|
|
||||||
setForegroundWindow(getHwnd());
|
setForegroundWindow(getHwnd());
|
||||||
} else {
|
} else {
|
||||||
parent_focused = new AtomicBoolean(false);
|
parent_focused = new AtomicBoolean(false);
|
||||||
|
@ -551,6 +553,12 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
|
if ( !deferredActions.isEmpty() ) {
|
||||||
|
for ( Runnable r : deferredActions )
|
||||||
|
r.run();
|
||||||
|
deferredActions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
nUpdate();
|
nUpdate();
|
||||||
|
|
||||||
if ( !isFocused && parent != null && parent_focused.compareAndSet(true, false) ) {
|
if ( !isFocused && parent != null && parent_focused.compareAndSet(true, false) ) {
|
||||||
|
@ -975,7 +983,6 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
switch ((int)wParam) {
|
switch ((int)wParam) {
|
||||||
case SIZE_RESTORED:
|
case SIZE_RESTORED:
|
||||||
case SIZE_MAXIMIZED:
|
case SIZE_MAXIMIZED:
|
||||||
maximized = ((int)wParam) == SIZE_MAXIMIZED;
|
|
||||||
resized = true;
|
resized = true;
|
||||||
updateWidthAndHeight();
|
updateWidthAndHeight();
|
||||||
setMinimized(false);
|
setMinimized(false);
|
||||||
|
@ -1155,31 +1162,59 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResizable(boolean resizable) {
|
public void setResizable(boolean resizable) {
|
||||||
if(this.resizable != resizable) {
|
if ( this.resizable == resizable )
|
||||||
int style = (int)getWindowLongPtr(hwnd, GWL_STYLE);
|
return;
|
||||||
int styleex = (int)getWindowLongPtr(hwnd, GWL_EXSTYLE);
|
|
||||||
|
|
||||||
// update frame style
|
setResizable(resizable, true);
|
||||||
if(resizable && !Display.isFullscreen()) {
|
}
|
||||||
setWindowLongPtr(hwnd, GWL_STYLE, style |= (WS_THICKFRAME | WS_MAXIMIZEBOX));
|
|
||||||
} else {
|
|
||||||
setWindowLongPtr(hwnd, GWL_STYLE, style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX));
|
|
||||||
}
|
|
||||||
|
|
||||||
// from the existing client rect, determine the new window rect
|
private void setResizable(boolean resizable, boolean defer) {
|
||||||
// based on the style changes - using AdjustWindowRectEx.
|
this.resized = false;
|
||||||
getClientRect(hwnd, rect_buffer);
|
|
||||||
rect.copyFromBuffer(rect_buffer);
|
|
||||||
adjustWindowRectEx(rect_buffer, style, false, styleex);
|
|
||||||
rect.copyFromBuffer(rect_buffer);
|
|
||||||
|
|
||||||
// force a frame update and resize accordingly
|
|
||||||
setWindowPos(hwnd, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
|
||||||
|
|
||||||
updateWidthAndHeight();
|
|
||||||
resized = false;
|
|
||||||
}
|
|
||||||
this.resizable = resizable;
|
this.resizable = resizable;
|
||||||
|
|
||||||
|
int style = (int)getWindowLongPtr(hwnd, GWL_STYLE);
|
||||||
|
int styleex = (int)getWindowLongPtr(hwnd, GWL_EXSTYLE);
|
||||||
|
|
||||||
|
// update frame style
|
||||||
|
setWindowLongPtr(
|
||||||
|
hwnd,
|
||||||
|
GWL_STYLE,
|
||||||
|
style = resizable && !Display.isFullscreen()
|
||||||
|
? (style | (WS_THICKFRAME | WS_MAXIMIZEBOX))
|
||||||
|
: (style & ~(WS_THICKFRAME | WS_MAXIMIZEBOX))
|
||||||
|
);
|
||||||
|
|
||||||
|
// from the existing client rect, determine the new window rect
|
||||||
|
// based on the style changes - using AdjustWindowRectEx.
|
||||||
|
getGlobalClientRect(hwnd, rect);
|
||||||
|
rect.copyToBuffer(rect_buffer);
|
||||||
|
adjustWindowRectEx(rect_buffer, style, false, styleex);
|
||||||
|
rect.copyFromBuffer(rect_buffer);
|
||||||
|
|
||||||
|
final int x = rect.left;
|
||||||
|
final int y = rect.top;
|
||||||
|
final int cx = rect.right - rect.left;
|
||||||
|
final int cy = rect.bottom - rect.top;
|
||||||
|
|
||||||
|
if ( defer ) {
|
||||||
|
// SWP_FRAMECHANGED does not play nice with WS_THICKFRAME on/off, the OpenGL client area
|
||||||
|
// ends up in the wrong position. Reshape the window later, this will reset the client
|
||||||
|
// area to the correct position.
|
||||||
|
deferredActions.add(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
setWindowPos(hwnd, 0L, x, y, cx, cy, SWP_NOZORDER);
|
||||||
|
updateWidthAndHeight();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// apply the style changes
|
||||||
|
setWindowPos(hwnd, 0L, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||||
|
} else {
|
||||||
|
// apply the style changes
|
||||||
|
setWindowPos(hwnd, 0L, x, y, cx, cy, SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWidthAndHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
private native boolean adjustWindowRectEx(IntBuffer rectBuffer, int style, boolean menu, int styleex);
|
private native boolean adjustWindowRectEx(IntBuffer rectBuffer, int style, boolean menu, int styleex);
|
||||||
|
@ -1191,44 +1226,50 @@ final class WindowsDisplay implements DisplayImplementation {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getPixelScaleFactor() {
|
public float getPixelScaleFactor() {
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class Rect {
|
private static final class Rect {
|
||||||
public int top;
|
|
||||||
public int bottom;
|
public int
|
||||||
public int left;
|
left,
|
||||||
public int right;
|
top,
|
||||||
|
right,
|
||||||
|
bottom;
|
||||||
|
|
||||||
public void copyToBuffer(IntBuffer buffer) {
|
public void copyToBuffer(IntBuffer buffer) {
|
||||||
buffer.put(0, top).put(1, bottom).put(2, left).put(3, right);
|
buffer
|
||||||
|
.put(0, left)
|
||||||
|
.put(1, top)
|
||||||
|
.put(2, right)
|
||||||
|
.put(3, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void copyFromBuffer(IntBuffer buffer) {
|
public void copyFromBuffer(IntBuffer buffer) {
|
||||||
top = buffer.get(0);
|
left = buffer.get(0);
|
||||||
bottom = buffer.get(1);
|
top = buffer.get(1);
|
||||||
left = buffer.get(2);
|
right = buffer.get(2);
|
||||||
right = buffer.get(3);
|
bottom = buffer.get(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void offset(int offset_x, int offset_y) {
|
public void offset(int offset_x, int offset_y) {
|
||||||
left += offset_x;
|
left += offset_x;
|
||||||
right += offset_x;
|
|
||||||
top += offset_y;
|
top += offset_y;
|
||||||
|
right += offset_x;
|
||||||
bottom += offset_y;
|
bottom += offset_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void intersect(Rect r1, Rect r2, Rect dst) {
|
public static void intersect(Rect r1, Rect r2, Rect dst) {
|
||||||
dst.top = Math.max(r1.top, r2.top);
|
|
||||||
dst.bottom = Math.min(r1.bottom, r2.bottom);
|
|
||||||
dst.left = Math.max(r1.left, r2.left);
|
dst.left = Math.max(r1.left, r2.left);
|
||||||
|
dst.top = Math.max(r1.top, r2.top);
|
||||||
dst.right = Math.min(r1.right, r2.right);
|
dst.right = Math.min(r1.right, r2.right);
|
||||||
|
dst.bottom = Math.min(r1.bottom, r2.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Rect: top = " + top + " bottom = " + bottom + " left = " + left + " right = " + right + ", width: " + (right - left) + ", height: " + (bottom - top);
|
return "Rect: left = " + left + " top = " + top + " right = " + right + " bottom = " + bottom + ", width: " + (right - left) + ", height: " + (bottom - top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,10 +245,10 @@ static void copyBufferToRect(JNIEnv *env, jobject buffer_handle, RECT *rect) {
|
||||||
throwFormattedRuntimeException(env, "Buffer size < 4", size);
|
throwFormattedRuntimeException(env, "Buffer size < 4", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rect->top = buffer[0];
|
rect->left = buffer[0];
|
||||||
rect->bottom = buffer[1];
|
rect->top = buffer[1];
|
||||||
rect->left = buffer[2];
|
rect->right = buffer[2];
|
||||||
rect->right = buffer[3];
|
rect->bottom = buffer[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copyRectToBuffer(JNIEnv *env, RECT *rect, jobject buffer_handle) {
|
static void copyRectToBuffer(JNIEnv *env, RECT *rect, jobject buffer_handle) {
|
||||||
|
@ -258,10 +258,10 @@ static void copyRectToBuffer(JNIEnv *env, RECT *rect, jobject buffer_handle) {
|
||||||
throwFormattedRuntimeException(env, "Buffer size < 4", size);
|
throwFormattedRuntimeException(env, "Buffer size < 4", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buffer[0] = rect->top;
|
buffer[0] = rect->left;
|
||||||
buffer[1] = rect->bottom;
|
buffer[1] = rect->top;
|
||||||
buffer[2] = rect->left;
|
buffer[2] = rect->right;
|
||||||
buffer[3] = rect->right;
|
buffer[3] = rect->bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_clipCursor(JNIEnv *env, jclass unused, jobject handle_buffer) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_clipCursor(JNIEnv *env, jclass unused, jobject handle_buffer) {
|
||||||
|
|
Loading…
Reference in New Issue