Merge pull request #15451 from Ondsel-Development/fix-single-instance-windows
Core: Fix single instance windows
This commit is contained in:
@@ -2001,10 +2001,9 @@ bool onlySingleInstance(GUISingleApplication& mainApp)
|
||||
fn = QDir::cleanPath(fn);
|
||||
}
|
||||
|
||||
QByteArray msg = fn.toUtf8();
|
||||
msg.prepend("OpenFile:");
|
||||
if (!mainApp.sendMessage(msg)) {
|
||||
qWarning("Failed to send message to server");
|
||||
fn.prepend(QLatin1String("OpenFile:"));
|
||||
if (!mainApp.sendMessage(fn)) {
|
||||
qWarning("Failed to send OpenFile message to server");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
# include <QAbstractSpinBox>
|
||||
# include <QByteArray>
|
||||
# include <QComboBox>
|
||||
# include <QDataStream>
|
||||
# include <QTextStream>
|
||||
# include <QFileInfo>
|
||||
# include <QFileOpenEvent>
|
||||
# include <QSessionManager>
|
||||
@@ -218,7 +218,7 @@ public:
|
||||
QTimer *timer;
|
||||
QLocalServer *server{nullptr};
|
||||
QString serverName;
|
||||
QList<QByteArray> messages;
|
||||
QList<QString> messages;
|
||||
bool running{false};
|
||||
};
|
||||
|
||||
@@ -237,15 +237,16 @@ bool GUISingleApplication::isRunning() const
|
||||
return d_ptr->running;
|
||||
}
|
||||
|
||||
bool GUISingleApplication::sendMessage(const QByteArray &message, int timeout)
|
||||
bool GUISingleApplication::sendMessage(const QString &message, int timeout)
|
||||
{
|
||||
QLocalSocket socket;
|
||||
bool connected = false;
|
||||
for(int i = 0; i < 2; i++) {
|
||||
socket.connectToServer(d_ptr->serverName);
|
||||
connected = socket.waitForConnected(timeout/2);
|
||||
if (connected || i > 0)
|
||||
if (connected || i > 0) {
|
||||
break;
|
||||
}
|
||||
int ms = 250;
|
||||
#if defined(Q_OS_WIN)
|
||||
Sleep(DWORD(ms));
|
||||
@@ -253,41 +254,60 @@ bool GUISingleApplication::sendMessage(const QByteArray &message, int timeout)
|
||||
usleep(ms*1000);
|
||||
#endif
|
||||
}
|
||||
if (!connected)
|
||||
if (!connected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QDataStream ds(&socket);
|
||||
ds << message;
|
||||
socket.waitForBytesWritten(timeout);
|
||||
return true;
|
||||
QTextStream ts(&socket);
|
||||
#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0)
|
||||
ts.setCodec("UTF-8");
|
||||
#else
|
||||
ts.setEncoding(QStringConverter::Utf8);
|
||||
#endif
|
||||
#if QT_VERSION <= QT_VERSION_CHECK(5, 15, 0)
|
||||
ts << message << endl;
|
||||
#else
|
||||
ts << message << Qt::endl;
|
||||
#endif
|
||||
|
||||
return socket.waitForBytesWritten(timeout);
|
||||
}
|
||||
|
||||
void GUISingleApplication::readFromSocket()
|
||||
{
|
||||
auto socket = qobject_cast<QLocalSocket*>(sender());
|
||||
if (socket) {
|
||||
QTextStream in(socket);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
in.setCodec("UTF-8");
|
||||
#else
|
||||
in.setEncoding(QStringConverter::Utf8);
|
||||
#endif
|
||||
while (socket->canReadLine()) {
|
||||
d_ptr->timer->stop();
|
||||
QString message = in.readLine();
|
||||
Base::Console().Log("Received message: %s\n", message.toStdString());
|
||||
d_ptr->messages.push_back(message);
|
||||
d_ptr->timer->start(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GUISingleApplication::receiveConnection()
|
||||
{
|
||||
QLocalSocket *socket = d_ptr->server->nextPendingConnection();
|
||||
if (!socket)
|
||||
if (!socket) {
|
||||
return;
|
||||
}
|
||||
|
||||
connect(socket, &QLocalSocket::disconnected,
|
||||
socket, &QLocalSocket::deleteLater);
|
||||
if (socket->waitForReadyRead()) {
|
||||
QDataStream in(socket);
|
||||
if (!in.atEnd()) {
|
||||
d_ptr->timer->stop();
|
||||
QByteArray message;
|
||||
in >> message;
|
||||
Base::Console().Log("Received message: %s\n", message.constData());
|
||||
d_ptr->messages.push_back(message);
|
||||
d_ptr->timer->start(1000);
|
||||
}
|
||||
}
|
||||
|
||||
socket->disconnectFromServer();
|
||||
connect(socket, &QLocalSocket::readyRead, this, &GUISingleApplication::readFromSocket);
|
||||
}
|
||||
|
||||
void GUISingleApplication::processMessages()
|
||||
{
|
||||
QList<QByteArray> msg = d_ptr->messages;
|
||||
QList<QString> msg = d_ptr->messages;
|
||||
d_ptr->messages.clear();
|
||||
Q_EMIT messageReceived(msg);
|
||||
}
|
||||
|
||||
@@ -69,14 +69,15 @@ public:
|
||||
~GUISingleApplication() override;
|
||||
|
||||
bool isRunning() const;
|
||||
bool sendMessage(const QByteArray &message, int timeout = 5000);
|
||||
bool sendMessage(const QString &message, int timeout = 5000);
|
||||
|
||||
private Q_SLOTS:
|
||||
void receiveConnection();
|
||||
void processMessages();
|
||||
void readFromSocket();
|
||||
|
||||
Q_SIGNALS:
|
||||
void messageReceived(const QList<QByteArray> &);
|
||||
void messageReceived(const QList<QString> &);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
|
||||
@@ -1557,16 +1557,16 @@ void MainWindow::hideEvent(QHideEvent* e)
|
||||
QMainWindow::hideEvent(e);
|
||||
}
|
||||
|
||||
void MainWindow::processMessages(const QList<QByteArray> & msg)
|
||||
void MainWindow::processMessages(const QList<QString> & msg)
|
||||
{
|
||||
// handle all the messages to open files
|
||||
try {
|
||||
WaitCursor wc;
|
||||
std::list<std::string> files;
|
||||
QByteArray action("OpenFile:");
|
||||
QString action = QString::fromStdString("OpenFile:");
|
||||
for (const auto & it : msg) {
|
||||
if (it.startsWith(action))
|
||||
files.emplace_back(it.mid(action.size()).constData());
|
||||
files.emplace_back(it.mid(action.size()).toStdString());
|
||||
}
|
||||
files = App::Application::processFiles(files);
|
||||
for (const auto & file : files) {
|
||||
|
||||
@@ -350,7 +350,7 @@ private Q_SLOTS:
|
||||
/**
|
||||
* \internal
|
||||
*/
|
||||
void processMessages(const QList<QByteArray> &);
|
||||
void processMessages(const QList<QString> &);
|
||||
/**
|
||||
* \internal
|
||||
*/
|
||||
|
||||
@@ -247,8 +247,8 @@ void StartupPostProcess::setWindowTitle()
|
||||
void StartupPostProcess::setProcessMessages()
|
||||
{
|
||||
if (!loadFromPythonModule) {
|
||||
QObject::connect(qtApp, SIGNAL(messageReceived(const QList<QByteArray> &)),
|
||||
mainWindow, SLOT(processMessages(const QList<QByteArray> &)));
|
||||
QObject::connect(qtApp, SIGNAL(messageReceived(const QList<QString> &)),
|
||||
mainWindow, SLOT(processMessages(const QList<QString> &)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,12 +77,12 @@ Section -Configure
|
||||
WriteRegStr SHCTX "${APP_DIR_REGKEY}" "" "$INSTDIR\${APP_RUN}"
|
||||
WriteRegStr SHCTX "Software\Classes\${APP_REGNAME_DOC}" "" "${APP_NAME} Document"
|
||||
WriteRegStr SHCTX "Software\Classes\${APP_REGNAME_DOC}\DefaultIcon" "" "$INSTDIR\${APP_RUN},0"
|
||||
WriteRegStr SHCTX "Software\Classes\${APP_REGNAME_DOC}\Shell\open\command" "" '"$INSTDIR\${APP_RUN}" "%1"'
|
||||
WriteRegStr SHCTX "Software\Classes\${APP_REGNAME_DOC}\Shell\open\command" "" '"$INSTDIR\${APP_RUN}" --single-instance "%1"'
|
||||
# we need to update also the automatically created entry about the FreeCAD.exe
|
||||
# otherwise .FCStd-files will could be opened with an older FreeCAD version
|
||||
ReadRegStr $0 SHCTX "Software\Classes\Applications\${BIN_FREECAD}\shell\open\command" ""
|
||||
${if} $0 != "" # if something was found
|
||||
WriteRegStr SHCTX "Software\Classes\Applications\${BIN_FREECAD}\shell\open\command" "" '"$INSTDIR\${APP_RUN}" "%1"'
|
||||
WriteRegStr SHCTX "Software\Classes\Applications\${BIN_FREECAD}\shell\open\command" "" '"$INSTDIR\${APP_RUN}" --single-instance "%1"'
|
||||
${endif}
|
||||
# .FCStd
|
||||
WriteRegStr SHCTX "Software\Classes\${APP_EXT}" "" "${APP_REGNAME_DOC}"
|
||||
|
||||
Reference in New Issue
Block a user