[Libreoffice-commits] core.git: vcl/unx
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Mon Oct 8 07:00:31 UTC 2018
vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx | 43 +++++++++++++++----
vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx | 55 ++++++++++---------------
2 files changed, 57 insertions(+), 41 deletions(-)
New commits:
commit 788716cebad012513cc2798589b817b86cbf1bbc
Author: Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Tue Oct 2 16:13:51 2018 +0200
Commit: Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Mon Oct 8 09:00:08 2018 +0200
tdf#120261 gtk3_kde5: Leave event handling on gtk3 side to gtk
This introduces a new thread that takes care of handling the IPC
command and result for executing the file picker
('Commands::Execute'), which is the only command in the file
picker that may block for a longer time until it receives its
result from the kde5 side (namely, when the dialog has been
closed).
While the file dialog is being executed, activate a dummy GTK dialog
that also takes care of handling events in its main loop as long
as the file dialog is shown. The dummy dialog is closed together
with the KDE file dialog.
(Since the actual KDE file dialog is run as a separate process,
this one is mostly "transparent" to the soffice process from the
point of view of a dialog.)
This allows dropping the custom event processing previously done
in 'Gtk3KDE5FilePickerIpc::readResponse()' that had the potential
to cause all kinds of problems, e.g. when another event related to
the file picker was triggered from a Java process via UNO.
Change-Id: I3d663253f09320f7a8e0d9ec32a8fd6ec191c189
Reviewed-on: https://gerrit.libreoffice.org/61253
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx
index 8cec9d853fbc..36ddcaf40f6e 100644
--- a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.cxx
@@ -106,6 +106,17 @@ OUString getResString(const char* pResId)
return VclResId(pResId);
}
+// handles the IPC commands for dialog execution and ends the dummy Gtk dialog once the IPC response is there
+void handleIpcForExecute(Gtk3KDE5FilePickerIpc* pFilePickerIpc, GtkWidget* pDummyDialog,
+ bool* bResult)
+{
+ auto id = pFilePickerIpc->sendCommand(Commands::Execute);
+ pFilePickerIpc->readResponse(id, *bResult);
+
+ // end the dummy dialog
+ gtk_widget_hide(pDummyDialog);
+}
+
// Gtk3KDE5FilePicker
Gtk3KDE5FilePickerIpc::Gtk3KDE5FilePickerIpc()
@@ -143,9 +154,29 @@ sal_Int16 Gtk3KDE5FilePickerIpc::execute()
{
auto restoreMainWindow = blockMainWindow();
- auto id = sendCommand(Commands::Execute);
+ // dummy gtk dialog that will take care of processing events,
+ // not meant to be actually seen by user
+ GtkWidget* pDummyDialog = gtk_dialog_new();
+
bool accepted = false;
- readResponse(id, accepted);
+
+ // send IPC command and read response in a separate thread
+ std::thread aIpcHandler(&handleIpcForExecute, this, pDummyDialog, &accepted);
+
+ // make dummy dialog not to be seen by user
+ gtk_window_set_decorated(GTK_WINDOW(pDummyDialog), false);
+ gtk_window_set_default_size(GTK_WINDOW(pDummyDialog), 0, 0);
+ gtk_window_set_accept_focus(GTK_WINDOW(pDummyDialog), false);
+ // gtk_widget_set_opacity() only has the desired effect when widget is already shown
+ gtk_widget_show(pDummyDialog);
+ gtk_widget_set_opacity(pDummyDialog, 0);
+ // run dialog, leaving event processing to GTK
+ // dialog will be closed by the separate 'aIpcHandler' thread once the IPC response is there
+ gtk_dialog_run(GTK_DIALOG(pDummyDialog));
+
+ aIpcHandler.join();
+
+ gtk_widget_destroy(pDummyDialog);
if (restoreMainWindow)
restoreMainWindow();
@@ -204,14 +235,6 @@ std::function<void()> Gtk3KDE5FilePickerIpc::blockMainWindow()
};
}
-void Gtk3KDE5FilePickerIpc::await(const std::future<void>& future)
-{
- while (future.wait_for(std::chrono::milliseconds(1)) != std::future_status::ready)
- {
- GetGtkSalData()->Yield(false, true);
- }
-}
-
void Gtk3KDE5FilePickerIpc::writeResponseLine(const std::string& line)
{
sal_uInt64 bytesWritten = 0;
diff --git a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx
index 90ec4e1d55ab..a9584b11fcd2 100644
--- a/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx
+++ b/vcl/unx/gtk3_kde5/gtk3_kde5_filepicker_ipc.hxx
@@ -30,7 +30,6 @@
#include "filepicker_ipc_commands.hxx"
#include <functional>
-#include <future>
#include <mutex>
#include <thread>
#include <sstream>
@@ -105,43 +104,37 @@ public:
template <typename... Args> void readResponse(uint64_t id, Args&... args)
{
- // read synchronously from a background thread and run the eventloop until the value becomes available
- // this allows us to keep the GUI responsive and also enables access to the LO clipboard
ArgsReader<Args...> argsReader(args...);
- await(std::async(std::launch::async, [&]() {
- while (true)
+ while (true)
+ {
+ // only let one thread read at any given time
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ // check if we need to read (and potentially wait) a response ID
+ if (m_incomingResponse == 0)
+ {
+ m_responseStream.clear();
+ m_responseStream.str(readResponseLine());
+ readIpcArgs(m_responseStream, m_incomingResponse);
+ }
+
+ if (m_incomingResponse == id)
{
- // only let one thread read at any given time
- std::lock_guard<std::mutex> lock(m_mutex);
-
- // check if we need to read (and potentially wait) a response ID
- if (m_incomingResponse == 0)
- {
- m_responseStream.clear();
- m_responseStream.str(readResponseLine());
- readIpcArgs(m_responseStream, m_incomingResponse);
- }
-
- if (m_incomingResponse == id)
- {
- // the response we are waiting for came in
- argsReader(m_responseStream);
- m_incomingResponse = 0;
- break;
- }
- else
- {
- // the next response answers some other request, yield
- std::this_thread::yield();
- }
+ // the response we are waiting for came in
+ argsReader(m_responseStream);
+ m_incomingResponse = 0;
+ break;
}
- }));
+ else
+ {
+ // the next response answers some other request, yield
+ std::this_thread::yield();
+ }
+ }
}
private:
std::function<void()> blockMainWindow();
-
- static void await(const std::future<void>& future);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list