Kaydet (Commit) 3b36855e authored tarafından Michael Weghorn's avatar Michael Weghorn

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: 's avatarMichael Weghorn <m.weghorn@posteo.de>
üst 307c29ec
......@@ -27,7 +27,6 @@
#include <iostream>
#include "filepicker_ipc_commands.hxx"
#include "kde5_filepicker.hxx"
#include <rtl/ustring.h>
......@@ -53,49 +52,180 @@ static 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;
}
......
......@@ -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: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment