Skip to content

Commit

Permalink
Only allow a single instance of program to be run at a time (nomic-ai…
Browse files Browse the repository at this point in the history
…#2923)

Signed-off-by: Adam Treat <[email protected]>
Signed-off-by: Jared Van Bortel <[email protected]>
Co-authored-by: Jared Van Bortel <[email protected]>
  • Loading branch information
manyoso and cebtenzzre authored Aug 30, 2024
1 parent e1d49d9 commit 2f02cd4
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
[submodule "gpt4all-chat/usearch"]
path = gpt4all-chat/deps/usearch
url = https://github.com/nomic-ai/usearch.git
[submodule "gpt4all-chat/deps/SingleApplication"]
path = gpt4all-chat/deps/SingleApplication
url = https://github.com/nomic-ai/SingleApplication.git
1 change: 1 addition & 0 deletions gpt4all-chat/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### Changed
- Smaller default window size, dynamic minimum size, and scaling tweaks ([#2904](https://github.com/nomic-ai/gpt4all/pull/2904))
- Only allow a single instance of program to be run at a time ([#2923](https://github.com/nomic-ai/gpt4all/pull/2923]))

### Fixed
- Bring back "Auto" option for Embeddings Device as "Application default," which went missing in v3.1.0 ([#2873](https://github.com/nomic-ai/gpt4all/pull/2873))
Expand Down
4 changes: 3 additions & 1 deletion gpt4all-chat/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ if (APPLE)
list(APPEND CHAT_EXE_RESOURCES "${LOCAL_EMBEDDING_MODEL_PATH}")
endif()

set(QAPPLICATION_CLASS QGuiApplication)
add_subdirectory(deps/SingleApplication)
add_subdirectory(src)

target_sources(chat PRIVATE ${APP_ICON_RESOURCE} ${CHAT_EXE_RESOURCES})
Expand Down Expand Up @@ -238,7 +240,7 @@ else()
PRIVATE Qt6::Quick Qt6::Svg Qt6::HttpServer Qt6::Sql Qt6::Pdf)
endif()
target_link_libraries(chat
PRIVATE llmodel)
PRIVATE llmodel SingleApplication)


# -- install --
Expand Down
1 change: 1 addition & 0 deletions gpt4all-chat/deps/SingleApplication
Submodule SingleApplication added at 21bdef
47 changes: 42 additions & 5 deletions gpt4all-chat/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,44 @@
#include "network.h"

#include <gpt4all-backend/llmodel.h>
#include <singleapplication.h>

#include <QCoreApplication>
#include <QGuiApplication>
#include <QObject>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QQuickWindow>
#include <QSettings>
#include <QString>
#include <QTranslator>
#include <QUrl>
#include <Qt>

#ifdef Q_OS_LINUX
# include <QIcon>
#endif

#ifdef Q_OS_WINDOWS
# include <windows.h>
#endif

using namespace Qt::Literals::StringLiterals;


static void raiseWindow(QWindow *window)
{
#ifdef Q_OS_WINDOWS
HWND hwnd = HWND(window->winId());

// check if window is minimized to Windows task bar
if (IsIconic(hwnd))
ShowWindow(hwnd, SW_RESTORE);

SetForegroundWindow(hwnd);
#else
window->show();
window->raise();
window->requestActivate();
#endif
}

int main(int argc, char *argv[])
{
Expand All @@ -36,7 +58,15 @@ int main(int argc, char *argv[])

Logger::globalInstance();

QGuiApplication app(argc, argv);
SingleApplication app(argc, argv, true /*allowSecondary*/);
if (app.isSecondary()) {
#ifdef Q_OS_WINDOWS
AllowSetForegroundWindow(DWORD(app.primaryPid()));
#endif
app.sendMessage("RAISE_WINDOW");
return 0;
}

#ifdef Q_OS_LINUX
app.setWindowIcon(QIcon(":/gpt4all/icons/gpt4all.svg"));
#endif
Expand Down Expand Up @@ -77,7 +107,7 @@ int main(int argc, char *argv[])
qmlRegisterSingletonInstance("localdocs", 1, 0, "LocalDocs", LocalDocs::globalInstance());
qmlRegisterUncreatableMetaObject(MySettingsEnums::staticMetaObject, "mysettingsenums", 1, 0, "MySettingsEnums", "Error: only enums");

const QUrl url(u"qrc:/gpt4all/main.qml"_qs);
const QUrl url(u"qrc:/gpt4all/main.qml"_s);

QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
Expand All @@ -86,6 +116,13 @@ int main(int argc, char *argv[])
}, Qt::QueuedConnection);
engine.load(url);

QObject *rootObject = engine.rootObjects().first();
QQuickWindow *windowObject = qobject_cast<QQuickWindow *>(rootObject);
Q_ASSERT(windowObject);
if (windowObject)
QObject::connect(&app, &SingleApplication::receivedMessage,
windowObject, [windowObject] () { raiseWindow(windowObject); } );

#if 0
QDirIterator it("qrc:", QDirIterator::Subdirectories);
while (it.hasNext()) {
Expand Down

0 comments on commit 2f02cd4

Please sign in to comment.