macOS port: build, rendering, daemon, and mining fixes
Build & setup: - Fix setup.sh and build.sh for macOS (bundle daemon, xmrig, sapling params, asmap.dat into .app) - Fix CMakeLists.txt libsodium linking for macOS - Fix incbin.h to use __DATA,__const section on macOS - Remove vendored libsodium-1.0.18 source tree (use fetch script instead) - Remove prebuilt-binaries/xmrig (replaced by xmrig-hac) - Add .DS_Store to .gitignore Rendering & UI: - Use GLSL #version 150 and OpenGL 3.2 Core Profile on macOS - Force dpiScale=1.0 on macOS to fix Retina double-scaling - Set default window/UI opacity to 100% on Mac/Linux - Add scroll fade shader guard for macOS GL compatibility - Add ImGui error recovery around render loop and mining tab Daemon & bootstrap: - Fix getDragonXDataDir() to return ~/Library/Application Support/Hush/DRAGONX/ on macOS - Fix isPortInUse() with connect() fallback (no /proc/net/tcp on macOS) - Increase daemon watchdog timeout from 3s to 15s - Add daemon status indicator (colored dot + label) in wizard bootstrap phases Mining tab: - Fix EmbeddedDaemon::getMemoryUsageMB() crash on macOS (was using Linux /proc) - Fix XmrigManager::getMemoryUsageMB() to use ps on macOS instead of /proc - Restructure RenderMiningTab with wrapper pattern for exception safety - Fix default pool URL to include port (pool.dragonx.is:3433)
This commit is contained in:
49
src/main.cpp
49
src/main.cpp
@@ -663,12 +663,20 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
#else
|
||||
// OpenGL path (Linux)
|
||||
// OpenGL path (Linux / macOS)
|
||||
#ifdef __APPLE__
|
||||
// macOS requires GL 3.2 Core Profile + GLSL 150
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
#else
|
||||
// GL 3.0 + GLSL 130
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
#endif
|
||||
|
||||
// Create window with graphics context
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
@@ -795,6 +803,10 @@ int main(int argc, char* argv[])
|
||||
|
||||
// If we're starting on a HiDPI display, scale the window so the UI
|
||||
// appears the same physical size as on a 100% display.
|
||||
// On macOS with HIGH_PIXEL_DENSITY, window sizes are already in logical
|
||||
// (point) coordinates and the framebuffer handles pixel density, so
|
||||
// we must NOT multiply the window size by the content scale.
|
||||
#ifndef __APPLE__
|
||||
if (currentDpiScale > 1.01f) {
|
||||
int curW = 0, curH = 0;
|
||||
SDL_GetWindowSize(window, &curW, &curH);
|
||||
@@ -819,6 +831,7 @@ int main(int argc, char* argv[])
|
||||
DEBUG_LOGF("HiDPI startup: window resized %dx%d -> %dx%d (scale %.2f)\n",
|
||||
curW, curH, newW, newH, currentDpiScale);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create application instance
|
||||
dragonx::App app;
|
||||
@@ -1104,6 +1117,9 @@ int main(int argc, char* argv[])
|
||||
waitEvent.window.windowID == SDL_GetWindowID(window)) {
|
||||
float actualScale = SDL_GetWindowDisplayScale(window);
|
||||
float storedScale = dragonx::ui::material::Typography::instance().getDpiScale();
|
||||
#ifdef __APPLE__
|
||||
actualScale = storedScale; // macOS Retina: scales always match (both 1.0)
|
||||
#endif
|
||||
bool isDpiResize = dpiResizePending ||
|
||||
std::abs(actualScale - storedScale) > 0.01f;
|
||||
if (dpiResizePending) dpiResizePending = false;
|
||||
@@ -1124,6 +1140,9 @@ int main(int argc, char* argv[])
|
||||
waitEvent.window.windowID == SDL_GetWindowID(window)) {
|
||||
float newScale = SDL_GetWindowDisplayScale(window);
|
||||
if (newScale <= 0.0f) newScale = 1.0f;
|
||||
#ifdef __APPLE__
|
||||
newScale = 1.0f; // macOS handles Retina via DisplayFramebufferScale
|
||||
#endif
|
||||
auto& typo = dragonx::ui::material::Typography::instance();
|
||||
float oldScale = typo.getDpiScale();
|
||||
if (std::abs(newScale - oldScale) > 0.01f) {
|
||||
@@ -1266,6 +1285,9 @@ int main(int argc, char* argv[])
|
||||
event.window.windowID == SDL_GetWindowID(window)) {
|
||||
float actualScale = SDL_GetWindowDisplayScale(window);
|
||||
float storedScale = dragonx::ui::material::Typography::instance().getDpiScale();
|
||||
#ifdef __APPLE__
|
||||
actualScale = storedScale; // macOS Retina: scales always match (both 1.0)
|
||||
#endif
|
||||
bool isDpiResize = dpiResizePending ||
|
||||
std::abs(actualScale - storedScale) > 0.01f;
|
||||
if (dpiResizePending) dpiResizePending = false;
|
||||
@@ -1296,6 +1318,9 @@ int main(int argc, char* argv[])
|
||||
event.window.windowID == SDL_GetWindowID(window)) {
|
||||
float newScale = SDL_GetWindowDisplayScale(window);
|
||||
if (newScale <= 0.0f) newScale = 1.0f;
|
||||
#ifdef __APPLE__
|
||||
newScale = 1.0f; // macOS handles Retina via DisplayFramebufferScale
|
||||
#endif
|
||||
auto& typo = dragonx::ui::material::Typography::instance();
|
||||
float oldScale = typo.getDpiScale();
|
||||
if (std::abs(newScale - oldScale) > 0.01f) {
|
||||
@@ -1592,14 +1617,18 @@ int main(int argc, char* argv[])
|
||||
// inserted into the BackgroundDrawList above. It fires
|
||||
// during RenderDrawData() at exactly the right moment.
|
||||
|
||||
ImGuiErrorRecoveryState erState;
|
||||
ImGui::ErrorRecoveryStoreState(&erState);
|
||||
try {
|
||||
PERF_BEGIN(_perfRender);
|
||||
app.render();
|
||||
PERF_END("AppRender", _perfRender);
|
||||
} catch (const std::exception& e) {
|
||||
DEBUG_LOGF("[Main] app.render() threw: %s\n", e.what());
|
||||
ImGui::ErrorRecoveryTryToRecoverState(&erState);
|
||||
} catch (...) {
|
||||
DEBUG_LOGF("[Main] app.render() threw unknown exception\n");
|
||||
ImGui::ErrorRecoveryTryToRecoverState(&erState);
|
||||
}
|
||||
|
||||
// Draw shutdown overlay on top of everything when shutting down
|
||||
@@ -1802,10 +1831,12 @@ int main(int argc, char* argv[])
|
||||
|
||||
// Watchdog: if cleanup takes too long the process lingers without a
|
||||
// window, showing up as a "Background Service" in Task Manager.
|
||||
// Force-exit after 3 seconds — all critical state (settings, daemon
|
||||
// Force-exit after timeout — all critical state (settings, daemon
|
||||
// stop) was handled in beginShutdown().
|
||||
// Allow enough time for the daemon to shut down gracefully (up to
|
||||
// 10s in stop()) plus RPC disconnect overhead.
|
||||
std::thread([]() {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(15));
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
_Exit(0);
|
||||
@@ -1932,11 +1963,23 @@ static bool InitImGui(SDL_Window* window, SDL_GLContext gl_context)
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL3_InitForOpenGL(window, gl_context);
|
||||
#ifdef __APPLE__
|
||||
ImGui_ImplOpenGL3_Init("#version 150");
|
||||
#else
|
||||
ImGui_ImplOpenGL3_Init("#version 130");
|
||||
#endif
|
||||
|
||||
// Query display DPI scale (e.g. 1.5 for 150% scaling)
|
||||
float dpiScale = SDL_GetWindowDisplayScale(window);
|
||||
if (dpiScale <= 0.0f) dpiScale = 1.0f;
|
||||
#ifdef __APPLE__
|
||||
// On macOS with SDL_WINDOW_HIGH_PIXEL_DENSITY, ImGui handles Retina
|
||||
// resolution automatically via io.DisplayFramebufferScale. Window
|
||||
// coordinates are already in logical points, so we must NOT also
|
||||
// scale fonts and style sizes by the content scale — that would
|
||||
// double everything.
|
||||
dpiScale = 1.0f;
|
||||
#endif
|
||||
DEBUG_LOGF("Display scale: %.2f\n", dpiScale);
|
||||
|
||||
// Load Material Design typography system with DPI awareness
|
||||
|
||||
Reference in New Issue
Block a user