mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Merge pull request #4183
tux3 (4): fix: Accept IDs as tox URIs, not just ToxDNS addresses fix: Various IPC event handling and related bugs on startup fix: Don't even try to add ourselves as a friend in the Tox URI handler fix: msleep in toxuri processEvents loops, to avoid 100% CPU
This commit is contained in:
commit
ea44095c94
|
@ -94,10 +94,13 @@ Core::~Core()
|
||||||
Q_ARG(bool, false));
|
Q_ARG(bool, false));
|
||||||
}
|
}
|
||||||
coreThread->exit(0);
|
coreThread->exit(0);
|
||||||
while (coreThread->isRunning())
|
if (QThread::currentThread() != coreThread)
|
||||||
{
|
{
|
||||||
qApp->processEvents();
|
while (coreThread->isRunning())
|
||||||
coreThread->wait(500);
|
{
|
||||||
|
qApp->processEvents();
|
||||||
|
coreThread->wait(500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deadifyTox();
|
deadifyTox();
|
||||||
|
|
|
@ -175,6 +175,10 @@ bool IPC::isCurrentOwner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a handler for an IPC event
|
||||||
|
* @param handler The handler callback. Should not block for more than a second, at worst
|
||||||
|
*/
|
||||||
void IPC::registerEventHandler(const QString &name, IPCEventHandler handler)
|
void IPC::registerEventHandler(const QString &name, IPCEventHandler handler)
|
||||||
{
|
{
|
||||||
eventHandlers[name] = handler;
|
eventHandlers[name] = handler;
|
||||||
|
|
|
@ -295,7 +295,8 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Nexus::getInstance().start();
|
Nexus& nexus = Nexus::getInstance();
|
||||||
|
nexus.start();
|
||||||
|
|
||||||
// Event was not handled by already running instance therefore we handle it ourselves
|
// Event was not handled by already running instance therefore we handle it ourselves
|
||||||
if (eventType == "uri")
|
if (eventType == "uri")
|
||||||
|
@ -303,8 +304,10 @@ int main(int argc, char *argv[])
|
||||||
else if (eventType == "save")
|
else if (eventType == "save")
|
||||||
handleToxSave(firstParam.toUtf8());
|
handleToxSave(firstParam.toUtf8());
|
||||||
|
|
||||||
// Run
|
// Run (unless we already quit before starting!)
|
||||||
int errorcode = a.exec();
|
int errorcode = 0;
|
||||||
|
if (nexus.isRunning())
|
||||||
|
errorcode = a.exec();
|
||||||
|
|
||||||
Nexus::destroyInstance();
|
Nexus::destroyInstance();
|
||||||
CameraSource::destroyInstance();
|
CameraSource::destroyInstance();
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
bool toxURIEventHandler(const QByteArray& eventData)
|
bool toxURIEventHandler(const QByteArray& eventData)
|
||||||
{
|
{
|
||||||
|
@ -51,33 +52,70 @@ bool toxURIEventHandler(const QByteArray& eventData)
|
||||||
*/
|
*/
|
||||||
bool handleToxURI(const QString &toxURI)
|
bool handleToxURI(const QString &toxURI)
|
||||||
{
|
{
|
||||||
Core* core = Core::getInstance();
|
Nexus& nexus = Nexus::getInstance();
|
||||||
|
Core* core = nexus.getCore();
|
||||||
|
|
||||||
while (!core)
|
while (!core)
|
||||||
{
|
{
|
||||||
core = Core::getInstance();
|
if (!nexus.isRunning())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
core = nexus.getCore();
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
|
QThread::msleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!core->isReady())
|
while (!core->isReady())
|
||||||
|
{
|
||||||
|
if (!nexus.isRunning())
|
||||||
|
return false;
|
||||||
|
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
|
QThread::msleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
QString toxaddr = toxURI.mid(4);
|
QString toxaddr = toxURI.mid(4);
|
||||||
|
|
||||||
ToxId toxId = Toxme::lookup(toxaddr);
|
ToxId toxId(toxaddr);
|
||||||
if (!toxId.isValid())
|
if (!toxId.isValid())
|
||||||
{
|
{
|
||||||
QMessageBox::warning(0, "qTox",
|
toxId = Toxme::lookup(toxaddr);
|
||||||
ToxURIDialog::tr("%1 is not a valid Toxme address.")
|
if (!toxId.isValid())
|
||||||
.arg(toxaddr));
|
{
|
||||||
|
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
||||||
|
QMessageBox::tr("Couldn't add friend"),
|
||||||
|
QMessageBox::tr("%1 is not a valid Toxme address.")
|
||||||
|
.arg(toxaddr), QMessageBox::Ok, nullptr);
|
||||||
|
messageBox->setButtonText(QMessageBox::Ok, QMessageBox::tr("Ok"));
|
||||||
|
QObject::connect(messageBox, &QMessageBox::finished, messageBox, &QMessageBox::deleteLater);
|
||||||
|
messageBox->show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toxId == core->getSelfId())
|
||||||
|
{
|
||||||
|
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
||||||
|
QMessageBox::tr("Couldn't add friend"),
|
||||||
|
QMessageBox::tr("You can't add yourself as a friend!",
|
||||||
|
"When trying to add your own Tox ID as friend"),
|
||||||
|
QMessageBox::Ok, nullptr);
|
||||||
|
messageBox->setButtonText(QMessageBox::Ok, QMessageBox::tr("Ok"));
|
||||||
|
QObject::connect(messageBox, &QMessageBox::finished, messageBox, &QMessageBox::deleteLater);
|
||||||
|
messageBox->show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToxURIDialog dialog(0, toxaddr, QObject::tr("%1 here! Tox me maybe?",
|
ToxURIDialog *dialog = new ToxURIDialog(0, toxaddr, QObject::tr("%1 here! Tox me maybe?",
|
||||||
"Default message in Tox URI friend requests. Write something appropriate!")
|
"Default message in Tox URI friend requests. Write something appropriate!")
|
||||||
.arg(Nexus::getCore()->getUsername()));
|
.arg(Nexus::getCore()->getUsername()));
|
||||||
if (dialog.exec() == QDialog::Accepted)
|
QObject::connect(dialog, &ToxURIDialog::finished, [=](int result) {
|
||||||
Core::getInstance()->requestFriendship(toxId, dialog.getRequestMessage());
|
if (result == QDialog::Accepted)
|
||||||
|
Core::getInstance()->requestFriendship(toxId, dialog->getRequestMessage());
|
||||||
|
|
||||||
|
dialog->deleteLater();
|
||||||
|
});
|
||||||
|
dialog->open();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,15 +59,20 @@ Nexus::Nexus(QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
profile{nullptr},
|
profile{nullptr},
|
||||||
widget{nullptr},
|
widget{nullptr},
|
||||||
loginScreen{nullptr}
|
loginScreen{nullptr},
|
||||||
|
running{true},
|
||||||
|
quitOnLastWindowClosed{true}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Nexus::~Nexus()
|
Nexus::~Nexus()
|
||||||
{
|
{
|
||||||
delete widget;
|
delete widget;
|
||||||
|
widget = nullptr;
|
||||||
delete loginScreen;
|
delete loginScreen;
|
||||||
|
loginScreen = nullptr;
|
||||||
delete profile;
|
delete profile;
|
||||||
|
profile = nullptr;
|
||||||
Settings::getInstance().saveGlobal();
|
Settings::getInstance().saveGlobal();
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
delete globalMenuBar;
|
delete globalMenuBar;
|
||||||
|
@ -104,6 +109,14 @@ void Nexus::start()
|
||||||
|
|
||||||
loginScreen = new LoginScreen();
|
loginScreen = new LoginScreen();
|
||||||
|
|
||||||
|
// We need this LastWindowClosed dance because the LoginScreen may be shown
|
||||||
|
// and closed in a processEvents() loop before the start of the real
|
||||||
|
// exec() event loop, meaning we wouldn't receive the onLastWindowClosed,
|
||||||
|
// and so we wouldn't have a chance to tell the processEvents() loop to quit.
|
||||||
|
qApp->setQuitOnLastWindowClosed(false);
|
||||||
|
connect(qApp, &QApplication::lastWindowClosed, this, &Nexus::onLastWindowClosed);
|
||||||
|
connect(loginScreen, &LoginScreen::closed, this, &Nexus::onLastWindowClosed);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
globalMenuBar = new QMenuBar(0);
|
globalMenuBar = new QMenuBar(0);
|
||||||
dockMenu = new QMenu(globalMenuBar);
|
dockMenu = new QMenu(globalMenuBar);
|
||||||
|
@ -161,14 +174,14 @@ void Nexus::showLogin()
|
||||||
loginScreen->reset();
|
loginScreen->reset();
|
||||||
loginScreen->move(QApplication::desktop()->screen()->rect().center() - loginScreen->rect().center());
|
loginScreen->move(QApplication::desktop()->screen()->rect().center() - loginScreen->rect().center());
|
||||||
loginScreen->show();
|
loginScreen->show();
|
||||||
((QApplication*)qApp)->setQuitOnLastWindowClosed(true);
|
quitOnLastWindowClosed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nexus::showMainGUI()
|
void Nexus::showMainGUI()
|
||||||
{
|
{
|
||||||
assert(profile);
|
assert(profile);
|
||||||
|
|
||||||
((QApplication*)qApp)->setQuitOnLastWindowClosed(false);
|
quitOnLastWindowClosed = false;
|
||||||
loginScreen->close();
|
loginScreen->close();
|
||||||
|
|
||||||
// Create GUI
|
// Create GUI
|
||||||
|
@ -220,6 +233,26 @@ void Nexus::showMainGUI()
|
||||||
profile->startCore();
|
profile->startCore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calls QApplication::quit(), and causes Nexus::isRunning() to return false
|
||||||
|
*/
|
||||||
|
void Nexus::quit()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
qApp->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true until Nexus::quit is called.
|
||||||
|
*
|
||||||
|
* Any blocking processEvents() loop should check this as a return condition,
|
||||||
|
* since the application can not quit until control is returned to the event loop.
|
||||||
|
*/
|
||||||
|
bool Nexus::isRunning()
|
||||||
|
{
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the singleton instance.
|
* @brief Returns the singleton instance.
|
||||||
*/
|
*/
|
||||||
|
@ -310,6 +343,12 @@ void Nexus::showLoginLater()
|
||||||
QMetaObject::invokeMethod(&getInstance(), "showLogin", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(&getInstance(), "showLogin", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nexus::onLastWindowClosed()
|
||||||
|
{
|
||||||
|
if (quitOnLastWindowClosed)
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
void Nexus::retranslateUi()
|
void Nexus::retranslateUi()
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,8 @@ class Nexus : public QObject
|
||||||
public:
|
public:
|
||||||
void start();
|
void start();
|
||||||
void showMainGUI();
|
void showMainGUI();
|
||||||
|
void quit();
|
||||||
|
bool isRunning();
|
||||||
|
|
||||||
static Nexus& getInstance();
|
static Nexus& getInstance();
|
||||||
static void destroyInstance();
|
static void destroyInstance();
|
||||||
|
@ -84,6 +86,9 @@ private:
|
||||||
QActionGroup* windowActions = nullptr;
|
QActionGroup* windowActions = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onLastWindowClosed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Nexus(QObject *parent = 0);
|
explicit Nexus(QObject *parent = 0);
|
||||||
~Nexus();
|
~Nexus();
|
||||||
|
@ -92,6 +97,8 @@ private:
|
||||||
Profile* profile;
|
Profile* profile;
|
||||||
Widget* widget;
|
Widget* widget;
|
||||||
LoginScreen* loginScreen;
|
LoginScreen* loginScreen;
|
||||||
|
bool running;
|
||||||
|
bool quitOnLastWindowClosed;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NEXUS_H
|
#endif // NEXUS_H
|
||||||
|
|
|
@ -211,7 +211,10 @@ Profile::~Profile()
|
||||||
saveToxSave();
|
saveToxSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete core;
|
core->deleteLater();
|
||||||
|
while (coreThread->isRunning())
|
||||||
|
qApp->processEvents();
|
||||||
|
|
||||||
delete coreThread;
|
delete coreThread;
|
||||||
if (!isRemoved)
|
if (!isRemoved)
|
||||||
{
|
{
|
||||||
|
|
|
@ -322,25 +322,34 @@ QString GUI::passwordDialog(const QString& cancel, const QString& body)
|
||||||
|
|
||||||
void GUI::_clearContacts()
|
void GUI::_clearContacts()
|
||||||
{
|
{
|
||||||
Nexus::getDesktopGUI()->clearContactsList();
|
Widget* w = Nexus::getDesktopGUI();
|
||||||
|
if (w)
|
||||||
|
w->clearContactsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::_setEnabled(bool state)
|
void GUI::_setEnabled(bool state)
|
||||||
{
|
{
|
||||||
Nexus::getDesktopGUI()->setEnabled(state);
|
Widget* w = Nexus::getDesktopGUI();
|
||||||
|
if (w)
|
||||||
|
w->setEnabled(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::_setWindowTitle(const QString& title)
|
void GUI::_setWindowTitle(const QString& title)
|
||||||
{
|
{
|
||||||
|
QWidget* w = getMainWidget();
|
||||||
|
if (!w)
|
||||||
|
return;
|
||||||
if (title.isEmpty())
|
if (title.isEmpty())
|
||||||
getMainWidget()->setWindowTitle("qTox");
|
w->setWindowTitle("qTox");
|
||||||
else
|
else
|
||||||
getMainWidget()->setWindowTitle("qTox - " + title);
|
w->setWindowTitle("qTox - " + title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::_reloadTheme()
|
void GUI::_reloadTheme()
|
||||||
{
|
{
|
||||||
Nexus::getDesktopGUI()->reloadTheme();
|
Widget* w = Nexus::getDesktopGUI();
|
||||||
|
if (w)
|
||||||
|
w->reloadTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::_showInfo(const QString& title, const QString& msg)
|
void GUI::_showInfo(const QString& title, const QString& msg)
|
||||||
|
@ -366,7 +375,9 @@ void GUI::_showError(const QString& title, const QString& msg)
|
||||||
|
|
||||||
void GUI::_showUpdateDownloadProgress()
|
void GUI::_showUpdateDownloadProgress()
|
||||||
{
|
{
|
||||||
Nexus::getDesktopGUI()->showUpdateDownloadProgress();
|
Widget* w = Nexus::getDesktopGUI();
|
||||||
|
if (w)
|
||||||
|
w->showUpdateDownloadProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GUI::_askQuestion(const QString& title, const QString& msg,
|
bool GUI::_askQuestion(const QString& title, const QString& msg,
|
||||||
|
|
|
@ -126,6 +126,11 @@ bool LoginScreen::event(QEvent* event)
|
||||||
return QWidget::event(event);
|
return QWidget::event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoginScreen::closeEvent(QCloseEvent*)
|
||||||
|
{
|
||||||
|
emit closed();
|
||||||
|
}
|
||||||
|
|
||||||
void LoginScreen::onNewProfilePageClicked()
|
void LoginScreen::onNewProfilePageClicked()
|
||||||
{
|
{
|
||||||
ui->stackedWidget->setCurrentIndex(0);
|
ui->stackedWidget->setCurrentIndex(0);
|
||||||
|
|
|
@ -42,6 +42,10 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void windowStateChanged(Qt::WindowStates states);
|
void windowStateChanged(Qt::WindowStates states);
|
||||||
|
void closed();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void closeEvent(QCloseEvent *event) final override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAutoLoginToggled(int state);
|
void onAutoLoginToggled(int state);
|
||||||
|
|
|
@ -594,7 +594,7 @@ void Widget::closeEvent(QCloseEvent *event)
|
||||||
saveWindowGeometry();
|
saveWindowGeometry();
|
||||||
saveSplitterGeometry();
|
saveSplitterGeometry();
|
||||||
QWidget::closeEvent(event);
|
QWidget::closeEvent(event);
|
||||||
qApp->quit();
|
Nexus::getInstance().quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,7 +647,7 @@ void Widget::onFailedToStartCore()
|
||||||
critical.setText(tr("toxcore failed to start, the application will terminate after you close this message."));
|
critical.setText(tr("toxcore failed to start, the application will terminate after you close this message."));
|
||||||
critical.setIcon(QMessageBox::Critical);
|
critical.setIcon(QMessageBox::Critical);
|
||||||
critical.exec();
|
critical.exec();
|
||||||
qApp->quit();
|
Nexus::getInstance().quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::onBadProxyCore()
|
void Widget::onBadProxyCore()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user