diff options
author | Katarina Behrens <Katarina.Behrens@cib.de> | 2018-11-01 13:57:56 +0100 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2018-11-27 14:53:53 +0100 |
commit | ba9fc43617d6203a09219a7c44978a1a820e1691 (patch) | |
tree | 55492d3475964ef0f84f885908038f5d2d7b1999 | |
parent | tdf#119856: thread-proof kde5 fpicker execute() and getFiles() (diff) | |
download | core-ba9fc43617d6203a09219a7c44978a1a820e1691.tar.gz core-ba9fc43617d6203a09219a7c44978a1a820e1691.zip |
tdf#119856: thread-proof creating frames and setting menus
This finally enables opening a new frame and setting its menu from
an extension, but it is still far from stable, loads of threading
landmines like this all over the code
Change-Id: Icf4b67796b0669425ecb7c2c142c21e184024534
Reviewed-on: https://gerrit.libreoffice.org/62737
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Conflicts:
vcl/unx/kde5/KDE5SalInstance.hxx
-rw-r--r-- | vcl/inc/qt5/Qt5Instance.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/qt5/Qt5Menu.hxx | 3 | ||||
-rw-r--r-- | vcl/qt5/Qt5Instance.cxx | 8 | ||||
-rw-r--r-- | vcl/qt5/Qt5Menu.cxx | 11 | ||||
-rw-r--r-- | vcl/unx/kde5/KDE5SalInstance.cxx | 8 | ||||
-rw-r--r-- | vcl/unx/kde5/KDE5SalInstance.hxx | 5 |
6 files changed, 34 insertions, 2 deletions
diff --git a/vcl/inc/qt5/Qt5Instance.hxx b/vcl/inc/qt5/Qt5Instance.hxx index a7a73afba09a..529ec3d2779c 100644 --- a/vcl/inc/qt5/Qt5Instance.hxx +++ b/vcl/inc/qt5/Qt5Instance.hxx @@ -52,6 +52,7 @@ private Q_SLOTS: Q_SIGNALS: bool ImplYieldSignal(bool bWait, bool bHandleAllCurrentEvents); + std::unique_ptr<SalMenu> createMenuSignal(bool, Menu*); public: explicit Qt5Instance(std::unique_ptr<SalYieldMutex> pMutex, bool bUseCairo = false); diff --git a/vcl/inc/qt5/Qt5Menu.hxx b/vcl/inc/qt5/Qt5Menu.hxx index f3111d01aa8a..366b68307182 100644 --- a/vcl/inc/qt5/Qt5Menu.hxx +++ b/vcl/inc/qt5/Qt5Menu.hxx @@ -59,6 +59,9 @@ public: unsigned GetItemCount() { return maItems.size(); } Qt5MenuItem* GetItemAtPos(unsigned nPos) { return maItems[nPos]; } +Q_SIGNALS: + void setFrameSignal(const SalFrame* pFrame); + private slots: void slotMenuTriggered(Qt5MenuItem* pQItem); }; diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx index 92a742562251..441eb4371c41 100644 --- a/vcl/qt5/Qt5Instance.cxx +++ b/vcl/qt5/Qt5Instance.cxx @@ -65,6 +65,8 @@ Qt5Instance::Qt5Instance(std::unique_ptr<SalYieldMutex> pMutex, bool bUseCairo) // is processed before the thread emitting the signal continues connect(this, SIGNAL(ImplYieldSignal(bool, bool)), this, SLOT(ImplYield(bool, bool)), Qt::BlockingQueuedConnection); + connect(this, &Qt5Instance::createMenuSignal, this, &Qt5Instance::CreateMenu, + Qt::BlockingQueuedConnection); } Qt5Instance::~Qt5Instance() @@ -120,6 +122,12 @@ Qt5Instance::CreateVirtualDevice(SalGraphics* pGraphics, long& nDX, long& nDY, D std::unique_ptr<SalMenu> Qt5Instance::CreateMenu(bool bMenuBar, Menu* pVCLMenu) { + if (qApp->thread() != QThread::currentThread()) + { + SolarMutexReleaser aReleaser; + return Q_EMIT createMenuSignal(bMenuBar, pVCLMenu); + } + Qt5Menu* pSalMenu = new Qt5Menu(bMenuBar); pSalMenu->SetMenu(pVCLMenu); return std::unique_ptr<SalMenu>(pSalMenu); diff --git a/vcl/qt5/Qt5Menu.cxx b/vcl/qt5/Qt5Menu.cxx index 8b65c32ad94f..9df4039f666c 100644 --- a/vcl/qt5/Qt5Menu.cxx +++ b/vcl/qt5/Qt5Menu.cxx @@ -23,6 +23,7 @@ Qt5Menu::Qt5Menu(bool bMenuBar) , mpFrame(nullptr) , mbMenuBar(bMenuBar) { + connect(this, &Qt5Menu::setFrameSignal, this, &Qt5Menu::SetFrame, Qt::BlockingQueuedConnection); } Qt5Menu::~Qt5Menu() { maItems.clear(); } @@ -63,6 +64,12 @@ void Qt5Menu::SetSubMenu(SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned) void Qt5Menu::SetFrame(const SalFrame* pFrame) { + if (qApp->thread() != QThread::currentThread()) + { + SolarMutexReleaser aReleaser; + return Q_EMIT setFrameSignal(pFrame); + } + SolarMutexGuard aGuard; assert(mbMenuBar); mpFrame = const_cast<Qt5Frame*>(static_cast<const Qt5Frame*>(pFrame)); @@ -71,9 +78,11 @@ void Qt5Menu::SetFrame(const SalFrame* pFrame) Qt5MainWindow* pMainWindow = mpFrame->GetTopLevelWindow(); if (pMainWindow) + { mpQMenuBar = pMainWindow->menuBar(); - DoFullMenuUpdate(mpVCLMenu); + DoFullMenuUpdate(mpVCLMenu); + } } void Qt5Menu::DoFullMenuUpdate(Menu* pMenuBar, QMenu* pParentMenu) diff --git a/vcl/unx/kde5/KDE5SalInstance.cxx b/vcl/unx/kde5/KDE5SalInstance.cxx index df02fc744055..d45c5f9ec174 100644 --- a/vcl/unx/kde5/KDE5SalInstance.cxx +++ b/vcl/unx/kde5/KDE5SalInstance.cxx @@ -46,12 +46,20 @@ KDE5SalInstance::KDE5SalInstance(std::unique_ptr<SalYieldMutex> pMutex) pSVData->maAppData.mpToolkitName = new OUString("kde5"); KDE5SalData::initNWF(); + + connect(this, &KDE5SalInstance::createFrameSignal, this, &KDE5SalInstance::CreateFrame, + Qt::BlockingQueuedConnection); connect(this, &KDE5SalInstance::createFilePickerSignal, this, &KDE5SalInstance::createFilePicker, Qt::BlockingQueuedConnection); } SalFrame* KDE5SalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nState) { + if (!IsMainThread()) + { + SolarMutexReleaser aReleaser; + return Q_EMIT createFrameSignal(pParent, nState); + } return new KDE5SalFrame(static_cast<KDE5SalFrame*>(pParent), nState, true); } diff --git a/vcl/unx/kde5/KDE5SalInstance.hxx b/vcl/unx/kde5/KDE5SalInstance.hxx index 8b7166c76144..f23f0fbde3c2 100644 --- a/vcl/unx/kde5/KDE5SalInstance.hxx +++ b/vcl/unx/kde5/KDE5SalInstance.hxx @@ -34,7 +34,6 @@ class KDE5SalInstance : public Qt5Instance Q_OBJECT public: explicit KDE5SalInstance(std::unique_ptr<SalYieldMutex> pMutex); - virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) override; virtual bool hasNativeFileSelection() const override { return true; } @@ -44,10 +43,14 @@ public: virtual bool IsMainThread() const override; Q_SIGNALS: + SalFrame* createFrameSignal(SalFrame* pParent, SalFrameStyleFlags nStyle); + css::uno::Reference<css::ui::dialogs::XFilePicker2> createFilePickerSignal(const css::uno::Reference<css::uno::XComponentContext>&); private Q_SLOTS: + virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) override; + virtual css::uno::Reference<css::ui::dialogs::XFilePicker2> createFilePicker(const css::uno::Reference<css::uno::XComponentContext>&) override; }; |