Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m
41152 views
1
/*
2
* Copyright (c) 2011, 2018, 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 "JNIUtilities.h"
27
28
#import <AppKit/AppKit.h>
29
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
30
31
32
#import "CMenuBar.h"
33
#import "CMenu.h"
34
#import "ThreadUtilities.h"
35
#import "ApplicationDelegate.h"
36
37
#import "sun_lwawt_macosx_CMenuBar.h"
38
39
__attribute__((visibility("default")))
40
NSString *CMenuBarDidReuseItemNotification =
41
@"CMenuBarDidReuseItemNotification";
42
43
static CMenuBar *sActiveMenuBar = nil;
44
static NSMenu *sDefaultHelpMenu = nil;
45
static BOOL sSetupHelpMenu = NO;
46
47
@interface CMenuBar (CMenuBar_Private)
48
+ (void) addDefaultHelpMenu;
49
@end
50
51
@implementation CMenuBar
52
53
+ (void)clearMenuBarExcludingAppleMenu_OnAppKitThread:(BOOL) excludingAppleMenu {
54
AWT_ASSERT_APPKIT_THREAD;
55
// Remove all Java menus from the main bar.
56
NSMenu *theMainMenu = [NSApp mainMenu];
57
NSUInteger i, menuCount = [theMainMenu numberOfItems];
58
59
for (i = menuCount; i > 1; i--) {
60
NSUInteger index = i-1;
61
62
NSMenuItem *currItem = [theMainMenu itemAtIndex:index];
63
NSMenu *currMenu = [currItem submenu];
64
65
if (excludingAppleMenu && ![currMenu isJavaMenu]) {
66
continue;
67
}
68
[currItem setSubmenu:nil];
69
[theMainMenu removeItemAtIndex:index];
70
}
71
72
[CMenuBar addDefaultHelpMenu];
73
}
74
75
+ (BOOL) isActiveMenuBar:(CMenuBar *)inMenuBar {
76
return (sActiveMenuBar == inMenuBar);
77
}
78
79
- (id) initWithPeer:(jobject)peer {
80
AWT_ASSERT_APPKIT_THREAD;
81
self = [super initWithPeer: peer];
82
if (self) {
83
fMenuList = [[NSMutableArray alloc] init];
84
}
85
return self;
86
}
87
88
-(void) dealloc {
89
[fMenuList release];
90
fMenuList = nil;
91
92
[fHelpMenu release];
93
fHelpMenu = nil;
94
95
[super dealloc];
96
}
97
98
+ (void) activate:(CMenuBar *)menubar modallyDisabled:(BOOL)modallyDisabled {
99
AWT_ASSERT_APPKIT_THREAD;
100
101
if (!menubar) {
102
[CMenuBar clearMenuBarExcludingAppleMenu_OnAppKitThread:YES];
103
return;
104
}
105
106
#ifdef DEBUG
107
NSLog(@"activating menu bar: %@", menubar);
108
#endif
109
110
@synchronized([CMenuBar class]) {
111
sActiveMenuBar = menubar;
112
}
113
114
@synchronized(menubar) {
115
menubar->fModallyDisabled = modallyDisabled;
116
}
117
118
NSUInteger i = 0, newMenuListSize = [menubar->fMenuList count];
119
120
NSMenu *theMainMenu = [NSApp mainMenu];
121
NSUInteger menuIndex, menuCount = [theMainMenu numberOfItems];
122
123
NSUInteger cmenuIndex = 0, cmenuCount = newMenuListSize;
124
NSMutableArray *removedMenuArray = [NSMutableArray array];
125
126
for (menuIndex = 0; menuIndex < menuCount; menuIndex++) {
127
NSMenuItem *currItem = [theMainMenu itemAtIndex:menuIndex];
128
NSMenu *currMenu = [currItem submenu];
129
130
if ([currMenu isJavaMenu]) {
131
// Ready to replace, find next candidate
132
CMenu *newMenu = nil;
133
if (cmenuIndex < cmenuCount) {
134
newMenu = (CMenu *)[menubar->fMenuList objectAtIndex:cmenuIndex];
135
if (newMenu == menubar->fHelpMenu) {
136
cmenuIndex++;
137
if (cmenuIndex < cmenuCount) {
138
newMenu = (CMenu *)[menubar->fMenuList objectAtIndex:cmenuIndex];
139
}
140
}
141
}
142
if (newMenu) {
143
NSMenu *menuToAdd = [newMenu menu];
144
if ([theMainMenu indexOfItemWithSubmenu:menuToAdd] == -1) {
145
[[NSNotificationCenter defaultCenter] postNotificationName:CMenuBarDidReuseItemNotification object:theMainMenu];
146
147
[currItem setSubmenu:menuToAdd];
148
[currItem setTitle:[menuToAdd title]];
149
cmenuIndex++;
150
}
151
152
BOOL newEnabledState = [newMenu isEnabled] && !menubar->fModallyDisabled;
153
[currItem setEnabled:newEnabledState];
154
} else {
155
[removedMenuArray addObject:[NSNumber numberWithInteger:menuIndex]];
156
}
157
}
158
}
159
160
// Clean up extra items
161
NSUInteger removedIndex, removedCount = [removedMenuArray count];
162
for (removedIndex=removedCount; removedIndex > 0; removedIndex--) {
163
NSUInteger index = [[removedMenuArray objectAtIndex:(removedIndex-1)] integerValue];
164
NSMenuItem *currItem = [theMainMenu itemAtIndex:index];
165
[currItem setSubmenu:nil];
166
[theMainMenu removeItemAtIndex:index];
167
}
168
169
i = cmenuIndex;
170
171
// Add all of the menus in the menu list.
172
for (; i < newMenuListSize; i++) {
173
CMenu *newMenu = (CMenu *)[menubar->fMenuList objectAtIndex:i];
174
175
if (newMenu != menubar->fHelpMenu) {
176
NSArray *args = [NSArray arrayWithObjects:newMenu, [NSNumber numberWithInt:-1], nil];
177
[menubar nativeAddMenuAtIndex_OnAppKitThread:args];
178
}
179
}
180
181
// Add the help menu last.
182
if (menubar->fHelpMenu) {
183
NSArray *args = [NSArray arrayWithObjects:menubar->fHelpMenu, [NSNumber numberWithInt:-1], nil];
184
[menubar nativeAddMenuAtIndex_OnAppKitThread:args];
185
} else {
186
[CMenuBar addDefaultHelpMenu];
187
}
188
}
189
190
-(void) deactivate {
191
AWT_ASSERT_APPKIT_THREAD;
192
193
BOOL isDeactivated = NO;
194
@synchronized([CMenuBar class]) {
195
if (sActiveMenuBar == self) {
196
sActiveMenuBar = nil;
197
isDeactivated = YES;
198
}
199
}
200
201
if (isDeactivated) {
202
#ifdef DEBUG
203
NSLog(@"deactivating menu bar: %@", self);
204
#endif
205
206
@synchronized(self) {
207
fModallyDisabled = NO;
208
}
209
210
// In theory, this might cause flickering if the window gaining focus
211
// has its own menu. However, I couldn't reproduce it on practice, so
212
// perhaps this is a non issue.
213
CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar];
214
if (defaultMenu != nil) {
215
[CMenuBar activate:defaultMenu modallyDisabled:NO];
216
}
217
}
218
}
219
220
-(void) javaAddMenu: (CMenu *)theMenu {
221
@synchronized(self) {
222
[fMenuList addObject: theMenu];
223
}
224
225
if (self == sActiveMenuBar) {
226
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:-1], nil];
227
[ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) on:self withObject:args waitUntilDone:YES];
228
[args release];
229
}
230
}
231
232
// This method is a special case for use by the screen menu bar.
233
// See ScreenMenuBar.java -- used to implement setVisible(boolean) by
234
// removing or adding the menu from the current menu bar's list.
235
-(void) javaAddMenu: (CMenu *)theMenu atIndex:(jint)index {
236
@synchronized(self) {
237
if (index == -1){
238
[fMenuList addObject:theMenu];
239
}else{
240
[fMenuList insertObject:theMenu atIndex:index];
241
}
242
}
243
244
if (self == sActiveMenuBar) {
245
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:index], nil];
246
[ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) on:self withObject:args waitUntilDone:YES];
247
[args release];
248
}
249
}
250
251
- (NSInteger) javaIndexToNSMenuIndex_OnAppKitThread:(jint)javaIndex {
252
AWT_ASSERT_APPKIT_THREAD;
253
NSInteger returnValue = -1;
254
NSMenu *theMainMenu = [NSApp mainMenu];
255
256
if (javaIndex == -1) {
257
if (fHelpMenu) {
258
returnValue = [theMainMenu indexOfItemWithSubmenu:[fHelpMenu menu]];
259
}
260
} else {
261
CMenu *requestedMenu = [fMenuList objectAtIndex:javaIndex];
262
263
if (requestedMenu == fHelpMenu) {
264
returnValue = [theMainMenu indexOfItemWithSubmenu:[fHelpMenu menu]];
265
} else {
266
NSUInteger i, menuCount = [theMainMenu numberOfItems];
267
jint currJavaMenuIndex = 0;
268
for (i = 0; i < menuCount; i++) {
269
NSMenuItem *currItem = [theMainMenu itemAtIndex:i];
270
NSMenu *currMenu = [currItem submenu];
271
272
if ([currMenu isJavaMenu]) {
273
if (javaIndex == currJavaMenuIndex) {
274
returnValue = i;
275
break;
276
}
277
278
currJavaMenuIndex++;
279
}
280
}
281
}
282
}
283
284
return returnValue;
285
}
286
287
- (void) nativeAddMenuAtIndex_OnAppKitThread:(NSArray *)args {
288
AWT_ASSERT_APPKIT_THREAD;
289
CMenu *theNewMenu = (CMenu*)[args objectAtIndex:0];
290
jint index = [(NSNumber*)[args objectAtIndex:1] intValue];
291
NSApplication *theApp = [NSApplication sharedApplication];
292
NSMenu *theMainMenu = [theApp mainMenu];
293
NSMenu *menuToAdd = [theNewMenu menu];
294
295
if ([theMainMenu indexOfItemWithSubmenu:menuToAdd] == -1) {
296
NSMenuItem *newItem = [[NSMenuItem alloc] init];
297
[newItem setSubmenu:[theNewMenu menu]];
298
[newItem setTitle:[[theNewMenu menu] title]];
299
300
NSInteger nsMenuIndex = [self javaIndexToNSMenuIndex_OnAppKitThread:index];
301
302
if (nsMenuIndex == -1) {
303
[theMainMenu addItem:newItem];
304
} else {
305
[theMainMenu insertItem:newItem atIndex:nsMenuIndex];
306
}
307
308
BOOL newEnabledState = [theNewMenu isEnabled] && !fModallyDisabled;
309
[newItem setEnabled:newEnabledState];
310
[newItem release];
311
}
312
}
313
314
- (void) javaDeleteMenu: (jint)index {
315
if (self == sActiveMenuBar) {
316
[ThreadUtilities performOnMainThread:@selector(nativeDeleteMenu_OnAppKitThread:) on:self withObject:[NSNumber numberWithInt:index] waitUntilDone:YES];
317
}
318
319
@synchronized(self) {
320
CMenu *menuToRemove = [fMenuList objectAtIndex:index];
321
322
if (menuToRemove == fHelpMenu) {
323
[fHelpMenu release];
324
fHelpMenu = nil;
325
}
326
327
[fMenuList removeObjectAtIndex:index];
328
}
329
}
330
331
- (void) nativeDeleteMenu_OnAppKitThread:(id)indexObj {
332
AWT_ASSERT_APPKIT_THREAD;
333
NSApplication *theApp = [NSApplication sharedApplication];
334
NSMenu *theMainMenu = [theApp mainMenu];
335
jint menuToRemove = [(NSNumber *)indexObj intValue];
336
NSInteger nsMenuToRemove = [self javaIndexToNSMenuIndex_OnAppKitThread:menuToRemove];
337
338
if (nsMenuToRemove != -1) {
339
[theMainMenu removeItemAtIndex:nsMenuToRemove];
340
}
341
}
342
343
- (void) javaSetHelpMenu:(CMenu *)theMenu {
344
@synchronized(self) {
345
[theMenu retain];
346
[fHelpMenu release];
347
fHelpMenu = theMenu;
348
}
349
}
350
351
+ (void) addDefaultHelpMenu {
352
AWT_ASSERT_APPKIT_THREAD;
353
354
// Look for a help book tag. If it's there, add the help menu.
355
@synchronized ([CMenuBar class]) {
356
if (!sSetupHelpMenu) {
357
if (sDefaultHelpMenu == nil) {
358
// If we are embedded, don't make a help menu.
359
// TODO(cpc): we don't have NSApplicationAWT yet...
360
//if (![NSApp isKindOfClass:[NSApplicationAWT class]]) {
361
// sSetupHelpMenu = YES;
362
// return;
363
//}
364
365
// If the developer specified a NIB, don't make a help menu.
366
// TODO(cpc): usingDefaultNib only defined on NSApplicationAWT
367
//if (![NSApp usingDefaultNib]) {
368
// sSetupHelpMenu = YES;
369
// return;
370
//}
371
372
// TODO: not implemented
373
}
374
375
sSetupHelpMenu = YES;
376
}
377
}
378
379
if (sDefaultHelpMenu) {
380
NSMenu *theMainMenu = [NSApp mainMenu];
381
382
if ([theMainMenu indexOfItemWithSubmenu:sDefaultHelpMenu] == -1) {
383
// Since we're re-using this NSMenu, we need to clear its parent before
384
// adding it to a new menu item, or else AppKit will complain.
385
[sDefaultHelpMenu setSupermenu:nil];
386
387
// Add the help menu to the main menu.
388
NSMenuItem *newItem = [[NSMenuItem alloc] init];
389
[newItem setSubmenu:sDefaultHelpMenu];
390
[newItem setTitle:[sDefaultHelpMenu title]];
391
[theMainMenu addItem:newItem];
392
393
// Release it so the main menu owns it.
394
[newItem release];
395
}
396
}
397
}
398
399
@end
400
401
/*
402
* Class: sun_lwawt_macosx_CMenuBar
403
* Method: nativeCreateMenuBar
404
* Signature: ()J
405
*/
406
JNIEXPORT jlong JNICALL
407
Java_sun_lwawt_macosx_CMenuBar_nativeCreateMenuBar
408
(JNIEnv *env, jobject peer)
409
{
410
__block CMenuBar *aCMenuBar = nil;
411
JNI_COCOA_ENTER(env);
412
413
jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
414
415
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
416
417
aCMenuBar = [[CMenuBar alloc] initWithPeer:cPeerObjGlobal];
418
// the aCMenuBar is released in CMenuComponent.dispose()
419
}];
420
if (aCMenuBar == nil) {
421
return 0L;
422
}
423
424
JNI_COCOA_EXIT(env);
425
return ptr_to_jlong(aCMenuBar);
426
}
427
428
/*
429
* Class: sun_lwawt_macosx_CMenuBar
430
* Method: nativeAddAtIndex
431
* Signature: (JJI)V
432
*/
433
JNIEXPORT void JNICALL
434
Java_sun_lwawt_macosx_CMenuBar_nativeAddAtIndex
435
(JNIEnv *env, jobject peer,
436
jlong menuBarObject, jlong menuObject, jint index)
437
{
438
JNI_COCOA_ENTER(env);
439
// Remove the specified item.
440
[((CMenuBar *) jlong_to_ptr(menuBarObject)) javaAddMenu:(CMenu *) jlong_to_ptr(menuObject) atIndex:index];
441
JNI_COCOA_EXIT(env);
442
}
443
444
/*
445
* Class: sun_lwawt_macosx_CMenuBar
446
* Method: nativeDelMenu
447
* Signature: (JI)V
448
*/
449
JNIEXPORT void JNICALL
450
Java_sun_lwawt_macosx_CMenuBar_nativeDelMenu
451
(JNIEnv *env, jobject peer, jlong menuBarObject, jint index)
452
{
453
JNI_COCOA_ENTER(env);
454
// Remove the specified item.
455
[((CMenuBar *) jlong_to_ptr(menuBarObject)) javaDeleteMenu: index];
456
JNI_COCOA_EXIT(env);
457
}
458
459
/*
460
* Class: sun_lwawt_macosx_CMenuBar
461
* Method: nativeSetHelpMenu
462
* Signature: (JJ)V
463
*/
464
JNIEXPORT void JNICALL
465
Java_sun_lwawt_macosx_CMenuBar_nativeSetHelpMenu
466
(JNIEnv *env, jobject peer, jlong menuBarObject, jlong menuObject)
467
{
468
JNI_COCOA_ENTER(env);
469
// Remove the specified item.
470
[((CMenuBar *) jlong_to_ptr(menuBarObject)) javaSetHelpMenu: ((CMenu *)jlong_to_ptr(menuObject))];
471
JNI_COCOA_EXIT(env);
472
}
473
474