Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native/sun/awt/AWTWindow.m
38829 views
1
/*
2
* Copyright (c) 2011, 2014, 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
#ifdef MACOSX_NOTIOS // prevent merge conflicts
27
#import <Cocoa/Cocoa.h>
28
#import <JavaNativeFoundation/JavaNativeFoundation.h>
29
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
30
31
#import "sun_lwawt_macosx_CPlatformWindow.h"
32
#import "com_apple_eawt_event_GestureHandler.h"
33
#import "com_apple_eawt_FullScreenHandler.h"
34
#import "ApplicationDelegate.h"
35
36
#import "AWTWindow.h"
37
#import "AWTView.h"
38
#import "CMenu.h"
39
#import "CMenuBar.h"
40
#import "LWCToolkit.h"
41
#import "GeomUtilities.h"
42
#import "ThreadUtilities.h"
43
#import "OSVersion.h"
44
45
#define MASK(KEY) \
46
(sun_lwawt_macosx_CPlatformWindow_ ## KEY)
47
48
#define IS(BITS, KEY) \
49
((BITS & MASK(KEY)) != 0)
50
51
#define SET(BITS, KEY, VALUE) \
52
BITS = VALUE ? BITS | MASK(KEY) : BITS & ~MASK(KEY)
53
54
static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");
55
56
// Cocoa windowDidBecomeKey/windowDidResignKey notifications
57
// doesn't provide information about "opposite" window, so we
58
// have to do a bit of tracking. This variable points to a window
59
// which had been the key window just before a new key window
60
// was set. It would be nil if the new key window isn't an AWT
61
// window or the app currently has no key window.
62
static AWTWindow* lastKeyWindow = nil;
63
64
// --------------------------------------------------------------
65
// NSWindow/NSPanel descendants implementation
66
#define AWT_NS_WINDOW_IMPLEMENTATION \
67
- (id) initWithDelegate:(AWTWindow *)delegate \
68
frameRect:(NSRect)contectRect \
69
styleMask:(NSUInteger)styleMask \
70
contentView:(NSView *)view \
71
{ \
72
self = [super initWithContentRect:contectRect \
73
styleMask:styleMask \
74
backing:NSBackingStoreBuffered \
75
defer:NO]; \
76
\
77
if (self == nil) return nil; \
78
\
79
[self setDelegate:delegate]; \
80
[self setContentView:view]; \
81
[self setInitialFirstResponder:view]; \
82
[self setReleasedWhenClosed:NO]; \
83
[self setPreservesContentDuringLiveResize:YES]; \
84
\
85
return self; \
86
} \
87
\
88
/* NSWindow overrides */ \
89
- (BOOL) canBecomeKeyWindow { \
90
return [(AWTWindow*)[self delegate] canBecomeKeyWindow]; \
91
} \
92
\
93
- (BOOL) canBecomeMainWindow { \
94
return [(AWTWindow*)[self delegate] canBecomeMainWindow]; \
95
} \
96
\
97
- (BOOL) worksWhenModal { \
98
return [(AWTWindow*)[self delegate] worksWhenModal]; \
99
} \
100
\
101
- (void)sendEvent:(NSEvent *)event { \
102
[(AWTWindow*)[self delegate] sendEvent:event]; \
103
[super sendEvent:event]; \
104
}
105
106
@implementation AWTWindow_Normal
107
AWT_NS_WINDOW_IMPLEMENTATION
108
109
// Gesture support
110
- (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {
111
AWT_ASSERT_APPKIT_THREAD;
112
113
JNIEnv *env = [ThreadUtilities getJNIEnv];
114
jobject platformWindow = [((AWTWindow *)self.delegate).javaPlatformWindow jObjectWithEnv:env];
115
if (platformWindow != NULL) {
116
// extract the target AWT Window object out of the CPlatformWindow
117
static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
118
jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
119
if (awtWindow != NULL) {
120
// translate the point into Java coordinates
121
NSPoint loc = [event locationInWindow];
122
loc.y = [self frame].size.height - loc.y;
123
124
// send up to the GestureHandler to recursively dispatch on the AWT event thread
125
static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");
126
static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");
127
JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);
128
(*env)->DeleteLocalRef(env, awtWindow);
129
}
130
(*env)->DeleteLocalRef(env, platformWindow);
131
}
132
}
133
134
- (void)beginGestureWithEvent:(NSEvent *)event {
135
[self postGesture:event
136
as:com_apple_eawt_event_GestureHandler_PHASE
137
a:-1.0
138
b:0.0];
139
}
140
141
- (void)endGestureWithEvent:(NSEvent *)event {
142
[self postGesture:event
143
as:com_apple_eawt_event_GestureHandler_PHASE
144
a:1.0
145
b:0.0];
146
}
147
148
- (void)magnifyWithEvent:(NSEvent *)event {
149
[self postGesture:event
150
as:com_apple_eawt_event_GestureHandler_MAGNIFY
151
a:[event magnification]
152
b:0.0];
153
}
154
155
- (void)rotateWithEvent:(NSEvent *)event {
156
[self postGesture:event
157
as:com_apple_eawt_event_GestureHandler_ROTATE
158
a:[event rotation]
159
b:0.0];
160
}
161
162
- (void)swipeWithEvent:(NSEvent *)event {
163
[self postGesture:event
164
as:com_apple_eawt_event_GestureHandler_SWIPE
165
a:[event deltaX]
166
b:[event deltaY]];
167
}
168
169
@end
170
@implementation AWTWindow_Panel
171
AWT_NS_WINDOW_IMPLEMENTATION
172
@end
173
// END of NSWindow/NSPanel descendants implementation
174
// --------------------------------------------------------------
175
176
177
@implementation AWTWindow
178
179
@synthesize nsWindow;
180
@synthesize javaPlatformWindow;
181
@synthesize javaMenuBar;
182
@synthesize javaMinSize;
183
@synthesize javaMaxSize;
184
@synthesize styleBits;
185
@synthesize isEnabled;
186
@synthesize ownerWindow;
187
@synthesize preFullScreenLevel;
188
@synthesize isMinimizing;
189
190
- (void) updateMinMaxSize:(BOOL)resizable {
191
if (resizable) {
192
[self.nsWindow setMinSize:self.javaMinSize];
193
[self.nsWindow setMaxSize:self.javaMaxSize];
194
} else {
195
NSRect currentFrame = [self.nsWindow frame];
196
[self.nsWindow setMinSize:currentFrame.size];
197
[self.nsWindow setMaxSize:currentFrame.size];
198
}
199
}
200
201
// creates a new NSWindow style mask based on the _STYLE_PROP_BITMASK bits
202
+ (NSUInteger) styleMaskForStyleBits:(jint)styleBits {
203
NSUInteger type = 0;
204
if (IS(styleBits, DECORATED)) {
205
type |= NSTitledWindowMask;
206
if (IS(styleBits, CLOSEABLE)) type |= NSClosableWindowMask;
207
if (IS(styleBits, MINIMIZABLE)) type |= NSMiniaturizableWindowMask;
208
if (IS(styleBits, RESIZABLE)) type |= NSResizableWindowMask;
209
if (IS(styleBits, FULL_WINDOW_CONTENT)) type |= NSFullSizeContentViewWindowMask;
210
} else {
211
type |= NSBorderlessWindowMask;
212
}
213
214
if (IS(styleBits, TEXTURED)) type |= NSTexturedBackgroundWindowMask;
215
if (IS(styleBits, UNIFIED)) type |= NSUnifiedTitleAndToolbarWindowMask;
216
if (IS(styleBits, UTILITY)) type |= NSUtilityWindowMask;
217
if (IS(styleBits, HUD)) type |= NSHUDWindowMask;
218
if (IS(styleBits, SHEET)) type |= NSDocModalWindowMask;
219
if (IS(styleBits, NONACTIVATING)) type |= NSNonactivatingPanelMask;
220
221
return type;
222
}
223
224
// updates _METHOD_PROP_BITMASK based properties on the window
225
- (void) setPropertiesForStyleBits:(jint)bits mask:(jint)mask {
226
if (IS(mask, RESIZABLE)) {
227
BOOL resizable = IS(bits, RESIZABLE);
228
[self updateMinMaxSize:resizable];
229
[self.nsWindow setShowsResizeIndicator:resizable];
230
// Zoom button should be disabled, if the window is not resizable,
231
// otherwise button should be restored to initial state.
232
BOOL zoom = resizable && IS(bits, ZOOMABLE);
233
[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:zoom];
234
}
235
236
if (IS(mask, HAS_SHADOW)) {
237
[self.nsWindow setHasShadow:IS(bits, HAS_SHADOW)];
238
}
239
240
if (IS(mask, ZOOMABLE)) {
241
[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:IS(bits, ZOOMABLE)];
242
}
243
244
if (IS(mask, ALWAYS_ON_TOP)) {
245
[self.nsWindow setLevel:IS(bits, ALWAYS_ON_TOP) ? NSFloatingWindowLevel : NSNormalWindowLevel];
246
}
247
248
if (IS(mask, HIDES_ON_DEACTIVATE)) {
249
[self.nsWindow setHidesOnDeactivate:IS(bits, HIDES_ON_DEACTIVATE)];
250
}
251
252
if (IS(mask, DRAGGABLE_BACKGROUND)) {
253
[self.nsWindow setMovableByWindowBackground:IS(bits, DRAGGABLE_BACKGROUND)];
254
}
255
256
if (IS(mask, DOCUMENT_MODIFIED)) {
257
[self.nsWindow setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];
258
}
259
260
if (IS(mask, FULLSCREENABLE) && [self.nsWindow respondsToSelector:@selector(toggleFullScreen:)]) {
261
if (IS(bits, FULLSCREENABLE)) {
262
[self.nsWindow setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
263
} else {
264
[self.nsWindow setCollectionBehavior:NSWindowCollectionBehaviorDefault];
265
}
266
}
267
268
if (IS(mask, TRANSPARENT_TITLE_BAR) && [self.nsWindow respondsToSelector:@selector(setTitlebarAppearsTransparent:)]) {
269
[self.nsWindow setTitlebarAppearsTransparent:IS(bits, TRANSPARENT_TITLE_BAR)];
270
}
271
}
272
273
- (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow
274
ownerWindow:owner
275
styleBits:(jint)bits
276
frameRect:(NSRect)rect
277
contentView:(NSView *)view
278
{
279
AWT_ASSERT_APPKIT_THREAD;
280
281
NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];
282
NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];
283
if (contentRect.size.width <= 0.0) {
284
contentRect.size.width = 1.0;
285
}
286
if (contentRect.size.height <= 0.0) {
287
contentRect.size.height = 1.0;
288
}
289
290
self = [super init];
291
292
if (self == nil) return nil; // no hope
293
294
if (IS(bits, UTILITY) ||
295
IS(bits, NONACTIVATING) ||
296
IS(bits, HUD) ||
297
IS(bits, HIDES_ON_DEACTIVATE))
298
{
299
self.nsWindow = [[AWTWindow_Panel alloc] initWithDelegate:self
300
frameRect:contentRect
301
styleMask:styleMask
302
contentView:view];
303
}
304
else
305
{
306
// These windows will appear in the window list in the dock icon menu
307
self.nsWindow = [[AWTWindow_Normal alloc] initWithDelegate:self
308
frameRect:contentRect
309
styleMask:styleMask
310
contentView:view];
311
}
312
313
if (self.nsWindow == nil) return nil; // no hope either
314
[self.nsWindow release]; // the property retains the object already
315
316
self.isEnabled = YES;
317
self.isMinimizing = NO;
318
self.javaPlatformWindow = platformWindow;
319
self.styleBits = bits;
320
self.ownerWindow = owner;
321
[self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
322
323
if (IS(self.styleBits, IS_POPUP)) {
324
[self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];
325
}
326
327
return self;
328
}
329
330
+ (BOOL) isAWTWindow:(NSWindow *)window {
331
return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
332
}
333
334
// Retrieves the list of possible window layers (levels)
335
+ (NSArray*) getWindowLayers {
336
static NSArray *windowLayers;
337
static dispatch_once_t token;
338
339
// Initialize the list of possible window layers
340
dispatch_once(&token, ^{
341
// The layers are ordered from front to back, (i.e. the toppest one is the first)
342
windowLayers = [NSArray arrayWithObjects:
343
[NSNumber numberWithInt:CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey)],
344
[NSNumber numberWithInt:CGWindowLevelForKey(kCGFloatingWindowLevelKey)],
345
[NSNumber numberWithInt:CGWindowLevelForKey(kCGNormalWindowLevelKey)],
346
nil
347
];
348
[windowLayers retain];
349
});
350
return windowLayers;
351
}
352
353
// returns id for the topmost window under mouse
354
+ (NSInteger) getTopmostWindowUnderMouseID {
355
NSInteger result = -1;
356
357
NSArray *windowLayers = [AWTWindow getWindowLayers];
358
// Looking for the window under mouse starting from the toppest layer
359
for (NSNumber *layer in windowLayers) {
360
result = [AWTWindow getTopmostWindowUnderMouseIDImpl:[layer integerValue]];
361
if (result != -1) {
362
break;
363
}
364
}
365
return result;
366
}
367
368
+ (NSInteger) getTopmostWindowUnderMouseIDImpl:(NSInteger)windowLayer {
369
NSInteger result = -1;
370
371
NSRect screenRect = [[NSScreen mainScreen] frame];
372
NSPoint nsMouseLocation = [NSEvent mouseLocation];
373
CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
374
375
NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
376
377
for (NSDictionary *window in windows) {
378
NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
379
if (layer == windowLayer) {
380
CGRect rect;
381
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
382
if (CGRectContainsPoint(rect, cgMouseLocation)) {
383
result = [[window objectForKey:(id)kCGWindowNumber] integerValue];
384
break;
385
}
386
}
387
}
388
[windows release];
389
return result;
390
}
391
392
// checks that this window is under the mouse cursor and this point is not overlapped by others windows
393
- (BOOL) isTopmostWindowUnderMouse {
394
return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
395
}
396
397
+ (AWTWindow *) getTopmostWindowUnderMouse {
398
NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
399
NSWindow *window;
400
401
NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
402
403
while ((window = [windowEnumerator nextObject]) != nil) {
404
if ([window windowNumber] == topmostWindowUnderMouseID) {
405
BOOL isAWTWindow = [AWTWindow isAWTWindow: window];
406
return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
407
}
408
}
409
return nil;
410
}
411
412
+ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {
413
414
NSPoint screenLocation = [NSEvent mouseLocation];
415
NSPoint windowLocation = [window convertScreenToBase: screenLocation];
416
int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
417
418
NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
419
location: windowLocation
420
modifierFlags: modifierFlags
421
timestamp: 0
422
windowNumber: [window windowNumber]
423
context: nil
424
eventNumber: 0
425
trackingNumber: 0
426
userData: nil
427
];
428
429
[[window contentView] deliverJavaMouseEvent: mouseEvent];
430
}
431
432
+ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
433
434
NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
435
NSArray *windows = [NSApp windows];
436
NSWindow *window;
437
438
NSEnumerator *windowEnumerator = [windows objectEnumerator];
439
while ((window = [windowEnumerator nextObject]) != nil) {
440
if ([AWTWindow isAWTWindow: window]) {
441
BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);
442
BOOL mouseIsOver = [[window contentView] mouseIsOver];
443
if (isUnderMouse && !mouseIsOver) {
444
[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];
445
} else if (!isUnderMouse && mouseIsOver) {
446
[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];
447
}
448
}
449
}
450
}
451
452
+ (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window {
453
AWT_ASSERT_APPKIT_THREAD;
454
NSScreen *screen = [window screen];
455
NSDictionary *deviceDescription = [screen deviceDescription];
456
return [deviceDescription objectForKey:@"NSScreenNumber"];
457
}
458
459
- (void) dealloc {
460
AWT_ASSERT_APPKIT_THREAD;
461
462
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
463
[self.javaPlatformWindow setJObject:nil withEnv:env];
464
self.javaPlatformWindow = nil;
465
self.nsWindow = nil;
466
self.ownerWindow = nil;
467
[super dealloc];
468
}
469
470
// Tests whether window is blocked by modal dialog/window
471
- (BOOL) isBlocked {
472
BOOL isBlocked = NO;
473
474
JNIEnv *env = [ThreadUtilities getJNIEnv];
475
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
476
if (platformWindow != NULL) {
477
static JNF_MEMBER_CACHE(jm_isBlocked, jc_CPlatformWindow, "isBlocked", "()Z");
478
isBlocked = JNFCallBooleanMethod(env, platformWindow, jm_isBlocked) == JNI_TRUE ? YES : NO;
479
(*env)->DeleteLocalRef(env, platformWindow);
480
}
481
482
return isBlocked;
483
}
484
485
- (BOOL) isSimpleWindowOwnedByEmbeddedFrame {
486
BOOL isSimpleWindowOwnedByEmbeddedFrame = NO;
487
488
JNIEnv *env = [ThreadUtilities getJNIEnv];
489
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
490
if (platformWindow != NULL) {
491
static JNF_MEMBER_CACHE(jm_isBlocked, jc_CPlatformWindow, "isSimpleWindowOwnedByEmbeddedFrame", "()Z");
492
isSimpleWindowOwnedByEmbeddedFrame = JNFCallBooleanMethod(env, platformWindow, jm_isBlocked) == JNI_TRUE ? YES : NO;
493
(*env)->DeleteLocalRef(env, platformWindow);
494
}
495
496
return isSimpleWindowOwnedByEmbeddedFrame;
497
}
498
499
// Tests whether the corresponding Java platform window is visible or not
500
+ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window {
501
BOOL isVisible = NO;
502
503
if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) {
504
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
505
[AWTToolkit eventCountPlusPlus];
506
507
JNIEnv *env = [ThreadUtilities getJNIEnv];
508
jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env];
509
if (platformWindow != NULL) {
510
static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z");
511
isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO;
512
(*env)->DeleteLocalRef(env, platformWindow);
513
514
}
515
}
516
return isVisible;
517
}
518
519
// Orders window's childs based on the current focus state
520
- (void) orderChildWindows:(BOOL)focus {
521
AWT_ASSERT_APPKIT_THREAD;
522
523
if (self.isMinimizing || [self isBlocked]) {
524
// Do not perform any ordering, if iconify is in progress
525
// or the window is blocked by a modal window
526
return;
527
}
528
529
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
530
NSWindow *window;
531
while ((window = [windowEnumerator nextObject]) != nil) {
532
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
533
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
534
AWTWindow *owner = awtWindow.ownerWindow;
535
if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) {
536
// Do not order 'always on top' windows
537
continue;
538
}
539
while (awtWindow.ownerWindow != nil) {
540
if (awtWindow.ownerWindow == self) {
541
if (focus) {
542
// Move the childWindow to floating level
543
// so it will appear in front of its
544
// parent which owns the focus
545
[window setLevel:NSFloatingWindowLevel];
546
} else {
547
// Focus owner has changed, move the childWindow
548
// back to normal window level
549
[window setLevel:NSNormalWindowLevel];
550
}
551
// The childWindow should be displayed in front of
552
// its nearest parentWindow
553
[window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];
554
break;
555
}
556
awtWindow = awtWindow.ownerWindow;
557
}
558
}
559
}
560
}
561
562
// NSWindow overrides
563
- (BOOL) canBecomeKeyWindow {
564
AWT_ASSERT_APPKIT_THREAD;
565
return self.isEnabled && (IS(self.styleBits, SHOULD_BECOME_KEY) || [self isSimpleWindowOwnedByEmbeddedFrame]);
566
}
567
568
- (BOOL) canBecomeMainWindow {
569
AWT_ASSERT_APPKIT_THREAD;
570
if (!self.isEnabled) {
571
// Native system can bring up the NSWindow to
572
// the top even if the window is not main.
573
// We should bring up the modal dialog manually
574
[AWTToolkit eventCountPlusPlus];
575
576
JNIEnv *env = [ThreadUtilities getJNIEnv];
577
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
578
if (platformWindow != NULL) {
579
static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,
580
"checkBlockingAndOrder", "()Z");
581
JNFCallBooleanMethod(env, platformWindow, jm_checkBlockingAndOrder);
582
(*env)->DeleteLocalRef(env, platformWindow);
583
}
584
}
585
586
return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);
587
}
588
589
- (BOOL) worksWhenModal {
590
AWT_ASSERT_APPKIT_THREAD;
591
return IS(self.styleBits, MODAL_EXCLUDED);
592
}
593
594
595
// NSWindowDelegate methods
596
597
- (void) _deliverMoveResizeEvent {
598
AWT_ASSERT_APPKIT_THREAD;
599
600
// deliver the event if this is a user-initiated live resize or as a side-effect
601
// of a Java initiated resize, because AppKit can override the bounds and force
602
// the bounds of the window to avoid the Dock or remain on screen.
603
[AWTToolkit eventCountPlusPlus];
604
JNIEnv *env = [ThreadUtilities getJNIEnv];
605
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
606
if (platformWindow == NULL) {
607
// TODO: create generic AWT assert
608
}
609
610
NSRect frame = ConvertNSScreenRect(env, [self.nsWindow frame]);
611
612
static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIIIZ)V");
613
JNFCallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,
614
(jint)frame.origin.x,
615
(jint)frame.origin.y,
616
(jint)frame.size.width,
617
(jint)frame.size.height,
618
(jboolean)[self.nsWindow inLiveResize]);
619
(*env)->DeleteLocalRef(env, platformWindow);
620
621
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
622
}
623
624
- (void)windowDidMove:(NSNotification *)notification {
625
AWT_ASSERT_APPKIT_THREAD;
626
627
[self _deliverMoveResizeEvent];
628
}
629
630
- (void)windowDidResize:(NSNotification *)notification {
631
AWT_ASSERT_APPKIT_THREAD;
632
633
[self _deliverMoveResizeEvent];
634
}
635
636
- (void)windowDidExpose:(NSNotification *)notification {
637
AWT_ASSERT_APPKIT_THREAD;
638
639
[AWTToolkit eventCountPlusPlus];
640
// TODO: don't see this callback invoked anytime so we track
641
// window exposing in _setVisible:(BOOL)
642
}
643
644
// Hides/shows window's childs during iconify/de-iconify operation
645
- (void) iconifyChildWindows:(BOOL)iconify {
646
AWT_ASSERT_APPKIT_THREAD;
647
648
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
649
NSWindow *window;
650
while ((window = [windowEnumerator nextObject]) != nil) {
651
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
652
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
653
while (awtWindow.ownerWindow != nil) {
654
if (awtWindow.ownerWindow == self) {
655
if (iconify) {
656
[window orderOut:window];
657
} else {
658
[window orderFront:window];
659
}
660
break;
661
}
662
awtWindow = awtWindow.ownerWindow;
663
}
664
}
665
}
666
}
667
668
- (void) _deliverIconify:(BOOL)iconify {
669
AWT_ASSERT_APPKIT_THREAD;
670
671
[AWTToolkit eventCountPlusPlus];
672
JNIEnv *env = [ThreadUtilities getJNIEnv];
673
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
674
if (platformWindow != NULL) {
675
static JNF_MEMBER_CACHE(jm_deliverIconify, jc_CPlatformWindow, "deliverIconify", "(Z)V");
676
JNFCallVoidMethod(env, platformWindow, jm_deliverIconify, iconify);
677
(*env)->DeleteLocalRef(env, platformWindow);
678
}
679
}
680
681
- (void)windowWillMiniaturize:(NSNotification *)notification {
682
AWT_ASSERT_APPKIT_THREAD;
683
684
self.isMinimizing = YES;
685
686
JNIEnv *env = [ThreadUtilities getJNIEnv];
687
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
688
if (platformWindow != NULL) {
689
static JNF_MEMBER_CACHE(jm_windowWillMiniaturize, jc_CPlatformWindow, "windowWillMiniaturize", "()V");
690
JNFCallVoidMethod(env, platformWindow, jm_windowWillMiniaturize);
691
(*env)->DeleteLocalRef(env, platformWindow);
692
}
693
// Excplicitly make myself a key window to avoid possible
694
// negative visual effects during iconify operation
695
[self.nsWindow makeKeyAndOrderFront:self.nsWindow];
696
[self iconifyChildWindows:YES];
697
}
698
699
- (void)windowDidMiniaturize:(NSNotification *)notification {
700
AWT_ASSERT_APPKIT_THREAD;
701
702
[self _deliverIconify:JNI_TRUE];
703
self.isMinimizing = NO;
704
}
705
706
- (void)windowDidDeminiaturize:(NSNotification *)notification {
707
AWT_ASSERT_APPKIT_THREAD;
708
709
[self _deliverIconify:JNI_FALSE];
710
[self iconifyChildWindows:NO];
711
}
712
713
- (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite {
714
//AWT_ASSERT_APPKIT_THREAD;
715
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
716
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
717
if (platformWindow != NULL) {
718
jobject oppositeWindow = [opposite.javaPlatformWindow jObjectWithEnv:env];
719
720
static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(ZLsun/lwawt/macosx/CPlatformWindow;)V");
721
JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused, oppositeWindow);
722
(*env)->DeleteLocalRef(env, platformWindow);
723
(*env)->DeleteLocalRef(env, oppositeWindow);
724
}
725
}
726
727
728
- (void) windowDidBecomeKey: (NSNotification *) notification {
729
AWT_ASSERT_APPKIT_THREAD;
730
[AWTToolkit eventCountPlusPlus];
731
AWTWindow *opposite = [AWTWindow lastKeyWindow];
732
733
// Finds appropriate menubar in our hierarchy,
734
AWTWindow *awtWindow = self;
735
while (awtWindow.ownerWindow != nil) {
736
awtWindow = awtWindow.ownerWindow;
737
}
738
739
CMenuBar *menuBar = nil;
740
BOOL isDisabled = NO;
741
if ([awtWindow.nsWindow isVisible]){
742
menuBar = awtWindow.javaMenuBar;
743
isDisabled = !awtWindow.isEnabled;
744
}
745
746
if (menuBar == nil) {
747
menuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
748
isDisabled = NO;
749
}
750
751
[CMenuBar activate:menuBar modallyDisabled:isDisabled];
752
753
[AWTWindow setLastKeyWindow:nil];
754
755
[self _deliverWindowFocusEvent:YES oppositeWindow: opposite];
756
[self orderChildWindows:YES];
757
}
758
759
- (void) windowDidResignKey: (NSNotification *) notification {
760
// TODO: check why sometimes at start is invoked *not* on AppKit main thread.
761
AWT_ASSERT_APPKIT_THREAD;
762
[AWTToolkit eventCountPlusPlus];
763
[self.javaMenuBar deactivate];
764
765
// In theory, this might cause flickering if the window gaining focus
766
// has its own menu. However, I couldn't reproduce it on practice, so
767
// perhaps this is a non issue.
768
CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
769
if (defaultMenu != nil) {
770
[CMenuBar activate:defaultMenu modallyDisabled:NO];
771
}
772
773
// the new key window
774
NSWindow *keyWindow = [NSApp keyWindow];
775
AWTWindow *opposite = nil;
776
if ([AWTWindow isAWTWindow: keyWindow]) {
777
opposite = (AWTWindow *)[keyWindow delegate];
778
[AWTWindow setLastKeyWindow: self];
779
} else {
780
[AWTWindow setLastKeyWindow: nil];
781
}
782
783
[self _deliverWindowFocusEvent:NO oppositeWindow: opposite];
784
[self orderChildWindows:NO];
785
}
786
787
- (void) windowDidBecomeMain: (NSNotification *) notification {
788
AWT_ASSERT_APPKIT_THREAD;
789
[AWTToolkit eventCountPlusPlus];
790
791
JNIEnv *env = [ThreadUtilities getJNIEnv];
792
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
793
if (platformWindow != NULL) {
794
static JNF_MEMBER_CACHE(jm_windowDidBecomeMain, jc_CPlatformWindow, "windowDidBecomeMain", "()V");
795
JNFCallVoidMethod(env, platformWindow, jm_windowDidBecomeMain);
796
(*env)->DeleteLocalRef(env, platformWindow);
797
}
798
}
799
800
- (BOOL)windowShouldClose:(id)sender {
801
AWT_ASSERT_APPKIT_THREAD;
802
[AWTToolkit eventCountPlusPlus];
803
JNIEnv *env = [ThreadUtilities getJNIEnv];
804
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
805
if (platformWindow != NULL) {
806
static JNF_MEMBER_CACHE(jm_deliverWindowClosingEvent, jc_CPlatformWindow, "deliverWindowClosingEvent", "()V");
807
JNFCallVoidMethod(env, platformWindow, jm_deliverWindowClosingEvent);
808
(*env)->DeleteLocalRef(env, platformWindow);
809
}
810
// The window will be closed (if allowed) as result of sending Java event
811
return NO;
812
}
813
814
815
- (void)_notifyFullScreenOp:(jint)op withEnv:(JNIEnv *)env {
816
static JNF_CLASS_CACHE(jc_FullScreenHandler, "com/apple/eawt/FullScreenHandler");
817
static JNF_STATIC_MEMBER_CACHE(jm_notifyFullScreenOperation, jc_FullScreenHandler, "handleFullScreenEventFromNative", "(Ljava/awt/Window;I)V");
818
static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
819
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
820
if (platformWindow != NULL) {
821
jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
822
if (awtWindow != NULL) {
823
JNFCallStaticVoidMethod(env, jm_notifyFullScreenOperation, awtWindow, op);
824
(*env)->DeleteLocalRef(env, awtWindow);
825
}
826
(*env)->DeleteLocalRef(env, platformWindow);
827
}
828
}
829
830
831
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
832
static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");
833
JNIEnv *env = [ThreadUtilities getJNIEnv];
834
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
835
if (platformWindow != NULL) {
836
JNFCallVoidMethod(env, platformWindow, jm_windowWillEnterFullScreen);
837
[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_ENTER withEnv:env];
838
(*env)->DeleteLocalRef(env, platformWindow);
839
}
840
}
841
842
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
843
static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");
844
JNIEnv *env = [ThreadUtilities getJNIEnv];
845
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
846
if (platformWindow != NULL) {
847
JNFCallVoidMethod(env, platformWindow, jm_windowDidEnterFullScreen);
848
[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_ENTER withEnv:env];
849
(*env)->DeleteLocalRef(env, platformWindow);
850
}
851
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
852
}
853
854
- (void)windowWillExitFullScreen:(NSNotification *)notification {
855
static JNF_MEMBER_CACHE(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");
856
JNIEnv *env = [ThreadUtilities getJNIEnv];
857
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
858
if (platformWindow != NULL) {
859
JNFCallVoidMethod(env, platformWindow, jm_windowWillExitFullScreen);
860
[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_EXIT withEnv:env];
861
(*env)->DeleteLocalRef(env, platformWindow);
862
}
863
}
864
865
- (void)windowDidExitFullScreen:(NSNotification *)notification {
866
static JNF_MEMBER_CACHE(jm_windowDidExitFullScreen, jc_CPlatformWindow, "windowDidExitFullScreen", "()V");
867
JNIEnv *env = [ThreadUtilities getJNIEnv];
868
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
869
if (platformWindow != NULL) {
870
JNFCallVoidMethod(env, platformWindow, jm_windowDidExitFullScreen);
871
[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_EXIT withEnv:env];
872
(*env)->DeleteLocalRef(env, platformWindow);
873
}
874
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
875
}
876
877
- (void)sendEvent:(NSEvent *)event {
878
if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
879
if ([self isBlocked]) {
880
// Move parent windows to front and make sure that a child window is displayed
881
// in front of its nearest parent.
882
if (self.ownerWindow != nil) {
883
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
884
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
885
if (platformWindow != NULL) {
886
static JNF_MEMBER_CACHE(jm_orderAboveSiblings, jc_CPlatformWindow, "orderAboveSiblings", "()V");
887
JNFCallVoidMethod(env,platformWindow, jm_orderAboveSiblings);
888
(*env)->DeleteLocalRef(env, platformWindow);
889
}
890
}
891
[self orderChildWindows:YES];
892
}
893
894
NSPoint p = [NSEvent mouseLocation];
895
NSRect frame = [self.nsWindow frame];
896
NSRect contentRect = [self.nsWindow contentRectForFrameRect:frame];
897
898
// Check if the click happened in the non-client area (title bar)
899
if (p.y >= (frame.origin.y + contentRect.size.height)) {
900
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
901
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
902
if (platformWindow != NULL) {
903
// Currently, no need to deliver the whole NSEvent.
904
static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
905
JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
906
(*env)->DeleteLocalRef(env, platformWindow);
907
}
908
}
909
}
910
}
911
912
- (void)constrainSize:(NSSize*)size {
913
float minWidth = 0.f, minHeight = 0.f;
914
915
if (IS(self.styleBits, DECORATED)) {
916
NSRect frame = [self.nsWindow frame];
917
NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[self.nsWindow styleMask]];
918
919
float top = frame.size.height - contentRect.size.height;
920
float left = contentRect.origin.x - frame.origin.x;
921
float bottom = contentRect.origin.y - frame.origin.y;
922
float right = frame.size.width - (contentRect.size.width + left);
923
924
// Speculative estimation: 80 - enough for window decorations controls
925
minWidth += left + right + 80;
926
minHeight += top + bottom;
927
}
928
929
minWidth = MAX(1.f, minWidth);
930
minHeight = MAX(1.f, minHeight);
931
932
size->width = MAX(size->width, minWidth);
933
size->height = MAX(size->height, minHeight);
934
}
935
936
- (void) setEnabled: (BOOL)flag {
937
self.isEnabled = flag;
938
939
if (IS(self.styleBits, CLOSEABLE)) {
940
[[self.nsWindow standardWindowButton:NSWindowCloseButton] setEnabled: flag];
941
}
942
943
if (IS(self.styleBits, MINIMIZABLE)) {
944
[[self.nsWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled: flag];
945
}
946
947
if (IS(self.styleBits, ZOOMABLE)) {
948
[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled: flag];
949
}
950
951
if (IS(self.styleBits, RESIZABLE)) {
952
[self updateMinMaxSize:flag];
953
[self.nsWindow setShowsResizeIndicator:flag];
954
}
955
}
956
957
+ (void) setLastKeyWindow:(AWTWindow *)window {
958
[window retain];
959
[lastKeyWindow release];
960
lastKeyWindow = window;
961
}
962
963
+ (AWTWindow *) lastKeyWindow {
964
return lastKeyWindow;
965
}
966
967
- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame {
968
return !NSEqualSizes(self.nsWindow.frame.size, newFrame.size);
969
}
970
971
972
@end // AWTWindow
973
974
975
/*
976
* Class: sun_lwawt_macosx_CPlatformWindow
977
* Method: nativeCreateNSWindow
978
* Signature: (JJIIII)J
979
*/
980
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
981
(JNIEnv *env, jobject obj, jlong contentViewPtr, jlong ownerPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
982
{
983
__block AWTWindow *window = nil;
984
985
JNF_COCOA_ENTER(env);
986
987
JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
988
NSView *contentView = OBJC(contentViewPtr);
989
NSRect frameRect = NSMakeRect(x, y, w, h);
990
AWTWindow *owner = [OBJC(ownerPtr) delegate];
991
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
992
993
window = [[AWTWindow alloc] initWithPlatformWindow:platformWindow
994
ownerWindow:owner
995
styleBits:styleBits
996
frameRect:frameRect
997
contentView:contentView];
998
// the window is released is CPlatformWindow.nativeDispose()
999
1000
if (window) [window.nsWindow retain];
1001
}];
1002
1003
JNF_COCOA_EXIT(env);
1004
1005
return ptr_to_jlong(window ? window.nsWindow : nil);
1006
}
1007
1008
/*
1009
* Class: sun_lwawt_macosx_CPlatformWindow
1010
* Method: nativeSetNSWindowStyleBits
1011
* Signature: (JII)V
1012
*/
1013
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowStyleBits
1014
(JNIEnv *env, jclass clazz, jlong windowPtr, jint mask, jint bits)
1015
{
1016
JNF_COCOA_ENTER(env);
1017
1018
NSWindow *nsWindow = OBJC(windowPtr);
1019
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1020
1021
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1022
1023
// scans the bit field, and only updates the values requested by the mask
1024
// (this implicitly handles the _CALLBACK_PROP_BITMASK case, since those are passive reads)
1025
jint newBits = window.styleBits & ~mask | bits & mask;
1026
1027
BOOL resized = NO;
1028
1029
// Check for a change to the full window content view option.
1030
// The content view must be resized first, otherwise the window will be resized to fit the existing
1031
// content view.
1032
if (IS(mask, FULL_WINDOW_CONTENT)) {
1033
if (IS(newBits, FULL_WINDOW_CONTENT) != IS(window.styleBits, FULL_WINDOW_CONTENT)) {
1034
NSRect frame = [nsWindow frame];
1035
NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:newBits];
1036
NSRect screenContentRect = [NSWindow contentRectForFrameRect:frame styleMask:styleMask];
1037
NSRect contentFrame = NSMakeRect(screenContentRect.origin.x - frame.origin.x,
1038
screenContentRect.origin.y - frame.origin.y,
1039
screenContentRect.size.width,
1040
screenContentRect.size.height);
1041
nsWindow.contentView.frame = contentFrame;
1042
resized = YES;
1043
}
1044
}
1045
1046
// resets the NSWindow's style mask if the mask intersects any of those bits
1047
if (mask & MASK(_STYLE_PROP_BITMASK)) {
1048
[nsWindow setStyleMask:[AWTWindow styleMaskForStyleBits:newBits]];
1049
}
1050
1051
// calls methods on NSWindow to change other properties, based on the mask
1052
if (mask & MASK(_METHOD_PROP_BITMASK)) {
1053
[window setPropertiesForStyleBits:newBits mask:mask];
1054
}
1055
1056
window.styleBits = newBits;
1057
1058
if (resized) {
1059
[window _deliverMoveResizeEvent];
1060
}
1061
}];
1062
1063
JNF_COCOA_EXIT(env);
1064
}
1065
1066
/*
1067
* Class: sun_lwawt_macosx_CPlatformWindow
1068
* Method: nativeSetNSWindowMenuBar
1069
* Signature: (JJ)V
1070
*/
1071
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMenuBar
1072
(JNIEnv *env, jclass clazz, jlong windowPtr, jlong menuBarPtr)
1073
{
1074
JNF_COCOA_ENTER(env);
1075
1076
NSWindow *nsWindow = OBJC(windowPtr);
1077
CMenuBar *menuBar = OBJC(menuBarPtr);
1078
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1079
1080
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1081
1082
if ([nsWindow isKeyWindow]) {
1083
[window.javaMenuBar deactivate];
1084
}
1085
1086
window.javaMenuBar = menuBar;
1087
1088
CMenuBar* actualMenuBar = menuBar;
1089
if (actualMenuBar == nil) {
1090
actualMenuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
1091
}
1092
1093
if ([nsWindow isKeyWindow]) {
1094
[CMenuBar activate:actualMenuBar modallyDisabled:NO];
1095
}
1096
}];
1097
1098
JNF_COCOA_EXIT(env);
1099
}
1100
1101
/*
1102
* Class: sun_lwawt_macosx_CPlatformWindow
1103
* Method: nativeGetNSWindowInsets
1104
* Signature: (J)Ljava/awt/Insets;
1105
*/
1106
JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowInsets
1107
(JNIEnv *env, jclass clazz, jlong windowPtr)
1108
{
1109
jobject ret = NULL;
1110
1111
JNF_COCOA_ENTER(env);
1112
1113
NSWindow *nsWindow = OBJC(windowPtr);
1114
__block NSRect contentRect = NSZeroRect;
1115
__block NSRect frame = NSZeroRect;
1116
1117
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
1118
1119
frame = [nsWindow frame];
1120
contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[nsWindow styleMask]];
1121
}];
1122
1123
jint top = (jint)(frame.size.height - contentRect.size.height);
1124
jint left = (jint)(contentRect.origin.x - frame.origin.x);
1125
jint bottom = (jint)(contentRect.origin.y - frame.origin.y);
1126
jint right = (jint)(frame.size.width - (contentRect.size.width + left));
1127
1128
static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");
1129
static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");
1130
ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);
1131
1132
JNF_COCOA_EXIT(env);
1133
return ret;
1134
}
1135
1136
/*
1137
* Class: sun_lwawt_macosx_CPlatformWindow
1138
* Method: nativeSetNSWindowBounds
1139
* Signature: (JDDDD)V
1140
*/
1141
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
1142
(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
1143
{
1144
JNF_COCOA_ENTER(env);
1145
1146
NSRect jrect = NSMakeRect(originX, originY, width, height);
1147
1148
// TODO: not sure we need displayIfNeeded message in our view
1149
NSWindow *nsWindow = OBJC(windowPtr);
1150
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1151
1152
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1153
1154
NSRect rect = ConvertNSScreenRect(NULL, jrect);
1155
[window constrainSize:&rect.size];
1156
1157
[nsWindow setFrame:rect display:YES];
1158
1159
// only start tracking events if pointer is above the toplevel
1160
// TODO: should post an Entered event if YES.
1161
NSPoint mLocation = [NSEvent mouseLocation];
1162
[nsWindow setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
1163
1164
// ensure we repaint the whole window after the resize operation
1165
// (this will also re-enable screen updates, which were disabled above)
1166
// TODO: send PaintEvent
1167
}];
1168
1169
JNF_COCOA_EXIT(env);
1170
}
1171
1172
/*
1173
* Class: sun_lwawt_macosx_CPlatformWindow
1174
* Method: nativeSetNSWindowMinMax
1175
* Signature: (JDDDD)V
1176
*/
1177
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
1178
(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
1179
{
1180
JNF_COCOA_ENTER(env);
1181
1182
if (minW < 1) minW = 1;
1183
if (minH < 1) minH = 1;
1184
if (maxW < 1) maxW = 1;
1185
if (maxH < 1) maxH = 1;
1186
1187
NSWindow *nsWindow = OBJC(windowPtr);
1188
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1189
1190
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1191
1192
NSSize min = { minW, minH };
1193
NSSize max = { maxW, maxH };
1194
1195
[window constrainSize:&min];
1196
[window constrainSize:&max];
1197
1198
window.javaMinSize = min;
1199
window.javaMaxSize = max;
1200
[window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
1201
}];
1202
1203
JNF_COCOA_EXIT(env);
1204
}
1205
1206
/*
1207
* Class: sun_lwawt_macosx_CPlatformWindow
1208
* Method: nativePushNSWindowToBack
1209
* Signature: (J)V
1210
*/
1211
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
1212
(JNIEnv *env, jclass clazz, jlong windowPtr)
1213
{
1214
JNF_COCOA_ENTER(env);
1215
1216
NSWindow *nsWindow = OBJC(windowPtr);
1217
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1218
[nsWindow orderBack:nil];
1219
// Order parent windows
1220
AWTWindow *awtWindow = (AWTWindow*)[nsWindow delegate];
1221
while (awtWindow.ownerWindow != nil) {
1222
awtWindow = awtWindow.ownerWindow;
1223
if ([AWTWindow isJavaPlatformWindowVisible:awtWindow.nsWindow]) {
1224
[awtWindow.nsWindow orderBack:nil];
1225
}
1226
}
1227
// Order child windows
1228
[(AWTWindow*)[nsWindow delegate] orderChildWindows:NO];
1229
}];
1230
1231
JNF_COCOA_EXIT(env);
1232
}
1233
1234
/*
1235
* Class: sun_lwawt_macosx_CPlatformWindow
1236
* Method: nativePushNSWindowToFront
1237
* Signature: (J)V
1238
*/
1239
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToFront
1240
(JNIEnv *env, jclass clazz, jlong windowPtr)
1241
{
1242
JNF_COCOA_ENTER(env);
1243
1244
NSWindow *nsWindow = OBJC(windowPtr);
1245
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1246
1247
if (![nsWindow isKeyWindow]) {
1248
[nsWindow makeKeyAndOrderFront:nsWindow];
1249
} else {
1250
[nsWindow orderFront:nsWindow];
1251
}
1252
}];
1253
1254
JNF_COCOA_EXIT(env);
1255
}
1256
1257
/*
1258
* Class: sun_lwawt_macosx_CPlatformWindow
1259
* Method: nativeSetNSWindowTitle
1260
* Signature: (JLjava/lang/String;)V
1261
*/
1262
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowTitle
1263
(JNIEnv *env, jclass clazz, jlong windowPtr, jstring jtitle)
1264
{
1265
JNF_COCOA_ENTER(env);
1266
1267
NSWindow *nsWindow = OBJC(windowPtr);
1268
[nsWindow performSelectorOnMainThread:@selector(setTitle:)
1269
withObject:JNFJavaToNSString(env, jtitle)
1270
waitUntilDone:NO];
1271
1272
JNF_COCOA_EXIT(env);
1273
}
1274
1275
/*
1276
* Class: sun_lwawt_macosx_CPlatformWindow
1277
* Method: nativeRevalidateNSWindowShadow
1278
* Signature: (J)V
1279
*/
1280
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow
1281
(JNIEnv *env, jclass clazz, jlong windowPtr)
1282
{
1283
JNF_COCOA_ENTER(env);
1284
1285
NSWindow *nsWindow = OBJC(windowPtr);
1286
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1287
[nsWindow invalidateShadow];
1288
}];
1289
1290
JNF_COCOA_EXIT(env);
1291
}
1292
1293
/*
1294
* Class: sun_lwawt_macosx_CPlatformWindow
1295
* Method: nativeScreenOn_AppKitThread
1296
* Signature: (J)I
1297
*/
1298
JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeScreenOn_1AppKitThread
1299
(JNIEnv *env, jclass clazz, jlong windowPtr)
1300
{
1301
jint ret = 0;
1302
1303
JNF_COCOA_ENTER(env);
1304
AWT_ASSERT_APPKIT_THREAD;
1305
1306
NSWindow *nsWindow = OBJC(windowPtr);
1307
NSDictionary *props = [[nsWindow screen] deviceDescription];
1308
ret = [[props objectForKey:@"NSScreenNumber"] intValue];
1309
1310
JNF_COCOA_EXIT(env);
1311
1312
return ret;
1313
}
1314
1315
/*
1316
* Class: sun_lwawt_macosx_CPlatformWindow
1317
* Method: nativeSetNSWindowMinimizedIcon
1318
* Signature: (JJ)V
1319
*/
1320
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinimizedIcon
1321
(JNIEnv *env, jclass clazz, jlong windowPtr, jlong nsImagePtr)
1322
{
1323
JNF_COCOA_ENTER(env);
1324
1325
NSWindow *nsWindow = OBJC(windowPtr);
1326
NSImage *image = OBJC(nsImagePtr);
1327
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1328
[nsWindow setMiniwindowImage:image];
1329
}];
1330
1331
JNF_COCOA_EXIT(env);
1332
}
1333
1334
/*
1335
* Class: sun_lwawt_macosx_CPlatformWindow
1336
* Method: nativeSetNSWindowRepresentedFilename
1337
* Signature: (JLjava/lang/String;)V
1338
*/
1339
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowRepresentedFilename
1340
(JNIEnv *env, jclass clazz, jlong windowPtr, jstring filename)
1341
{
1342
JNF_COCOA_ENTER(env);
1343
1344
NSWindow *nsWindow = OBJC(windowPtr);
1345
NSURL *url = (filename == NULL) ? nil : [NSURL fileURLWithPath:JNFNormalizedNSStringForPath(env, filename)];
1346
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1347
[nsWindow setRepresentedURL:url];
1348
}];
1349
1350
JNF_COCOA_EXIT(env);
1351
}
1352
1353
/*
1354
* Class: sun_lwawt_macosx_CPlatformWindow
1355
* Method: nativeGetTopmostPlatformWindowUnderMouse
1356
* Signature: (J)V
1357
*/
1358
JNIEXPORT jobject
1359
JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
1360
(JNIEnv *env, jclass clazz)
1361
{
1362
__block jobject topmostWindowUnderMouse = nil;
1363
1364
JNF_COCOA_ENTER(env);
1365
1366
[ThreadUtilities performOnMainThreadWaiting:YES block:^{
1367
AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
1368
if (awtWindow != nil) {
1369
topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
1370
}
1371
}];
1372
1373
JNF_COCOA_EXIT(env);
1374
1375
return topmostWindowUnderMouse;
1376
}
1377
1378
/*
1379
* Class: sun_lwawt_macosx_CPlatformWindow
1380
* Method: nativeSynthesizeMouseEnteredExitedEvents
1381
* Signature: ()V
1382
*/
1383
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__
1384
(JNIEnv *env, jclass clazz)
1385
{
1386
JNF_COCOA_ENTER(env);
1387
1388
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1389
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
1390
}];
1391
1392
JNF_COCOA_EXIT(env);
1393
}
1394
1395
/*
1396
* Class: sun_lwawt_macosx_CPlatformWindow
1397
* Method: nativeSynthesizeMouseEnteredExitedEvents
1398
* Signature: (JI)V
1399
*/
1400
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__JI
1401
(JNIEnv *env, jclass clazz, jlong windowPtr, jint eventType)
1402
{
1403
JNF_COCOA_ENTER(env);
1404
1405
if (eventType == NSMouseEntered || eventType == NSMouseExited) {
1406
NSWindow *nsWindow = OBJC(windowPtr);
1407
1408
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1409
[AWTWindow synthesizeMouseEnteredExitedEvents:nsWindow withType:eventType];
1410
}];
1411
} else {
1412
[JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];
1413
}
1414
1415
JNF_COCOA_EXIT(env);
1416
}
1417
1418
/*
1419
* Class: sun_lwawt_macosx_CPlatformWindow
1420
* Method: _toggleFullScreenMode
1421
* Signature: (J)V
1422
*/
1423
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow__1toggleFullScreenMode
1424
(JNIEnv *env, jobject peer, jlong windowPtr)
1425
{
1426
JNF_COCOA_ENTER(env);
1427
1428
NSWindow *nsWindow = OBJC(windowPtr);
1429
SEL toggleFullScreenSelector = @selector(toggleFullScreen:);
1430
if (![nsWindow respondsToSelector:toggleFullScreenSelector]) return;
1431
1432
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1433
[nsWindow performSelector:toggleFullScreenSelector withObject:nil];
1434
}];
1435
1436
JNF_COCOA_EXIT(env);
1437
}
1438
1439
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled
1440
(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean isEnabled)
1441
{
1442
JNF_COCOA_ENTER(env);
1443
1444
NSWindow *nsWindow = OBJC(windowPtr);
1445
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1446
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1447
1448
[window setEnabled: isEnabled];
1449
}];
1450
1451
JNF_COCOA_EXIT(env);
1452
}
1453
1454
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeDispose
1455
(JNIEnv *env, jclass clazz, jlong windowPtr)
1456
{
1457
JNF_COCOA_ENTER(env);
1458
1459
NSWindow *nsWindow = OBJC(windowPtr);
1460
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1461
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1462
1463
if ([AWTWindow lastKeyWindow] == window) {
1464
[AWTWindow setLastKeyWindow: nil];
1465
}
1466
1467
// AWTWindow holds a reference to the NSWindow in its nsWindow
1468
// property. Unsetting the delegate allows it to be deallocated
1469
// which releases the reference. This, in turn, allows the window
1470
// itself be deallocated.
1471
[nsWindow setDelegate: nil];
1472
1473
[window release];
1474
}];
1475
1476
JNF_COCOA_EXIT(env);
1477
}
1478
1479
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeEnterFullScreenMode
1480
(JNIEnv *env, jclass clazz, jlong windowPtr)
1481
{
1482
JNF_COCOA_ENTER(env);
1483
1484
NSWindow *nsWindow = OBJC(windowPtr);
1485
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1486
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1487
NSNumber* screenID = [AWTWindow getNSWindowDisplayID_AppKitThread: nsWindow];
1488
CGDirectDisplayID aID = [screenID intValue];
1489
1490
if (CGDisplayCapture(aID) == kCGErrorSuccess) {
1491
// remove window decoration
1492
NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];
1493
[nsWindow setStyleMask:(styleMask & ~NSTitledWindowMask) | NSBorderlessWindowMask];
1494
1495
int shieldLevel = CGShieldingWindowLevel();
1496
window.preFullScreenLevel = [nsWindow level];
1497
[nsWindow setLevel: shieldLevel];
1498
1499
NSRect screenRect = [[nsWindow screen] frame];
1500
[nsWindow setFrame:screenRect display:YES];
1501
} else {
1502
[JNFException raise:[ThreadUtilities getJNIEnv]
1503
as:kRuntimeException
1504
reason:"Failed to enter full screen."];
1505
}
1506
}];
1507
1508
JNF_COCOA_EXIT(env);
1509
}
1510
1511
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeExitFullScreenMode
1512
(JNIEnv *env, jclass clazz, jlong windowPtr)
1513
{
1514
JNF_COCOA_ENTER(env);
1515
1516
NSWindow *nsWindow = OBJC(windowPtr);
1517
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
1518
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1519
NSNumber* screenID = [AWTWindow getNSWindowDisplayID_AppKitThread: nsWindow];
1520
CGDirectDisplayID aID = [screenID intValue];
1521
1522
if (CGDisplayRelease(aID) == kCGErrorSuccess) {
1523
NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];
1524
[nsWindow setStyleMask:styleMask];
1525
[nsWindow setLevel: window.preFullScreenLevel];
1526
1527
// GraphicsDevice takes care of restoring pre full screen bounds
1528
} else {
1529
[JNFException raise:[ThreadUtilities getJNIEnv]
1530
as:kRuntimeException
1531
reason:"Failed to exit full screen."];
1532
}
1533
}];
1534
1535
JNF_COCOA_EXIT(env);
1536
}
1537
#endif
1538
1539
1540