diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 07e23ff92..90ee2fb87 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -243,7 +243,7 @@ jobs: uses: actions/cache@v5 with: path: qt_wasm_lite - key: ${{ matrix.config }}_qt-${{ env.QT_VERSION }}_emcc-${{ env.WEBASSEMBLY_VERSION }}_qtpositioning + key: ${{ matrix.config }}_qt-${{ env.QT_VERSION }}_emcc-${{ env.WEBASSEMBLY_VERSION }}_qtpositioning_${{ hashFiles('misc/qt_lite.txt', 'misc/qt_68_qtbase_remove_dejavu_fonts.patch') }} - name: Download and patch Qt if: steps.qt-cache.outputs.cache-hit != 'true' @@ -255,6 +255,9 @@ jobs: $QT_SRC_CONFIGURE -qt-host-path $QT_ROOT_DIR -platform wasm-emscripten -init-submodules -submodules qtdeclarative,qtbase,qtpositioning -skip qtlanguageserver,qtquicktimeline,qtimageformats cd ${{github.workspace}}/qt_src/qtbase git apply ${{github.workspace}}/misc/qt_68_qtbase_remove_dejavu_fonts.patch + cd ${{ github.workspace }} + rm -rf qt_wasm_build + mkdir qt_wasm_build - name: Build Qt for Webassembly (custom version) diff --git a/.gitignore b/.gitignore index 10388004f..9db9daf94 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /doc /build/* /.qtcreator/CMakeLists.txt.user +**/.qmlls.ini diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ff0e6b33..d3dcef8b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,11 @@ option(ALP_ENABLE_AVLANCHE_WARNING_LAYER "Enables avalanche warning layer (requi option(ALP_ENABLE_LABELS "Enables label rendering" ON) set(ALP_EXTERN_DIR "extern" CACHE STRING "name of the directory to store external libraries, fonts etc..") +set(ALP_ANDROID_MIN_SDK_VERSION 28 CACHE STRING "minimum Android API level") +set(ALP_ANDROID_TARGET_SDK_VERSION 36 CACHE STRING "target Android API level") +set(ALP_ANDROID_COMPILE_SDK_VERSION 36 CACHE STRING "compile Android API level") + +include(cmake/alp_configure_target.cmake) if(ALP_ENABLE_TRACK_OBJECT_LIFECYCLE) add_definitions(-DALP_ENABLE_TRACK_OBJECT_LIFECYCLE) diff --git a/README.md b/README.md index fab11962d..ad0ab309a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ After that it should be a normal cmake project. That is, you run cmake to genera We use Qt Creator (with mingw on Windows), which is the only tested setup atm and makes setup of Android and WebAssembly builds reasonably easy. If you have questions, please go to Discord. ## Dependencies -* Qt 6.8.0, or greater +* Qt 6.11.1, or greater * g++ 12+, clang or msvc * OpenGL * Qt Positioning and Charts modules diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index ff072bc3a..d75aa6eb3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -129,6 +129,7 @@ set_target_properties(alpineapp PROPERTIES QT_ANDROID_VERSION_CODE "${ALP_VERSION_INTEGER}" ) target_link_libraries(alpineapp PUBLIC gl_engine Qt::Quick Qt::QuickControls2) +alp_configure_target(alpineapp) if (ALP_ENABLE_QML_HOT_RELOAD) message(WARNING "building alpine app with qml-hot-reload. It'll slow incremental building due to a fix for hotreload.") @@ -178,11 +179,6 @@ else() endif() if (ANDROID) - set_target_properties(alpineapp PROPERTIES - QT_ANDROID_COMPILE_SDK_VERSION "36" - QT_ANDROID_TARGET_SDK_VERSION "35" - ) - add_android_openssl_libraries(alpineapp) find_package(Qt6 REQUIRED COMPONENTS Widgets) # for QFileDialogue (adding tracks) target_link_libraries(alpineapp PUBLIC Qt::Widgets) @@ -195,17 +191,18 @@ endif() if (EMSCRIPTEN) target_link_options(alpineapp PUBLIC -sASYNCIFY) - set(ALP_INSTALL_FILES - "$/alpineapp.js" - "$/alpineapp.wasm" - "$/alpineapp.html" - "$/qtloader.js" + install( + FILES + "$/alpineapp.js" + "$/alpineapp.wasm" + "$/alpineapp.html" + "$/qtloader.js" + DESTINATION + ${ALP_WWW_INSTALL_DIR}) + install(FILES "$/alpineapp.worker.js" + DESTINATION ${ALP_WWW_INSTALL_DIR} + OPTIONAL ) - - if (ALP_ENABLE_THREADING) - list(APPEND ALP_INSTALL_FILES "$/alpineapp.worker.js") - endif() - install(FILES ${ALP_INSTALL_FILES} DESTINATION ${ALP_WWW_INSTALL_DIR}) else() find_package(Qt6 REQUIRED COMPONENTS Widgets) target_link_libraries(alpineapp PUBLIC Qt::Widgets) diff --git a/app/GnssInformation.cpp b/app/GnssInformation.cpp index 0492f3468..caf65769e 100644 --- a/app/GnssInformation.cpp +++ b/app/GnssInformation.cpp @@ -75,6 +75,11 @@ QDateTime GnssInformation::timestamp() const void GnssInformation::position_updated(const QGeoPositionInfo& position) { #ifdef ALP_ENABLE_GNSS + if (!position.coordinate().isValid()) { + qDebug() << "GnssInformation: Ignoring invalid position update"; + return; + } + m_latitude = position.coordinate().latitude(); m_longitude = position.coordinate().longitude(); m_altitude = position.coordinate().altitude(); @@ -86,6 +91,21 @@ void GnssInformation::position_updated(const QGeoPositionInfo& position) #endif } +void GnssInformation::start_position_updates() +{ +#ifdef ALP_ENABLE_GNSS + if (!m_position_source) + return; + + m_position_source->startUpdates(); + + int timeout_ms = m_position_source->minimumUpdateInterval(); + if (timeout_ms < 10000) + timeout_ms = 10000; + m_position_source->requestUpdate(timeout_ms); +#endif +} + bool GnssInformation::enabled() const { return m_enabled; @@ -93,8 +113,20 @@ bool GnssInformation::enabled() const void GnssInformation::set_enabled(bool new_enabled) { + qDebug("GnssInformation::set_enabled(%s)", new_enabled ? "true" : "false"); if (m_enabled == new_enabled) return; + +#ifdef ALP_ENABLE_GNSS + if (new_enabled && !m_position_source) { + qDebug("GnssInformation: Cannot enable without QGeoPositionInfoSource"); + return; + } +#else + if (new_enabled) + return; +#endif + m_enabled = new_enabled; #ifdef ALP_ENABLE_GNSS if (m_enabled) { @@ -107,11 +139,12 @@ void GnssInformation::set_enabled(bool new_enabled) qApp->requestPermission(gnssPermission, this, [this](const QPermission& permission) { qDebug() << "qApp->requestPermission" << permission; if (permission.status() == Qt::PermissionStatus::Granted) { - m_position_source->startUpdates(); + start_position_updates(); } else { set_enabled(false); } }); + emit enabled_changed(); return; case Qt::PermissionStatus::Denied: qDebug() << "Qt::PermissionStatus::Denied"; @@ -119,7 +152,7 @@ void GnssInformation::set_enabled(bool new_enabled) return; case Qt::PermissionStatus::Granted: qDebug() << "Qt::PermissionStatus::Granted"; - m_position_source->startUpdates(); + start_position_updates(); } } else { m_position_source->stopUpdates(); diff --git a/app/GnssInformation.h b/app/GnssInformation.h index c07b334b2..db7c6a01c 100644 --- a/app/GnssInformation.h +++ b/app/GnssInformation.h @@ -49,6 +49,7 @@ class GnssInformation : public QQuickItem { private: void position_updated(const QGeoPositionInfo& position); + void start_position_updates(); private: double m_latitude = 0; diff --git a/cmake/alp_add_unittest.cmake b/cmake/alp_add_unittest.cmake index 1cdcbfaa7..557f20965 100644 --- a/cmake/alp_add_unittest.cmake +++ b/cmake/alp_add_unittest.cmake @@ -37,21 +37,24 @@ function(alp_add_unittest name) FILES ${alpineapp_fonts_SOURCE_DIR}/Roboto/Roboto-Regular.ttf ) - set(ALP_INSTALL_FILES - "$/${name}.js" - "$/${name}.wasm" - "$/${name}.html" - "$/qtloader.js" + install( + FILES + "$/${name}.js" + "$/${name}.wasm" + "$/${name}.html" + "$/qtloader.js" + DESTINATION + ${ALP_WWW_INSTALL_DIR}) + install( + FILES "$/${name}.worker.js" + DESTINATION ${ALP_WWW_INSTALL_DIR} + OPTIONAL ) - - if (ALP_ENABLE_THREADING) - list(APPEND ALP_INSTALL_FILES "$/${name}.worker.js") - endif() - install(FILES ${ALP_INSTALL_FILES} DESTINATION ${ALP_WWW_INSTALL_DIR}) elseif(ANDROID) add_qml_catch2_console_unittests(${name} ${ARGN}) else() qt_add_executable(${name} ${ARGN} ${CMAKE_SOURCE_DIR}/unittests/main.cpp) target_link_libraries(${name} PUBLIC Catch2::Catch2) endif() + alp_configure_target(${name}) endfunction() diff --git a/cmake/alp_configure_target.cmake b/cmake/alp_configure_target.cmake new file mode 100644 index 000000000..e6477af6d --- /dev/null +++ b/cmake/alp_configure_target.cmake @@ -0,0 +1,9 @@ +function(alp_configure_target target_name) + if (ANDROID) + set_target_properties(${target_name} PROPERTIES + QT_ANDROID_MIN_SDK_VERSION "${ALP_ANDROID_MIN_SDK_VERSION}" + QT_ANDROID_TARGET_SDK_VERSION "${ALP_ANDROID_TARGET_SDK_VERSION}" + QT_ANDROID_COMPILE_SDK_VERSION "${ALP_ANDROID_COMPILE_SDK_VERSION}" + ) + endif() +endfunction() diff --git a/misc/qt_lite.txt b/misc/qt_lite.txt index 7d75fd176..f1e821195 100644 --- a/misc/qt_lite.txt +++ b/misc/qt_lite.txt @@ -1,5 +1,5 @@ -static -reduce-exports -gc-binaries --disable-deprecated-up-to 0x070000 +-disable-deprecated-up-to 0x060000 -no-dbus -no-sql-sqlite -no-widgets @@ -50,14 +50,12 @@ -no-feature-imageformat_xbm -no-feature-sql-sqlite -no-feature-jpeg --no-feature-tiff -no-feature-ico -no-feature-gif -no-feature-qml-jit -no-feature-quickcontrols2-fluentwinui3 -no-feature-qml-profiler -no-feature-dom --no-feature-webp -no-feature-dbus -no-feature-quickcontrols2-fluentwinui3 -no-feature-stack_protector diff --git a/plain_renderer/CMakeLists.txt b/plain_renderer/CMakeLists.txt index d6c7acf42..8ef70f152 100644 --- a/plain_renderer/CMakeLists.txt +++ b/plain_renderer/CMakeLists.txt @@ -29,20 +29,27 @@ set_target_properties(plain_renderer PROPERTIES target_link_libraries(plain_renderer PUBLIC gl_engine) target_include_directories(plain_renderer PRIVATE .) +alp_configure_target(plain_renderer) if (EMSCRIPTEN) message(NOTICE "ALP_WWW_INSTALL_DIR = ${ALP_WWW_INSTALL_DIR}") configure_file(../site/mascot.png mascot.png COPYONLY) set(ALP_INSTALL_FILES - "$/plain_renderer.js" - "$/plain_renderer.wasm" - "$/plain_renderer.html" - "$/qtloader.js" - "${CMAKE_SOURCE_DIR}/site/mascot.png" ) - if (ALP_ENABLE_THREADING) - list(APPEND ALP_INSTALL_FILES "$/plain_renderer.worker.js") - endif() - install(FILES ${ALP_INSTALL_FILES} DESTINATION ${ALP_WWW_INSTALL_DIR}) + install( + FILES + "$/plain_renderer.js" + "$/plain_renderer.wasm" + "$/plain_renderer.html" + "$/qtloader.js" + "${CMAKE_SOURCE_DIR}/site/mascot.png" + DESTINATION + ${ALP_WWW_INSTALL_DIR} + ) + install( + FILES "$/plain_renderer.worker.js" + DESTINATION ${ALP_WWW_INSTALL_DIR} + OPTIONAL + ) endif()