From cd2e3fcc19bdecd0295790a5b3a79ad68a5a4036 Mon Sep 17 00:00:00 2001 From: Matej Bagar Date: Fri, 16 Jan 2026 11:17:49 +0100 Subject: [PATCH 1/5] Add squish support for Android --- CMakeLists.txt | 8 ++++++++ INSTALL.md | 28 +++++++++++++++++++++++++++- app/CMakeLists.txt | 21 +++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 652a7a031..3e55e0892 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,10 @@ message(STATUS "Mergin Maps Mobile ${version_desc} - ${platform_desc}") # FIND PACKAGES # ######################################################################################## +if(SquishQtBuiltinHook_ROOT) + list(APPEND CMAKE_FIND_ROOT_PATH ${SquishQtBuiltinHook_ROOT}) +endif() + find_package( Qt6 COMPONENTS Quick @@ -260,6 +264,10 @@ if (ENABLE_TESTS) ) endif () +if (SquishQtBuiltinHook_ROOT) + find_package(SquishQtBuiltinHook) +endif () + # ######################################################################################## # GLOBAL SETUP # ######################################################################################## diff --git a/INSTALL.md b/INSTALL.md index 461a92e22..d1113eb00 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -627,6 +627,7 @@ Once the project is opened, build it from Xcode. # 9. Auto Testing +## Mergin API tests You need to add cmake define `-DENABLE_TESTING=TRUE` on your cmake configure line. Also, you need to open Passbolt and check for password for user `test_mobileapp` on `app.dev.merginmaps.com`, or you need some user with unlimited projects limit. First workspace from list is taken. @@ -641,4 +642,29 @@ TEST_API_PASSWORD= ``` Build binary, and you can run tests either with `ctest` or you can run individual tests by adding `--test` -e.g. ` ./MerginMaps --testMerginApi` \ No newline at end of file +e.g. ` ./MerginMaps --testMerginApi` + +## Squish tests +### Prerequisites + - Squish for Qt for Android (ARMv8/ARMv7 depending on architecture you build for) + - Squish for Qt (Windows/Mac/Linux), this should also include the Squish IDE +### Android +After you unpack both and install Squish IDE, add another cmake argument `-DSquishQtBuiltinHook_ROOT=/////`. +This will build the apk with squish hook inside. You can verify that squish is working by finding these lines in log after startup: +```shell +I/Squish (26459): Setting SQUISH_PREFIX to '/data/data/uk.co.lutraconsulting' +I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: Loading Qt Wrapper configuration from ":/squish/etc/qtwrapper.ini" +I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: QObject lifetime tracking is disabled +I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: Listening on port 7757 for incoming connections +``` + +In the squish IDE it's necessary to follow these steps to set it up completely and start testing the application. +1. In Squish IDE choose File, New Test Suite to create a new Test Suite and follow the wizard. When asked for the GUI Toolkit choose Qt. When asked for the Application Under Test choose \. +2. [Register attachable AUT](https://doc.qt.io/squish/attaching-to-running-applications.html#register-the-attachable-aut) + 1. As _Name_ set `MerginMaps`, _Host_ is the IP address of your phone (has to be on the same Wifi) and set _Port_ to `7757` + 2. You can also use USB cable to connect both devices. However, there is some further setup to do, first you need to forward the device port to your PC with: + ```shell + $ adb forward tcp:portnumber tcp:portnumber + ``` + After that the setup is the same as in point 1, just _Host_ will become `localhost`. +3. The test script should start with `attachToApplication("MerginMaps")` \ No newline at end of file diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index e49bfd223..f47a318e8 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -606,3 +606,24 @@ qt_add_qml_module( QML_FILES ${MM_QML_SRCS} RESOURCE_PREFIX /com.merginmaps/imports ) + +# ######################################################################################## +# Other +# ######################################################################################## + +if(ANDROID AND SquishQtBuiltinHook_FOUND) + squish_qt_add_builtin_hook(MerginMaps ATTACH_PORT 7757) + # copy squish hook libs + list(APPEND SquishLibs + "${SquishQtBuiltinHook_ROOT}/lib/libsquishhook.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtquickcommon.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtwrapper.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqgraphicsview.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtabwidget.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquick.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquicktypes.so" + ) + set_target_properties(MerginMaps PROPERTIES + QT_ANDROID_EXTRA_LIBS "${SquishLibs}" + ) +endif() \ No newline at end of file From 551a9fe6ae0c20ff18abc637fa4526b36540d6db Mon Sep 17 00:00:00 2001 From: Matej Bagar Date: Fri, 16 Jan 2026 11:24:01 +0100 Subject: [PATCH 2/5] Fix formatting --- CMakeLists.txt | 4 ++-- app/CMakeLists.txt | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e55e0892..efbc014df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,9 +162,9 @@ message(STATUS "Mergin Maps Mobile ${version_desc} - ${platform_desc}") # FIND PACKAGES # ######################################################################################## -if(SquishQtBuiltinHook_ROOT) +if (SquishQtBuiltinHook_ROOT) list(APPEND CMAKE_FIND_ROOT_PATH ${SquishQtBuiltinHook_ROOT}) -endif() +endif () find_package( Qt6 diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index f47a318e8..04f71dae1 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -611,19 +611,19 @@ qt_add_qml_module( # Other # ######################################################################################## -if(ANDROID AND SquishQtBuiltinHook_FOUND) +if (ANDROID AND SquishQtBuiltinHook_FOUND) squish_qt_add_builtin_hook(MerginMaps ATTACH_PORT 7757) # copy squish hook libs - list(APPEND SquishLibs - "${SquishQtBuiltinHook_ROOT}/lib/libsquishhook.so" - "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtquickcommon.so" - "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtwrapper.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqgraphicsview.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtabwidget.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquick.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquicktypes.so" - ) - set_target_properties(MerginMaps PROPERTIES - QT_ANDROID_EXTRA_LIBS "${SquishLibs}" + list( + APPEND + SquishLibs + "${SquishQtBuiltinHook_ROOT}/lib/libsquishhook.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtquickcommon.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtwrapper.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqgraphicsview.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtabwidget.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquick.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquicktypes.so" ) -endif() \ No newline at end of file + set_target_properties(MerginMaps PROPERTIES QT_ANDROID_EXTRA_LIBS "${SquishLibs}") +endif () From 65ee543e548eaf9e8071b5887afd5f97588a1f60 Mon Sep 17 00:00:00 2001 From: Matej Bagar Date: Thu, 29 Jan 2026 18:40:55 +0100 Subject: [PATCH 3/5] Improve StackView support for Squish --- app/qml/CMakeLists.txt | 1 + app/qml/components/MMStackView.qml | 27 +++++++++++++++++++++++ app/qml/form/MMFormStackController.qml | 4 +++- app/qml/layers/MMLayersController.qml | 3 ++- app/qml/main.qml | 2 +- app/qml/project/MMProjectController.qml | 3 ++- app/qml/settings/MMSettingsController.qml | 2 +- gallery/qml/pages/OnboardingPage.qml | 4 +++- gallery/qml/pages/PagesPage.qml | 4 +++- 9 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 app/qml/components/MMStackView.qml diff --git a/app/qml/CMakeLists.txt b/app/qml/CMakeLists.txt index 926d9f1e9..a54db8270 100644 --- a/app/qml/CMakeLists.txt +++ b/app/qml/CMakeLists.txt @@ -52,6 +52,7 @@ set(MM_QML components/MMToolbar.qml components/MMToolbarButton.qml components/MMSingleClickMouseArea.qml + components/MMStackView.qml components/private/MMBaseInput.qml components/private/MMBaseSingleLineInput.qml components/private/MMToolbarLongButton.qml diff --git a/app/qml/components/MMStackView.qml b/app/qml/components/MMStackView.qml new file mode 100644 index 000000000..b3eab081b --- /dev/null +++ b/app/qml/components/MMStackView.qml @@ -0,0 +1,27 @@ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +import QtQuick +import QtQuick.Controls + +// StackView wrapper, which improves Squish support. Should be used instead of pure QML StackView. + +StackView { + id: root + + onEmptyChanged: function() { + visible = !empty + } + + Component.onCompleted: { + if (empty) { + visible = false + } + } +} diff --git a/app/qml/form/MMFormStackController.qml b/app/qml/form/MMFormStackController.qml index 79ddd8f84..912bfc607 100644 --- a/app/qml/form/MMFormStackController.qml +++ b/app/qml/form/MMFormStackController.qml @@ -10,6 +10,8 @@ import QtQuick import QtQuick.Controls +import MMInput + Item { id: root @@ -252,7 +254,7 @@ Item { form.controllerToApply = null } - StackView { + MMStackView { id: formsStack function popOneOrClose() { diff --git a/app/qml/layers/MMLayersController.qml b/app/qml/layers/MMLayersController.qml index 8b7d5487c..e9b46b1ac 100644 --- a/app/qml/layers/MMLayersController.qml +++ b/app/qml/layers/MMLayersController.qml @@ -11,6 +11,7 @@ import QtQuick import QtQuick.Controls import mm 1.0 as MM +import MMInput import "../components" import "../inputs" @@ -41,7 +42,7 @@ Item { } } - StackView { + MMStackView { id: pagesStackView anchors.fill: parent diff --git a/app/qml/main.qml b/app/qml/main.qml index 0c9f8332f..abdcab27e 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -411,7 +411,7 @@ ApplicationWindow { onClosed: stateManager.state = "map" } - StackView { + MMStackView { id: mapPanelsStackView // diff --git a/app/qml/project/MMProjectController.qml b/app/qml/project/MMProjectController.qml index ab83449fe..b6360067e 100644 --- a/app/qml/project/MMProjectController.qml +++ b/app/qml/project/MMProjectController.qml @@ -14,6 +14,7 @@ import Qt5Compat.GraphicalEffects import QtQuick.Dialogs import mm 1.0 as MM +import MMInput import "../components" import "../inputs" @@ -88,7 +89,7 @@ Item { stackView.focus = true } - StackView { + MMStackView { id: stackView initialItem: workspaceProjectsPanelComp diff --git a/app/qml/settings/MMSettingsController.qml b/app/qml/settings/MMSettingsController.qml index 938ca22e0..4b57758af 100644 --- a/app/qml/settings/MMSettingsController.qml +++ b/app/qml/settings/MMSettingsController.qml @@ -56,7 +56,7 @@ Item { } - StackView { + MMStackView { id: stackview width: ApplicationWindow.window?.width ?? 0 diff --git a/gallery/qml/pages/OnboardingPage.qml b/gallery/qml/pages/OnboardingPage.qml index e3c09b76d..c61793128 100644 --- a/gallery/qml/pages/OnboardingPage.qml +++ b/gallery/qml/pages/OnboardingPage.qml @@ -11,13 +11,15 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import MMInput + import "../../app/qml/components" import "../../app/qml/account" Page { id: root - StackView { + MMStackView { id: stackview anchors.fill: parent diff --git a/gallery/qml/pages/PagesPage.qml b/gallery/qml/pages/PagesPage.qml index 0effaf990..3eff2cc27 100644 --- a/gallery/qml/pages/PagesPage.qml +++ b/gallery/qml/pages/PagesPage.qml @@ -11,6 +11,8 @@ import QtQuick import QtQuick.Controls import QtQuick.Controls.Basic +import MMInput + import "../../app/qml/components" import "../../app/qml" import "../../app/qml/project" @@ -21,7 +23,7 @@ import "../../app/qml/account" Page { id: root - StackView { + MMStackView { id: stackview anchors.fill: parent From 724f82cd428bd8a84c6e4afa6fd52c44409e9769 Mon Sep 17 00:00:00 2001 From: Matej Bagar Date: Thu, 29 Jan 2026 20:18:33 +0100 Subject: [PATCH 4/5] Tidy cmake --- CMakeLists.txt | 8 ++++---- app/CMakeLists.txt | 35 ++++++++++++++--------------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index efbc014df..8a5d0945c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,10 +162,6 @@ message(STATUS "Mergin Maps Mobile ${version_desc} - ${platform_desc}") # FIND PACKAGES # ######################################################################################## -if (SquishQtBuiltinHook_ROOT) - list(APPEND CMAKE_FIND_ROOT_PATH ${SquishQtBuiltinHook_ROOT}) -endif () - find_package( Qt6 COMPONENTS Quick @@ -369,6 +365,10 @@ if (ANDROID) # Make sure the generator for android_deployment_settings.json can figure out the # architecture list(APPEND CMAKE_FIND_ROOT_PATH /) + # Make sure the generator for android_deployment_settings.json can find Squish libs + if (SquishQtBuiltinHook_ROOT) + list(APPEND CMAKE_FIND_ROOT_PATH ${SquishQtBuiltinHook_ROOT}) + endif () endif () # ######################################################################################## diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 04f71dae1..a73c71061 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -339,6 +339,19 @@ if (ANDROID) ${CMAKE_CURRENT_SOURCE_DIR}/android/build.gradle @ONLY ) + if (SquishQtBuiltinHook_FOUND) + squish_qt_add_builtin_hook(MerginMaps ATTACH_PORT 7757) + list(APPEND SquishLibs + "${SquishQtBuiltinHook_ROOT}/lib/libsquishhook.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtquickcommon.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtwrapper.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqgraphicsview.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtabwidget.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquick.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquicktypes.so" + ) + endif () + set_target_properties( MerginMaps PROPERTIES QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android @@ -346,6 +359,7 @@ if (ANDROID) QT_ANDROID_MIN_SDK_VERSION ${MM_ANDROID_MIN_SDK_VERSION} QT_ANDROID_VERSION_CODE ${MM_VERSION_CODE} QT_ANDROID_VERSION_NAME ${MM_VERSION} + QT_ANDROID_EXTRA_LIBS "${SquishLibs}" ) endif () @@ -606,24 +620,3 @@ qt_add_qml_module( QML_FILES ${MM_QML_SRCS} RESOURCE_PREFIX /com.merginmaps/imports ) - -# ######################################################################################## -# Other -# ######################################################################################## - -if (ANDROID AND SquishQtBuiltinHook_FOUND) - squish_qt_add_builtin_hook(MerginMaps ATTACH_PORT 7757) - # copy squish hook libs - list( - APPEND - SquishLibs - "${SquishQtBuiltinHook_ROOT}/lib/libsquishhook.so" - "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtquickcommon.so" - "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtwrapper.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqgraphicsview.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtabwidget.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquick.so" - "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquicktypes.so" - ) - set_target_properties(MerginMaps PROPERTIES QT_ANDROID_EXTRA_LIBS "${SquishLibs}") -endif () From 47acff17d3bca6a8f6953b0019f04d326b7e5fdc Mon Sep 17 00:00:00 2001 From: Matej Bagar Date: Thu, 29 Jan 2026 21:03:27 +0100 Subject: [PATCH 5/5] Add iOS support WIP --- app/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index a73c71061..02b0a95c9 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -453,6 +453,15 @@ if (IOS) ) message(STATUS "Using automatic code sign") endif () + + #squish + if (SquishQtBuiltinHook_FOUND) + squish_qt_add_builtin_hook(MerginMaps ATTACH_PORT 7757) + target_include_directories( + MerginMaps + PRIVATE "${SquishQtBuiltinHook_ROOT}/include" + ) + endif () endif () # ######################################################################################## @@ -568,6 +577,9 @@ if (IOS) ) # TODO is this needed? this change requires cmake 3.28+ # qt_add_ios_ffmpeg_libraries(MerginMaps) # Qt Multimedia + if (SquishQtBuiltinHook_FOUND) + target_link_libraries(MerginMaps PRIVATE SquishQtBuiltinHook) + endif () endif () if (WIN)