Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,9 @@ endif ()

if (APPLE AND NOT IOS AND NOT TVOS)
find_library(APPKIT_FRAMEWORK AppKit REQUIRED)
target_sources(dusklight PRIVATE src/dusk/file_select_macos.mm)
target_sources(dusklight PRIVATE src/dusk/file_select_macos.mm src/dusk/macos_menu.mm)
set_source_files_properties(src/dusk/file_select_macos.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
set_source_files_properties(src/dusk/macos_menu.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
target_link_libraries(dusklight PRIVATE ${APPKIT_FRAMEWORK})
endif ()

Expand Down
13 changes: 13 additions & 0 deletions src/dusk/macos_menu.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

// Only include this header on macOS
#if defined(__APPLE__) && !TARGET_OS_IOS && !TARGET_OS_TV && !TARGET_OS_MACCATALYST

namespace dusk {

// App menu actions (e.g., "Open Data Folder..." in the app name menu)
void InstallMacOSAppMenuActions();

} // namespace dusk

#endif
60 changes: 60 additions & 0 deletions src/dusk/macos_menu.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "macos_menu.hpp"

#include "dusk/data.hpp"

#import <AppKit/AppKit.h>

@interface DuskAppMenuTarget : NSObject
- (void)openDataFolder:(id)sender;
@end

@implementation DuskAppMenuTarget
- (void)openDataFolder:(id)sender {
(void)sender;
dusk::data::open_data_path();
}
@end

namespace dusk {
namespace {

DuskAppMenuTarget *shared_app_menu_target() {
static DuskAppMenuTarget *target = [DuskAppMenuTarget new];
return target;
}

} // namespace

void InstallMacOSAppMenuActions() {
NSMenu *mainMenu = [NSApp mainMenu];
if (mainMenu == nil || [mainMenu numberOfItems] == 0) {
return;
}

NSMenu *appMenu = [[mainMenu itemAtIndex:0] submenu];
if (appMenu == nil) {
return;
}

if ([appMenu itemWithTitle:@"Open Data Folder..."] != nil) {
return;
}

NSUInteger insertIndex = [appMenu numberOfItems];

for (NSMenuItem *existingItem in [appMenu itemArray]) {
if ([existingItem action] == @selector(terminate:)) {
insertIndex = [appMenu indexOfItem:existingItem];
break;
}
}

NSMenuItem *item =
[[NSMenuItem alloc] initWithTitle:@"Open Data Folder..."
action:@selector(openDataFolder:)
keyEquivalent:@""];

[item setTarget:shared_app_menu_target()];
[appMenu insertItem:item atIndex:insertIndex];
}
} // namespace dusk
6 changes: 6 additions & 0 deletions src/m_Do/m_Do_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
#include "tracy/Tracy.hpp"
#include <RmlUi/Core.h>
#ifdef __APPLE__
#include "dusk/macos_menu.hpp"
#include <TargetConditionals.h>
#endif

Expand Down Expand Up @@ -590,6 +591,11 @@ int game_main(int argc, char* argv[]) {
auroraInfo = aurora_initialize(argc, argv, &config);
}

#if defined(__APPLE__) && !TARGET_OS_IOS && !TARGET_OS_TV && !TARGET_OS_MACCATALYST
// macOS specific app menu actions
dusk::InstallMacOSAppMenuActions();
#endif

#ifdef DUSK_DISCORD
if (dusk::getSettings().game.enableDiscordPresence) {
dusk::discord::initialize();
Expand Down
Loading