Migrated main.m functions. Before we merge this back in I absoltuely must do something about main.m and menu.m, even if ethereal.
This commit is contained in:
parent
60e71c7174
commit
1381edfa6e
|
@ -1,23 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
// main.m
|
|
||||||
@interface applicationClass : NSApplication
|
|
||||||
@end
|
|
||||||
// this is needed because NSApp is of type id, confusing clang
|
|
||||||
#define realNSApp() ((applicationClass *) NSApp)
|
|
||||||
@interface appDelegate : NSObject <NSApplicationDelegate>
|
|
||||||
@property (strong) uiprivMenuManager *menuManager;
|
|
||||||
@end
|
|
||||||
#define appDelegate() ((appDelegate *) [realNSApp() delegate])
|
|
||||||
struct nextEventArgs {
|
|
||||||
NSEventMask mask;
|
|
||||||
NSDate *duration;
|
|
||||||
// LONGTERM no NSRunLoopMode?
|
|
||||||
NSString *mode;
|
|
||||||
BOOL dequeue;
|
|
||||||
};
|
|
||||||
extern int mainStep(struct nextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *));
|
|
||||||
|
|
||||||
// util.m
|
// util.m
|
||||||
extern void disableAutocorrect(NSTextView *);
|
extern void disableAutocorrect(NSTextView *);
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
|
|
||||||
static BOOL canQuit = NO;
|
static BOOL canQuit = NO;
|
||||||
static NSAutoreleasePool *globalPool;
|
static NSAutoreleasePool *globalPool;
|
||||||
static applicationClass *app;
|
static uiprivApplicationClass *app;
|
||||||
static appDelegate *delegate;
|
static uiprivAppDelegate *delegate;
|
||||||
|
|
||||||
static BOOL (^isRunning)(void);
|
static BOOL (^isRunning)(void);
|
||||||
static BOOL stepsIsRunning;
|
static BOOL stepsIsRunning;
|
||||||
|
|
||||||
@implementation applicationClass
|
@implementation uiprivApplicationClass
|
||||||
|
|
||||||
- (void)sendEvent:(NSEvent *)e
|
- (void)sendEvent:(NSEvent *)e
|
||||||
{
|
{
|
||||||
|
@ -59,7 +59,7 @@ static BOOL stepsIsRunning;
|
||||||
if (!canQuit)
|
if (!canQuit)
|
||||||
uiprivImplBug("call to [NSApp terminate:] when not ready to terminate; definitely contact andlabs");
|
uiprivImplBug("call to [NSApp terminate:] when not ready to terminate; definitely contact andlabs");
|
||||||
|
|
||||||
[realNSApp() stop:realNSApp()];
|
[uiprivNSApp() stop:uiprivNSApp()];
|
||||||
// stop: won't register until another event has passed; let's synthesize one
|
// stop: won't register until another event has passed; let's synthesize one
|
||||||
e = [NSEvent otherEventWithType:NSApplicationDefined
|
e = [NSEvent otherEventWithType:NSApplicationDefined
|
||||||
location:NSZeroPoint
|
location:NSZeroPoint
|
||||||
|
@ -70,7 +70,7 @@ static BOOL stepsIsRunning;
|
||||||
subtype:0
|
subtype:0
|
||||||
data1:0
|
data1:0
|
||||||
data2:0];
|
data2:0];
|
||||||
[realNSApp() postEvent:e atStart:NO]; // let pending events take priority (this is what PostQuitMessage() on Windows does so we have to do it here too for parity; thanks to mikeash in irc.freenode.net/#macdev for confirming that this parameter should indeed be NO)
|
[uiprivNSApp() postEvent:e atStart:NO]; // let pending events take priority (this is what PostQuitMessage() on Windows does so we have to do it here too for parity; thanks to mikeash in irc.freenode.net/#macdev for confirming that this parameter should indeed be NO)
|
||||||
|
|
||||||
// and in case uiMainSteps() was called
|
// and in case uiMainSteps() was called
|
||||||
stepsIsRunning = NO;
|
stepsIsRunning = NO;
|
||||||
|
@ -78,7 +78,7 @@ static BOOL stepsIsRunning;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation appDelegate
|
@implementation uiprivAppDelegate
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
|
@ -112,20 +112,20 @@ const char *uiInit(uiInitOptions *o)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
uiprivOptions = *o;
|
uiprivOptions = *o;
|
||||||
app = [[applicationClass sharedApplication] retain];
|
app = [[uiprivApplicationClass sharedApplication] retain];
|
||||||
// don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy!
|
// don't check for a NO return; something (launch services?) causes running from application bundles to always return NO when asking to change activation policy, even if the change is to the same activation policy!
|
||||||
// see https://github.com/andlabs/ui/issues/6
|
// see https://github.com/andlabs/ui/issues/6
|
||||||
[realNSApp() setActivationPolicy:NSApplicationActivationPolicyRegular];
|
[uiprivNSApp() setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
delegate = [appDelegate new];
|
delegate = [uiprivAppDelegate new];
|
||||||
[realNSApp() setDelegate:delegate];
|
[uiprivNSApp() setDelegate:delegate];
|
||||||
|
|
||||||
initAlloc();
|
initAlloc();
|
||||||
loadFutures();
|
loadFutures();
|
||||||
loadUndocumented();
|
loadUndocumented();
|
||||||
|
|
||||||
// always do this so we always have an application menu
|
// always do this so we always have an application menu
|
||||||
appDelegate().menuManager = [[uiprivMenuManager new] autorelease];
|
uiprivAppDelegate().menuManager = [[uiprivMenuManager new] autorelease];
|
||||||
[realNSApp() setMainMenu:[appDelegate().menuManager makeMenubar]];
|
[uiprivNSApp() setMainMenu:[uiprivAppDelegate().menuManager makeMenubar]];
|
||||||
|
|
||||||
uiprivSetupFontPanel();
|
uiprivSetupFontPanel();
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ void uiUninit(void)
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
uiprivUninitUnderlineColors();
|
uiprivUninitUnderlineColors();
|
||||||
[delegate release];
|
[delegate release];
|
||||||
[realNSApp() setDelegate:nil];
|
[uiprivNSApp() setDelegate:nil];
|
||||||
[app release];
|
[app release];
|
||||||
uninitAlloc();
|
uninitAlloc();
|
||||||
}
|
}
|
||||||
|
@ -159,15 +159,15 @@ void uiFreeInitError(const char *err)
|
||||||
void uiMain(void)
|
void uiMain(void)
|
||||||
{
|
{
|
||||||
isRunning = ^{
|
isRunning = ^{
|
||||||
return [realNSApp() isRunning];
|
return [uiprivNSApp() isRunning];
|
||||||
};
|
};
|
||||||
[realNSApp() run];
|
[uiprivNSApp() run];
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiMainSteps(void)
|
void uiMainSteps(void)
|
||||||
{
|
{
|
||||||
// SDL does this and it seems to be necessary for the menubar to work (see #182)
|
// SDL does this and it seems to be necessary for the menubar to work (see #182)
|
||||||
[realNSApp() finishLaunching];
|
[uiprivNSApp() finishLaunching];
|
||||||
isRunning = ^{
|
isRunning = ^{
|
||||||
return stepsIsRunning;
|
return stepsIsRunning;
|
||||||
};
|
};
|
||||||
|
@ -176,7 +176,7 @@ void uiMainSteps(void)
|
||||||
|
|
||||||
int uiMainStep(int wait)
|
int uiMainStep(int wait)
|
||||||
{
|
{
|
||||||
struct nextEventArgs nea;
|
uiprivNextEventArgs nea;
|
||||||
|
|
||||||
nea.mask = NSAnyEventMask;
|
nea.mask = NSAnyEventMask;
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ int uiMainStep(int wait)
|
||||||
nea.mode = NSDefaultRunLoopMode;
|
nea.mode = NSDefaultRunLoopMode;
|
||||||
nea.dequeue = YES;
|
nea.dequeue = YES;
|
||||||
|
|
||||||
return mainStep(&nea, ^(NSEvent *e) {
|
return uiprivMainStep(&nea, ^(NSEvent *e) {
|
||||||
return NO;
|
return NO;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ int uiMainStep(int wait)
|
||||||
// see also:
|
// see also:
|
||||||
// - http://www.cocoawithlove.com/2009/01/demystifying-nsapplication-by.html
|
// - http://www.cocoawithlove.com/2009/01/demystifying-nsapplication-by.html
|
||||||
// - https://github.com/gnustep/gui/blob/master/Source/NSApplication.m
|
// - https://github.com/gnustep/gui/blob/master/Source/NSApplication.m
|
||||||
int mainStep(struct nextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *e))
|
int uiprivMainStep(uiprivNextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *e))
|
||||||
{
|
{
|
||||||
NSDate *expire;
|
NSDate *expire;
|
||||||
NSEvent *e;
|
NSEvent *e;
|
||||||
|
@ -207,7 +207,7 @@ int mainStep(struct nextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *e))
|
||||||
if (!isRunning())
|
if (!isRunning())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
e = [realNSApp() nextEventMatchingMask:nea->mask
|
e = [uiprivNSApp() nextEventMatchingMask:nea->mask
|
||||||
untilDate:nea->duration
|
untilDate:nea->duration
|
||||||
inMode:nea->mode
|
inMode:nea->mode
|
||||||
dequeue:nea->dequeue];
|
dequeue:nea->dequeue];
|
||||||
|
@ -216,13 +216,13 @@ int mainStep(struct nextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *e))
|
||||||
|
|
||||||
type = [e type];
|
type = [e type];
|
||||||
if (!interceptEvent(e))
|
if (!interceptEvent(e))
|
||||||
[realNSApp() sendEvent:e];
|
[uiprivNSApp() sendEvent:e];
|
||||||
[realNSApp() updateWindows];
|
[uiprivNSApp() updateWindows];
|
||||||
|
|
||||||
// GNUstep does this
|
// GNUstep does this
|
||||||
// it also updates the Services menu but there doesn't seem to be a public API for that so
|
// it also updates the Services menu but there doesn't seem to be a public API for that so
|
||||||
if (type != NSPeriodic && type != NSMouseMoved)
|
if (type != NSPeriodic && type != NSMouseMoved)
|
||||||
[[realNSApp() mainMenu] update];
|
[[uiprivNSApp() mainMenu] update];
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ int mainStep(struct nextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *e))
|
||||||
void uiQuit(void)
|
void uiQuit(void)
|
||||||
{
|
{
|
||||||
canQuit = YES;
|
canQuit = YES;
|
||||||
[realNSApp() terminate:realNSApp()];
|
[uiprivNSApp() terminate:uiprivNSApp()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch for this
|
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch for this
|
||||||
|
|
|
@ -66,7 +66,7 @@ static void mapItemReleaser(void *key, void *value)
|
||||||
if (item->type == typeCheckbox)
|
if (item->type == typeCheckbox)
|
||||||
uiMenuItemSetChecked(item, !uiMenuItemChecked(item));
|
uiMenuItemSetChecked(item, !uiMenuItemChecked(item));
|
||||||
// use the key window as the source of the menu event; it's the active window
|
// use the key window as the source of the menu event; it's the active window
|
||||||
(*(item->onClicked))(item, windowFromNSWindow([realNSApp() keyWindow]), item->onClickedData);
|
(*(item->onClicked))(item, windowFromNSWindow([uiprivNSApp() keyWindow]), item->onClickedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)onQuitClicked:(id)sender
|
- (IBAction)onQuitClicked:(id)sender
|
||||||
|
@ -154,7 +154,7 @@ static void mapItemReleaser(void *key, void *value)
|
||||||
item = [[[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""] autorelease];
|
item = [[[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""] autorelease];
|
||||||
servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease];
|
servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease];
|
||||||
[item setSubmenu:servicesMenu];
|
[item setSubmenu:servicesMenu];
|
||||||
[realNSApp() setServicesMenu:servicesMenu];
|
[uiprivNSApp() setServicesMenu:servicesMenu];
|
||||||
[appMenu addItem:item];
|
[appMenu addItem:item];
|
||||||
|
|
||||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||||
|
@ -246,13 +246,13 @@ static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
|
||||||
item->type = type;
|
item->type = type;
|
||||||
switch (item->type) {
|
switch (item->type) {
|
||||||
case typeQuit:
|
case typeQuit:
|
||||||
item->item = [appDelegate().menuManager.quitItem retain];
|
item->item = [uiprivAppDelegate().menuManager.quitItem retain];
|
||||||
break;
|
break;
|
||||||
case typePreferences:
|
case typePreferences:
|
||||||
item->item = [appDelegate().menuManager.preferencesItem retain];
|
item->item = [uiprivAppDelegate().menuManager.preferencesItem retain];
|
||||||
break;
|
break;
|
||||||
case typeAbout:
|
case typeAbout:
|
||||||
item->item = [appDelegate().menuManager.aboutItem retain];
|
item->item = [uiprivAppDelegate().menuManager.aboutItem retain];
|
||||||
break;
|
break;
|
||||||
case typeSeparator:
|
case typeSeparator:
|
||||||
item->item = [[NSMenuItem separatorItem] retain];
|
item->item = [[NSMenuItem separatorItem] retain];
|
||||||
|
@ -260,12 +260,12 @@ static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
item->item = [[NSMenuItem alloc] initWithTitle:uiprivToNSString(name) action:@selector(onClicked:) keyEquivalent:@""];
|
item->item = [[NSMenuItem alloc] initWithTitle:uiprivToNSString(name) action:@selector(onClicked:) keyEquivalent:@""];
|
||||||
[item->item setTarget:appDelegate().menuManager];
|
[item->item setTarget:uiprivAppDelegate().menuManager];
|
||||||
[m->menu addItem:item->item];
|
[m->menu addItem:item->item];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[appDelegate().menuManager register:item->item to:item];
|
[uiprivAppDelegate().menuManager register:item->item to:item];
|
||||||
item->onClicked = defaultOnClicked;
|
item->onClicked = defaultOnClicked;
|
||||||
|
|
||||||
[m->items addObject:[NSValue valueWithPointer:item]];
|
[m->items addObject:[NSValue valueWithPointer:item]];
|
||||||
|
@ -329,7 +329,7 @@ uiMenu *uiNewMenu(const char *name)
|
||||||
|
|
||||||
m->items = [NSMutableArray new];
|
m->items = [NSMutableArray new];
|
||||||
|
|
||||||
[[realNSApp() mainMenu] addItem:m->item];
|
[[uiprivNSApp() mainMenu] addItem:m->item];
|
||||||
|
|
||||||
[menus addObject:[NSValue valueWithPointer:m]];
|
[menus addObject:[NSValue valueWithPointer:m]];
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,9 @@ static char *runSavePanel(NSWindow *parent, NSSavePanel *s)
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
[s beginSheetModalForWindow:parent completionHandler:^(NSInteger result) {
|
[s beginSheetModalForWindow:parent completionHandler:^(NSInteger result) {
|
||||||
[realNSApp() stopModalWithCode:result];
|
[uiprivNSApp() stopModalWithCode:result];
|
||||||
}];
|
}];
|
||||||
if ([realNSApp() runModalForWindow:s] != NSFileHandlingPanelOKButton)
|
if ([uiprivNSApp() runModalForWindow:s] != NSFileHandlingPanelOKButton)
|
||||||
return NULL;
|
return NULL;
|
||||||
filename = uiDarwinNSStringToText([[s URL] path]);
|
filename = uiDarwinNSStringToText([[s URL] path]);
|
||||||
return filename;
|
return filename;
|
||||||
|
@ -84,12 +84,12 @@ char *uiSaveFile(uiWindow *parent)
|
||||||
modalDelegate:self
|
modalDelegate:self
|
||||||
didEndSelector:@selector(panelEnded:result:data:)
|
didEndSelector:@selector(panelEnded:result:data:)
|
||||||
contextInfo:NULL];
|
contextInfo:NULL];
|
||||||
return [realNSApp() runModalForWindow:[self->panel window]];
|
return [uiprivNSApp() runModalForWindow:[self->panel window]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)panelEnded:(NSAlert *)panel result:(NSInteger)result data:(void *)data
|
- (void)panelEnded:(NSAlert *)panel result:(NSInteger)result data:(void *)data
|
||||||
{
|
{
|
||||||
[realNSApp() stopModalWithCode:result];
|
[uiprivNSApp() stopModalWithCode:result];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -49,4 +49,23 @@ extern void uiprivMapReset(uiprivMap *m);
|
||||||
extern void uiprivFinalizeMenus(void);
|
extern void uiprivFinalizeMenus(void);
|
||||||
extern void uiprivUninitMenus(void);
|
extern void uiprivUninitMenus(void);
|
||||||
|
|
||||||
|
// main.m
|
||||||
|
@interface uiprivApplicationClass : NSApplication
|
||||||
|
@end
|
||||||
|
// this is needed because NSApp is of type id, confusing clang
|
||||||
|
#define uiprivNSApp() ((uiprivApplicationClass *) NSApp)
|
||||||
|
@interface uiprivAppDelegate : NSObject<NSApplicationDelegate>
|
||||||
|
@property (strong) uiprivMenuManager *menuManager;
|
||||||
|
@end
|
||||||
|
#define uiprivAppDelegate() ((uiprivAppDelegate *) [uiprivNSApp() delegate])
|
||||||
|
typedef struct uiprivNextEventArgs uiprivNextEventArgs;
|
||||||
|
struct uiprivNextEventArgs {
|
||||||
|
NSEventMask mask;
|
||||||
|
NSDate *duration;
|
||||||
|
// LONGTERM no NSRunLoopMode?
|
||||||
|
NSString *mode;
|
||||||
|
BOOL dequeue;
|
||||||
|
};
|
||||||
|
extern int uiprivMainStep(uiprivNextEventArgs *nea, BOOL (^interceptEvent)(NSEvent *));
|
||||||
|
|
||||||
#import "OLD_uipriv_darwin.h"
|
#import "OLD_uipriv_darwin.h"
|
||||||
|
|
|
@ -46,7 +46,7 @@ void onMoveDrag(struct onMoveDragParams *p, NSEvent *e)
|
||||||
void doManualMove(NSWindow *w, NSEvent *initialEvent)
|
void doManualMove(NSWindow *w, NSEvent *initialEvent)
|
||||||
{
|
{
|
||||||
__block struct onMoveDragParams mdp;
|
__block struct onMoveDragParams mdp;
|
||||||
struct nextEventArgs nea;
|
uiprivNextEventArgs nea;
|
||||||
BOOL (^handleEvent)(NSEvent *e);
|
BOOL (^handleEvent)(NSEvent *e);
|
||||||
__block BOOL done;
|
__block BOOL done;
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ void doManualMove(NSWindow *w, NSEvent *initialEvent)
|
||||||
return YES; // do not send
|
return YES; // do not send
|
||||||
};
|
};
|
||||||
done = NO;
|
done = NO;
|
||||||
while (mainStep(&nea, handleEvent))
|
while (uiprivMainStep(&nea, handleEvent))
|
||||||
if (done)
|
if (done)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ static void onResizeDrag(struct onResizeDragParams *p, NSEvent *e)
|
||||||
void doManualResize(NSWindow *w, NSEvent *initialEvent, uiWindowResizeEdge edge)
|
void doManualResize(NSWindow *w, NSEvent *initialEvent, uiWindowResizeEdge edge)
|
||||||
{
|
{
|
||||||
__block struct onResizeDragParams rdp;
|
__block struct onResizeDragParams rdp;
|
||||||
struct nextEventArgs nea;
|
uiprivNextEventArgs nea;
|
||||||
BOOL (^handleEvent)(NSEvent *e);
|
BOOL (^handleEvent)(NSEvent *e);
|
||||||
__block BOOL done;
|
__block BOOL done;
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ void doManualResize(NSWindow *w, NSEvent *initialEvent, uiWindowResizeEdge edge)
|
||||||
return YES; // do not send
|
return YES; // do not send
|
||||||
};
|
};
|
||||||
done = NO;
|
done = NO;
|
||||||
while (mainStep(&nea, handleEvent))
|
while (uiprivMainStep(&nea, handleEvent))
|
||||||
if (done)
|
if (done)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue