aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortrembovetski <[email protected]>2009-08-20 10:32:13 -0700
committertrembovetski <[email protected]>2009-08-20 10:32:13 -0700
commit29b675c229e3d797f2c454803e289765b0bc801c (patch)
tree7a18a750f9ee3b4cb009f5d19e5751cc73420857
parent7bed517f4ebf9323b1ee96d6194579792ed5dfd9 (diff)
newt: one more attempt to commit insets-related changes
-rw-r--r--src/newt/classes/com/sun/javafx/newt/Insets.java13
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/Window.java33
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java48
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java15
-rw-r--r--src/newt/native/MacWindow.m7
-rw-r--r--src/newt/native/NewtMacWindow.h2
-rwxr-xr-x[-rw-r--r--]src/newt/native/NewtMacWindow.m41
-rwxr-xr-xsrc/newt/native/WindowsWindow.c117
8 files changed, 262 insertions, 14 deletions
diff --git a/src/newt/classes/com/sun/javafx/newt/Insets.java b/src/newt/classes/com/sun/javafx/newt/Insets.java
index 653ae8a10..7d379cd92 100644
--- a/src/newt/classes/com/sun/javafx/newt/Insets.java
+++ b/src/newt/classes/com/sun/javafx/newt/Insets.java
@@ -33,10 +33,11 @@
package com.sun.javafx.newt;
/**
- *
+ * Simple class representing insets.
+ *
* @author tdv
*/
-public class Insets {
+public class Insets implements Cloneable {
public int top;
public int left;
public int bottom;
@@ -93,4 +94,12 @@ public class Insets {
",bottom=" + bottom + ",right=" + right + "]";
}
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
}
diff --git a/src/newt/classes/com/sun/javafx/newt/Window.java b/src/newt/classes/com/sun/javafx/newt/Window.java
index 8970298d6..46eaf402f 100755
--- a/src/newt/classes/com/sun/javafx/newt/Window.java
+++ b/src/newt/classes/com/sun/javafx/newt/Window.java
@@ -306,14 +306,33 @@ public abstract class Window implements NativeWindow
return config;
}
+ /**
+ * Returns the width of the client area of this window
+ * @return width of the client area
+ */
public int getWidth() {
return width;
}
+ /**
+ * Returns the height of the client area of this window
+ * @return height of the client area
+ */
public int getHeight() {
return height;
}
+ /**
+ * Returns the insets for this native window (the difference between the
+ * size of the toplevel window with the decorations and the client area).
+ *
+ * @return insets for this platform window
+ */
+ // this probably belongs to NativeWindow interface
+ public Insets getInsets() {
+ return new Insets(0,0,0,0);
+ }
+
/** If this Window actually wraps one from another toolkit such as
the AWT, this will return a non-null value. */
public Object getWrappedWindow() {
@@ -381,7 +400,21 @@ public abstract class Window implements NativeWindow
}
public abstract void setVisible(boolean visible);
+ /**
+ * Sets the size of the client area of the window, excluding decorations
+ * Total size of the window will be
+ * {@code width+insets.left+insets.right, height+insets.top+insets.bottom}
+ * @param width of the client area of the window
+ * @param height of the client area of the window
+ */
public abstract void setSize(int width, int height);
+ /**
+ * Sets the location of the top left corner of the window, including
+ * decorations (so the client area will be placed at
+ * {@code x+insets.left,y+insets.top}.
+ * @param x coord of the top left corner
+ * @param y coord of the top left corner
+ */
public abstract void setPosition(int x, int y);
public abstract boolean setFullscreen(boolean fullscreen);
diff --git a/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java b/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java
index 704b578c4..ca7954a1c 100755
--- a/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java
+++ b/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java
@@ -130,6 +130,7 @@ public class MacWindow extends Window {
private volatile long surfaceHandle;
// non fullscreen dimensions ..
private int nfs_width, nfs_height, nfs_x, nfs_y;
+ private final Insets insets = new Insets(0,0,0,0);
static {
MacDisplay.initSingleton();
@@ -183,6 +184,31 @@ public class MacWindow extends Window {
}
}
+ class EnsureWindowCreatedAction implements Runnable {
+ public void run() {
+ nsViewLock.lock();
+ try {
+ createWindow(false);
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+ }
+ private EnsureWindowCreatedAction ensureWindowCreatedAction =
+ new EnsureWindowCreatedAction();
+
+ public Insets getInsets() {
+ // in order to properly calculate insets we need the window to be
+ // created
+ MainThread.invoke(true, ensureWindowCreatedAction);
+ nsViewLock.lock();
+ try {
+ return (Insets) insets.clone();
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
private ToolkitLock nsViewLock = new ToolkitLock() {
private Thread owner;
private int recursionCount;
@@ -233,6 +259,9 @@ public class MacWindow extends Window {
if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.VisibleAction "+visible+" "+Thread.currentThread().getName());
if (visible) {
createWindow(false);
+ if (windowHandle != 0) {
+ makeKeyAndOrderFront(windowHandle);
+ }
} else {
if (windowHandle != 0) {
orderOut(windowHandle);
@@ -344,6 +373,9 @@ public class MacWindow extends Window {
System.err.println("MacWindow fs: "+fullscreen+" "+x+"/"+y+" "+width+"x"+height);
}
createWindow(true);
+ if (windowHandle != 0) {
+ makeKeyAndOrderFront(windowHandle);
+ }
} finally {
nsViewLock.unlock();
}
@@ -386,6 +418,19 @@ public class MacWindow extends Window {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
}
+ private void insetsChanged(int left, int top, int right, int bottom) {
+ if (DEBUG_IMPLEMENTATION) {
+ System.out.println(Thread.currentThread().getName()+
+ " Insets changed to " + left + ", " + top + ", " + right + ", " + bottom);
+ }
+ if (left != -1 && top != -1 && right != -1 && bottom != -1) {
+ insets.left = left;
+ insets.top = top;
+ insets.right = right;
+ insets.bottom = bottom;
+ }
+ }
+
private void positionChanged(int newX, int newY) {
if (DEBUG_IMPLEMENTATION) {
System.out.println(Thread.currentThread().getName()+" Position changed to " + newX + ", " + newY);
@@ -527,7 +572,8 @@ public class MacWindow extends Window {
}
surfaceHandle = contentView(windowHandle);
setTitle0(windowHandle, getTitle());
- makeKeyAndOrderFront(windowHandle);
+ // don't make the window visible on window creation
+// makeKeyAndOrderFront(windowHandle);
sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
diff --git a/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java b/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java
index 18dc7dae3..f725874ef 100755
--- a/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java
+++ b/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java
@@ -34,9 +34,7 @@
package com.sun.javafx.newt.windows;
import javax.media.nativewindow.*;
-
import com.sun.javafx.newt.*;
-import com.sun.javafx.newt.impl.*;
public class WindowsWindow extends Window {
@@ -45,6 +43,7 @@ public class WindowsWindow extends Window {
private long windowHandleClose;
// non fullscreen dimensions ..
private int nfs_width, nfs_height, nfs_x, nfs_y;
+ private final Insets insets = new Insets(0, 0, 0, 0);
static {
WindowsDisplay.initSingleton();
@@ -204,6 +203,10 @@ public class WindowsWindow extends Window {
}
}
+ public Insets getInsets() {
+ return (Insets)insets.clone();
+ }
+
//----------------------------------------------------------------------
// Internals only
//
@@ -223,6 +226,14 @@ public class WindowsWindow extends Window {
private static native void setTitle(long windowHandle, String title);
private static native void requestFocus(long windowHandle);
+ private void insetsChanged(int left, int top, int right, int bottom) {
+ if (left != -1 && top != -1 && right != -1 && bottom != -1) {
+ insets.left = left;
+ insets.top = top;
+ insets.right = right;
+ insets.bottom = bottom;
+ }
+ }
private void sizeChanged(int newWidth, int newHeight) {
width = newWidth;
height = newHeight;
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 008a2417c..a93157c3f 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -55,7 +55,8 @@ NSString* jstringToNSString(JNIEnv* env, jstring jstr)
void setFrameTopLeftPoint(NSWindow* win, jint x, jint y)
{
NSScreen* screen = [NSScreen mainScreen];
- NSRect visibleScreenRect = [screen visibleFrame];
+ // this allows for better compatibility with awt behavior
+ NSRect visibleScreenRect = [screen frame];
NSPoint pt;
pt = NSMakePoint(x, visibleScreenRect.origin.y + visibleScreenRect.size.height - y);
@@ -89,6 +90,10 @@ NS_ENDHANDLER
}
[win setContentView: newView];
+ // make sure the insets are updated in the java object
+ NewtMacWindow* newtw = (NewtMacWindow*)win;
+ [newtw updateInsets: env];
+
return oldView;
}
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 09f9ffbd2..e19be2ed8 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -61,6 +61,8 @@
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jobject) clazz;
+- (void) updateInsets: (JNIEnv*) env;
+
- (id) initWithContentRect: (NSRect) contentRect
styleMask: (NSUInteger) windowStyle
backing: (NSBackingStoreType) bufferingType
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 62c6a6e25..f52d3b1bb 100644..100755
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -67,6 +67,7 @@
static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
+static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
@@ -80,16 +81,46 @@ static jmethodID windowDestroyedID = NULL;
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
- if (sendMouseEventID && sendKeyEventID && sizeChangedID && positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID) {
+ if (sendMouseEventID && sendKeyEventID && sizeChangedID && insetsChangedID &&
+ positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID)
+ {
return YES;
}
return NO;
}
+- (void) updateInsets: (JNIEnv*) env
+{
+ NSView* nsview = [self contentView];
+ if( ! [nsview isMemberOfClass:[NewtView class]] ) {
+ return;
+ }
+ NewtView* view = (NewtView *) nsview;
+ jobject javaWindowObject = [view getJavaWindowObject];
+ if (env==NULL || javaWindowObject == NULL) {
+ return;
+ }
+
+ NSRect frameRect = [self frame];
+ NSRect contentRect = [self contentRectForFrameRect: frameRect];
+
+ // note: this is a simplistic implementation which doesn't take
+ // into account DPI and scaling factor
+ CGFloat l = contentRect.origin.x - frameRect.origin.x;
+ jint top = (jint)(frameRect.size.height - contentRect.size.height);
+ jint left = (jint)l;
+ jint bottom = (jint)(contentRect.origin.y - frameRect.origin.y);
+ jint right = (jint)(frameRect.size.width - (contentRect.size.width + l));
+
+ (*env)->CallVoidMethod(env, javaWindowObject, insetsChangedID,
+ left, top, right, bottom);
+}
+
- (id) initWithContentRect: (NSRect) contentRect
styleMask: (NSUInteger) windowStyle
backing: (NSBackingStoreType) bufferingType
@@ -299,6 +330,9 @@ static jint mods2JavaMods(NSUInteger mods)
return;
}
+ // update insets on every window resize for lack of better hook place
+ [self updateInsets: env];
+
NSRect frameRect = [self frame];
NSRect contentRect = [self contentRectForFrameRect: frameRect];
@@ -321,14 +355,13 @@ static jint mods2JavaMods(NSUInteger mods)
}
NSRect rect = [self frame];
- NSScreen* menuBarScreen = NULL;
NSScreen* screen = NULL;
NSRect screenRect;
NSPoint pt;
- // FIXME: unclear whether this works correctly in multiple monitor situations
screen = [self screen];
- screenRect = [screen visibleFrame];
+ // this allows for better compatibility with awt behavior
+ screenRect = [screen frame];
pt = NSMakePoint(rect.origin.x, screenRect.origin.y + screenRect.size.height - rect.origin.y - rect.size.height);
(*env)->CallVoidMethod(env, javaWindowObject, positionChangedID,
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 5bd929ef7..5628fac81 100755
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -97,6 +97,7 @@
#include "KeyEvent.h"
static jmethodID sizeChangedID = NULL;
+static jmethodID insetsChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
@@ -105,6 +106,8 @@ static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID sendPaintEventID = NULL;
+static RECT* UpdateInsets(JNIEnv *env, HWND hwnd, jobject window);
+
typedef struct {
JNIEnv* jenv;
jobject jinstance;
@@ -590,10 +593,91 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
return 0;
}
+static RECT * UpdateInsets(JNIEnv *env, HWND hwnd, jobject window)
+{
+ // being naughty here
+ static RECT m_insets = { 0, 0, 0, 0 };
+ RECT outside;
+ RECT inside;
+
+ if (IsIconic(hwnd)) {
+ m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = -1;
+ return FALSE;
+ }
+
+ m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
+
+ GetClientRect(hwnd, &inside);
+ GetWindowRect(hwnd, &outside);
+
+ if (outside.right - outside.left > 0 && outside.bottom - outside.top > 0) {
+ MapWindowPoints(hwnd, 0, (LPPOINT)&inside, 2);
+ m_insets.top = inside.top - outside.top;
+ m_insets.bottom = outside.bottom - inside.bottom;
+ m_insets.left = inside.left - outside.left;
+ m_insets.right = outside.right - inside.right;
+ } else {
+ m_insets.top = -1;
+ }
+ if (m_insets.left < 0 || m_insets.top < 0 ||
+ m_insets.right < 0 || m_insets.bottom < 0)
+ {
+ LONG style = GetWindowLong(hwnd, GWL_STYLE);
+ // TODO: TDV: better undecorated checking needed
+ BOOL bIsUndecorated = (style & (WS_POPUP|WS_SYSMENU)) != 0;
+ if (!bIsUndecorated) {
+ /* Get outer frame sizes. */
+ if (style & WS_THICKFRAME) {
+ m_insets.left = m_insets.right =
+ GetSystemMetrics(SM_CXSIZEFRAME);
+ m_insets.top = m_insets.bottom =
+ GetSystemMetrics(SM_CYSIZEFRAME);
+ } else {
+ m_insets.left = m_insets.right =
+ GetSystemMetrics(SM_CXDLGFRAME);
+ m_insets.top = m_insets.bottom =
+ GetSystemMetrics(SM_CYDLGFRAME);
+ }
+
+ /* Add in title. */
+ m_insets.top += GetSystemMetrics(SM_CYCAPTION);
+ } else {
+ /* undo the -1 set above */
+ m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
+ }
+ }
+
+ (*env)->CallVoidMethod(env, window, insetsChangedID,
+ m_insets.left, m_insets.top,
+ m_insets.right, m_insets.bottom);
+ return &m_insets;
+}
+
+static void WmSize(JNIEnv *env, HWND wnd, jobject window, UINT type)
+{
+ RECT rc;
+ int w, h;
+
+ // make sure insets are up to date
+ (void)UpdateInsets(env, wnd, window);
+
+ if (type == SIZE_MINIMIZED) {
+ // TODO: deal with minimized window sizing
+ return;
+ }
+
+ GetClientRect(wnd, &rc);
+
+ // we report back the dimensions of the client area
+ w = rc.right - rc.left;
+ h = rc.bottom - rc.top;
+
+ (*env)->CallVoidMethod(env, window, sizeChangedID, w, h);
+}
+
static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
- RECT rc;
int useDefWindowProc = 0;
JNIEnv *env = NULL;
jobject window = NULL;
@@ -660,10 +744,20 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_SIZE:
- GetClientRect(wnd, &rc);
- (*env)->CallVoidMethod(env, window, sizeChangedID, (jint) rc.right, (jint) rc.bottom);
+ WmSize(env, wnd, window, (UINT)wParam);
+ break;
+
+ case WM_SETTINGCHANGE:
+ if (wParam == SPI_SETNONCLIENTMETRICS) {
+ // make sure insets are updated, we don't need to resize the window
+ // because the size of the client area doesn't change
+ (void)UpdateInsets(env, wnd, window);
+ } else {
+ useDefWindowProc = 1;
+ }
break;
+
case WM_LBUTTONDOWN:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
@@ -911,6 +1005,7 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initID
(JNIEnv *env, jclass clazz)
{
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(JZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
@@ -919,6 +1014,7 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initID
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
sendPaintEventID = (*env)->GetMethodID(env, clazz, "sendPaintEvent", "(IIIII)V");
if (sizeChangedID == NULL ||
+ insetsChangedID == NULL ||
positionChangedID == NULL ||
focusChangedID == NULL ||
windowDestroyNotifyID == NULL ||
@@ -980,6 +1076,9 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_CreateWin
#else
SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud);
#endif
+
+ UpdateInsets(env, window, obj);
+
ShowWindow(window, SW_SHOWNORMAL);
}
@@ -989,6 +1088,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_CreateWin
(*env)->ReleaseStringUTFChars(env, jWndName, wndName);
#endif
+
return (jlong) (intptr_t) window;
}
@@ -1066,8 +1166,17 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_setSize0
{
RECT r;
HWND w = (HWND) window;
+ // since width, height are the size of the client area, we need to add
+ // insets
+ RECT *pInsets = UpdateInsets(env, w, obj);
+ int nWidth, nHeight;
+
GetWindowRect(w, &r);
- MoveWindow(w, r.left, r.top, width, height, TRUE);
+
+ nWidth = width + pInsets->left + pInsets->right;
+ nHeight = height + pInsets->top + pInsets->bottom;
+ MoveWindow(w, r.left, r.top, nWidth, nHeight, TRUE);
+ // we report back the size of client area
(*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height);
}