From 2c4b7fa02a822754049610781a8137ddb650b830 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 30 Apr 2024 18:05:17 +0200 Subject: [PATCH 1/7] Core: Use Windows API to create path to explorer.exe Searching after "explorer.exe" in PATH can fail, as seen in a report on #qtcreator channel on Discord. Explorer.exe is always part of %systemroot%, which can be programatically obtained via SHGetFolderPath function. Fixes: QTCREATORBUG-30765 Change-Id: Id2c4f3bd9c51234cb9e16d936202dfbcb1975606 Reviewed-by: Alessandro Portale Reviewed-by: David Schulz --- src/plugins/coreplugin/fileutils.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/plugins/coreplugin/fileutils.cpp b/src/plugins/coreplugin/fileutils.cpp index e432543604f..c066e977d31 100644 --- a/src/plugins/coreplugin/fileutils.cpp +++ b/src/plugins/coreplugin/fileutils.cpp @@ -32,10 +32,28 @@ #include #include +#ifdef Q_OS_WIN +#ifdef QTCREATOR_PCH_H +#define CALLBACK WINAPI +#endif +#include +#include +#endif + using namespace Utils; namespace Core { +static FilePath windowsDirectory() +{ +#ifdef Q_OS_WIN + wchar_t str[UNICODE_STRING_MAX_CHARS] = {}; + if (SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_WINDOWS, nullptr, 0, str))) + return FilePath::fromUserInput(QString::fromUtf16(reinterpret_cast(str))); +#endif + return {}; +} + // Show error with option to open settings. static void showGraphicalShellError(QWidget *parent, const QString &app, const QString &error) { @@ -56,13 +74,7 @@ void FileUtils::showInGraphicalShell(QWidget *parent, const FilePath &pathIn) const QFileInfo fileInfo = pathIn.toFileInfo(); // Mac, Windows support folder or file. if (HostOsInfo::isWindowsHost()) { - const FilePath explorer = FilePath("explorer.exe").searchInPath(); - if (explorer.isEmpty()) { - QMessageBox::warning(parent, - Tr::tr("Launching Windows Explorer Failed"), - Tr::tr("Could not find explorer.exe in path to launch Windows Explorer.")); - return; - } + const FilePath explorer = windowsDirectory().pathAppended("explorer.exe"); QStringList param; if (!pathIn.isDir()) param += QLatin1String("/select,"); From 67ab041903bead454187b75e6ee5621f4854e0cb Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 19 Apr 2024 20:45:18 +0200 Subject: [PATCH 2/7] Android: Disable "Make [NDK] default" button while NDKs list is empty When pressing the "Make [NDK] Default" button while the list is empty leads to a crash. The button should actually not be enabled if the list is empty. This change disables the button while the NDKs list is empty. Fixes: QTCREATORBUG-30716 Change-Id: I5f10fd180f62d20210f1b0c0261e4d821d0582dd Reviewed-by: Reviewed-by: Jarek Kobus --- src/plugins/android/androidsettingswidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index 86034b9373e..80821867d4e 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -813,6 +813,7 @@ void AndroidSettingsWidget::updateUI() } } + m_makeDefaultNdkButton->setEnabled(m_ndkListWidget->count() > 0); m_makeDefaultNdkButton->setText(isDefaultNdkSelected() ? Tr::tr("Unset Default") : Tr::tr("Make Default")); } From d3fb3a163c97dfa3a2c9b41dbdd0307522968628 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 29 Apr 2024 18:46:04 +0200 Subject: [PATCH 3/7] Debugger: Ignore stops in libart.so and other Android runtime specific places From https://issuetracker.google.com/issues/240007217#comment17 "Some a background on the technical aspect of SEGVs: Android Runtime (ART) uses SEGV for various internal purposes (it triggers a SEGV and handles it without crashing the app, the app doesn't know it happened). When the native debugger is connected, the debugger must intercept all SEGV signals. When running the debugger on Android API level 27 and newer, we make the debugger skip these SEGV signals (i.e., forward them to be handled by ART), because we know how to handle real SEGV signals inside ART. For older Android versions (26 or older), we did not have this support, so the debugger stops at every SEGV (i.e., it cannot know if the signal is a real crash or an ART-internal thing)." Arguably, this should be caught by the LLDB Android platform bits, but... Task-number: QTCREATORBUG-30759 Task-number: QTCREATORBUG-29928 Task-number: QTCREATORBUG-30080 Change-Id: I8cabe4a0675c596a9617520aff0d62ad11321f0e Reviewed-by: Reviewed-by: Cristian Adam Reviewed-by: Alessandro Portale --- share/qtcreator/debugger/lldbbridge.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 7809a6a3dcb..f2387ac913c 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1456,6 +1456,21 @@ class Dumper(DumperBase): if bp is not None: self.reportBreakpointUpdate(bp) + def wantAutoContinue(self, frame): + if self.platform_ != 'remote-android': + return False + funcname = frame.GetFunctionName() + if funcname and funcname.startswith('java.'): + return True + module = frame.GetModule() + filespec = module.GetPlatformFileSpec() # Not GetFileSpec + filename = filespec.GetFilename() + if filename == 'libart.so': + return True + if funcname == None and not frame.line_entry.file.IsValid() and filename == None: + return True + return False + def handleEvent(self, event): if lldb.SBBreakpoint.EventIsBreakpointEvent(event): self.handleBreakpointEvent(event) @@ -1490,8 +1505,12 @@ class Dumper(DumperBase): if state == lldb.eStateStopped: stoppedThread = self.firstStoppedThread() if stoppedThread: - #self.report("STOPPED THREAD: %s" % stoppedThread) frame = stoppedThread.GetFrameAtIndex(0) + if self.wantAutoContinue(frame): + #self.warn("AUTO CONTINUE") + error = self.process.Continue() + return + #self.report("FRAME: %s" % frame) function = frame.GetFunction() functionName = function.GetName() From a0b19d9fba713232527d84a7c124e335f567678f Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 11 Apr 2024 17:11:56 +0200 Subject: [PATCH 4/7] Welcome: Restore legibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the release of Qt Creator 13.0.0, a couple of bug reports and comments regarding reduced legibility appeared. They boil down to: 1) Text appears blurry 2) Text is too small 3) Text contrast is too low This change fixes the blurryness by setting less custom font weights for non-HighDpi systems in StyleHelper::uiFont(). Bigger texts are used for the "Session" and "Recent Project" delegates. The text contrast is being increased by making Token_Text_Accent darker for light themes and brighter for dark themes. Token_Background_Muted, which is used as background color is made a bit brighter for light themes. Fixes: QTCREATORBUG-30579 Fixes: QTCREATORBUG-30637 Fixes: QTCREATORBUG-30650 Change-Id: I8eeb9db6854a19b0de0bcee14b10e2ef66234e06 Reviewed-by: André Hartmann Reviewed-by: hjk --- share/qtcreator/themes/dark.figmatokens | 8 +- share/qtcreator/themes/light.figmatokens | 9 +- src/libs/utils/stylehelper.cpp | 8 +- .../projectexplorer/projectwelcomepage.cpp | 109 +++++++++--------- 4 files changed, 75 insertions(+), 59 deletions(-) diff --git a/share/qtcreator/themes/dark.figmatokens b/share/qtcreator/themes/dark.figmatokens index 8937a3cc2d7..194ce7fab25 100644 --- a/share/qtcreator/themes/dark.figmatokens +++ b/share/qtcreator/themes/dark.figmatokens @@ -20,7 +20,13 @@ Token_Foreground_Subtle=ff2A2A2A Token_Text_Default=ffF8F8F8 Token_Text_Muted=ffAEAEAE Token_Text_Subtle=ff595959 -Token_Text_Accent=ff23B26A + +; Token_Text_Accent value from Figma is still too dark. Therefore, it is modified, here. +; Text (consisting of thin lines) needs to be substantially brighter than accent colors used for +; larger-area elements like the filled button. + +; Token_Text_Accent=ff23B26A +Token_Text_Accent=ff30C06A Token_Stroke_Strong=ffeeeeee Token_Stroke_Muted=ff727272 diff --git a/share/qtcreator/themes/light.figmatokens b/share/qtcreator/themes/light.figmatokens index 6ef243d17da..138ad74afdf 100644 --- a/share/qtcreator/themes/light.figmatokens +++ b/share/qtcreator/themes/light.figmatokens @@ -10,7 +10,12 @@ Token_Accent_Muted=ff1f9b5d Token_Accent_Subtle=ff1a8550 Token_Background_Default=fffcfcfc -Token_Background_Muted=ffF2F2F2 + +; Token_Background_Muted value from Figma is too dark to ensure proper contrast when used as +; text bachground. Therefore, it is modified, here. + +;Token_Background_Muted=ffF2F2F2 +Token_Background_Muted=ffF6F6F6 Token_Background_Subtle=ffe7e7e7 Token_Foreground_Default=ffD8D8D8 @@ -20,7 +25,7 @@ Token_Foreground_Subtle=ffEFEFEF Token_Text_Default=ff393939 Token_Text_Muted=ff6a6a6a Token_Text_Subtle=ffbebebe -Token_Text_Accent=ff28C878 +Token_Text_Accent=ff1F9B5D Token_Stroke_Strong=ff464646 Token_Stroke_Muted=ff727272 diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index 69b5e395565..07f526a4af0 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -1010,7 +1010,13 @@ QFont StyleHelper::uiFont(UiElement element) const qreal qrealPointSize = metrics.pixelSize * pixelsToPointSizeFactor; font.setPointSizeF(qrealPointSize); - font.setWeight(metrics.weight); + // Intermediate font weights can produce blurry rendering and are harder to read. + // For "non-retina" screens, apply the weight only for some fonts. + static const bool isHighDpi = qApp->devicePixelRatio() >= 2; + const bool setWeight = isHighDpi || element == UiElementCaptionStrong + || element <= UiElementH4; + if (setWeight) + font.setWeight(metrics.weight); return font; } diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index 29742256443..4928ae826e0 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -47,10 +47,9 @@ const char PROJECT_BASE_ID[] = "Welcome.OpenRecentProject"; namespace ProjectExplorer { namespace Internal { -constexpr TextFormat projectNameTF {Theme::Token_Text_Accent, StyleHelper::UiElementH6}; -constexpr TextFormat projectPathTF {Theme::Token_Text_Muted, StyleHelper::UiElementCaptionStrong}; -constexpr TextFormat sessionNameTF = {projectNameTF.themeColor, projectNameTF.uiElement, - Qt::AlignVCenter | Qt::TextDontClip}; +constexpr TextFormat projectNameTF {Theme::Token_Text_Accent, StyleHelper::UiElementH5}; +constexpr TextFormat projectPathTF {Theme::Token_Text_Muted, StyleHelper::UiElementH6}; +constexpr TextFormat sessionNameTF = projectNameTF; constexpr TextFormat sessionProjectNameTF {Theme::Token_Text_Default, projectNameTF.uiElement}; constexpr TextFormat shortcutNumberTF {Theme::Token_Text_Default, StyleHelper::UiElementCaptionStrong, @@ -59,7 +58,7 @@ constexpr TextFormat actionTF {Theme::Token_Text_Default, StyleHelper::UiElement Qt::AlignCenter | Qt::TextDontClip}; constexpr TextFormat actionDisabledTF {Theme::Token_Text_Subtle, actionTF.uiElement, actionTF.drawTextFlags}; -constexpr int shortcutNumberWidth = 16; +constexpr int shortcutNumberWidth = 6; constexpr int actionSepWidth = 1; constexpr int sessionScrollBarGap = HPaddingXs; @@ -316,36 +315,36 @@ public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final { - // visible on withIcon() Gap + arrow visible on hover Extra margin right of project item - // | | | - // +-----------+----------+ +--------+-------+ +----------+----------+ - // | | | | | | + // visible on withIcon() Gap + arrow visible on hover Extra margin right of project item + // | | | + // +----------+----------+ +--------+-------+ +----------+----------+ + // | | | | | | // - // +------------+--------+---------+------------+---------+-------------+--------+-------+------------+---------------------+ --+ - // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | - // | | | +------------+ +-------------+ | | | | | - // |(HPaddingXs)||(HGapXxs)| |(HGapXxs)||(HGapXs)|| | | +-- Header - // | |(16x16) | +------------+ +-------------+ | | | | | - // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | - // |------------+--------+---------+------------+---------+-------------+--------+-------+ | | --+ - // | +-- | (VPaddingXxs) | | | | - // | | +------------------------------+(HPaddingXs)| | | - // | | | | | | | - // | | +------------------------------+ | | | - // | Per project in session --+ | (ExPaddingGapS) | |(sessionScrollBarGap)| | - // | | +------------------------------+ | | | - // | | | | | | | - // | | +------------------------------+ | | +-- Expansion - // | +-- | (VPaddingXxs) | | | | - // +------------------------------------------------------+------------------------------+------------+ | | - // | (VPaddingXs) | | | - // +-----------------------------------------+--------------+-----------------------------------------+ | | - // +-- | || | | | - // | +-----------------------------------------+--------------+-----------------------------------------+ | | - // | | (VPaddingXs) | | | - // | +--------------------------------------------------------------------------------------------------+---------------------+ --+ - // | | (VGapL) | +-- Gap between session items - // | +------------------------------------------------------------------------------------------------------------------------+ --+ + // +------------+--------+--------+------------+--------+-------------+--------+-------+------------+---------------------+ --+ + // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | + // | | | +------------+ +-------------+ | | | | | + // |(HPaddingXs)||(HGapXs)| |(HGapXs)||(HGapXs)|| | | +-- Header + // | |(w:6) | +------------+ +-------------+ | | | | | + // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | + // |------------+--------+--------+------------+--------+-------------+--------+-------+ | | --+ + // | +-- | (VPaddingXxs) | | | | + // | | +------------------------------+(HPaddingXs)| | | + // | | | | | | | + // | | +------------------------------+ | | | + // | Per project in session --+ | (ExPaddingGapS) | |(sessionScrollBarGap)| | + // | | +------------------------------+ | | | + // | | | | | | | + // | | +------------------------------+ | | +-- Expansion + // | +-- | (VPaddingXxs) | | | | + // +----------------------------------------------------+------------------------------+------------+ | | + // | (VPaddingXs) | | | + // +---------------------------------------+--------------+-----------------------------------------+ | | + // +-- | || | | | + // | +---------------------------------------+--------------+-----------------------------------------+ | | + // | | (VPaddingXs) | | | + // | +------------------------------------------------------------------------------------------------+---------------------+ --+ + // | | (VGapL) | +-- Gap between session items + // | +----------------------------------------------------------------------------------------------------------------------+ --+ // | // \ session action "buttons" and dividers // +-----------------------------------------------+--------+---------+--------+ @@ -381,11 +380,11 @@ public: const int y = bgR.y(); const int numberX = x + s(HPaddingXs); - const int iconX = numberX + shortcutNumberWidth + s(HGapXxs); + const int iconX = numberX + shortcutNumberWidth + s(HGapXs); const int arrowX = bgR.right() - s(HPaddingXs) - arrowS.width(); const QRect arrowHoverR(arrowX - s(HGapXs) + 1, y, s(HGapXs) + arrowS.width() + s(HPaddingXs), hdR.height()); - const int textX = withIcon() ? iconX + iconS.width() + s(HGapXxs) : iconX; + const int textX = withIcon() ? iconX + iconS.width() + s(HGapXs) : iconX; const int iconY = y + (hdR.height() - iconS.height()) / 2; const int arrowY = y + (hdR.height() - arrowS.height()) / 2; @@ -622,24 +621,24 @@ class ProjectDelegate : public BaseDelegate public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final { - // visible on with Icon() Extra margin right of project item - // | | - // +--------+-------+ +------+-----+ - // | | | | + // visible on with Icon() Extra margin right of project item + // | | + // +--------+-------+ +------+-----+ + // | | | | // - // +------------+--------+---------+------+---------+-------------+------------+------------+ - // | | | | | | (VPaddingXs)| | | - // | | | | | +-------------+ | | - // | | | | | || | | - // | | | | | +-------------+ | | - // |(HPaddingXs)||(HGapXxs)||(HGapXxs)| (VGapXs) |(HPaddingXs)|(HPaddingXs)| - // | |(16x16) | | | +-------------+ | | - // | | | | | || | | - // | | | | | +-------------+ | | - // | | | | | | (VPaddingXs)| | | - // +------------+--------+---------+------+---------+-------------+------------+------------+ --+ - // | (VGapL) | +-- Gap between project items - // +----------------------------------------------------------------------------------------+ --+ + // +------------+--------+--------+------+---------+-------------+------------+------------+ + // | | | | | | (VPaddingXs)| | | + // | | | | | +-------------+ | | + // | | | | | || | | + // | | | | | +-------------+ | | + // |(HPaddingXs)||(HGapXs)||(HGapXxs)| (VGapXs) |(HPaddingXs)|(HPaddingXs)| + // | |(w:6) | | | +-------------+ | | + // | | | | | || | | + // | | | | | +-------------+ | | + // | | | | | | (VPaddingXs)| | | + // +------------+--------+--------+------+---------+-------------+------------+------------+ --+ + // | (VGapL) | +-- Gap between project items + // +---------------------------------------------------------------------------------------+ --+ const bool hovered = option.widget->isActiveWindow() && option.state & QStyle::State_MouseOver; @@ -651,9 +650,9 @@ public: const int x = bgR.x(); const int numberX = x + s(HPaddingXs); - const int iconX = numberX + shortcutNumberWidth + s(HGapXxs); + const int iconX = numberX + shortcutNumberWidth + s(HGapXs); const int iconWidth = iconS.width(); - const int textX = withIcon() ? iconX + iconWidth + s(HGapXxs) : iconX; + const int textX = withIcon() ? iconX + iconWidth + s(HGapXs) : iconX; const int textWidth = bgR.width() - s(HPaddingXs) - textX; const int y = bgR.y(); From cc9ffdb685119a7c11248f08cf88308927252b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= Date: Tue, 30 Apr 2024 16:06:28 +0200 Subject: [PATCH 5/7] ClangFormat: Fix compiliation with LLVM19 Change-Id: I4b166da2e477ffd101a5c4b9aa07c710f7698da9 Reviewed-by: Christian Kandeler --- src/plugins/clangformat/clangformatbaseindenter.cpp | 4 ++++ src/plugins/clangformat/llvmfilesystem.h | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 1d5dc2730c3..b491bd293f1 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -65,7 +65,11 @@ static void adjustFormatStyleForLineBreak(clang::format::FormatStyle &style, static llvm::StringRef clearExtraNewline(llvm::StringRef text) { +#if LLVM_VERSION_MAJOR >= 16 + while (text.starts_with("\n\n")) +#else while (text.startswith("\n\n")) +#endif text = text.drop_front(); return text; } diff --git a/src/plugins/clangformat/llvmfilesystem.h b/src/plugins/clangformat/llvmfilesystem.h index fface01fc08..b2d1c5de7e7 100644 --- a/src/plugins/clangformat/llvmfilesystem.h +++ b/src/plugins/clangformat/llvmfilesystem.h @@ -127,7 +127,11 @@ public: /// Gets real path of \p Path e.g. collapse all . and .. patterns, resolve /// symlinks. For real file system, this uses `llvm::sys::fs::real_path`. /// This returns errc::operation_not_permitted if not implemented by subclass. - std::error_code getRealPath(const Twine &Path, SmallVectorImpl &Output) const override + std::error_code getRealPath(const Twine &Path, SmallVectorImpl &Output) +#if LLVM_VERSION_MAJOR < 19 + const +#endif + override { Q_UNUSED(Path); Q_UNUSED(Output); From b0009782787ebc316a62f1aa0cb48e2eb6f42baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20L=C3=B6hning?= Date: Fri, 12 Apr 2024 22:16:29 +0200 Subject: [PATCH 6/7] SquishTests: Remove dead code The Qt Quick Application template doesn't allow changing the build system. skipBuildsystemChooser is True above. Change-Id: I413fa6c3b4d97e1f1212dbab96d2a39458ce3751 Reviewed-by: Christian Stenger Reviewed-by: --- tests/system/suite_general/tst_create_proj_wizard/test.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py index 78178d82bb8..176b606b8bf 100644 --- a/tests/system/suite_general/tst_create_proj_wizard/test.py +++ b/tests/system/suite_general/tst_create_proj_wizard/test.py @@ -113,10 +113,7 @@ def handleBuildSystemVerifyKits(category, template, kits, displayedPlatforms, return fixedBuildSystems = list(availableBuildSystems) - if template == 'Qt Quick Application': - fixedBuildSystems.remove('qmake') - test.log("Skipped qmake (not supported).") - elif template == 'Qt Quick 2 Extension Plugin': + if template == 'Qt Quick 2 Extension Plugin': fixedBuildSystems.remove('Qbs') test.log("Skipped Qbs (not supported).") @@ -126,7 +123,7 @@ def handleBuildSystemVerifyKits(category, template, kits, displayedPlatforms, clickButton(waitForObject(":Next_QPushButton")) if specialHandlingFunc: specialHandlingFunc(displayedPlatforms, *args) - if not ('Plain C' in template or template == 'Qt Quick Application'): + if not ('Plain C' in template): __createProjectHandleTranslationSelection__() verifyKitCheckboxes(kits, displayedPlatforms) safeClickButton("Cancel") From 732f37685ced250e35ca10ed9a4679c963f293d1 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 3 May 2024 15:36:41 +0200 Subject: [PATCH 7/7] Update qbs submodule to HEAD of 2.3 branch Change-Id: Ib3182e394222e4323982983b557cabbc60e1c0d8 Reviewed-by: Christian Stenger --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index 12bc60c93d6..488fbe40e86 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 12bc60c93d684432af1b28576f21f853b8922d99 +Subproject commit 488fbe40e86602d06e568a1749277387fd4a565e