2018-06-26 14:09:39 +02:00
|
|
|
#include "Application.hpp"
|
2018-06-26 17:06:17 +02:00
|
|
|
#include "common/NetworkManager.hpp"
|
2018-06-28 19:46:45 +02:00
|
|
|
#include "singletons/NativeMessaging.hpp"
|
|
|
|
#include "singletons/Paths.hpp"
|
|
|
|
#include "singletons/Updates.hpp"
|
2018-06-26 14:09:39 +02:00
|
|
|
#include "util/DebugCount.hpp"
|
2018-06-26 15:11:45 +02:00
|
|
|
#include "widgets/dialogs/LastRunCrashDialog.hpp"
|
2017-01-11 01:08:20 +01:00
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
#include <QAbstractNativeEventFilter>
|
2017-01-11 01:08:20 +01:00
|
|
|
#include <QApplication>
|
2018-04-09 22:59:19 +02:00
|
|
|
#include <QFile>
|
2017-09-21 17:34:41 +02:00
|
|
|
#include <QLibrary>
|
2018-04-09 22:59:19 +02:00
|
|
|
#include <QStringList>
|
2018-05-23 19:42:42 +02:00
|
|
|
#include <QStyleFactory>
|
2018-06-23 16:10:20 +02:00
|
|
|
#include <pajlada/settings/settingmanager.hpp>
|
2018-04-09 22:59:19 +02:00
|
|
|
|
2018-04-12 00:09:16 +02:00
|
|
|
#include <fstream>
|
|
|
|
#include <iostream>
|
2018-04-09 22:59:19 +02:00
|
|
|
|
2018-05-28 18:25:19 +02:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <io.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#endif
|
|
|
|
|
2018-06-28 01:26:15 +02:00
|
|
|
#ifdef C_USE_BREAKPAD
|
2018-06-28 01:06:37 +02:00
|
|
|
#include <QBreakpadHandler.h>
|
|
|
|
#endif
|
|
|
|
|
2018-06-13 13:27:10 +02:00
|
|
|
int runGui(QApplication &a, int argc, char *argv[]);
|
2018-05-28 18:25:19 +02:00
|
|
|
void runNativeMessagingHost();
|
2018-06-01 14:20:46 +02:00
|
|
|
void installCustomPalette();
|
2018-04-09 22:59:19 +02:00
|
|
|
|
2018-06-26 17:33:26 +02:00
|
|
|
//
|
|
|
|
// Main entry point of the application.
|
|
|
|
// Decides if it should run in gui mode, daemon mode, ...
|
|
|
|
// Sets up the QApplication
|
|
|
|
//
|
2017-04-13 18:51:46 +02:00
|
|
|
int main(int argc, char *argv[])
|
2018-04-09 22:59:19 +02:00
|
|
|
{
|
2018-06-26 17:33:26 +02:00
|
|
|
// set up the QApplication flags
|
2018-06-24 17:33:55 +02:00
|
|
|
QApplication::setAttribute(Qt::AA_Use96Dpi, true);
|
2018-06-13 13:27:10 +02:00
|
|
|
#ifdef Q_OS_WIN32
|
2018-06-24 23:58:29 +02:00
|
|
|
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true);
|
2018-06-13 13:27:10 +02:00
|
|
|
#endif
|
|
|
|
// QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL, true);
|
2018-06-26 17:33:26 +02:00
|
|
|
|
|
|
|
// instanciate the QApplication
|
2018-06-13 13:27:10 +02:00
|
|
|
QApplication a(argc, argv);
|
|
|
|
|
2018-06-26 17:33:26 +02:00
|
|
|
// FOURTF: might get arguments from the commandline passed in the future
|
2018-06-26 17:06:17 +02:00
|
|
|
chatterino::PathManager::initInstance();
|
2018-06-13 13:27:10 +02:00
|
|
|
|
2018-04-09 22:59:19 +02:00
|
|
|
// read args
|
|
|
|
QStringList args;
|
|
|
|
|
|
|
|
for (int i = 1; i < argc; i++) {
|
|
|
|
args << argv[i];
|
|
|
|
}
|
|
|
|
|
2018-06-26 17:33:26 +02:00
|
|
|
// run native messaging host for the browser extension
|
2018-06-13 13:27:10 +02:00
|
|
|
if (args.size() > 0 &&
|
|
|
|
(args[0].startsWith("chrome-extension://") || args[0].endsWith(".json"))) {
|
2018-05-28 18:25:19 +02:00
|
|
|
runNativeMessagingHost();
|
2018-04-09 22:59:19 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// run gui
|
2018-06-13 13:27:10 +02:00
|
|
|
return runGui(a, argc, argv);
|
2018-04-09 22:59:19 +02:00
|
|
|
}
|
|
|
|
|
2018-06-13 13:27:10 +02:00
|
|
|
int runGui(QApplication &a, int argc, char *argv[])
|
2016-12-29 17:31:07 +01:00
|
|
|
{
|
2018-05-23 19:42:42 +02:00
|
|
|
QApplication::setStyle(QStyleFactory::create("Fusion"));
|
|
|
|
|
2018-06-01 14:20:46 +02:00
|
|
|
installCustomPalette();
|
2017-09-21 17:34:41 +02:00
|
|
|
|
2017-10-27 20:09:02 +02:00
|
|
|
// Initialize NetworkManager
|
2018-06-26 17:06:17 +02:00
|
|
|
chatterino::NetworkManager::init();
|
2017-10-27 20:09:02 +02:00
|
|
|
|
2018-06-01 14:20:46 +02:00
|
|
|
// Check for upates
|
2018-06-26 17:06:17 +02:00
|
|
|
chatterino::UpdateManager::getInstance().checkForUpdates();
|
2018-06-01 14:20:46 +02:00
|
|
|
|
2018-04-27 22:11:19 +02:00
|
|
|
// Initialize application
|
|
|
|
chatterino::Application::instantiate(argc, argv);
|
|
|
|
auto app = chatterino::getApp();
|
|
|
|
|
|
|
|
app->construct();
|
|
|
|
|
2018-06-28 01:26:15 +02:00
|
|
|
#ifdef C_USE_BREAKPAD
|
2018-06-28 01:06:37 +02:00
|
|
|
QBreakpadInstance.setDumpPath(app->paths->settingsFolderPath + "/Crashes");
|
|
|
|
#endif
|
|
|
|
|
2018-04-27 22:11:19 +02:00
|
|
|
auto &pathMan = *app->paths;
|
2018-04-20 00:15:57 +02:00
|
|
|
// Running file
|
2018-06-21 13:02:34 +02:00
|
|
|
auto runningPath = pathMan.miscDirectory + "/running_" + pathMan.applicationFilePathHash;
|
2018-04-20 00:15:57 +02:00
|
|
|
|
|
|
|
if (QFile::exists(runningPath)) {
|
2018-06-28 01:26:15 +02:00
|
|
|
#ifndef C_DISABLE_CRASH_DIALOG
|
2018-06-26 17:06:17 +02:00
|
|
|
chatterino::LastRunCrashDialog dialog;
|
2018-06-01 14:20:46 +02:00
|
|
|
|
|
|
|
switch (dialog.exec()) {
|
|
|
|
case QDialog::Accepted: {
|
|
|
|
}; break;
|
|
|
|
default: {
|
|
|
|
_exit(0);
|
|
|
|
}
|
|
|
|
}
|
2018-04-22 20:48:00 +02:00
|
|
|
#endif
|
2018-04-20 00:15:57 +02:00
|
|
|
} else {
|
|
|
|
QFile runningFile(runningPath);
|
|
|
|
|
|
|
|
runningFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
|
|
|
runningFile.flush();
|
|
|
|
runningFile.close();
|
|
|
|
}
|
|
|
|
|
2018-04-27 22:11:19 +02:00
|
|
|
app->initialize();
|
2016-12-29 17:31:07 +01:00
|
|
|
|
2018-04-27 22:11:19 +02:00
|
|
|
// Start the application
|
|
|
|
// This is a blocking call
|
|
|
|
app->run(a);
|
2017-01-03 21:19:33 +01:00
|
|
|
|
2018-04-27 22:11:19 +02:00
|
|
|
// We have finished our application, make sure we save stuff
|
|
|
|
app->save();
|
2017-01-23 09:49:30 +01:00
|
|
|
|
2018-04-20 00:15:57 +02:00
|
|
|
// Running file
|
|
|
|
QFile::remove(runningPath);
|
|
|
|
|
2017-05-30 15:22:44 +02:00
|
|
|
// Save settings
|
|
|
|
pajlada::Settings::SettingManager::save();
|
|
|
|
|
2017-10-27 20:09:02 +02:00
|
|
|
// Deinitialize NetworkManager (stop thread and wait for finish, should be instant)
|
2018-06-26 17:06:17 +02:00
|
|
|
chatterino::NetworkManager::deinit();
|
2017-10-27 20:09:02 +02:00
|
|
|
|
2018-06-26 17:33:26 +02:00
|
|
|
// None of the singletons has a proper destructor
|
2018-01-18 07:56:02 +01:00
|
|
|
_exit(0);
|
2016-12-29 17:31:07 +01:00
|
|
|
}
|
2018-05-28 18:25:19 +02:00
|
|
|
|
|
|
|
void runNativeMessagingHost()
|
|
|
|
{
|
2018-06-26 17:06:17 +02:00
|
|
|
auto *nm = new chatterino::NativeMessagingManager;
|
2018-05-28 18:25:19 +02:00
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
_setmode(_fileno(stdin), _O_BINARY);
|
|
|
|
_setmode(_fileno(stdout), _O_BINARY);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
bool bigEndian = isBigEndian();
|
|
|
|
#endif
|
|
|
|
|
2018-05-30 17:17:27 +02:00
|
|
|
std::atomic<bool> ping(false);
|
|
|
|
|
|
|
|
QTimer timer;
|
|
|
|
QObject::connect(&timer, &QTimer::timeout, [&ping] {
|
|
|
|
if (!ping.exchange(false)) {
|
|
|
|
_exit(0);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
timer.setInterval(11000);
|
|
|
|
timer.start();
|
|
|
|
|
2018-05-28 18:25:19 +02:00
|
|
|
while (true) {
|
|
|
|
char size_c[4];
|
|
|
|
std::cin.read(size_c, 4);
|
|
|
|
|
|
|
|
if (std::cin.eof()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t size = *reinterpret_cast<uint32_t *>(size_c);
|
|
|
|
#if 0
|
|
|
|
// To avoid breaking strict-aliasing rules and potentially inducing undefined behaviour, the following code can be run instead
|
|
|
|
uint32_t size = 0;
|
|
|
|
if (bigEndian) {
|
|
|
|
size = size_c[3] | static_cast<uint32_t>(size_c[2]) << 8 |
|
|
|
|
static_cast<uint32_t>(size_c[1]) << 16 | static_cast<uint32_t>(size_c[0]) << 24;
|
|
|
|
} else {
|
|
|
|
size = size_c[0] | static_cast<uint32_t>(size_c[1]) << 8 |
|
|
|
|
static_cast<uint32_t>(size_c[2]) << 16 | static_cast<uint32_t>(size_c[3]) << 24;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
std::unique_ptr<char[]> b(new char[size + 1]);
|
|
|
|
std::cin.read(b.get(), size);
|
|
|
|
*(b.get() + size) = '\0';
|
|
|
|
|
|
|
|
nm->sendToGuiProcess(QByteArray::fromRawData(b.get(), static_cast<int32_t>(size)));
|
|
|
|
}
|
|
|
|
}
|
2018-06-01 14:20:46 +02:00
|
|
|
|
|
|
|
void installCustomPalette()
|
|
|
|
{
|
|
|
|
// borrowed from
|
|
|
|
// https://stackoverflow.com/questions/15035767/is-the-qt-5-dark-fusion-theme-available-for-windows
|
|
|
|
QPalette darkPalette = qApp->palette();
|
|
|
|
|
|
|
|
darkPalette.setColor(QPalette::Window, QColor(22, 22, 22));
|
|
|
|
darkPalette.setColor(QPalette::WindowText, Qt::white);
|
|
|
|
darkPalette.setColor(QPalette::Text, Qt::white);
|
|
|
|
darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127));
|
|
|
|
darkPalette.setColor(QPalette::Base, QColor("#333"));
|
|
|
|
darkPalette.setColor(QPalette::AlternateBase, QColor("#444"));
|
|
|
|
darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
|
|
|
|
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
|
|
|
|
darkPalette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127));
|
|
|
|
darkPalette.setColor(QPalette::Dark, QColor(35, 35, 35));
|
|
|
|
darkPalette.setColor(QPalette::Shadow, QColor(20, 20, 20));
|
|
|
|
darkPalette.setColor(QPalette::Button, QColor(70, 70, 70));
|
|
|
|
darkPalette.setColor(QPalette::ButtonText, Qt::white);
|
|
|
|
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127));
|
|
|
|
darkPalette.setColor(QPalette::BrightText, Qt::red);
|
|
|
|
darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
|
|
|
|
darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
|
|
|
darkPalette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80, 80, 80));
|
|
|
|
darkPalette.setColor(QPalette::HighlightedText, Qt::white);
|
|
|
|
darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(127, 127, 127));
|
|
|
|
|
|
|
|
qApp->setPalette(darkPalette);
|
|
|
|
}
|