Another attempt to fix focus problems with Display.setParent on Windows:

- Reverted to WS_CHILD in window flags.
- Added WM_MOUSEACTIVATE handling: Focus the display + return MA_NOACTIVATE.
- Removed unnecessary appActivate calls in WM_ACTIVATE. We don't receive WM_ACTIVATE with WS_CHILD and the focus events do the job just fine.
- Detect parent window focus in update and force focus the display. This is useful when we alt-tab to the parent window and we don't receive any events.
This commit is contained in:
Ioannis Tsakpinis 2013-04-17 22:19:38 +03:00
parent 1f81b30f66
commit c0b19b7743
5 changed files with 42 additions and 56 deletions

View File

@ -43,7 +43,10 @@ package org.lwjgl.opengl;
* @author foo
*/
import org.lwjgl.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.Sys;
import org.lwjgl.input.Controllers;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
@ -58,7 +61,6 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashSet;
import javax.swing.*;
public final class Display {
@ -122,12 +124,6 @@ public final class Display {
private static float r, g, b;
private static final ComponentListener component_listener = new ComponentAdapter() {
public void componentMoved(ComponentEvent e) {
synchronized ( GlobalLock.lock ) {
parent_resized = true;
}
}
public void componentResized(ComponentEvent e) {
synchronized ( GlobalLock.lock ) {
parent_resized = true;
@ -305,7 +301,6 @@ public final class Display {
throw new LWJGLException("Parent.isDisplayable() must be true");
if ( tmp_parent != null ) {
tmp_parent.addComponentListener(component_listener);
SwingUtilities.windowForComponent(parent).addComponentListener(component_listener);
}
DisplayMode mode = getEffectiveMode();
display_impl.createWindow(drawable, mode, tmp_parent, getWindowX(), getWindowY());
@ -343,7 +338,6 @@ public final class Display {
}
if ( parent != null ) {
parent.removeComponentListener(component_listener);
SwingUtilities.windowForComponent(parent).removeComponentListener(component_listener);
}
releaseDrawable();

View File

@ -85,6 +85,7 @@ final class WindowsDisplay implements DisplayImplementation {
private static final int WM_CHAR = 258;
private static final int WM_SETICON = 0x0080;
private static final int WM_SETCURSOR = 0x0020;
private static final int WM_MOUSEACTIVATE = 0x0021;
private static final int WM_QUIT = 0x0012;
private static final int WM_SYSCOMMAND = 0x0112;
@ -204,7 +205,7 @@ final class WindowsDisplay implements DisplayImplementation {
static {
try {
final 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);
setWindowProc(windowProc);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
@ -224,7 +225,7 @@ final class WindowsDisplay implements DisplayImplementation {
maximized = false;
this.parent = parent;
hasParent = parent != null;
long parent_hwnd = parent != null ? nGetParent(getHwnd(parent)) : 0;
long parent_hwnd = parent != null ? getHwnd(parent) : 0;
this.hwnd = nCreateWindow(x, y, mode.getWidth(), mode.getHeight(), Display.isFullscreen() || isUndecorated(), parent != null, parent_hwnd);
this.resizable=false;
if (hwnd == 0) {
@ -245,8 +246,6 @@ final class WindowsDisplay implements DisplayImplementation {
((DrawableGLES)drawable).initialize(hwnd, hdc, EGL.EGL_WINDOW_BIT, (org.lwjgl.opengles.PixelFormat)drawable.getPixelFormat());
}
peer_info.initDC(getHwnd(), getHdc());
if ( parent != null )
reshape(0, 0, mode.getWidth(), mode.getHeight());
showWindow(getHwnd(), SW_SHOWDEFAULT);
updateWidthAndHeight();
@ -256,8 +255,8 @@ final class WindowsDisplay implements DisplayImplementation {
setResizable(true);
}
setForegroundWindow(getHwnd());
setFocus(getHwnd());
}
setFocus(getHwnd());
} catch (LWJGLException e) {
nReleaseDC(hwnd, hdc);
nDestroyWindow(hwnd);
@ -289,8 +288,6 @@ final class WindowsDisplay implements DisplayImplementation {
}
}
private static native long nGetParent(long hWnd);
public void destroyWindow() {
nReleaseDC(hwnd, hdc);
nDestroyWindow(hwnd);
@ -356,8 +353,8 @@ final class WindowsDisplay implements DisplayImplementation {
showWindow(getHwnd(), SW_RESTORE);
}
setForegroundWindow(getHwnd());
setFocus(getHwnd());
}
setFocus(getHwnd());
redoMakeContextCurrent = true;
if (Display.isFullscreen())
updateClipping();
@ -512,6 +509,11 @@ final class WindowsDisplay implements DisplayImplementation {
public void update() {
nUpdate();
// This happens when we alt-tab to the frame that contains the parent. The WM_ACTIVATE event is received by AWT instead of our window proc.
if ( !isFocused && parent != null && SwingUtilities.isDescendingFrom(parent, KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()) )
setFocus(getHwnd());
if (redoMakeContextCurrent) {
redoMakeContextCurrent = false;
/**
@ -531,15 +533,6 @@ final class WindowsDisplay implements DisplayImplementation {
private static native void nUpdate();
public void reshape(int x, int y, int width, int height) {
if ( parent != null ) {
// Translate canvas location to screen coordinates
Point p = new Point();
SwingUtilities.convertPointToScreen(p, parent);
x += p.getX();
y += p.getY();
}
nReshape(getHwnd(), x, y, width, height, Display.isFullscreen() || isUndecorated(), parent != null);
}
private static native void nReshape(long hwnd, int x, int y, int width, int height, boolean undecorated, boolean child);
@ -884,15 +877,19 @@ final class WindowsDisplay implements DisplayImplementation {
}
private long doHandleMessage(long hwnd, int msg, long wParam, long lParam, long millis) {
if ( hwnd != getHwnd() ) {
// Can happen at start-up
return defWindowProc(hwnd, msg, wParam, lParam);
}
/*switch ( msg ) {
case 0x0020:
case 0x0084:
case WM_MOUSEMOVE:
break;
default:
WindowsEventDebug.printMessage(msg, wParam, lParam);
}*/
switch (msg) {
// disable screen saver and monitor power down messages which wreak havoc
case WM_ACTIVATE:
switch ((int)wParam) {
/*switch ((int)wParam) {
case WA_ACTIVE:
case WA_CLICKACTIVE:
appActivate(true);
@ -900,7 +897,7 @@ final class WindowsDisplay implements DisplayImplementation {
case WA_INACTIVE:
appActivate(false);
break;
}
}*/
return 0L;
case WM_SIZE:
switch ((int)wParam) {
@ -915,15 +912,11 @@ final class WindowsDisplay implements DisplayImplementation {
setMinimized(true);
break;
}
return defWindowProc(hwnd, msg, wParam, lParam);
case WM_ENTERSIZEMOVE:
return defWindowProc(hwnd, msg, wParam, lParam);
case WM_EXITSIZEMOVE:
return defWindowProc(hwnd, msg, wParam, lParam);
break;
case WM_SIZING:
resized = true;
updateWidthAndHeight();
return defWindowProc(hwnd, msg, wParam, lParam);
break;
case WM_SETCURSOR:
if((lParam & 0xFFFF) == HTCLIENT) {
// if the cursor is inside the client area, reset it
@ -940,6 +933,11 @@ final class WindowsDisplay implements DisplayImplementation {
case WM_SETFOCUS:
appActivate(true);
return 0L;
case WM_MOUSEACTIVATE:
if ( !isFocused )
setFocus(getHwnd());
return 3L; // MA_NOACTIVATE
case WM_MOUSEMOVE:
int xPos = (int)(short)(lParam & 0xFFFF);
int yPos = transformY(getHwnd(), (int)(short)((lParam >> 16) & 0xFFFF));
@ -1007,7 +1005,7 @@ final class WindowsDisplay implements DisplayImplementation {
/* Fall through */
case WM_KEYDOWN:
handleKeyButton(wParam, lParam, millis);
return defWindowProc(hwnd, msg, wParam, lParam);
break;
case WM_QUIT:
close_requested = true;
return 0L;
@ -1024,14 +1022,14 @@ final class WindowsDisplay implements DisplayImplementation {
default:
break;
}
return defWindowProc(hwnd, msg, wParam, lParam);
break;
case WM_PAINT:
is_dirty = true;
return defWindowProc(hwnd, msg, wParam, lParam);
break;
case WM_MOUSELEAVE:
mouseInside = false;
trackingMouse = false;
return defWindowProc(hwnd, msg, wParam, lParam);
break;
case WM_CANCELMODE:
nReleaseCapture();
/* fall through */
@ -1049,10 +1047,10 @@ final class WindowsDisplay implements DisplayImplementation {
} else {
LWJGLUtil.log("WM_WINDOWPOSCHANGED: Unable to get window rect");
}
return defWindowProc(hwnd, msg, wParam, lParam);
default:
return defWindowProc(hwnd, msg, wParam, lParam);
break;
}
return defWindowProc(hwnd, msg, wParam, lParam);
}
private native boolean getWindowRect(long hwnd, IntBuffer rectBuffer);

View File

@ -2,7 +2,9 @@
#ifdef AMD_FP
#pragma OPENCL EXTENSION cl_amd_fp64 : enable
#else
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#ifndef CL_VERSION_1_2
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#endif
#endif
#define varfloat double
#define _255 255.0

View File

@ -118,7 +118,7 @@ void getWindowFlags(DWORD *windowflags_return, DWORD *exstyle_return, bool undec
windowflags = WS_POPUP;
} else if (child_window) {
exstyle = 0;
windowflags = WS_POPUP;
windowflags = WS_CHILD;
} else {
exstyle = WS_EX_APPWINDOW;
windowflags = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;

View File

@ -186,10 +186,6 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nCreateWindow(JNIEn
return (INT_PTR)hwnd;
}
JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nGetParent(JNIEnv *env, jclass clazz, jlong hwnd_ptr) {
return (INT_PTR)GetParent((HWND)(INT_PTR)hwnd_ptr);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nReleaseDC(JNIEnv *env, jclass clazz, jlong hwnd_ptr, jlong hdc_ptr) {
HWND hwnd = (HWND)(INT_PTR)hwnd_ptr;
HDC hdc = (HDC)(INT_PTR)hdc_ptr;
@ -332,7 +328,6 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nGetVersion(JNIEn
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nReshape(JNIEnv *env, jclass unused, jlong hwnd_ptr, jint x, jint y, jint width, jint height, jboolean undecorated, jboolean child) {
HWND hwnd = (HWND)(INT_PTR)hwnd_ptr;
/*
DWORD exstyle, windowflags;
RECT clientSize;
@ -351,10 +346,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nReshape(JNIEnv *env
FALSE, // menu-present option
exstyle // extended window style
);
SetWindowPos(hwnd, HWND_TOP, x, y, clientSize.right - clientSize.left, clientSize.bottom - clientSize.top, SWP_NOZORDER);
*/
SetWindowPos(hwnd, HWND_TOP, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
}
static HICON createWindowIcon(JNIEnv *env, jint *pixels, jint width, jint height) {