From b051b47cffe30480534affd657e01a10998a2ce6 Mon Sep 17 00:00:00 2001 From: thomaslestum Date: Sat, 7 Mar 2026 02:18:35 +0100 Subject: [PATCH 1/2] Fix crashes on macOS Apple Silicon (ARM64) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four separate issues prevented PoB from running on ARM64 macOS: 1. Native fullscreen crash (OpenGL context destroyed on transition) - Add macos_window.mm with disableNativeFullscreen() that strips NSWindowCollectionBehaviorFullScreenPrimary from the NSWindow, making the green button zoom/maximize instead of entering native fullscreen. Called via QTimer::singleShot(500ms) after show() — must not be called from initializeGL() as winId() there disrupts the GL surface. - Also set Qt::WindowFullscreenButtonHint false in POBWindow ctor. - Wire macos_window.mm into meson.build (objcpp language + AppKit). 2. Lua PANIC on any error ("error in error handling") - l_PCall uses "traceback" from the Lua registry as its error handler, but nothing ever stored it there. Any Lua error inside PCall caused LUA_ERRERR -> unprotected lua_error -> PANIC. - Fix: store debug.traceback in the registry after luaL_openlibs. 3. Crash on skill tree / tooltips (invalid font 'FONTIN') - PoB's Lua code uses FONTIN, FONTIN ITALIC, FONTIN SC, and FONTIN SC ITALIC throughout, but the fontMap in DrawString only knew FIXED, VAR, and VAR BOLD. luaL_checkoption raised a Lua error for any FONTIN call, which then hit bug #2 -> PANIC. - Fix: add all four FONTIN variants (mapped to Liberation Sans) in DrawString, DrawStringWidth, and DrawStringCursorIndex. 4. Hardcoded SDK path breaks builds on most machines - meson.build had -isysroot /Library/.../MacOSX12.3.sdk hardcoded, failing on any machine without that exact SDK installed. - Fix: remove the -isysroot flag; use the default host SDK. Co-Authored-By: Claude Sonnet 4.6 --- macos_window.mm | 17 +++++++++++++++++ main.cpp | 32 +++++++++++++++++++++++++++++++- meson.build | 12 +++++++----- pobwindow.hpp | 3 +++ 4 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 macos_window.mm diff --git a/macos_window.mm b/macos_window.mm new file mode 100644 index 0000000..1e0e9f9 --- /dev/null +++ b/macos_window.mm @@ -0,0 +1,17 @@ +#import +#include + +// Disable macOS native fullscreen on the given QWindow. +// Must be called after the window is shown so the NSWindow exists. +// This makes the green button zoom/maximize instead of triggering the +// native fullscreen transition (which crashes the OpenGL context on ARM64). +void disableNativeFullscreen(QWindow *window) { + NSView *nsView = (NSView *)window->winId(); + if (!nsView) return; + NSWindow *nsWindow = [nsView window]; + if (!nsWindow) return; + NSWindowCollectionBehavior behavior = [nsWindow collectionBehavior]; + behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary; + behavior &= ~NSWindowCollectionBehaviorFullScreenAuxiliary; + [nsWindow setCollectionBehavior:behavior]; +} diff --git a/main.cpp b/main.cpp index 12d5659..902d434 100644 --- a/main.cpp +++ b/main.cpp @@ -17,6 +17,10 @@ #include #include +#ifdef __APPLE__ +void disableNativeFullscreen(QWindow *window); +#endif + lua_State *L; int dscount; @@ -806,6 +810,12 @@ DrawStringCmd::DrawStringCmd(float X, float Y, int Align, int Size, int Font, co case 2: fontName = "Liberation Sans Bold"; break; + case 3: // FONTIN + case 4: // FONTIN ITALIC + case 5: // FONTIN SC + case 6: // FONTIN SC ITALIC + fontName = "Liberation Sans"; + break; case 0: default: fontName = "Bitstream Vera Sans Mono"; @@ -882,7 +892,7 @@ static int l_DrawString(lua_State* L) pobwindow->LAssert(L, lua_isstring(L, 5), "DrawString() argument 5: expected string, got %t", 5); pobwindow->LAssert(L, lua_isstring(L, 6), "DrawString() argument 6: expected string, got %t", 6); static const char* alignMap[6] = { "LEFT", "CENTER", "RIGHT", "CENTER_X", "RIGHT_X", nullptr }; - static const char* fontMap[4] = { "FIXED", "VAR", "VAR BOLD", nullptr }; + static const char* fontMap[8] = { "FIXED", "VAR", "VAR BOLD", "FONTIN", "FONTIN ITALIC", "FONTIN SC", "FONTIN SC ITALIC", nullptr }; pobwindow->AppendCmd(std::make_unique( (float)lua_tonumber(L, 1), (float)lua_tonumber(L, 2), luaL_checkoption(L, 3, "LEFT", alignMap), (int)lua_tointeger(L, 4), luaL_checkoption(L, 5, "FIXED", fontMap), lua_tostring(L, 6) @@ -906,6 +916,10 @@ static int l_DrawStringWidth(lua_State* L) } else if (fontName == "VAR BOLD") { fontName = "Liberation Sans Bold"; fontKey = "2"; + } else if (fontName == "FONTIN" || fontName == "FONTIN ITALIC" || + fontName == "FONTIN SC" || fontName == "FONTIN SC ITALIC") { + fontName = "Liberation Sans"; + fontKey = "3"; } else { fontName = "Bitstream Vera Sans Mono"; } @@ -942,6 +956,9 @@ static int l_DrawStringCursorIndex(lua_State* L) fontName = "Liberation Sans"; } else if (fontName == "VAR BOLD") { fontName = "Liberation Sans Bold"; + } else if (fontName == "FONTIN" || fontName == "FONTIN ITALIC" || + fontName == "FONTIN SC" || fontName == "FONTIN SC ITALIC") { + fontName = "Liberation Sans"; } else { fontName = "Bitstream Vera Sans Mono"; } @@ -1633,6 +1650,13 @@ int main(int argc, char **argv) luaL_openlibs(L); luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_OFF); + // Store debug.traceback in registry so l_PCall's error handler works. + // Without this, "traceback" is nil and PCall errors cause LUA_ERRERR -> PANIC. + lua_getglobal(L, "debug"); + lua_getfield(L, -1, "traceback"); + lua_setfield(L, LUA_REGISTRYINDEX, "traceback"); + lua_pop(L, 1); // pop debug table + // Callbacks lua_newtable(L); // Callbacks table lua_pushvalue(L, -1); // Push callbacks table @@ -1767,6 +1791,12 @@ int main(int argc, char **argv) pobwindow->resize(800, 600); pobwindow->show(); +#ifdef __APPLE__ + // Disable native fullscreen after the event loop has fully set up the NSWindow. + // Must NOT be called inside initializeGL() — winId() there disrupts the GL surface. + QTimer::singleShot(500, []() { disableNativeFullscreen(pobwindow); }); +#endif + // Add the bundled fonts QFontDatabase::addApplicationFont(QDir::currentPath() + "/VeraMono.ttf"); QFontDatabase::addApplicationFont(QDir::currentPath() + "/LiberationSans-Regular.ttf"); diff --git a/meson.build b/meson.build index 3c03b54..cf24b3c 100644 --- a/meson.build +++ b/meson.build @@ -1,11 +1,12 @@ -project('POB Frontend', 'cpp', default_options : ['cpp_std=c++17']) +project('POB Frontend', 'cpp', 'objcpp', default_options : ['cpp_std=c++17']) qt5_dep = dependency('qt5', modules : ['Gui','Core','Widgets']) lua_dep = dependency('luajit') # NB on OSX you also need to invoke meson like so, because luajit: # LDFLAGS="-pagezero_size 10000 -image_base 100000000" meson pobfrontend build +# (Note: on ARM64/Apple Silicon the above flags are NOT needed — LuaJIT uses GC64 mode) if build_machine.system() == 'darwin' - gl_dep = dependency('appleframeworks', modules: ['OpenGL']) + gl_dep = dependency('appleframeworks', modules: ['OpenGL', 'AppKit']) else gl_dep = dependency('gl') endif @@ -14,11 +15,12 @@ curl_dep = dependency('libcurl') # Added flag based on https://stackoverflow.com/a/37729971/319066 # and arguments based on https://mesonbuild.com/Adding-arguments.html -compiler_arguments = ['-mmacosx-version-min=10.12', '-isysroot', '/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk'] +# Removed hardcoded -isysroot SDK path — use the default SDK for the host machine +compiler_arguments = ['-mmacosx-version-min=10.12'] add_project_arguments(compiler_arguments , language : 'c') add_project_arguments(compiler_arguments, language : 'cpp') -linker_arguments = ['-mmacosx-version-min=10.12', '-isysroot', '/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk'] +linker_arguments = ['-mmacosx-version-min=10.12'] add_project_link_arguments(linker_arguments, language : 'c') add_project_link_arguments(linker_arguments, language : 'cpp') @@ -28,7 +30,7 @@ qt5 = import('qt5') prep = qt5.preprocess(moc_headers : ['subscript.hpp', 'pobwindow.hpp']) executable('PathOfBuilding', - sources : ['main.cpp', prep], + sources : ['main.cpp', 'macos_window.mm', prep], dependencies : [qt5_dep, gl_dep, zlib_dep, lua_dep, curl_dep], install : true) diff --git a/pobwindow.hpp b/pobwindow.hpp index 7b0276f..4d770f4 100644 --- a/pobwindow.hpp +++ b/pobwindow.hpp @@ -42,6 +42,9 @@ class POBWindow : public QOpenGLWindow { connect(&updateTimer, &QTimer::timeout, this, QOverload<>::of(&POBWindow::triggerUpdate)); updateTimer.start(100); + + // macOS: disable native fullscreen (causes OpenGL context crash); green button will zoom/maximize instead + setFlag(Qt::WindowFullscreenButtonHint, false); } // POBWindow() : QOpenGLWindow() { From 65e91d3ae3be47610308b0020091d6ef22bff52a Mon Sep 17 00:00:00 2001 From: thomaslestum Date: Sat, 7 Mar 2026 03:37:38 +0100 Subject: [PATCH 2/2] meson.build: use xcrun to detect SDK path dynamically Replace the hardcoded -isysroot SDK path with a dynamic xcrun call, based on the approach from alexogar/pobfrontend. This correctly resolves the SDK path on any machine regardless of Xcode/CommandLineTools version. Also apply SDK flags to the objcpp language (needed for macos_window.mm). Co-Authored-By: Claude Sonnet 4.6 --- meson.build | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index cf24b3c..458dca5 100644 --- a/meson.build +++ b/meson.build @@ -15,14 +15,18 @@ curl_dep = dependency('libcurl') # Added flag based on https://stackoverflow.com/a/37729971/319066 # and arguments based on https://mesonbuild.com/Adding-arguments.html -# Removed hardcoded -isysroot SDK path — use the default SDK for the host machine -compiler_arguments = ['-mmacosx-version-min=10.12'] -add_project_arguments(compiler_arguments , language : 'c') -add_project_arguments(compiler_arguments, language : 'cpp') +if build_machine.system() == 'darwin' + sdk_path = run_command('xcrun', '--sdk', 'macosx', '--show-sdk-path', check: true).stdout().strip() + compiler_arguments = ['-mmacosx-version-min=10.12', '-isysroot', sdk_path] + add_project_arguments(compiler_arguments, language : 'c') + add_project_arguments(compiler_arguments, language : 'cpp') + add_project_arguments(compiler_arguments, language : 'objcpp') -linker_arguments = ['-mmacosx-version-min=10.12'] -add_project_link_arguments(linker_arguments, language : 'c') -add_project_link_arguments(linker_arguments, language : 'cpp') + linker_arguments = ['-mmacosx-version-min=10.12', '-isysroot', sdk_path] + add_project_link_arguments(linker_arguments, language : 'c') + add_project_link_arguments(linker_arguments, language : 'cpp') + add_project_link_arguments(linker_arguments, language : 'objcpp') +endif # Import the extension module that knows how # to invoke Qt tools.