diff --git a/src/main.cpp b/src/main.cpp index a468b24d..cf81a5b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "utils/vutils.h" #include "vsingleinstanceguard.h" @@ -233,5 +234,13 @@ int main(int argc, char *argv[]) w.kickOffStartUpTimer(filePaths); - return app.exec(); + int ret = app.exec(); + if (ret == RESTART_EXIT_CODE) { + // Ask to restart VNote. + guard.exit(); + QProcess::startDetached(qApp->applicationFilePath(), QStringList()); + return 0; + } + + return ret; } diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index edfa73cb..7aca8390 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -1097,6 +1097,12 @@ void VMainWindow::initFileMenu() fileMenu->addSeparator(); + // Restart. + QAction *restartAct = new QAction(tr("Restart"), this); + connect(restartAct, &QAction::triggered, + this, &VMainWindow::restartVNote); + fileMenu->addAction(restartAct); + // Exit. QAction *exitAct = new QAction(tr("&Quit"), this); exitAct->setToolTip(tr("Quit VNote")); @@ -3394,3 +3400,8 @@ void VMainWindow::initUpdateTimer() m_noteToolBar->update(); }); } + +void VMainWindow::restartVNote() +{ + QCoreApplication::exit(RESTART_EXIT_CODE); +} diff --git a/src/vmainwindow.h b/src/vmainwindow.h index 0751ed10..ef8ae7c1 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -46,6 +46,8 @@ class VHistoryList; class VExplorer; class VTagExplorer; +#define RESTART_EXIT_CODE 1000 + enum class PanelViewState { ExpandMode = 0, @@ -130,6 +132,9 @@ public: void setCaptainModeEnabled(bool p_enabled); +public slots: + void restartVNote(); + signals: // Emit when editor related configurations were changed by user. void editorConfigUpdated(); diff --git a/src/vsingleinstanceguard.cpp b/src/vsingleinstanceguard.cpp index 42437190..d2a39654 100644 --- a/src/vsingleinstanceguard.cpp +++ b/src/vsingleinstanceguard.cpp @@ -7,12 +7,15 @@ const QString VSingleInstanceGuard::c_memKey = "vnote_shared_memory"; const int VSingleInstanceGuard::c_magic = 133191933; VSingleInstanceGuard::VSingleInstanceGuard() - : m_sharedMemory(c_memKey) + : m_sharedMemory(c_memKey), + m_online(false) { } bool VSingleInstanceGuard::tryRun() { + m_online = false; + // If we can attach to the sharedmemory, there is another instance running. // In Linux, crashes may cause the shared memory segment remains. In this case, // this will attach to the old segment, then exit, freeing the old segment. @@ -31,6 +34,8 @@ bool VSingleInstanceGuard::tryRun() str->m_filesBufIdx = 0; str->m_askedToShow = false; m_sharedMemory.unlock(); + + m_online = true; return true; } else { qDebug() << "fail to create shared memory segment"; @@ -109,6 +114,11 @@ bool VSingleInstanceGuard::appendFileToBuffer(SharedStruct *p_str, const QString QStringList VSingleInstanceGuard::fetchFilesToOpen() { QStringList files; + + if (!m_online) { + return files; + } + Q_ASSERT(m_sharedMemory.isAttached()); m_sharedMemory.lock(); SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); @@ -153,15 +163,28 @@ void VSingleInstanceGuard::showInstance() bool VSingleInstanceGuard::fetchAskedToShow() { - bool ret = false; + if (!m_online) { + return false; + } Q_ASSERT(m_sharedMemory.isAttached()); m_sharedMemory.lock(); SharedStruct *str = (SharedStruct *)m_sharedMemory.data(); Q_ASSERT(str->m_magic == c_magic); - ret = str->m_askedToShow; + bool ret = str->m_askedToShow; str->m_askedToShow = false; m_sharedMemory.unlock(); return ret; } + +void VSingleInstanceGuard::exit() +{ + if (!m_online) { + return; + } + + Q_ASSERT(m_sharedMemory.isAttached()); + m_sharedMemory.detach(); + m_online = false; +} diff --git a/src/vsingleinstanceguard.h b/src/vsingleinstanceguard.h index 750f3a3a..f212aeaf 100644 --- a/src/vsingleinstanceguard.h +++ b/src/vsingleinstanceguard.h @@ -28,6 +28,9 @@ public: // Whether this instance is asked to show itself. bool fetchAskedToShow(); + // A running instance requests to exit. + void exit(); + private: // The count of the entries in the buffer to hold the path of the files to open. enum { FilesBufCount = 1024 }; @@ -53,6 +56,8 @@ private: // Returns true if succeeds or false if there is no enough space. bool appendFileToBuffer(SharedStruct *p_str, const QString &p_file); + bool m_online; + QSharedMemory m_sharedMemory; static const QString c_memKey;