diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-08-15 16:07:47 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-08-29 17:21:38 +0200 |
commit | 8a110242b90273aaf54c87057f7739ae910fcdb3 (patch) | |
tree | 1058ec1c0f6e4c57901b63ccf7d26270365fa3cc | |
parent | beff195273334df189b3bcc656d007043917c81e (diff) |
Resolves: tdf#111760 cancel file dialog on terminate
schedule cancel dialog in query termination, take ownership of the desktop and
re-schedule terminate to be re-attempted after the dialog is cancelled
Change-Id: I5c061b47959baba138c6c23aaae365f28e9cf167
Reviewed-on: https://gerrit.libreoffice.org/41677
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r-- | vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx | 8 | ||||
-rw-r--r-- | vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx | 4 | ||||
-rw-r--r-- | vcl/unx/gtk/fpicker/SalGtkPicker.cxx | 56 | ||||
-rw-r--r-- | vcl/unx/gtk/fpicker/SalGtkPicker.hxx | 9 |
4 files changed, 64 insertions, 13 deletions
diff --git a/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx index ea58932bb194..89ce64f82cc0 100644 --- a/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx +++ b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx @@ -888,10 +888,14 @@ sal_Int16 SAL_CALL SalGtkFilePicker::execute() awt::Toolkit::create(m_xContext), UNO_QUERY_THROW ); + uno::Reference< frame::XDesktop > xDesktop( + frame::Desktop::create(m_xContext), + UNO_QUERY_THROW ); + GtkWindow *pParent = RunDialog::GetTransientFor(); if (pParent) gtk_window_set_transient_for(GTK_WINDOW(m_pDialog), pParent); - RunDialog* pRunDialog = new RunDialog(m_pDialog, xToolkit); + RunDialog* pRunDialog = new RunDialog(m_pDialog, xToolkit, xDesktop); uno::Reference < awt::XTopWindowListener > xLifeCycle(pRunDialog); while( GTK_RESPONSE_NO == btn ) { @@ -984,7 +988,7 @@ sal_Int16 SAL_CALL SalGtkFilePicker::execute() if (pParent) gtk_window_set_transient_for(GTK_WINDOW(dlg), pParent); #endif - RunDialog* pAnotherDialog = new RunDialog(dlg, xToolkit); + RunDialog* pAnotherDialog = new RunDialog(dlg, xToolkit, xDesktop); uno::Reference < awt::XTopWindowListener > xAnotherLifeCycle(pAnotherDialog); btn = pAnotherDialog->run(); diff --git a/vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx b/vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx index 249194fc9eec..b8d12c1e4385 100644 --- a/vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx +++ b/vcl/unx/gtk/fpicker/SalGtkFolderPicker.cxx @@ -138,10 +138,12 @@ sal_Int16 SAL_CALL SalGtkFolderPicker::execute() awt::Toolkit::create(m_xContext), uno::UNO_QUERY); + uno::Reference<frame::XDesktop> xDesktop(frame::Desktop::create(m_xContext), uno::UNO_QUERY); + GtkWindow *pParent = RunDialog::GetTransientFor(); if (pParent) gtk_window_set_transient_for(GTK_WINDOW(m_pDialog), pParent); - RunDialog* pRunDialog = new RunDialog(m_pDialog, xToolkit); + RunDialog* pRunDialog = new RunDialog(m_pDialog, xToolkit, xDesktop); uno::Reference < awt::XTopWindowListener > xLifeCycle(pRunDialog); gint nStatus = pRunDialog->run(); switch( nStatus ) diff --git a/vcl/unx/gtk/fpicker/SalGtkPicker.cxx b/vcl/unx/gtk/fpicker/SalGtkPicker.cxx index 060cf23abab1..7a79bc50c62a 100644 --- a/vcl/unx/gtk/fpicker/SalGtkPicker.cxx +++ b/vcl/unx/gtk/fpicker/SalGtkPicker.cxx @@ -23,6 +23,7 @@ #undef _LINUX_SOURCE_COMPAT #endif +#include <com/sun/star/frame/TerminationVetoException.hpp> #include <com/sun/star/lang/XMultiComponentFactory.hpp> #include <com/sun/star/uri/ExternalUriReferenceTranslator.hpp> #include <com/sun/star/accessibility/XAccessibleContext.hpp> @@ -120,9 +121,13 @@ GtkWindow* RunDialog::GetTransientFor() return pParent; } -RunDialog::RunDialog( GtkWidget *pDialog, uno::Reference< awt::XExtendedToolkit >& rToolkit ) : - cppu::WeakComponentImplHelper< awt::XTopWindowListener, frame::XTerminateListener >( maLock ), - mpDialog(pDialog), mxToolkit(rToolkit) +RunDialog::RunDialog(GtkWidget *pDialog, const uno::Reference<awt::XExtendedToolkit>& rToolkit, + const uno::Reference<frame::XDesktop>& rDesktop) + : cppu::WeakComponentImplHelper<awt::XTopWindowListener, frame::XTerminateListener>(maLock) + , mpDialog(pDialog) + , mbTerminateDesktop(false) + , mxToolkit(rToolkit) + , mxDesktop(rDesktop) { } @@ -154,13 +159,17 @@ void SAL_CALL RunDialog::windowOpened(const css::lang::EventObject& e) void SAL_CALL RunDialog::queryTermination( const css::lang::EventObject& ) { + SolarMutexGuard g; + + g_timeout_add_full(G_PRIORITY_HIGH_IDLE, 0, reinterpret_cast<GSourceFunc>(canceldialog), this, nullptr); + + mbTerminateDesktop = true; + + throw css::frame::TerminationVetoException(); } void SAL_CALL RunDialog::notifyTermination( const css::lang::EventObject& ) { - SolarMutexGuard g; - - g_timeout_add_full(G_PRIORITY_HIGH_IDLE, 0, reinterpret_cast<GSourceFunc>(canceldialog), this, nullptr); } void RunDialog::cancel() @@ -169,19 +178,52 @@ void RunDialog::cancel() gtk_widget_hide( mpDialog ); } +namespace +{ + class ExecuteInfo + { + private: + css::uno::Reference<css::frame::XDesktop> mxDesktop; + public: + ExecuteInfo(const css::uno::Reference<css::frame::XDesktop>& rDesktop) + : mxDesktop(rDesktop) + { + } + void terminate() + { + mxDesktop->terminate(); + } + }; +} + gint RunDialog::run() { if (mxToolkit.is()) mxToolkit->addTopWindowListener(this); - gint nStatus = gtk_dialog_run( GTK_DIALOG( mpDialog ) ); + mxDesktop->addTerminateListener(this); + gint nStatus = gtk_dialog_run(GTK_DIALOG(mpDialog)); + mxDesktop->removeTerminateListener(this); if (mxToolkit.is()) mxToolkit->removeTopWindowListener(this); + if (mbTerminateDesktop) + { + ExecuteInfo* pExecuteInfo = new ExecuteInfo(mxDesktop); + Application::PostUserEvent(LINK(nullptr, RunDialog, TerminateDesktop), pExecuteInfo); + } + return nStatus; } +IMPL_STATIC_LINK(RunDialog, TerminateDesktop, void*, p, void) +{ + ExecuteInfo* pExecuteInfo = static_cast<ExecuteInfo*>(p); + pExecuteInfo->terminate(); + delete pExecuteInfo; +} + SalGtkPicker::SalGtkPicker( const uno::Reference<uno::XComponentContext>& xContext ) : m_pDialog( nullptr ), m_xContext( xContext ) { diff --git a/vcl/unx/gtk/fpicker/SalGtkPicker.hxx b/vcl/unx/gtk/fpicker/SalGtkPicker.hxx index b5bca9f75da2..6af2459562eb 100644 --- a/vcl/unx/gtk/fpicker/SalGtkPicker.hxx +++ b/vcl/unx/gtk/fpicker/SalGtkPicker.hxx @@ -80,7 +80,10 @@ class RunDialog : private: osl::Mutex maLock; GtkWidget *mpDialog; - css::uno::Reference< css::awt::XExtendedToolkit> mxToolkit; + bool mbTerminateDesktop; + css::uno::Reference<css::awt::XExtendedToolkit> mxToolkit; + css::uno::Reference<css::frame::XDesktop> mxDesktop; + DECL_STATIC_LINK(RunDialog, TerminateDesktop, void*, void); public: // XTopWindowListener @@ -99,8 +102,8 @@ public: virtual void SAL_CALL notifyTermination( const css::lang::EventObject& aEvent ) override; public: RunDialog(GtkWidget *pDialog, - css::uno::Reference< css::awt::XExtendedToolkit > &rToolkit - ); + const css::uno::Reference<css::awt::XExtendedToolkit>& rToolkit, + const css::uno::Reference<css::frame::XDesktop>& rDesktop); virtual ~RunDialog() override; gint run(); void cancel(); |