summaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native')
-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
4 files changed, 158 insertions, 9 deletions
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);
}