#if defined(__APPLE__)
#include <FL/platform.H>
#include <FL/fl_string_functions.h>
#include "drivers/Cocoa/Fl_MacOS_Sys_Menu_Bar_Driver.H"
#include "flstring.h"
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include "Fl_System_Driver.H"
#import <Cocoa/Cocoa.h>
typedef const Fl_Menu_Item *pFl_Menu_Item;
static Fl_Menu_Bar *custom_menu;
static NSString *localized_Window = nil;
static char *remove_ampersand(const char *s);
extern void (*fl_lock_function)();
extern void (*fl_unlock_function)();
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
static void previous_tab_cb(Fl_Widget *, void *data);
static void next_tab_cb(Fl_Widget *, void *data);
static void move_tab_cb(Fl_Widget *, void *data);
static void merge_all_windows_cb(Fl_Widget *, void *data);
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13
const NSInteger NSControlStateValueOn = NSOnState;
const NSInteger NSControlStateValueOff = NSOffState;
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
const NSUInteger NSEventModifierFlagCommand = NSCommandKeyMask;
const NSUInteger NSEventModifierFlagOption = NSAlternateKeyMask;
const NSUInteger NSEventModifierFlagControl = NSControlKeyMask;
const NSUInteger NSEventModifierFlagShift = NSShiftKeyMask;
#endif
void Fl_MacOS_Sys_Menu_Bar_Driver::draw() {
bar->deactivate(); }
Fl_MacOS_Sys_Menu_Bar_Driver* Fl_MacOS_Sys_Menu_Bar_Driver::driver() {
static Fl_MacOS_Sys_Menu_Bar_Driver *once = new Fl_MacOS_Sys_Menu_Bar_Driver();
if (driver_ != once) {
if (driver_) {
once->bar = driver_->bar;
delete driver_;
}
driver_ = once;
if (driver_->bar) driver_->update();
}
return once;
}
const char *Fl_Mac_App_Menu::about = "About %@";
const char *Fl_Mac_App_Menu::print = "Print Front Window & Titlebar";
const char *Fl_Mac_App_Menu::print_no_titlebar = "Print Front Window";
const char *Fl_Mac_App_Menu::toggle_print_titlebar = "Toggle printing of titlebar";
const char *Fl_Mac_App_Menu::services = "Services";
const char *Fl_Mac_App_Menu::hide = "Hide %@";
const char *Fl_Mac_App_Menu::hide_others = "Hide Others";
const char *Fl_Mac_App_Menu::show = "Show All";
const char *Fl_Mac_App_Menu::quit = "Quit %@";
@interface FLMenuItem : NSMenuItem {
}
- (const Fl_Menu_Item*) getFlItem;
- (void) itemCallback:(Fl_Menu_*)menu;
- (void) doCallback;
- (void) customCallback;
- (void) directCallback;
- (void) setKeyEquivalentModifierMask:(int)value;
- (void) setFltkShortcut:(int)key;
+ (int) addNewItem:(const Fl_Menu_Item*)mitem menu:(NSMenu*)menu action:(SEL)selector;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
- (BOOL)validateMenuItem:(NSMenuItem *)item;
#endif
@end
@implementation FLMenuItem
- (const Fl_Menu_Item*) getFlItem
{
NSInteger tag = [self tag];
if (tag >= 0) return fl_sys_menu_bar->menu() + tag;
return *(const Fl_Menu_Item**)[(NSData*)[self representedObject] bytes];
}
- (void) itemCallback:(Fl_Menu_*)menu
{
const Fl_Menu_Item *item = [self getFlItem];
menu->picked(item);
Fl::flush();
if ( item->flags & FL_MENU_TOGGLE ) { [self setState:(item->value() ? NSControlStateValueOn : NSControlStateValueOff)];
}
else if ( item->flags & FL_MENU_RADIO ) { NSMenu* this_menu = [self menu];
NSInteger flRank = [this_menu indexOfItem:self];
NSInteger last = [this_menu numberOfItems] - 1;
int from = (int)flRank;
while(from > 0) {
if ([[this_menu itemAtIndex:from-1] isSeparatorItem]) break;
item = [(FLMenuItem*)[this_menu itemAtIndex:from-1] getFlItem];
if ( !(item->flags & FL_MENU_RADIO) ) break;
from--;
}
int to = (int)flRank;
while (to < last) {
if ([[this_menu itemAtIndex:to+1] isSeparatorItem]) break;
item = [(FLMenuItem*)[this_menu itemAtIndex:to+1] getFlItem];
if (!(item->flags & FL_MENU_RADIO)) break;
to++;
}
for(int i = from; i <= to; i++) {
NSMenuItem *nsitem = [this_menu itemAtIndex:i];
[nsitem setState:(nsitem != self ? NSControlStateValueOff : NSControlStateValueOn)];
}
}
}
- (void) doCallback
{
fl_lock_function();
[self itemCallback:fl_sys_menu_bar];
fl_unlock_function();
}
- (void) customCallback
{
fl_lock_function();
[self itemCallback:custom_menu];
fl_unlock_function();
}
- (void) directCallback
{
fl_lock_function();
Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes];
if ( item && item->callback() ) item->do_callback(NULL);
fl_unlock_function();
}
- (void) setKeyEquivalentModifierMask:(int)value
{
NSUInteger macMod = 0;
if ( value & FL_META ) macMod = NSEventModifierFlagCommand;
if ( value & FL_SHIFT || (value > 0 && value < 127 && isupper(value)) ) macMod |= NSEventModifierFlagShift;
if ( value & FL_ALT ) macMod |= NSEventModifierFlagOption;
if ( value & FL_CTRL ) macMod |= NSEventModifierFlagControl;
[super setKeyEquivalentModifierMask:macMod];
}
- (void) setFltkShortcut:(int)key
{
int mod = key;
mod &= ~FL_KEY_MASK; key &= FL_KEY_MASK; unichar mac_key = (unichar)key;
if ( (key >= (FL_F+1)) && (key <= FL_F_Last) ) { int fkey_num = (key - FL_F); mac_key = NSF1FunctionKey + fkey_num - 1;
} else if (key == FL_Escape) {
mac_key = 27;
} else if (key == FL_Tab) {
mac_key = NSTabCharacter;
} else if (key == FL_Enter) {
mac_key = 0x0d;
} else if (key == FL_BackSpace) {
mac_key = NSBackspaceCharacter;
} else if (key == FL_Delete) {
mac_key = NSDeleteCharacter;
} else if (key == FL_Up) {
mac_key = NSUpArrowFunctionKey;
} else if (key == FL_Down) {
mac_key = NSDownArrowFunctionKey;
} else if (key == FL_Left) {
mac_key = NSLeftArrowFunctionKey;
} else if (key == FL_Right) {
mac_key = NSRightArrowFunctionKey;
} else if (key == FL_Page_Up) {
mac_key = NSPageUpFunctionKey;
} else if (key == FL_Page_Down) {
mac_key = NSPageDownFunctionKey;
} else if (key == FL_KP_Enter) {
mac_key = 0x2324; } else if (key == FL_Home) {
mac_key = NSHomeFunctionKey;
} else if (key == FL_End) {
mac_key = NSEndFunctionKey;
}
[self setKeyEquivalent:[NSString stringWithCharacters:&mac_key length:1]];
[self setKeyEquivalentModifierMask:mod];
}
+ (int) addNewItem:(const Fl_Menu_Item*)mitem menu:(NSMenu*)menu action:(SEL)selector
{
char *name = remove_ampersand(mitem->label());
NSString *title = NSLocalizedString([NSString stringWithUTF8String:name], nil);
free(name);
FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:title
action:selector
keyEquivalent:@""];
NSInteger index = (fl_sys_menu_bar ? fl_sys_menu_bar->find_index(mitem) : -1);
[item setTag:index];
if (index < 0) {
NSData *pointer = [[NSData alloc] initWithBytes:&mitem length:sizeof(Fl_Menu_Item*)];
[item setRepresentedObject:pointer];
[pointer release]; }
[menu addItem:item];
[item setTarget:item];
int retval = (int)[menu indexOfItem:item];
[item release];
return retval;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
- (BOOL)validateMenuItem:(NSMenuItem *)item {
if (fl_mac_os_version < 101200 ||
Fl_Sys_Menu_Bar::window_menu_style() <= Fl_Sys_Menu_Bar::tabbing_mode_none ||
[item hasSubmenu]) return YES;
NSString *title = [[item parentItem] title]; if (!title || !localized_Window || [title compare:localized_Window] != NSOrderedSame) return YES;
const Fl_Menu_Item *flitem = [(FLMenuItem*)item getFlItem];
Fl_Callback *item_cb = flitem->callback();
if (item_cb == previous_tab_cb || item_cb == next_tab_cb || item_cb == move_tab_cb) {
Fl_Window *win = Fl::first_window();
NSWindow *main = win ? (NSWindow*)fl_xid(win) : nil;
return (main && [main tabbedWindows] != nil);
} else if (item_cb == merge_all_windows_cb) {
int total = 0, untabbed = 0;
while ((++flitem)->label()) {
total++;
NSWindow *nsw = (NSWindow*)fl_xid( (Fl_Window*)flitem->user_data() );
if (![nsw tabbedWindows] && [nsw tabbingMode] != NSWindowTabbingModeDisallowed) {
untabbed++;
}
}
return (untabbed > 0 && total >= 2);
}
return YES;
}
#endif
@end
void Fl_MacOS_Sys_Menu_Bar_Driver::about( Fl_Callback *cb, void *user_data)
{
Fl_Menu_Item aboutItem;
memset(&aboutItem, 0, sizeof(Fl_Menu_Item));
aboutItem.callback(cb);
aboutItem.user_data(user_data);
NSMenu *appleMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu itemAtIndex:0] title]);
[appleMenu removeItemAtIndex:0];
FLMenuItem *item = [[[FLMenuItem alloc] initWithTitle:(NSString*)cfname
action:@selector(directCallback)
keyEquivalent:@""] autorelease];
NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)];
[item setRepresentedObject:pointer];
[appleMenu insertItem:item atIndex:0];
CFRelease(cfname);
[item setTarget:item];
}
static void setMenuShortcut( NSMenu* mh, int miCnt, const Fl_Menu_Item *m )
{
if ( !m->shortcut_ )
return;
if ( m->flags & FL_SUBMENU )
return;
if ( m->flags & FL_SUBMENU_POINTER )
return;
FLMenuItem* menuItem = (FLMenuItem*)[mh itemAtIndex:miCnt];
[menuItem setFltkShortcut:(m->shortcut_)];
}
static void setMenuFlags( NSMenu* mh, int miCnt, const Fl_Menu_Item *m )
{
if ( m->flags & FL_MENU_TOGGLE )
{
NSMenuItem *menuItem = [mh itemAtIndex:miCnt];
[menuItem setState:(m->flags & FL_MENU_VALUE ? NSControlStateValueOn : NSControlStateValueOff)];
}
else if ( m->flags & FL_MENU_RADIO ) {
NSMenuItem *menuItem = [mh itemAtIndex:miCnt];
[menuItem setState:(m->flags & FL_MENU_VALUE ? NSControlStateValueOn : NSControlStateValueOff)];
}
}
static char *remove_ampersand(const char *s)
{
char *ret = fl_strdup(s);
const char *p = s;
char *q = ret;
while(*p != 0) {
if (p[0]=='&') {
if (p[1]=='&') {
*q++ = '&'; p+=2;
} else {
p++;
}
} else {
*q++ = *p++;
}
}
*q = 0;
return ret;
}
static void createSubMenu( NSMenu *mh, pFl_Menu_Item &mm, const Fl_Menu_Item *mitem, SEL selector)
{
NSMenu *submenu;
int miCnt, flags;
if (mitem) {
NSMenuItem *menuItem;
char *ts = remove_ampersand(mitem->text);
NSString *title = NSLocalizedString([NSString stringWithUTF8String:ts], nil);
free(ts);
submenu = [[NSMenu alloc] initWithTitle:(NSString*)title];
[submenu setAutoenablesItems:NO];
int cnt;
cnt = (int)[mh numberOfItems];
cnt--;
menuItem = [mh itemAtIndex:cnt];
[menuItem setSubmenu:submenu];
[submenu release];
} else submenu = mh;
while ( mm->text ) {
if (!mm->visible() ) { mm = mm->next(0);
continue;
}
miCnt = [FLMenuItem addNewItem:mm menu:submenu
action:( (mm->flags & (FL_SUBMENU+FL_SUBMENU_POINTER) && !mm->callback()) ? nil : selector)
];
setMenuFlags( submenu, miCnt, mm );
setMenuShortcut( submenu, miCnt, mm );
if (mitem && (mm->flags & FL_MENU_INACTIVE || mitem->flags & FL_MENU_INACTIVE)) {
NSMenuItem *item = [submenu itemAtIndex:miCnt];
[item setEnabled:NO];
}
flags = mm->flags;
if ( mm->flags & FL_SUBMENU )
{
mm++;
createSubMenu( submenu, mm, mm - 1, selector);
}
else if ( mm->flags & FL_SUBMENU_POINTER )
{
const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
createSubMenu( submenu, smm, mm, selector);
}
if ( flags & FL_MENU_DIVIDER ) {
[submenu addItem:[NSMenuItem separatorItem]];
}
mm++;
}
}
static void convertToMenuBar(const Fl_Menu_Item *mm)
{
NSMenu *fl_system_menu = [NSApp mainMenu];
int count; count = (int)[fl_system_menu numberOfItems];
for(int i = count - 1; i > 0; i--) {
[fl_system_menu removeItem:[fl_system_menu itemAtIndex:i]];
}
if (mm) createSubMenu(fl_system_menu, mm, NULL, @selector(doCallback));
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
if (localized_Window) {
NSMenuItem *item = [fl_system_menu itemWithTitle:localized_Window];
if (item) [[item submenu] setAutoenablesItems:YES];
}
#endif
}
void Fl_MacOS_Sys_Menu_Bar_Driver::update()
{
convertToMenuBar(bar->Fl_Menu_::menu());
}
static int process_sys_menu_shortcuts(int event)
{
if (event != FL_SHORTCUT || !fl_sys_menu_bar || Fl::modal()) return 0;
const Fl_Menu_Item *item = fl_sys_menu_bar->menu()->test_shortcut();
if (!item) return 0;
if (item->visible()) [[NSApp mainMenu] performKeyEquivalent:[NSApp currentEvent]];
else fl_sys_menu_bar->picked(item);
return 1;
}
Fl_MacOS_Sys_Menu_Bar_Driver::Fl_MacOS_Sys_Menu_Bar_Driver() : Fl_Sys_Menu_Bar_Driver()
{
window_menu_items = NULL;
first_window_menu_item = 0;
Fl::add_handler(process_sys_menu_shortcuts);
}
Fl_MacOS_Sys_Menu_Bar_Driver::~Fl_MacOS_Sys_Menu_Bar_Driver()
{
Fl::remove_handler(process_sys_menu_shortcuts);
}
void Fl_MacOS_Sys_Menu_Bar_Driver::menu(const Fl_Menu_Item *m)
{
fl_open_display();
bar->Fl_Menu_Bar::menu( m );
convertToMenuBar(m);
}
void Fl_MacOS_Sys_Menu_Bar_Driver::clear()
{
bar->Fl_Menu_::clear();
convertToMenuBar(NULL);
}
int Fl_MacOS_Sys_Menu_Bar_Driver::clear_submenu(int index)
{
int retval = bar->Fl_Menu_::clear_submenu(index);
if (retval != -1) update();
return retval;
}
void Fl_MacOS_Sys_Menu_Bar_Driver::remove(int index)
{
bar->Fl_Menu_::remove(index);
update();
}
void Fl_MacOS_Sys_Menu_Bar_Driver::replace(int index, const char *name)
{
bar->Fl_Menu_::replace(index, name);
update();
}
void Fl_MacOS_Sys_Menu_Bar_Driver::mode(int i, int fl) {
bar->Fl_Menu_::mode(i, fl);
update();
}
void Fl_MacOS_Sys_Menu_Bar_Driver::shortcut (int i, int s) {
bar->Fl_Menu_Bar::shortcut(i, s);
update();
}
void Fl_MacOS_Sys_Menu_Bar_Driver::setonly (Fl_Menu_Item *item) {
bar->Fl_Menu_::setonly(item);
update();
}
int Fl_MacOS_Sys_Menu_Bar_Driver::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
{
fl_open_display();
int index = bar->Fl_Menu_::add(label, shortcut, cb, user_data, flags);
update();
return index;
}
int Fl_MacOS_Sys_Menu_Bar_Driver::add(const char* str)
{
fl_open_display();
int index = bar->Fl_Menu_::add(str);
update();
return index;
}
int Fl_MacOS_Sys_Menu_Bar_Driver::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
{
fl_open_display();
int menu_index = bar->Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags);
update();
return menu_index;
}
void Fl_Mac_App_Menu::custom_application_menu_items(const Fl_Menu_Item *m)
{
fl_open_display(); custom_menu = new Fl_Menu_Bar(0,0,0,0);
custom_menu->menu(m);
NSMenu *menu = [[[NSApp mainMenu] itemAtIndex:0] submenu]; NSInteger to_index;
if ([[menu itemAtIndex:2] action] != @selector(printPanel)) { [menu insertItem:[NSMenuItem separatorItem] atIndex:1];
to_index = 2;
} else to_index = 5; NSInteger count = [menu numberOfItems];
createSubMenu(menu, m, NULL, @selector(customCallback)); NSInteger count2 = [menu numberOfItems];
for (NSInteger i = count; i < count2; i++) { NSMenuItem *item = [menu itemAtIndex:i];
[item retain];
[menu removeItemAtIndex:i];
[menu insertItem:item atIndex:to_index++];
[item release];
}
}
static void minimize_win_cb(Fl_Widget *, void *data)
{
[[NSApp mainWindow] miniaturize:nil];
}
static void window_menu_cb(Fl_Widget *, void *data)
{
if (data) ((Fl_Window*)data)->show();
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
static void previous_tab_cb(Fl_Widget *, void *data)
{
[[NSApp mainWindow] selectPreviousTab:nil];
}
static void next_tab_cb(Fl_Widget *, void *data)
{
[[NSApp mainWindow] selectNextTab:nil];
}
static void move_tab_cb(Fl_Widget *, void *data)
{
[[NSApp mainWindow] moveTabToNewWindow:nil];
}
static void merge_all_windows_cb(Fl_Widget *, void *)
{
Fl_Window *first = Fl::first_window();
while (first && (first->parent() || !first->border()))
first = Fl::next_window(first);
if (first) {
[(NSWindow*)fl_xid(first) mergeAllWindows:nil];
}
}
#endif
static bool window_menu_installed = false;
static int window_menu_items_count = 0;
void Fl_MacOS_Sys_Menu_Bar_Driver::create_window_menu(void)
{
if (window_menu_style() == Fl_Sys_Menu_Bar::no_window_menu) return;
if (window_menu_installed) return;
window_menu_installed = true;
int rank = 0;
if (fl_sys_menu_bar && fl_sys_menu_bar->menu()) {
if (fl_sys_menu_bar->find_index("Window") >= 0) { window_menu_style_ = Fl_Sys_Menu_Bar::no_window_menu;
return;
}
const Fl_Menu_Item *item = fl_sys_menu_bar->menu();
while (item->label() && strcmp(item->label(), "Help") != 0) {
item = item->next();
}
rank = fl_sys_menu_bar->find_index(item);
} else if (!fl_sys_menu_bar) {
fl_open_display();
new Fl_Sys_Menu_Bar(0,0,0,0);
}
if (!window_menu_items_count) {
window_menu_items_count = 6;
window_menu_items = (Fl_Menu_Item*)calloc(window_menu_items_count, sizeof(Fl_Menu_Item));
}
rank = fl_sys_menu_bar->Fl_Menu_::insert(rank, "Window", 0, NULL, window_menu_items, FL_SUBMENU_POINTER);
localized_Window = NSLocalizedString(@"Window", nil);
window_menu_items[0].label("Minimize");
window_menu_items[0].callback(minimize_win_cb);
window_menu_items[0].shortcut(FL_COMMAND+'m');
window_menu_items[0].flags = FL_MENU_DIVIDER;
first_window_menu_item = 1;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
if (fl_mac_os_version >= 101200 && window_menu_style() != Fl_Sys_Menu_Bar::tabbing_mode_none) {
window_menu_items[1].label("Show Previous Tab");
window_menu_items[1].callback(previous_tab_cb);
window_menu_items[1].shortcut(FL_SHIFT+FL_CTRL+0x9);
window_menu_items[2].label("Show Next Tab");
window_menu_items[2].callback(next_tab_cb);
window_menu_items[2].shortcut(FL_CTRL+0x9);
window_menu_items[3].label("Move Tab To New Window");
window_menu_items[3].callback(move_tab_cb);
window_menu_items[4].label("Merge All Windows");
window_menu_items[4].callback(merge_all_windows_cb);
window_menu_items[4].flags = FL_MENU_DIVIDER;
first_window_menu_item = 5;
}
#endif
fl_sys_menu_bar->menu_end();
fl_sys_menu_bar->update();
}
void Fl_MacOS_Sys_Menu_Bar_Driver::new_window(Fl_Window *win)
{
if (!window_menu_style() || !win->label()) return;
int index = window_menu_items->size() - 1;
if (index >= window_menu_items_count - 1) {
window_menu_items_count += 5;
window_menu_items = (Fl_Menu_Item*)realloc(window_menu_items,
window_menu_items_count * sizeof(Fl_Menu_Item));
Fl_Menu_Item *item = (Fl_Menu_Item*)fl_sys_menu_bar->find_item("Window");
item->user_data(window_menu_items);
}
const char *p = win->iconlabel() ? win->iconlabel() : win->label();
window_menu_items[index].label(p);
window_menu_items[index].callback(window_menu_cb);
window_menu_items[index].user_data(win);
window_menu_items[index].flags = FL_MENU_RADIO;
window_menu_items[index+1].label(NULL);
window_menu_items[index].setonly();
fl_sys_menu_bar->update();
}
void Fl_MacOS_Sys_Menu_Bar_Driver::remove_window(Fl_Window *win)
{
if (!window_menu_style()) return;
int index = first_window_menu_item;
if (index < 1) return;
while (true) {
Fl_Menu_Item *item = window_menu_items + index;
if (!item->label()) return;
if (item->user_data() == win) {
bool doit = item->value();
int count = window_menu_items->size();
if (count - index - 1 > 0) memmove(item, item + 1, (count - index - 1)*sizeof(Fl_Menu_Item));
memset(window_menu_items + count - 2, 0, sizeof(Fl_Menu_Item));
if (doit) { item = window_menu_items + first_window_menu_item;
while (item->label() && item->user_data() != Fl::first_window()) item++;
if (item->label()) {
((Fl_Window*)item->user_data())->show();
item->setonly();
}
}
bar->update();
break;
}
index++;
}
}
void Fl_MacOS_Sys_Menu_Bar_Driver::rename_window(Fl_Window *win)
{
if (!window_menu_style()) return;
int index = first_window_menu_item;
if (index < 1) return;
while (true) {
Fl_Menu_Item *item = window_menu_items + index;
if (!item->label()) return;
if (item->user_data() == win) {
item->label(win->iconlabel() ? win->iconlabel() : win->label());
bar->update();
return;
}
index++;
}
}
void fl_mac_set_about(Fl_Callback *cb, void *user_data, int shortcut) {
Fl_Sys_Menu_Bar::about(cb, user_data);
}
void Fl_MacOS_Sys_Menu_Bar_Driver::play_menu(const Fl_Menu_Item *item) {
CFArrayRef children = NULL;
CFIndex count = 0;
AXUIElementRef element;
char *label = remove_ampersand(item->label());
NSString *mac_name = NSLocalizedString([NSString stringWithUTF8String:label], nil);
free(label);
AXUIElementRef appElement = AXUIElementCreateApplication(getpid());
AXUIElementRef menu_bar = NULL;
AXError error = AXUIElementCopyAttributeValue(appElement, kAXMenuBarAttribute,
(CFTypeRef *)&menu_bar);
if (!error) error = AXUIElementGetAttributeValueCount(menu_bar, kAXChildrenAttribute, &count);
if (!error) error = AXUIElementCopyAttributeValues(menu_bar, kAXChildrenAttribute, 0, count,
&children);
if (!error) {
NSEnumerator *enumerator = [(NSArray*)children objectEnumerator];
[enumerator nextObject]; [enumerator nextObject]; bool need_more = true;
while (need_more && (element = (AXUIElementRef)[enumerator nextObject]) != nil) {
CFTypeRef title = NULL;
need_more = ( AXUIElementCopyAttributeValue(element, kAXTitleAttribute, &title) == 0 );
if (need_more && [(NSString*)title isEqualToString:mac_name]) {
AXUIElementPerformAction(element, kAXPressAction);
need_more = false;
}
if (title) CFRelease(title);
}
}
if (menu_bar) CFRelease(menu_bar);
if (children) CFRelease(children);
CFRelease(appElement);
}
#endif