summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2018-10-02 16:08:35 +0200
committerCaolán McNamara <caolanm@redhat.com>2018-10-11 10:04:21 +0200
commitd6391f474a94becf3a30963356515c1a1d5c434e (patch)
tree086d7b88809f678eeb4a5142321e22179e4d91a8
parent72a44569af5d69b3093d01e4d16448509a8ad807 (diff)
tdf#120261 gtk3_kde5: Read IPC cmds in own thread on kde5 side
Move reading IPC commands and arguments to those commands to a separate thread and use the signal/slot mechanism to notify 'FilePickerIpc' whenever a new command and its arguments have been read. This allows to handle the events of other commands that have been received while the dialog is being executed. This will be needed by a subsequent change that will modify how IPC is handled on the gtk3 side. Change-Id: Ia77b21045b0196710cbe164fb640b36a128d5081 Reviewed-on: https://gerrit.libreoffice.org/61252 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> (cherry picked from commit 3b36855e48f6ef3f4e52e998c52c531fe5191477) Reviewed-on: https://gerrit.libreoffice.org/61510 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx229
-rw-r--r--vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx18
2 files changed, 186 insertions, 61 deletions
diff --git a/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx
index aeb864eae2ef..803e5bedd853 100644
--- a/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx
+++ b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx
@@ -27,7 +27,6 @@
#include <iostream>
-#include "filepicker_ipc_commands.hxx"
#include "kde5_filepicker.hxx"
#include <rtl/ustring.h>
@@ -53,49 +52,180 @@ void sendIpcArg(std::ostream& stream, const QStringList& list)
}
}
-FilePickerIpc::FilePickerIpc(KDE5FilePicker* filePicker, QObject* parent)
- : QObject(parent)
- , m_filePicker(filePicker)
- , m_stdinNotifier(new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this))
+void readCommandArgs(Commands command, QList<QVariant>& args)
{
- connect(m_stdinNotifier, &QSocketNotifier::activated, this, &FilePickerIpc::readCommands);
+ switch (command)
+ {
+ case Commands::SetTitle:
+ {
+ QString title;
+ readIpcArgs(std::cin, title);
+ args.append(title);
+ break;
+ }
+ case Commands::SetWinId:
+ {
+ sal_uIntPtr winId = 0;
+ readIpcArgs(std::cin, winId);
+ QVariant aWinIdVariant;
+ aWinIdVariant.setValue(winId);
+ args.append(aWinIdVariant);
+ break;
+ }
+ case Commands::SetMultiSelectionMode:
+ {
+ bool multiSelection = false;
+ readIpcArgs(std::cin, multiSelection);
+ args.append(multiSelection);
+ break;
+ }
+ case Commands::SetDefaultName:
+ {
+ QString name;
+ readIpcArgs(std::cin, name);
+ args.append(name);
+ break;
+ }
+ case Commands::SetDisplayDirectory:
+ {
+ QString dir;
+ readIpcArgs(std::cin, dir);
+ args.append(dir);
+ break;
+ }
+ case Commands::AppendFilter:
+ {
+ QString title, filter;
+ readIpcArgs(std::cin, title, filter);
+ args.append(title);
+ args.append(filter);
+ break;
+ }
+ case Commands::SetCurrentFilter:
+ {
+ QString title;
+ readIpcArgs(std::cin, title);
+ args.append(title);
+ break;
+ }
+ case Commands::SetValue:
+ {
+ sal_Int16 controlId = 0;
+ sal_Int16 nControlAction = 0;
+ bool value = false;
+ readIpcArgs(std::cin, controlId, nControlAction, value);
+ args.append(controlId);
+ args.append(nControlAction);
+ args.append(value);
+ break;
+ }
+ case Commands::GetValue:
+ {
+ sal_Int16 controlId = 0;
+ sal_Int16 nControlAction = 0;
+ readIpcArgs(std::cin, controlId, nControlAction);
+ args.append(controlId);
+ args.append(nControlAction);
+ break;
+ }
+ case Commands::EnableControl:
+ {
+ sal_Int16 controlId = 0;
+ bool enabled = false;
+ readIpcArgs(std::cin, controlId, enabled);
+ args.append(controlId);
+ args.append(enabled);
+ break;
+ }
+ case Commands::SetLabel:
+ {
+ sal_Int16 controlId = 0;
+ QString label;
+ readIpcArgs(std::cin, controlId, label);
+ args.append(controlId);
+ args.append(label);
+ break;
+ }
+ case Commands::GetLabel:
+ {
+ sal_Int16 controlId = 0;
+ readIpcArgs(std::cin, controlId);
+ args.append(controlId);
+ break;
+ }
+ case Commands::AddCheckBox:
+ {
+ sal_Int16 controlId = 0;
+ bool hidden = false;
+ QString label;
+ readIpcArgs(std::cin, controlId, hidden, label);
+ args.append(controlId);
+ args.append(hidden);
+ args.append(label);
+ break;
+ }
+ case Commands::Initialize:
+ {
+ bool saveDialog = false;
+ readIpcArgs(std::cin, saveDialog);
+ args.append(saveDialog);
+ break;
+ }
+ default:
+ {
+ // no extra parameters/arguments
+ break;
+ }
+ };
}
-FilePickerIpc::~FilePickerIpc() = default;
-
-void FilePickerIpc::readCommands()
+void readCommands(FilePickerIpc* ipc)
{
- // don't trigger again, loop runs until all is done
- disconnect(m_stdinNotifier, &QSocketNotifier::activated, this, &FilePickerIpc::readCommands);
-
- while (readCommand())
+ while (!std::cin.eof())
{
- // read next command
+ uint64_t messageId = 0;
+ Commands command;
+ readIpcArgs(std::cin, messageId, command);
+
+ // retrieve additional command-specific arguments
+ QList<QVariant> args;
+ readCommandArgs(command, args);
+
+ emit ipc->commandReceived(messageId, command, args);
}
}
-bool FilePickerIpc::readCommand()
+FilePickerIpc::FilePickerIpc(KDE5FilePicker* filePicker, QObject* parent)
+ : QObject(parent)
+ , m_filePicker(filePicker)
{
- if (std::cin.eof())
- return false;
+ // required to be able to pass those via signal/slot
+ qRegisterMetaType<uint64_t>("uint64_t");
+ qRegisterMetaType<Commands>("Commands");
+
+ connect(this, &FilePickerIpc::commandReceived, this, &FilePickerIpc::handleCommand);
+
+ // read IPC commands and their args in a separate thread, so this does not block everything else;
+ // 'commandReceived' signal is emitted every time a command and its args have been read;
+ // thread will run until the filepicker process is terminated
+ m_ipcReaderThread = std::unique_ptr<std::thread>{ new std::thread(readCommands, this) };
+}
- uint64_t messageId = 0;
- Commands command;
- readIpcArgs(std::cin, messageId, command);
+FilePickerIpc::~FilePickerIpc() = default;
+bool FilePickerIpc::handleCommand(uint64_t messageId, Commands command, QList<QVariant> args)
+{
switch (command)
{
case Commands::SetTitle:
{
- QString title;
- readIpcArgs(std::cin, title);
+ QString title = args.takeFirst().toString();
m_filePicker->setTitle(title);
return true;
}
case Commands::SetWinId:
{
- sal_uIntPtr winId = 0;
- readIpcArgs(std::cin, winId);
+ sal_uIntPtr winId = args.takeFirst().value<sal_uIntPtr>();
m_filePicker->setWinId(winId);
return true;
}
@@ -106,22 +236,19 @@ bool FilePickerIpc::readCommand()
}
case Commands::SetMultiSelectionMode:
{
- bool multiSelection = false;
- readIpcArgs(std::cin, multiSelection);
+ bool multiSelection = args.takeFirst().toBool();
m_filePicker->setMultiSelectionMode(multiSelection);
return true;
}
case Commands::SetDefaultName:
{
- QString name;
- readIpcArgs(std::cin, name);
+ QString name = args.takeFirst().toString();
m_filePicker->setDefaultName(name);
return true;
}
case Commands::SetDisplayDirectory:
{
- QString dir;
- readIpcArgs(std::cin, dir);
+ QString dir = args.takeFirst().toString();
m_filePicker->setDisplayDirectory(dir);
return true;
}
@@ -155,15 +282,14 @@ bool FilePickerIpc::readCommand()
}
case Commands::AppendFilter:
{
- QString title, filter;
- readIpcArgs(std::cin, title, filter);
+ QString title = args.takeFirst().toString();
+ QString filter = args.takeFirst().toString();
m_filePicker->appendFilter(title, filter);
return true;
}
case Commands::SetCurrentFilter:
{
- QString title;
- readIpcArgs(std::cin, title);
+ QString title = args.takeFirst().toString();
m_filePicker->setCurrentFilter(title);
return true;
}
@@ -174,57 +300,50 @@ bool FilePickerIpc::readCommand()
}
case Commands::SetValue:
{
- sal_Int16 controlId = 0;
- sal_Int16 nControlAction = 0;
- bool value = false;
- readIpcArgs(std::cin, controlId, nControlAction, value);
+ sal_Int16 controlId = args.takeFirst().value<sal_Int16>();
+ sal_Int16 nControlAction = args.takeFirst().value<sal_Int16>();
+ bool value = args.takeFirst().toBool();
m_filePicker->setValue(controlId, nControlAction, value);
return true;
}
case Commands::GetValue:
{
- sal_Int16 controlId = 0;
- sal_Int16 nControlAction = 0;
- readIpcArgs(std::cin, controlId, nControlAction);
+ sal_Int16 controlId = args.takeFirst().value<sal_Int16>();
+ sal_Int16 nControlAction = args.takeFirst().value<sal_Int16>();
sendIpcArgs(std::cout, messageId, m_filePicker->getValue(controlId, nControlAction));
return true;
}
case Commands::EnableControl:
{
- sal_Int16 controlId = 0;
- bool enabled = false;
- readIpcArgs(std::cin, controlId, enabled);
+ sal_Int16 controlId = args.takeFirst().value<sal_Int16>();
+ bool enabled = args.takeFirst().toBool();
m_filePicker->enableControl(controlId, enabled);
return true;
}
case Commands::SetLabel:
{
- sal_Int16 controlId = 0;
- QString label;
- readIpcArgs(std::cin, controlId, label);
+ sal_Int16 controlId = args.takeFirst().value<sal_Int16>();
+ QString label = args.takeFirst().toString();
m_filePicker->setLabel(controlId, label);
return true;
}
case Commands::GetLabel:
{
- sal_Int16 controlId = 0;
- readIpcArgs(std::cin, controlId);
+ sal_Int16 controlId = args.takeFirst().value<sal_Int16>();
sendIpcArgs(std::cout, messageId, m_filePicker->getLabel(controlId));
return true;
}
case Commands::AddCheckBox:
{
- sal_Int16 controlId = 0;
- bool hidden = false;
- QString label;
- readIpcArgs(std::cin, controlId, hidden, label);
+ sal_Int16 controlId = args.takeFirst().value<sal_Int16>();
+ bool hidden = args.takeFirst().toBool();
+ QString label = args.takeFirst().toString();
m_filePicker->addCheckBox(controlId, label, hidden);
return true;
}
case Commands::Initialize:
{
- bool saveDialog = false;
- readIpcArgs(std::cin, saveDialog);
+ bool saveDialog = args.takeFirst().toBool();
m_filePicker->initialize(saveDialog);
return true;
}
diff --git a/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx
index ff5abd250a2a..fa9be696c565 100644
--- a/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx
+++ b/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.hxx
@@ -19,8 +19,13 @@
#pragma once
+#include <memory>
+#include <thread>
+
#include <QObject>
+#include "filepicker_ipc_commands.hxx"
+
class KDE5FilePicker;
class WinIdEmbedder;
class QSocketNotifier;
@@ -32,14 +37,15 @@ public:
explicit FilePickerIpc(KDE5FilePicker* filePicker, QObject* parent = nullptr);
~FilePickerIpc() override;
-private Q_SLOTS:
- void readCommands();
-
private:
- bool readCommand();
-
KDE5FilePicker* m_filePicker = nullptr;
- QSocketNotifier* m_stdinNotifier = nullptr;
+ std::unique_ptr<std::thread> m_ipcReaderThread;
+
+private Q_SLOTS:
+ bool handleCommand(uint64_t messageId, Commands command, QList<QVariant> args);
+
+Q_SIGNALS:
+ bool commandReceived(uint64_t messageId, Commands command, QList<QVariant> args);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */