diff --git a/CMakeLists.txt b/CMakeLists.txt index ea056830a..148efc8a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ endif() if(${BUILD_ENGINE}) add_subdirectory(src/engine) endif() -if(UNIX) +if(UNIX AND NOT APPLE) option(BUILD_TESTING "Don't build gperftools tests" OFF) add_subdirectory(src/gperftools) endif() diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 1c8ae10c4..d3a774c25 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -37,6 +37,10 @@ if(${LINUX_DEPLOY}) endif() option(USE_SKIA_SYSTEM_LIBS "Use skia (third-party) system libraries on Linux" ON) +if(APPLE) + set(USE_SKIA_SYSTEM_LIBS OFF) +endif() + if(${USE_SKIA_SYSTEM_LIBS} AND UNIX) pkg_check_modules(EXPAT REQUIRED expat) pkg_check_modules(FREETYPE REQUIRED freetype2) @@ -54,7 +58,7 @@ endif() if(APPLE) set(ICON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/icons/${PROJECT_NAME}.icns) - set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) + set(MACOSX_BUNDLE_BUNDLE_NAME "Friction") set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) set(MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION}) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") diff --git a/src/app/GUI/mainwindow.cpp b/src/app/GUI/mainwindow.cpp index efc377713..2ddc3f724 100644 --- a/src/app/GUI/mainwindow.cpp +++ b/src/app/GUI/mainwindow.cpp @@ -1045,13 +1045,19 @@ void MainWindow::setupMenuBar() }); help->addSeparator(); + + QString cmdDefKey = "Ctrl+Space"; +#ifdef Q_OS_MAC + cmdDefKey = "Alt+Space"; +#endif + help->addAction(QIcon::fromTheme("cmd"), tr("Command Palette"), this, [this]() { CommandPalette dialog(mDocument, this); dialog.exec(); }, QKeySequence(AppSupport::getSettings("shortcuts", "cmdPalette", - "Ctrl+Space").toString())); + cmdDefKey).toString())); help->addSeparator(); help->addAction(QIcon::fromTheme("renderlayers"), @@ -1075,6 +1081,7 @@ void MainWindow::setupMenuBar() setMenuBar(mMenuBar); +#ifndef Q_OS_MAC const auto frictionButton = new QPushButton(this); frictionButton->setFlat(true); frictionButton->setIcon(QIcon::fromTheme(AppSupport::getAppID())); @@ -1086,6 +1093,7 @@ void MainWindow::setupMenuBar() mMenuBar->setCornerWidget(frictionButton, Qt::TopRightCorner); +#endif } BoundingBox *MainWindow::getCurrentBox() @@ -1325,8 +1333,11 @@ void MainWindow::setupToolBar() mToolbar->setFocusPolicy(Qt::NoFocus); mToolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mToolbar->setMovable(false); +#ifdef Q_OS_MAC + mToolbar->setStyleSheet(QString("font-size: %1pt;").arg(font().pointSize())); +#endif eSizesUI::widget.add(mToolbar, [this](const int size) { - mToolbar->setIconSize(QSize(size, size)); + mToolbar->setIconSize({size, size}); }); addToolBar(Qt::TopToolBarArea, mToolbar); } diff --git a/src/app/memorychecker.cpp b/src/app/memorychecker.cpp index fb8bfb8bd..4514fcd9d 100644 --- a/src/app/memorychecker.cpp +++ b/src/app/memorychecker.cpp @@ -29,9 +29,9 @@ #if defined(Q_OS_WIN) #include "windowsincludes.h" #elif defined(Q_OS_UNIX) - #include "gperftools/tcmalloc.h" - #include "../gperftools/include/gperftools/malloc_extension.h" #if defined(Q_OS_LINUX) + #include "gperftools/tcmalloc.h" + #include "../gperftools/include/gperftools/malloc_extension.h" #include #include #elif defined(Q_OS_MACOS) @@ -39,6 +39,9 @@ #include #include #include + #include + #include + #include #endif #endif @@ -62,12 +65,14 @@ MemoryChecker::MemoryChecker(QObject * const parent) : QObject(parent) { char MemoryChecker::sLine[256]; -void MemoryChecker::sGetFreeKB(intKB& procFreeKB, intKB& sysFreeKB) { +void MemoryChecker::sGetFreeKB(intKB& procFreeKB, intKB& sysFreeKB) +{ const auto usageCap = eSettings::sInstance->fRamMBCap; longB enveUsedB(0); qint64 freeInternal = 0; intKB freeExternal(0); + #if defined(Q_OS_WIN) const auto processID = GetCurrentProcessId(); const auto hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, @@ -86,53 +91,54 @@ void MemoryChecker::sGetFreeKB(intKB& procFreeKB, intKB& sysFreeKB) { const longB availPhysB(statex.ullAvailPhys); freeExternal = intKB(availPhysB); #elif defined(Q_OS_UNIX) - // qDebug() << ""; - size_t virtual_memory_used; - size_t physical_memory_used; - size_t bytes_in_use_by_app; + size_t physical_memory_used = 0; + size_t bytes_in_use_by_app = 0; +#if defined(Q_OS_LINUX) + size_t virtual_memory_used = 0; MallocExtension::instance()->eMemoryStats(&virtual_memory_used, &physical_memory_used, &bytes_in_use_by_app); -// qDebug() << "virtual_memory_used" << intMB(longB(virtual_memory_used)).fValue; -// qDebug() << "physical_memory_used" << intMB(longB(physical_memory_used)).fValue; -// qDebug() << "bytes_in_use_by_app" << intMB(longB(bytes_in_use_by_app)).fValue; +#elif defined(Q_OS_MACOS) + struct mach_task_basic_info info; + mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; + if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, + (task_info_t)&info, &infoCount ) == KERN_SUCCESS ) { + bytes_in_use_by_app = info.resident_size; + } +#endif +#endif enveUsedB = longB(static_cast(bytes_in_use_by_app)); freeInternal = physical_memory_used - bytes_in_use_by_app; - #if defined(Q_OS_LINUX) +#if defined(Q_OS_LINUX) int found = 0; FILE * const meminfo = fopen("/proc/meminfo", "r"); - if(!meminfo) RuntimeThrow("Failed to open /proc/meminfo"); + if (!meminfo) { RuntimeThrow("Failed to open /proc/meminfo"); } while(fgets(sLine, sizeof(sLine), meminfo)) { int ramPartKB; - if(sscanf(sLine, "MemFree: %d kB", &ramPartKB) == 1) { - // qDebug() << "MemFree" << intMB(intKB(ramPartKB)).fValue; + if (sscanf(sLine, "MemFree: %d kB", &ramPartKB) == 1) { } else if(sscanf(sLine, "Cached: %d kB", &ramPartKB) == 1) { - // qDebug() << "Cached" << intMB(intKB(ramPartKB)).fValue; } else if(sscanf(sLine, "Buffers: %d kB", &ramPartKB) == 1) { - // qDebug() << "Buffers" << intMB(intKB(ramPartKB)).fValue; - } else continue; + } else { continue; } freeExternal.fValue += ramPartKB; if(++found == 3) break; } fclose(meminfo); if(found != 3) RuntimeThrow("Entries missing from /proc/meminfo"); - #elif defined(Q_OS_MACOS) +#elif defined(Q_OS_MACOS) mach_msg_type_number_t count = HOST_VM_INFO_COUNT; vm_statistics_data_t vmstat; const auto ret = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count); - if(ret != KERN_SUCCESS) RuntimeThrow("Could not retrieve memory usage"); - // auto total = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count; + if (ret != KERN_SUCCESS) { RuntimeThrow("Could not retrieve memory usage"); } const int pageSize = 4; - freeExternal.fValue += vmstat.inactive_count * 4; - freeExternal.fValue += vmstat.free_count * 4; - #endif + freeExternal.fValue += vmstat.inactive_count * pageSize; + freeExternal.fValue += vmstat.free_count * pageSize; #endif const intKB enveUsedKB(enveUsedB); - if(usageCap.fValue > 0) { + if (usageCap.fValue > 0) { procFreeKB = intKB(usageCap) - enveUsedKB; } else { procFreeKB = HardwareInfo::sRamKB() - enveUsedKB; @@ -140,17 +146,12 @@ void MemoryChecker::sGetFreeKB(intKB& procFreeKB, intKB& sysFreeKB) { sysFreeKB = intKB(longB(freeInternal)) + freeExternal; -// qDebug() << "free" << intMB(sysFreeKB).fValue; -// qDebug() << "usage" << 100 - 100*sysFreeKB.fValue/HardwareInfo::sRamKB().fValue; +#if defined(Q_OS_LINUX) const qint64 releaseBytes = 500L*1024L*1024L; - if(freeInternal > releaseBytes) { -#if defined(Q_OS_WIN) - -#elif defined(Q_OS_UNIX) - MallocExtension::instance()->ReleaseToSystem(releaseBytes); -// qDebug() << "released"; -#endif + if (freeInternal > releaseBytes) { + MallocExtension::instance()->ReleaseToSystem(releaseBytes); } +#endif } void MemoryChecker::checkMemory() { diff --git a/src/cmake/friction-common.cmake b/src/cmake/friction-common.cmake index 3acf0cee7..94ea047a1 100644 --- a/src/cmake/friction-common.cmake +++ b/src/cmake/friction-common.cmake @@ -37,10 +37,12 @@ if(${WIN_DEPLOY}) add_definitions(-DWIN_DEPLOY) endif() -if(UNIX AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - message(FATAL_ERROR "Only Clang is supported.") -elseif(WIN32 AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - message(FATAL_ERROR "Only MSVC is supported.") +if(NOT APPLE) + if(UNIX AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Only Clang is supported.") + elseif(WIN32 AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + message(FATAL_ERROR "Only MSVC is supported.") + endif() endif() if(UNIX) diff --git a/src/core/appsupport.cpp b/src/core/appsupport.cpp index 95abbf9d2..ccd8b8939 100644 --- a/src/core/appsupport.cpp +++ b/src/core/appsupport.cpp @@ -1001,8 +1001,9 @@ void AppSupport::checkFFmpeg(const bool &isRenderer) void AppSupport::initEnv(const bool &isRenderer) { +#if defined(Q_OS_WIN) + Q_UNUSED(isRenderer) // windows theme integration -#ifdef Q_OS_WIN #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) // Set window title bar color based on dark/light theme // https://www.qt.io/blog/dark-mode-on-windows-11-with-qt-6.5 @@ -1011,12 +1012,14 @@ void AppSupport::initEnv(const bool &isRenderer) QSettings::NativeFormat); if (registry.value("AppsUseLightTheme", 0).toInt() == 0) { qputenv("QT_QPA_PLATFORM", "windows:darkmode=1"); } #endif -#else +#elif defined(Q_OS_LINUX) if (isRenderer) { // Force Mesa if Renderer qputenv("LIBGL_ALWAYS_SOFTWARE", "1"); } // Force XCB on Linux until we support Wayland qputenv("QT_QPA_PLATFORM", isRenderer ? "offscreen" : "xcb"); +#else + Q_UNUSED(isRenderer) #endif } diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index 5228e6a09..a2f6fb69b 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -31,6 +31,10 @@ option(SYNC_SKIA_DEPS "Sync third-party depends" ON) set(SKIA_SRC "${CMAKE_CURRENT_SOURCE_DIR}/skia") set(SKIA_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/skia") +if(APPLE) + set(USE_SKIA_SYSTEM_LIBS OFF) +endif() + if(${USE_SKIA_SYSTEM_LIBS} AND UNIX) set(SKIA_ENABLE_EXTERNAL "true") else() @@ -71,6 +75,11 @@ else() else() set(SKIA_ARGS "${SKIA_ARGS} extra_cflags=[\"-Wno-error\", \"-Wno-psabi\"]") endif() + if(APPLE) + set(GN_PATH ${SKIA_SRC}/bin/gn.bin) + set(SKIA_UPDATE_CMD python3 "tools/git-sync-deps") + set(SKIA_ARGS "${SKIA_ARGS} extra_cflags_cc=[\"-frtti\"]") + endif() endif() set(SKIA_ARGS "${SKIA_ARGS} is_official_build=true is_debug=false") @@ -87,6 +96,9 @@ endif() if(UNIX AND NOT APPLE) set(SKIA_ARGS "${SKIA_ARGS} skia_use_system_freetype2=${SKIA_ENABLE_EXTERNAL}") endif() +if(APPLE) + set(SKIA_ARGS "${SKIA_ARGS} skia_use_libgifcodec=false") +endif() message("-- skia args: ${SKIA_ARGS}") diff --git a/src/engine/skia b/src/engine/skia index 3d55448fe..e4dfe1480 160000 --- a/src/engine/skia +++ b/src/engine/skia @@ -1 +1 @@ -Subproject commit 3d55448feb27f949b19d4a3809e40ecf3bb5532a +Subproject commit e4dfe1480dd3388be77907bb198de9d3cb39f63b diff --git a/src/ui/widgets/canvastoolbar.cpp b/src/ui/widgets/canvastoolbar.cpp index 44e3f734c..0b2a98423 100644 --- a/src/ui/widgets/canvastoolbar.cpp +++ b/src/ui/widgets/canvastoolbar.cpp @@ -46,6 +46,9 @@ CanvasToolBar::CanvasToolBar(QWidget *parent) setWindowTitle(tr("Canvas Toolbar")); setObjectName("CanvasToolBar"); setToolButtonStyle(Qt::ToolButtonTextBesideIcon); +#ifdef Q_OS_MAC + setStyleSheet(QString("font-size: %1pt;").arg(font().pointSize())); +#endif { const auto space = new QWidget(this); diff --git a/src/ui/widgets/colortoolbar.cpp b/src/ui/widgets/colortoolbar.cpp index 534ff116f..388a5ca1e 100644 --- a/src/ui/widgets/colortoolbar.cpp +++ b/src/ui/widgets/colortoolbar.cpp @@ -43,6 +43,9 @@ ColorToolBar::ColorToolBar(Document &document, setWindowTitle(tr("Color Toolbar")); setObjectName("ColorToolBar"); setToolButtonStyle(Qt::ToolButtonTextBesideIcon); +#ifdef Q_OS_MAC + setStyleSheet(QString("font-size: %1pt;").arg(font().pointSize())); +#endif setEnabled(false); setMovable(AppSupport::getSettings("ui", "ColorToolBarMovable",