vcl/inc/qt5/QtGraphicsBase.hxx | 5 ++++- vcl/inc/qt5/QtInstance.hxx | 22 +++++++++++++++++++++- vcl/qt5/QtFrame.cxx | 6 ++---- vcl/qt5/QtGraphicsBase.cxx | 5 ++--- vcl/qt5/QtInstance.cxx | 7 +++---- vcl/qt5/QtMenu.cxx | 20 ++++++++++---------- 6 files changed, 42 insertions(+), 23 deletions(-)
New commits: commit 696c241c03d3773fd82cedc390192dfa784c2493 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Fri Feb 14 21:13:10 2025 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Mon Feb 17 10:54:52 2025 +0100 Some more need for EmscriptenLightweightRunInMainThread Calls to qApp->devicePixelRatio() can internally call out to main-browser-thread-only JS objects when the data keeps getting invalidated by e.g. > setInterval(function() { window.dispatchEvent(new Event('resize')); }, 1000); at <https://github.com/allotropia/zetajs/commit/c7d80ed5c2d7336d0daedf8c34ac4055fb7f9626#diff-9fc68f096a70ca06e4a5b52d47a44abebeec78c757dab340b9b177cac35a65a8R42>. Change-Id: Ic1387f2a49c9a231842d88b6220f8efc8bc32479 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181682 Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> Tested-by: Jenkins diff --git a/vcl/inc/qt5/QtGraphicsBase.hxx b/vcl/inc/qt5/QtGraphicsBase.hxx index 26ee871d068b..55f97cf47872 100644 --- a/vcl/inc/qt5/QtGraphicsBase.hxx +++ b/vcl/inc/qt5/QtGraphicsBase.hxx @@ -10,6 +10,7 @@ #pragma once #include "QtFrame.hxx" +#include "QtInstance.hxx" #include <QtWidgets/QApplication> @@ -21,7 +22,9 @@ class QtGraphicsBase public: QtGraphicsBase() - : m_fDPR(qApp ? qApp->devicePixelRatio() : 1.0) + : m_fDPR(qApp ? GetQtInstance().EmscriptenLightweightRunInMainThread( + [] { return qApp->devicePixelRatio(); }) + : 1.0) { } commit 1c928cb4f34c3925a585e07fe3bddedf3f49809f Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Mon Feb 17 08:23:43 2025 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Mon Feb 17 10:54:42 2025 +0100 Support non-void QtInstance::EmscriptenLightweightRunInMainThread return types Change-Id: Ic0e02dd21c6dd59dc89088c3e797788bcea91273 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181763 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx index 50c6fd64bbbf..3227a234719e 100644 --- a/vcl/inc/qt5/QtInstance.hxx +++ b/vcl/inc/qt5/QtInstance.hxx @@ -30,9 +30,12 @@ #include <QtCore/QObject> +#include <concepts> #include <cstdlib> #include <functional> #include <memory> +#include <type_traits> +#include <utility> #include <vector> #include "QtFilePicker.hxx" @@ -89,6 +92,8 @@ class VCLPLUG_QT_PUBLIC QtInstance : public QObject, static QWidget* GetNativeParentFromWeldParent(weld::Widget* pParent); + void EmscriptenLightweightRunInMainThread_(std::function<void()> func); + private Q_SLOTS: bool ImplYield(bool bWait, bool bHandleAllCurrentEvents); static void deleteObjectLater(QObject* pObject); @@ -127,7 +132,22 @@ public: static std::unique_ptr<QApplication> CreateQApplication(int& nArgc, char** pArgv); void RunInMainThread(std::function<void()> func); - void EmscriptenLightweightRunInMainThread(std::function<void()> func); + template <typename F> + requires std::invocable<F> std::invoke_result_t<F> + EmscriptenLightweightRunInMainThread(F&& func) + { + if constexpr (std::is_same_v<std::invoke_result_t<F>, void>) + { + EmscriptenLightweightRunInMainThread_(std::move(func)); + } + else + { + std::invoke_result_t<F> ret; + EmscriptenLightweightRunInMainThread_( + [&func, &ret] { ret = std::forward<std::invoke_result_t<F>>(func()); }); + return ret; + } + } virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) override; virtual SalFrame* CreateChildFrame(SystemParentData* pParent, diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx index 4d020ec93395..e7f12183bbc5 100644 --- a/vcl/qt5/QtFrame.cxx +++ b/vcl/qt5/QtFrame.cxx @@ -262,10 +262,8 @@ QWidget* QtFrame::asChild() const qreal QtFrame::devicePixelRatioF() const { - qreal ret; - GetQtInstance().EmscriptenLightweightRunInMainThread( - [ child = asChild(), &ret ] { ret = child->devicePixelRatioF(); }); - return ret; + return GetQtInstance().EmscriptenLightweightRunInMainThread( + [child = asChild()] { return child->devicePixelRatioF(); }); } bool QtFrame::isWindow() const { return asChild()->isWindow(); } diff --git a/vcl/qt5/QtGraphicsBase.cxx b/vcl/qt5/QtGraphicsBase.cxx index bfed88a8954b..e285e2af4e9e 100644 --- a/vcl/qt5/QtGraphicsBase.cxx +++ b/vcl/qt5/QtGraphicsBase.cxx @@ -27,9 +27,8 @@ void QtGraphicsBase::ImplGetResolution(QtFrame* pFrame, sal_Int32& rDPIX, sal_In return; QScreen* pScreen = pFrame->GetQWidget()->screen(); - qreal devicePixelRatio; - GetQtInstance().EmscriptenLightweightRunInMainThread( - [pScreen, &devicePixelRatio] { devicePixelRatio = pScreen->devicePixelRatio(); }); + qreal devicePixelRatio = GetQtInstance().EmscriptenLightweightRunInMainThread( + [pScreen] { return pScreen->devicePixelRatio(); }); rDPIX = pScreen->logicalDotsPerInchX() * devicePixelRatio + 0.5; rDPIY = pScreen->logicalDotsPerInchY() * devicePixelRatio + 0.5; } diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx index 7c8c1b41a552..1c1f05fa5dc7 100644 --- a/vcl/qt5/QtInstance.cxx +++ b/vcl/qt5/QtInstance.cxx @@ -232,7 +232,7 @@ void QtInstance::RunInMainThread(std::function<void()> func) } } -void QtInstance::EmscriptenLightweightRunInMainThread(std::function<void()> func) +void QtInstance::EmscriptenLightweightRunInMainThread_(std::function<void()> func) { #if defined EMSCRIPTEN && ENABLE_QT6 && HAVE_EMSCRIPTEN_JSPI && !HAVE_EMSCRIPTEN_PROXY_TO_PTHREAD if (pthread_self() != emscripten_main_runtime_thread_id()) @@ -650,9 +650,8 @@ QtInstance::CreateClipboard(const css::uno::Sequence<css::uno::Any>& arguments) if (it != m_aClipboards.end()) return it->second; - css::uno::Reference<css::uno::XInterface> xClipboard; - EmscriptenLightweightRunInMainThread( - [&sel, &xClipboard] { xClipboard = QtClipboard::create(sel); }); + css::uno::Reference<css::uno::XInterface> xClipboard + = EmscriptenLightweightRunInMainThread([&sel] { return QtClipboard::create(sel); }); if (xClipboard.is()) m_aClipboards[sel] = xClipboard; diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx index 2d677bf6112a..0a8942015948 100644 --- a/vcl/qt5/QtMenu.cxx +++ b/vcl/qt5/QtMenu.cxx @@ -769,16 +769,16 @@ QPushButton* QtMenu::ImplAddMenuBarButton(const QIcon& rIcon, const QString& rTo if (!pWidget) { assert(!m_pButtonGroup); - GetQtInstance().EmscriptenLightweightRunInMainThread( - [this, &pWidget] { pWidget = new QWidget(mpQMenuBar); }); + pWidget = GetQtInstance().EmscriptenLightweightRunInMainThread( + [this] { return new QWidget(mpQMenuBar); }); assert(!pWidget->layout()); - GetQtInstance().EmscriptenLightweightRunInMainThread( - [&pLayout] { pLayout = new QHBoxLayout(); }); + pLayout = GetQtInstance().EmscriptenLightweightRunInMainThread( + [] { return new QHBoxLayout(); }); pLayout->setContentsMargins(QMargins()); pLayout->setSpacing(0); pWidget->setLayout(pLayout); - GetQtInstance().EmscriptenLightweightRunInMainThread( - [this, pLayout] { m_pButtonGroup = new QButtonGroup(pLayout); }); + m_pButtonGroup = GetQtInstance().EmscriptenLightweightRunInMainThread( + [pLayout] { return new QButtonGroup(pLayout); }); m_pButtonGroup->setObjectName(gButtonGroupKey); m_pButtonGroup->setExclusive(false); connect(m_pButtonGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, @@ -797,8 +797,8 @@ QPushButton* QtMenu::ImplAddMenuBarButton(const QIcon& rIcon, const QString& rTo if (pButton) RemoveMenuBarButton(nId); - GetQtInstance().EmscriptenLightweightRunInMainThread( - [&pButton] { pButton = new QPushButton(); }); + pButton + = GetQtInstance().EmscriptenLightweightRunInMainThread([] { return new QPushButton(); }); // we don't want the button to increase the QMenuBar height, so a fixed size square it is const int nFixedLength = mpQMenuBar->height() - 2 * mpQMenuBar->style()->pixelMetric(QStyle::PM_MenuBarVMargin); @@ -835,8 +835,8 @@ void QtMenu::connectHelpShortcut(QMenu* pMenu) assert(pMenu); QKeySequence sequence(QKeySequence::HelpContents); QShortcut* pQShortcut; - GetQtInstance().EmscriptenLightweightRunInMainThread( - [&sequence, pMenu, &pQShortcut] { pQShortcut = new QShortcut(sequence, pMenu); }); + pQShortcut = GetQtInstance().EmscriptenLightweightRunInMainThread( + [&sequence, pMenu] { return new QShortcut(sequence, pMenu); }); connect(pQShortcut, &QShortcut::activated, this, QtMenu::slotShowHelp); connect(pQShortcut, &QShortcut::activatedAmbiguously, this, QtMenu::slotShowHelp); }