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 [self->view notifyScaleFactorChanged:GetScreenScaleFactor([self->nsWindow screen])]; 141 } 142 143 // Screen.notifySettingsChanged() calls Window.setScreen(), and the latter 144 // generates the Window.EventHandler.handleScreenChangedEvent notification. 145 } 146 147 - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize 148 { 149 //NSLog(@"windowWillResize"); 150 return proposedFrameSize; 151 } 152 153 - (void)windowDidResize:(NSNotification *)notification 154 { 155 //NSLog(@"windowDidResize"); 156 NSRect frame = [self _flipFrame]; 157 158 if ((int)self->lastReportedLocation.x != (int)frame.origin.x || 159 (int)self->lastReportedLocation.y != (int)frame.origin.y) 160 { 161 [self _sendJavaWindowMoveEventForFrame:frame]; 162 163 // Refetch the frame since it might've been modified due to the previous call 164 frame = [self _flipFrame]; 165 } 166 167 [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_RESIZE forFrame:frame]; 168 } 169 170 - (void)windowDidMiniaturize:(NSNotification *)notification 171 { 172 [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_MINIMIZE forFrame:[self _flipFrame]]; 173 } 174 175 - (void)windowDidDeminiaturize:(NSNotification *)notification 176 { 177 [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_RESTORE forFrame:[self _flipFrame]]; 178 } 179 180 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame 181 { 182 GET_MAIN_JENV; 183 184 if ([window isZoomed]) { 185 return NO; 186 } 187 188 (*env)->CallVoidMethod(env, jWindow, jWindowNotifyResize, com_sun_glass_events_WindowEvent_MAXIMIZE, (int)newFrame.size.width, (int)newFrame.size.height); 189 190 return YES; 191 } 192 193 - (void)windowWillEnterFullScreen:(NSNotification *)notification 194 { 195 //NSLog(@"windowWillEnterFullScreen"); 196 } 197 198 - (void)windowDidEnterFullScreen:(NSNotification *)notification 199 { 200 //NSLog(@"windowDidEnterFullScreen"); 201 [(GlassViewDelegate*)[self->view delegate] sendJavaFullScreenEvent:YES withNativeWidget:YES]; 202 [GlassApplication leaveFullScreenExitingLoopIfNeeded]; 203 } 204 205 - (void)windowWillExitFullScreen:(NSNotification *)notification 206 { 207 //NSLog(@"windowWillExitFullScreen"); 208 } 209 - (void)windowDidExitFullScreen:(NSNotification *)notification 210 { 211 //NSLog(@"windowDidExitFullScreen"); 212 [(GlassViewDelegate*)[self->view delegate] sendJavaFullScreenEvent:NO withNativeWidget:YES]; 213 [GlassApplication leaveFullScreenExitingLoopIfNeeded]; 214 } 215 216 - (BOOL)windowShouldClose:(NSNotification *)notification 217 { 218 if (self->isEnabled) 219 { 220 GET_MAIN_JENV; 221 (*env)->CallVoidMethod(env, jWindow, jWindowNotifyClose); 222 } 223 224 // it's up to app to decide if the window should be closed 225 return FALSE; 226 } 227 228 #pragma mark --- Title Icon 229 230 - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu 231 { 232 return NO; 233 } 234 235 - (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard 236 { 237 return NO; 238 } 239 240 @end