diff options
Diffstat (limited to 'src/newt/native/NewtMacWindow.m')
-rw-r--r-- | src/newt/native/NewtMacWindow.m | 257 |
1 files changed, 145 insertions, 112 deletions
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index ce41673c4..402389e71 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -238,10 +238,14 @@ static jmethodID windowRepaintID = NULL; DBG_PRINT("*************** dirtyRect: %p %lf/%lf %lfx%lf\n", javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height); + if(NULL==javaWindowObject) { + DBG_PRINT("drawRect: null javaWindowObject\n"); + return; + } int shallBeDetached = 0; JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); if(NULL==env) { - DBG_PRINT("viewDidHide: null JNIEnv\n"); + DBG_PRINT("drawRect: null JNIEnv\n"); return; } @@ -258,6 +262,10 @@ static jmethodID windowRepaintID = NULL; - (void) viewDidHide { + if(NULL==javaWindowObject) { + DBG_PRINT("viewDidHide: null javaWindowObject\n"); + return; + } int shallBeDetached = 0; JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); if(NULL==env) { @@ -276,10 +284,14 @@ static jmethodID windowRepaintID = NULL; - (void) viewDidUnhide { + if(NULL==javaWindowObject) { + DBG_PRINT("viewDidUnhide: null javaWindowObject\n"); + return; + } int shallBeDetached = 0; JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); if(NULL==env) { - DBG_PRINT("viewDidHide: null JNIEnv\n"); + DBG_PRINT("viewDidUnhide: null JNIEnv\n"); return; } @@ -328,12 +340,14 @@ static jmethodID windowRepaintID = NULL; backing: (NSBackingStoreType) bufferingType defer: (BOOL) deferCreation screen:(NSScreen *)screen + isFullscreenWindow:(BOOL)isfs { id res = [super initWithContentRect: contentRect styleMask: windowStyle backing: bufferingType defer: deferCreation screen: screen]; + isFullscreenWindow = isfs; // Why is this necessary? Without it we don't get any of the // delegate methods like resizing and window movement. [self setDelegate: self]; @@ -389,8 +403,10 @@ static jmethodID windowRepaintID = NULL; { DBG_PRINT( "detachFromParent.1\n"); [self setParentWindow: nil]; - DBG_PRINT( "detachFromParent.2\n"); - [parent removeChildWindow: self]; + if(NULL != parent) { + DBG_PRINT( "detachFromParent.2\n"); + [parent removeChildWindow: self]; + } DBG_PRINT( "detachFromParent.X\n"); } @@ -463,15 +479,60 @@ static jmethodID windowRepaintID = NULL; // NSRect rS = [win convertRectFromScreen: r]; // 10.7 NSPoint oS = [self convertScreenToBase: r.origin]; oS.y = viewFrame.size.height - oS.y; // y-flip - return oS; } -- (BOOL) canBecomeKeyWindow +- (BOOL) isMouseInside { - // Even if the window is borderless, we still want it to be able - // to become the key window to receive keyboard events - return YES; + NSView* view = [self contentView]; + NSRect viewFrame = [view frame]; + NSPoint l1 = [NSEvent mouseLocation]; + NSPoint l0 = [self screenPos2NewtClientWinPos: l1]; + return viewFrame.origin.x <= l0.x && l0.x < (viewFrame.origin.x+viewFrame.size.width) && + viewFrame.origin.y <= l0.y && l0.y < (viewFrame.origin.y+viewFrame.size.height) ; +} + +- (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus +{ + mouseVisible = v; + mouseInside = [self isMouseInside]; + DBG_PRINT( "setMouseVisible: confined %d, visible %d (current: %d), mouseInside %d, hasFocus %d\n", + mouseConfined, mouseVisible, !cursorIsHidden, mouseInside, focus); + if(YES == focus && YES == mouseInside) { + [self cursorHide: !mouseVisible]; + } +} + +- (void) cursorHide:(BOOL)v +{ + DBG_PRINT( "cursorHide: %d -> %d\n", cursorIsHidden, v); + if(v) { + if(!cursorIsHidden) { + [NSCursor hide]; + cursorIsHidden = YES; + } + } else { + if(cursorIsHidden) { + [NSCursor unhide]; + cursorIsHidden = NO; + } + } +} + +- (void) setMouseConfined:(BOOL)v +{ + mouseConfined = v; + DBG_PRINT( "setMouseConfined: confined %d, visible %d\n", mouseConfined, mouseVisible); +} + +- (void) setMousePosition:(NSPoint)p +{ + NSScreen* screen = [self screen]; + NSRect screenRect = [screen frame]; + + CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin) + CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft); + CGEventPost (kCGHIDEventTap, ev); } static jint mods2JavaMods(NSUInteger mods) @@ -538,17 +599,6 @@ static jint mods2JavaMods(NSUInteger mods) } } -- (void) keyDown: (NSEvent*) theEvent -{ - [self sendKeyEvent: theEvent eventType: EVENT_KEY_PRESSED]; -} - -- (void) keyUp: (NSEvent*) theEvent -{ - [self sendKeyEvent: theEvent eventType: EVENT_KEY_RELEASED]; - [self sendKeyEvent: theEvent eventType: EVENT_KEY_TYPED]; -} - - (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType { NSView* nsview = [self contentView]; @@ -624,53 +674,100 @@ static jint mods2JavaMods(NSUInteger mods) } } -- (void) setMouseVisible:(BOOL)v +- (void) focusChanged: (BOOL) gained { - mouseVisible = v; - DBG_PRINT( "setMouseVisible: confined %d, visible %d\n", mouseConfined, mouseVisible); - if(YES == mouseInside) { - [self cursorHide: !mouseVisible]; + DBG_PRINT( "focusChanged: gained %d\n", gained); + NSView* nsview = [self contentView]; + if( ! [nsview isMemberOfClass:[NewtView class]] ) { + return; + } + NewtView* view = (NewtView *) nsview; + jobject javaWindowObject = [view getJavaWindowObject]; + if (javaWindowObject == NULL) { + DBG_PRINT("focusChanged: null javaWindowObject\n"); + return; + } + int shallBeDetached = 0; + JavaVM *jvmHandle = [view getJVMHandle]; + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + if(NULL==env) { + DBG_PRINT("focusChanged: null JNIEnv\n"); + return; + } + + (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE); + + if (shallBeDetached) { + (*jvmHandle)->DetachCurrentThread(jvmHandle); } } -- (void) cursorHide:(BOOL)v +- (BOOL) becomeFirstResponder { - if(v) { - if(!cursorIsHidden) { - [NSCursor hide]; - cursorIsHidden = YES; - } - } else { - if(cursorIsHidden) { - [NSCursor unhide]; - cursorIsHidden = NO; - } + DBG_PRINT( "*************** becomeFirstResponder\n"); + return [super becomeFirstResponder]; +} + +- (BOOL) resignFirstResponder +{ + DBG_PRINT( "*************** resignFirstResponder\n"); + return [super resignFirstResponder]; +} + +- (BOOL) canBecomeKeyWindow +{ + // Even if the window is borderless, we still want it to be able + // to become the key window to receive keyboard events + return YES; +} + +- (void) becomeKeyWindow +{ + DBG_PRINT( "*************** becomeKeyWindow\n"); + [super becomeKeyWindow]; +} + +- (void) resignKeyWindow +{ + DBG_PRINT( "*************** resignKeyWindow: isFullscreen %d\n", (int)isFullscreenWindow); + if(!isFullscreenWindow) { + [super resignKeyWindow]; } } -- (void) setMouseConfined:(BOOL)v +- (void) windowDidBecomeKey: (NSNotification *) notification { - mouseConfined = v; - DBG_PRINT( "setMouseConfined: confined %d, visible %d\n", mouseConfined, mouseVisible); + DBG_PRINT( "*************** windowDidBecomeKey\n"); + mouseInside = [self isMouseInside]; + if(YES == mouseInside) { + [self cursorHide: !mouseVisible]; + } + [self focusChanged: YES]; } -- (void) setMousePosition:(NSPoint)p +- (void) windowDidResignKey: (NSNotification *) notification { - NSScreen* screen = [self screen]; - NSRect screenRect = [screen frame]; + DBG_PRINT( "*************** windowDidResignKey\n"); + // Implicit mouse exit by OS X + [self focusChanged: NO]; +} - CGPoint pt = { p.x, screenRect.size.height - p.y }; // y-flip (CG is top-left origin) - CGEventRef ev = CGEventCreateMouseEvent (NULL, kCGEventMouseMoved, pt, kCGMouseButtonLeft); - CGEventPost (kCGHIDEventTap, ev); - NSPoint l0 = [NSEvent mouseLocation]; - [self screenPos2NewtClientWinPos: l0]; +- (void) keyDown: (NSEvent*) theEvent +{ + [self sendKeyEvent: theEvent eventType: EVENT_KEY_PRESSED]; +} + +- (void) keyUp: (NSEvent*) theEvent +{ + [self sendKeyEvent: theEvent eventType: EVENT_KEY_RELEASED]; + [self sendKeyEvent: theEvent eventType: EVENT_KEY_TYPED]; } - (void) mouseEntered: (NSEvent*) theEvent { DBG_PRINT( "mouseEntered: confined %d, visible %d\n", mouseConfined, mouseVisible); mouseInside = YES; - [self setMouseVisible: mouseVisible]; + [self cursorHide: !mouseVisible]; if(NO == mouseConfined) { [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; } @@ -859,68 +956,4 @@ static jint mods2JavaMods(NSUInteger mods) [pool release]; } -- (BOOL) becomeFirstResponder -{ - DBG_PRINT( "*************** becomeFirstResponder\n"); - return [super becomeFirstResponder]; -} - -- (BOOL) resignFirstResponder -{ - DBG_PRINT( "*************** resignFirstResponder\n"); - return [super resignFirstResponder]; -} - -- (void) becomeKeyWindow -{ - DBG_PRINT( "*************** becomeKeyWindow\n"); - [super becomeKeyWindow]; -} - -- (void) resignKeyWindow -{ - DBG_PRINT( "*************** resignKeyWindow\n"); - [super resignKeyWindow]; -} - -- (void) windowDidBecomeKey: (NSNotification *) notification -{ - DBG_PRINT( "*************** windowDidBecomeKey\n"); - [self focusChanged: YES]; -} - -- (void) windowDidResignKey: (NSNotification *) notification -{ - DBG_PRINT( "*************** windowDidResignKey\n"); - [self focusChanged: NO]; -} - -- (void) focusChanged: (BOOL) gained -{ - DBG_PRINT( "focusChanged: gained %d\n", gained); - NSView* nsview = [self contentView]; - if( ! [nsview isMemberOfClass:[NewtView class]] ) { - return; - } - NewtView* view = (NewtView *) nsview; - jobject javaWindowObject = [view getJavaWindowObject]; - if (javaWindowObject == NULL) { - DBG_PRINT("focusChanged: null javaWindowObject\n"); - return; - } - int shallBeDetached = 0; - JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); - if(NULL==env) { - DBG_PRINT("focusChanged: null JNIEnv\n"); - return; - } - - (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE); - - if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } -} - @end |