1 /* 2 * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #import "common.h" 27 #import "com_sun_glass_events_ViewEvent.h" 28 #import "com_sun_glass_events_WindowEvent.h" 29 #import "com_sun_glass_ui_Window.h" 30 #import "com_sun_glass_ui_Window_Level.h" 31 #import "com_sun_glass_ui_mac_MacWindow.h" 32 33 #import "GlassMacros.h" 34 #import "GlassWindow.h" 35 #import "GlassTouches.h" 36 #import "GlassWindow+Java.h" 37 #import "GlassWindow+Overrides.h" 38 #import "GlassViewDelegate.h" 39 #import "GlassApplication.h" 40 #import "GlassScreen.h" 41 42 #import <AppKit/NSGraphics.h> // NSBeep(); 43 44 @implementation GlassWindow (Overrides) 45 46 - (void)dealloc 47 { 48 assert(pthread_main_np() == 1); 49 JNIEnv *env = jEnv; 50 if (env != NULL) 51 { 52 (*env)->DeleteGlobalRef(env, self->jWindow); 53 GLASS_CHECK_EXCEPTION(env); 54 } 55 56 self->jWindow = NULL; 57 58 [super dealloc]; 59 } 60 61 #pragma mark --- Delegate 62 63 - (void)windowDidBecomeKey:(NSNotification *)notification 64 { 65 if (self->fullscreenWindow) 66 { 67 return; 68 } 69 70 GET_MAIN_JENV; 71 if (!self->isEnabled) 72 { 73 NSBeep(); 74 (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocusDisabled); 75 return; 76 } 77 78 (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocus, com_sun_glass_events_WindowEvent_FOCUS_GAINED); 79 80 if (self->menubar != nil) 81 { 82 [NSApp setMainMenu:self->menubar->menu]; 83 } 84 [[NSApp mainMenu] update]; 85 } 86 87 - (void)windowDidResignKey:(NSNotification *)notification 88 { 89 if (self->fullscreenWindow) 90 { 91 return; 92 } 93 94 [self _ungrabFocus]; 95 96 GET_MAIN_JENV; 97 (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocus, com_sun_glass_events_WindowEvent_FOCUS_LOST); 98 } 99 100 - (void)windowWillClose:(NSNotification *)notification 101 { 102 // Unparent self. Otherwise the code hangs 103 if ([self->nsWindow parentWindow]) 104 { 105 [[self->nsWindow parentWindow] removeChildWindow:self->nsWindow]; 106 } 107 108 // Finally, close owned windows to mimic MS Windows behavior 109 NSArray *children = [self->nsWindow childWindows]; 110 for (NSUInteger i=0; i<[children count]; i++) 111 { 112 NSWindow *child = (NSWindow*)[children objectAtIndex:i]; 113 [child close]; 114 } 115 116 // Call the notification method 117 assert(pthread_main_np() == 1); 118 JNIEnv *env = jEnv; 119 if (env != NULL) { 120 (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyDestroy); 121 } 122 } 123 124 - (void)windowWillMove:(NSNotification *)notification 125 { 126 //NSLog(@"windowWillMove"); 127 } 128 129 - (void)windowDidMove:(NSNotification *)notification 130 { 131 //NSLog(@"windowDidMove"); 132 [self _sendJavaWindowMoveEventForFrame:[self _flipFrame]]; 133 } 134 135 - (void)windowDidChangeBackingProperties:(NSNotification *)notification 136 { 137 // The spec for [NSWindow backingScaleFactor] only mentions 1.0 and 2.0 138 // whereas NSScreen's one is more generic. So use the latter. 139 if ([self->nsWindow screen]) { 140 CGFloat scale = GetScreenScaleFactor([self->nsWindow screen]); 141 [self->view notifyScaleFactorChanged:scale]; 142 [self _sendJavaWindowNotifyScaleChanged:scale]; 143 } 144 145 // Screen.notifySettingsChanged() calls Window.setScreen(), and the latter 146 // generates the Window.EventHandler.handleScreenChangedEvent notification. 147 } 148 149 - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize 150 { 151 //NSLog(@"windowWillResize"); 152 return proposedFrameSize; 153 } 154 155 - (void)windowDidResize:(NSNotification *)notification 156 { 157 //NSLog(@"windowDidResize"); 158 NSRect frame = [self _flipFrame]; 159 160 if ((int)self->lastReportedLocation.x != (int)frame.origin.x || 161 (int)self->lastReportedLocation.y != (int)frame.origin.y) 162 { 163 [self _sendJavaWindowMoveEventForFrame:frame]; 164 165 // Refetch the frame since it might've been modified due to the previous call 166 frame = [self _flipFrame]; 167 } 168 169 [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_RESIZE forFrame:frame]; 170 } 171 172 - (void)windowDidMiniaturize:(NSNotification *)notification 173 { 174 [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_MINIMIZE forFrame:[self _flipFrame]]; 175 } 176 177 - (void)windowDidDeminiaturize:(NSNotification *)notification 178 { 179 [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_RESTORE forFrame:[self _flipFrame]]; 180 } 181 182 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame 183 { 184 GET_MAIN_JENV; 185 186 if ([window isZoomed]) { 187 return NO; 188 } 189 190 (*env)->CallVoidMethod(env, jWindow, jWindowNotifyResize, com_sun_glass_events_WindowEvent_MAXIMIZE, (int)newFrame.size.width, (int)newFrame.size.height); 191 192 return YES; 193 } 194 195 - (void)windowWillEnterFullScreen:(NSNotification *)notification 196 { 197 //NSLog(@"windowWillEnterFullScreen"); 198 } 199 200 - (void)windowDidEnterFullScreen:(NSNotification *)notification 201 { 202 //NSLog(@"windowDidEnterFullScreen"); 203 [(GlassViewDelegate*)[self->view delegate] sendJavaFullScreenEvent:YES withNativeWidget:YES]; 204 [GlassApplication leaveFullScreenExitingLoopIfNeeded]; 205 } 206 207 - (void)windowWillExitFullScreen:(NSNotification *)notification 208 { 209 //NSLog(@"windowWillExitFullScreen"); 210 } 211 - (void)windowDidExitFullScreen:(NSNotification *)notification 212 { 213 //NSLog(@"windowDidExitFullScreen"); 214 [(GlassViewDelegate*)[self->view delegate] sendJavaFullScreenEvent:NO withNativeWidget:YES]; 215 [GlassApplication leaveFullScreenExitingLoopIfNeeded]; 216 } 217 218 - (BOOL)windowShouldClose:(NSNotification *)notification 219 { 220 if (self->isEnabled) 221 { 222 GET_MAIN_JENV; 223 (*env)->CallVoidMethod(env, jWindow, jWindowNotifyClose); 224 } 225 226 // it's up to app to decide if the window should be closed 227 return FALSE; 228 } 229 230 #pragma mark --- Title Icon 231 232 - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu 233 { 234 return NO; 235 } 236 237 - (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard 238 { 239 return NO; 240 } 241 242 @end