Fixed executable/bundle paths procs
This commit is contained in:
parent
440668129c
commit
1d77a36640
|
@ -254,6 +254,7 @@ typedef struct mp_event
|
||||||
mp_char_event character;
|
mp_char_event character;
|
||||||
mp_move_event move;
|
mp_move_event move;
|
||||||
mp_frame_event frame;
|
mp_frame_event frame;
|
||||||
|
str8 path;
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO(martin): chain externally ?
|
//TODO(martin): chain externally ?
|
||||||
|
|
183
src/osx_app.m
183
src/osx_app.m
|
@ -168,6 +168,8 @@ typedef struct mp_app_data
|
||||||
bool init;
|
bool init;
|
||||||
bool shouldQuit;
|
bool shouldQuit;
|
||||||
|
|
||||||
|
str8 pendingPathDrop;
|
||||||
|
mem_arena eventArena;
|
||||||
mp_input_state inputState;
|
mp_input_state inputState;
|
||||||
ringbuffer eventQueue;
|
ringbuffer eventQueue;
|
||||||
|
|
||||||
|
@ -674,6 +676,10 @@ static void mp_dispatch_event(mp_event* event)
|
||||||
{
|
{
|
||||||
__mpAppData.eventCallback(*event, __mpAppData.eventData);
|
__mpAppData.eventCallback(*event, __mpAppData.eventData);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mp_queue_event(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
@ -689,10 +695,22 @@ static void mp_dispatch_event(mp_event* event)
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface MPAppDelegate : NSObject <NSApplicationDelegate>
|
@interface MPAppDelegate : NSObject <NSApplicationDelegate>
|
||||||
|
-(id)init;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MPAppDelegate
|
@implementation MPAppDelegate
|
||||||
|
|
||||||
|
-(id)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
|
||||||
|
andSelector:@selector(handleAppleEvent:withReplyEvent:)
|
||||||
|
forEventClass:kInternetEventClass
|
||||||
|
andEventID:kAEGetURL];
|
||||||
|
|
||||||
|
return(self);
|
||||||
|
}
|
||||||
|
|
||||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||||
{
|
{
|
||||||
//NOTE: We set shouldQuit to true and send a Quit event
|
//NOTE: We set shouldQuit to true and send a Quit event
|
||||||
|
@ -726,6 +744,7 @@ static void mp_dispatch_event(mp_event* event)
|
||||||
[appMenu addItemWithTitle: @"Quit"
|
[appMenu addItemWithTitle: @"Quit"
|
||||||
action: @selector(terminate:)
|
action: @selector(terminate:)
|
||||||
keyEquivalent: @"q"];
|
keyEquivalent: @"q"];
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
- (void)timerElapsed:(NSTimer*)timer
|
- (void)timerElapsed:(NSTimer*)timer
|
||||||
|
@ -744,6 +763,7 @@ static void mp_dispatch_event(mp_event* event)
|
||||||
// versions of macOS.
|
// versions of macOS.
|
||||||
|
|
||||||
//NOTE(martin): send a dummy event to wake-up the run loop and exit from the run loop.
|
//NOTE(martin): send a dummy event to wake-up the run loop and exit from the run loop.
|
||||||
|
|
||||||
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
|
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
|
||||||
location:NSMakePoint(0, 0)
|
location:NSMakePoint(0, 0)
|
||||||
modifierFlags:0
|
modifierFlags:0
|
||||||
|
@ -753,10 +773,34 @@ static void mp_dispatch_event(mp_event* event)
|
||||||
subtype:0
|
subtype:0
|
||||||
data1:0
|
data1:0
|
||||||
data2:0];
|
data2:0];
|
||||||
|
|
||||||
[NSApp postEvent:event atStart:YES];
|
[NSApp postEvent:event atStart:YES];
|
||||||
[NSApp stop:nil];
|
[NSApp stop:nil];
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
- (BOOL)application:(NSApplication *)application openFile:(NSString *)filename
|
||||||
|
{
|
||||||
|
mp_event event = {};
|
||||||
|
event.window = (mp_window){0};
|
||||||
|
event.type = MP_EVENT_PATHDROP;
|
||||||
|
event.path = str8_push_cstring(&__mpAppData.eventArena, [filename UTF8String]);
|
||||||
|
|
||||||
|
mp_dispatch_event(&event);
|
||||||
|
return(YES);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleAppleEvent:(NSAppleEventDescriptor*)appleEvent withReplyEvent:(NSAppleEventDescriptor*)replyEvent
|
||||||
|
{
|
||||||
|
NSString* nsPath = [[appleEvent paramDescriptorForKeyword:keyDirectObject] stringValue];
|
||||||
|
|
||||||
|
mp_event event = {};
|
||||||
|
event.window = (mp_window){0};
|
||||||
|
event.type = MP_EVENT_PATHDROP;
|
||||||
|
event.path = str8_push_cstring(&__mpAppData.eventArena, [nsPath UTF8String]);
|
||||||
|
|
||||||
|
mp_dispatch_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
@end // @implementation MPAppDelegate
|
@end // @implementation MPAppDelegate
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
@ -773,6 +817,85 @@ static void mp_dispatch_event(mp_event* event)
|
||||||
{
|
{
|
||||||
return(!(mpWindow->style & MP_WINDOW_STYLE_NO_FOCUS));
|
return(!(mpWindow->style & MP_WINDOW_STYLE_NO_FOCUS));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||||
|
{
|
||||||
|
if([sender draggingSourceOperationMask] & NSDragOperationGeneric)
|
||||||
|
{
|
||||||
|
return NSDragOperationGeneric;
|
||||||
|
}
|
||||||
|
return NSDragOperationNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||||
|
{@autoreleasepool
|
||||||
|
{
|
||||||
|
NSPasteboard *pasteboard = [sender draggingPasteboard];
|
||||||
|
NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType];
|
||||||
|
NSString *desiredType = [pasteboard availableTypeFromArray:types];
|
||||||
|
|
||||||
|
NSData *data;
|
||||||
|
NSArray *array;
|
||||||
|
NSPoint point;
|
||||||
|
|
||||||
|
if (desiredType == nil) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = [pasteboard dataForType:desiredType];
|
||||||
|
if (data == nil) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]);
|
||||||
|
array = [pasteboard propertyListForType:@"NSFilenamesPboardType"];
|
||||||
|
|
||||||
|
// Code addon to update the mouse location
|
||||||
|
point = [sender draggingLocation];
|
||||||
|
mouse = SDL_GetMouse();
|
||||||
|
x = (int)point.x;
|
||||||
|
y = (int)(sdlwindow->h - point.y);
|
||||||
|
if (x >= 0 && x < sdlwindow->w && y >= 0 && y < sdlwindow->h) {
|
||||||
|
SDL_SendMouseMotion(sdlwindow, mouse->mouseID, 0, x, y);
|
||||||
|
}
|
||||||
|
// Code addon to update the mouse location
|
||||||
|
|
||||||
|
for (NSString *path in array) {
|
||||||
|
NSURL *fileURL = [NSURL fileURLWithPath:path];
|
||||||
|
NSNumber *isAlias = nil;
|
||||||
|
|
||||||
|
[fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
|
||||||
|
|
||||||
|
// If the URL is an alias, resolve it.
|
||||||
|
if ([isAlias boolValue]) {
|
||||||
|
NSURLBookmarkResolutionOptions opts = NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI;
|
||||||
|
NSData *bookmark = [NSURL bookmarkDataWithContentsOfURL:fileURL error:nil];
|
||||||
|
if (bookmark != nil) {
|
||||||
|
NSURL *resolvedURL = [NSURL URLByResolvingBookmarkData:bookmark
|
||||||
|
options:opts
|
||||||
|
relativeToURL:nil
|
||||||
|
bookmarkDataIsStale:nil
|
||||||
|
error:nil];
|
||||||
|
|
||||||
|
if (resolvedURL != nil) {
|
||||||
|
fileURL = resolvedURL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SendDropComplete(sdlwindow);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)wantsPeriodicDraggingUpdates;
|
||||||
|
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
|
||||||
|
*/
|
||||||
|
|
||||||
@end //@implementation MPNativeWindow
|
@end //@implementation MPNativeWindow
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
|
@ -1388,6 +1511,8 @@ void mp_init()
|
||||||
{
|
{
|
||||||
memset(&__mpAppData, 0, sizeof(__mpAppData));
|
memset(&__mpAppData, 0, sizeof(__mpAppData));
|
||||||
|
|
||||||
|
mem_arena_init(&__mpAppData.eventArena);
|
||||||
|
|
||||||
mp_clock_init();
|
mp_clock_init();
|
||||||
|
|
||||||
LOG_MESSAGE("init keys\n");
|
LOG_MESSAGE("init keys\n");
|
||||||
|
@ -1432,6 +1557,7 @@ void mp_terminate()
|
||||||
//TODO: proper app data cleanup (eg delegate, etc)
|
//TODO: proper app data cleanup (eg delegate, etc)
|
||||||
if(__mpAppData.init)
|
if(__mpAppData.init)
|
||||||
{
|
{
|
||||||
|
mem_arena_release(&__mpAppData.eventArena);
|
||||||
__mpAppData = (mp_app_data){0};
|
__mpAppData = (mp_app_data){0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2124,14 +2250,24 @@ void mp_run_loop()
|
||||||
|
|
||||||
while(!__mpAppData.shouldQuit)
|
while(!__mpAppData.shouldQuit)
|
||||||
{
|
{
|
||||||
NSEvent* event = [NSApp nextEventMatchingMask: NSEventMaskAny
|
mp_event event;
|
||||||
|
while(mp_next_event(&event))
|
||||||
|
{
|
||||||
|
//send pending event that might have accumulated before we started run loop
|
||||||
|
if(__mpAppData.eventCallback)
|
||||||
|
{
|
||||||
|
__mpAppData.eventCallback(event, __mpAppData.eventData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSEvent* nsEvent = [NSApp nextEventMatchingMask: NSEventMaskAny
|
||||||
untilDate:[NSDate distantFuture]
|
untilDate:[NSDate distantFuture]
|
||||||
inMode: NSDefaultRunLoopMode
|
inMode: NSDefaultRunLoopMode
|
||||||
dequeue: YES];
|
dequeue: YES];
|
||||||
|
|
||||||
if(event != nil)
|
if(nsEvent != nil)
|
||||||
{
|
{
|
||||||
[NSApp sendEvent:event];
|
[NSApp sendEvent:nsEvent];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2141,6 +2277,7 @@ void mp_run_loop()
|
||||||
void mp_end_input_frame()
|
void mp_end_input_frame()
|
||||||
{
|
{
|
||||||
__mpAppData.inputState.frameCounter++;
|
__mpAppData.inputState.frameCounter++;
|
||||||
|
mem_arena_clear(&__mpAppData.eventArena);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -2299,35 +2436,21 @@ str8 mp_input_text_utf8(mem_arena* arena)
|
||||||
|
|
||||||
str8 mp_app_get_resource_path(mem_arena* arena, const char* name)
|
str8 mp_app_get_resource_path(mem_arena* arena, const char* name)
|
||||||
{
|
{
|
||||||
str8 cwd = {0};
|
str8_list list = {};
|
||||||
@autoreleasepool
|
mem_arena* scratch = mem_scratch();
|
||||||
{
|
|
||||||
NSBundle* mainBundle = [NSBundle mainBundle];
|
str8 executablePath = mp_app_get_executable_path(scratch);
|
||||||
if(!mainBundle)
|
str8 dirPath = mp_path_directory(executablePath);
|
||||||
{
|
|
||||||
//NOTE(martin): we assume we are running from the command line in debug mode
|
str8_list_push(scratch, &list, dirPath);
|
||||||
char* currentPath = getcwd(0, 0);
|
str8_list_push(scratch, &list, str8_lit("/"));
|
||||||
cwd = str8_push_cstring(arena, currentPath);
|
str8_list_push(scratch, &list, str8_push_cstring(scratch, name));
|
||||||
free(currentPath);
|
str8 path = str8_list_join(scratch, list);
|
||||||
}
|
char* pathCString = str8_to_cstring(scratch, path);
|
||||||
else
|
char* buffer = mem_arena_alloc_array(scratch, char, path.len+1);
|
||||||
{
|
char* real = realpath(pathCString, buffer);
|
||||||
NSString* nsName = [[NSString alloc] initWithUTF8String:name];
|
|
||||||
NSString* nsPath = [mainBundle executablePath];
|
|
||||||
const char* utf8Path = [nsPath UTF8String];
|
|
||||||
const char* dir = dirname((char*)utf8Path);
|
|
||||||
cwd = str8_push_cstring(arena, dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char* buffer = mem_arena_alloc_array(arena, char, cwd.len + strlen(name) + 2);
|
|
||||||
strncpy(buffer, cwd.ptr, cwd.len);
|
|
||||||
buffer[cwd.len] = '\0';
|
|
||||||
strcat(buffer, "/");
|
|
||||||
strcat(buffer, name);
|
|
||||||
char* real = realpath(buffer, 0);
|
|
||||||
|
|
||||||
str8 result = str8_push_cstring(arena, real);
|
str8 result = str8_push_cstring(arena, real);
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
src/ui.c
18
src/ui.c
|
@ -491,12 +491,20 @@ ui_box* ui_box_make_str8(str8 string, ui_flags flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: setup hierarchy
|
//NOTE: setup hierarchy
|
||||||
ListInit(&box->children);
|
if(box->frameCounter != ui->frameCounter)
|
||||||
box->parent = ui_box_top();
|
|
||||||
if(box->parent)
|
|
||||||
{
|
{
|
||||||
ListAppend(&box->parent->children, &box->listElt);
|
ListInit(&box->children);
|
||||||
box->parentClosed = box->parent->closed || box->parent->parentClosed;
|
box->parent = ui_box_top();
|
||||||
|
if(box->parent)
|
||||||
|
{
|
||||||
|
ListAppend(&box->parent->children, &box->listElt);
|
||||||
|
box->parentClosed = box->parent->closed || box->parent->parentClosed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//maybe this should be a warning that we're trying to make the box twice in the same frame?
|
||||||
|
LOG_WARNING("trying to make ui box '%.*s' multiple times in the same frame\n", (int)box->string.len, box->string.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: setup per-frame state
|
//NOTE: setup per-frame state
|
||||||
|
|
Loading…
Reference in New Issue