diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 166 |
1 files changed, 56 insertions, 110 deletions
diff --git a/src/main.cpp b/src/main.cpp index dad1f73..8cd1d34 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,36 +7,15 @@ */ #include "browser.h" -#include "builtins.h" #include "configuration.h" -#include "crashhandler.h" #include "session/sessiondialog.h" #include "session_json.hpp" -#include "settings.h" -#include "util.h" -#include "version.h" +#include <QCommandLineParser> #include <QFile> #include <QPluginLoader> #include <QStandardPaths> -#include <iostream> -#include <memory> -#include <pluginloader.h> #include <spdlog/spdlog.h> -// a helper function to join the keys of a command_map into a string -inline std::string join_keys(const command_map &map, const std::string sep = ", ") -{ - std::vector<std::string> keys(map.size()); - std::transform(map.begin(), map.end(), keys.begin(), [](auto pair) { return pair.first; }); - std::sort(keys.begin(), keys.end()); - - std::string k; - std::for_each(keys.begin(), keys.end() - 1, [&k, &sep](const std::string &piece) { k += piece + sep; }); - k += keys.back(); - - return k; -} - int main(int argc, char **argv) { // change log pattern @@ -45,104 +24,71 @@ int main(int argc, char **argv) spdlog::set_level(spdlog::level::debug); // Set global log level to debug #endif - const command_map commands{ - { "configuration", builtins::configuration }, - { "bookmarks", builtins::bookmarks }, - }; - - const std::vector<std::string> args(argv + 1, argv + argc); - args::ArgumentParser parser("smolbote: yet another no-frills browser", "Subcommands: " + join_keys(commands)); - parser.Prog(argv[0]); - - args::HelpFlag cmd_help(parser, "help", "Display this help message.", { 'h', "help" }); - args::Flag cmd_version(parser, "version", "Display version information.", { 'v', "version" }); - args::Flag cmd_build(parser, "build", "Display build commit.", { 'b', "build" }); - - args::ValueFlag<std::string> cmd_config(parser, "config", "Set the configuration file.", { 'c', "config" }); - - args::Flag cmd_noRemote(parser, "no-remote", "Do not accept or send remote commands.", { "no-remote" }); - - args::Flag cmd_pickSession(parser, "pick-session", "Show all available sessions and select which one to open", { "pick-session" }); - args::ValueFlag<std::string> cmd_session(parser, "session", "Open the specified session.", { 's', "session" }); - - args::PositionalList<std::string> cmd_args(parser, "URL(s)", "List of URLs to open"); - cmd_args.KickOut(true); - - try { - auto next = parser.ParseArgs(args); - - if(cmd_version) - return builtins::version(); - if(cmd_build) - return builtins::build(); - - // create and load configuration - spdlog::debug("Loading configuration {}", init_conf(args::get(cmd_config))); - - if(cmd_args) { - const auto front = args::get(cmd_args).front(); - const auto cmd = commands.find(front); - if(cmd != commands.end()) { - return cmd->second(argv[0], next, std::end(args)); + QCommandLineParser parser; + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("url", "URLs to open"); + + // generic options + QCommandLineOption cmd_config({ "c", "config" }, "Set the configuration file.", "path"); + parser.addOption(cmd_config); + + QCommandLineOption cmd_session({ "s", "session" }, "Open the specified session.", "path"); + parser.addOption(cmd_session); + + QCommandLineOption cmd_pick_session("pick-session", "Show all available sessions and select which one to open."); + parser.addOption(cmd_pick_session); + + // Qt options + QCommandLineOption cmd_renderer("renderer", "Select the OpenGL renderer used by the application. Available options are: desktop, gles, software", "value"); + parser.addOption(cmd_renderer); + + // SingleApplication options + QCommandLineOption cmd_no_remote("no-remote", "Start a new instance that won't accept or send remote commands."); + parser.addOption(cmd_no_remote); + + { // handle command line options that need to be set before the QApplication object is created + QStringList args; + for(int i = 0; i < argc; ++i) + args.append(argv[i]); + parser.parse(args); + + // the OpenGL implementation needs to be manually set to software if it's not properly configured + if(parser.isSet(cmd_renderer)) { + const auto value = parser.value(cmd_renderer); + if(value == QLatin1String("desktop")) { + QApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true); + } else if(value == QLatin1String("gles")) { + QApplication::setAttribute(Qt::AA_UseOpenGLES, true); + } else if(value == QLatin1String("software")) { + QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL, true); + } else { + spdlog::error("Unknown cmd_renderer flag: {}", qUtf8Printable(value)); } } - - } catch(args::Help &) { - std::cout << parser; - return 0; - - } catch(args::Error &e) { - std::cerr << e.what() << std::endl; - std::cerr << parser; - return -1; } - // argc, argv, allowSecondary - Browser app(argc, argv); // set this, otherwise the webview becomes black when using a stylesheet - app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); - - { - Configuration conf; - - if(conf.value<bool>("usebreakpad").value()) { - CrashHandler::Context ctx( - conf.value<std::string>("path.crashdump").value(), - conf.value<std::string>("path.crashhandler").value()); + QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); - if(CrashHandler::install_handler(ctx)) { - spdlog::info("Installed breakpad crash handler: {}", ctx.dumppath); - } else { - spdlog::warn("Failed to install breakpad crash handler: {}", ctx.dumppath); - } - } + spdlog::info("Loaded configuration: {}", Configuration::init_global(parser.value(cmd_config).toStdString())); - // load plugins - for(const QString &path : Util::files(conf.value<QString>("plugins.path").value(), { "*.so", "*.dll" })) { - if(app.loadPlugin(path)) { - spdlog::debug("Loaded plugin [{}]", qUtf8Printable(path)); - } else { - spdlog::warn("Failed loading plugin [{}]", qUtf8Printable(path)); - } - } - } + Browser app(argc, argv); + parser.process(app); const auto profile = []() { - Configuration c; - return c.value<QString>("profile.default").value(); + Configuration conf; + return conf.value<QString>("profile/default").value(); }(); - QStringList urls; - for(const auto &u : args::get(cmd_args)) { - urls.append(QString::fromStdString(u)); - } + QStringList urls = parser.positionalArguments(); if(urls.isEmpty()) { urls.append(QString()); } // if app is primary, create new sessions from received messages - if(app.isPrimary() && !cmd_noRemote) { - QObject::connect(&app, &Browser::receivedMessage, &app, [&app](quint32 instanceId, QByteArray message) { + if(app.isPrimary() && !parser.isSet(cmd_no_remote)) { + QObject::connect(&app, &Browser::receivedMessage, &app, [&app](quint32 instanceId, const QByteArray &message) { Q_UNUSED(instanceId); JsonSession session(message); app.open(session.get()); @@ -151,13 +97,13 @@ int main(int argc, char **argv) { const auto session = [&]() { - if(cmd_session) { - QFile sessionJson(QString::fromStdString(args::get(cmd_session))); + if(parser.isSet(cmd_session)) { + QFile sessionJson(parser.value(cmd_session)); if(sessionJson.open(QIODevice::ReadOnly | QIODevice::Text)) { return JsonSession(sessionJson.readAll()); } } - if(cmd_pickSession) { + if(parser.isSet(cmd_pick_session)) { SessionDialog dlg; if(const auto pick = dlg.pickSession()) { return JsonSession(pick.value()); @@ -166,13 +112,13 @@ int main(int argc, char **argv) return JsonSession(profile, urls); }(); - if(app.isPrimary() || cmd_noRemote) { + if(app.isPrimary() || parser.isSet(cmd_no_remote)) { app.open(session.get()); } else { // app is secondary and not standalone - return app.sendMessage(session.serialize()); + return app.sendMessage(session.serialize()) ? EXIT_SUCCESS : EXIT_FAILURE; } } - return app.exec(); + return QApplication::exec(); } |