diff --git a/applications/kube/main.cpp b/applications/kube/main.cpp index b3b77566..db146abe 100644 --- a/applications/kube/main.cpp +++ b/applications/kube/main.cpp @@ -1,220 +1,222 @@ /* Copyright (c) 2017 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #ifndef Q_OS_WIN #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "backtrace.h" #include "framework/src/keyring.h" #include "kube_version.h" static int sCounter = 0; void crashHandler(int signal) { //Guard against crashing in here if (sCounter > 1) { std::_Exit(EXIT_FAILURE); } sCounter++; if (signal == SIGABRT) { std::cerr << "SIGABRT received\n"; } else if (signal == SIGSEGV) { std::cerr << "SIGSEV received\n"; } else { std::cerr << "Unexpected signal " << signal << " received\n"; } printStacktrace(); std::fprintf(stdout, "Sleeping for 10s to attach a debugger: gdb attach %i\n", getpid()); std::this_thread::sleep_for(std::chrono::seconds(10)); // std::system("exec gdb -p \"$PPID\" -ex \"thread apply all bt\""); // This only works if we actually have xterm and X11 available // std::system("exec xterm -e gdb -p \"$PPID\""); std::_Exit(EXIT_FAILURE); } void terminateHandler() { // std::exception_ptr exptr = std::current_exception(); // if (exptr != 0) // { // // the only useful feature of std::exception_ptr is that it can be rethrown... // try { // std::rethrow_exception(exptr); // } catch (std::exception &ex) { // std::fprintf(stderr, "Terminated due to exception: %s\n", ex.what()); // } catch (...) { // std::fprintf(stderr, "Terminated due to unknown exception\n"); // } // } else { std::fprintf(stderr, "Terminated due to unknown reason.\n"); // } std::abort(); } QString findFile(const QString file, const QStringList importPathList) { for (const auto &path : importPathList) { const QString f = path + file; if (QFileInfo::exists(f)) { return f; } } return {}; } int main(int argc, char *argv[]) { std::signal(SIGSEGV, crashHandler); std::signal(SIGABRT, crashHandler); std::set_terminate(terminateHandler); //Instead of QtWebEngine::initialize(); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); QCoreApplication::setApplicationVersion(QString("%1 Branch: %2 Commit: %3").arg(kube_VERSION_STRING).arg(kube_BRANCH).arg(kube_COMMIT)); QCoreApplication::setOrganizationName("kube"); QCoreApplication::setOrganizationDomain("kube-project.com"); QCoreApplication::setApplicationName("kube"); QApplication app(argc, argv); auto fontSize = app.font().pointSize(); #if defined(Q_OS_UNIX) && (!defined(Q_OS_MAC)) if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORMTHEME")) { //The hardcoded default in qgenericunixthemes.cpp of 9 is tiny, so we default to something larger. fontSize = 11; } #endif app.setFont(QFont{"Noto Sans", fontSize, QFont::Normal}); //Get info about actually used font const QFontInfo fontInfo{app.font()}; qInfo() << "Font name:" << fontInfo.family(); qInfo() << "Font size:" << fontInfo.pointSize(); + qInfo() << "Device pixel ratio:" << app.devicePixelRatio(); QCommandLineParser parser; parser.setApplicationDescription("A communication and collaboration client."); parser.addHelpOption(); parser.addVersionOption(); parser.addOption({{"k", "keyring"}, QCoreApplication::translate("main", "To automatically unlock the keyring pass in a keyring in the form of {\"accountId\": {\"resourceId\": \"secret\", *}}"), "keyring dictionary"} ); parser.addOption({{"l", "lockfile"}, "Use a lockfile to enforce that only a single instance can be started.", ""}); parser.process(app); static QString location = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kube"; QDir{}.mkpath(location); QLockFile lockfile(location + QString("/%1.lock").arg(QString("kube"))); lockfile.setStaleLockTime(500); if (parser.isSet("lockfile")) { if (!lockfile.tryLock(0)) { const auto error = lockfile.error(); if (error == QLockFile::LockFailedError) { qint64 pid; QString hostname, appname; lockfile.getLockInfo(&pid, &hostname, &appname); qWarning() << "Failed to acquire exclusive lock. You can only run one instance of Kube."; qWarning() << "Pid:" << pid << "Host:" << hostname << "App:" << appname; } else { qWarning() << "Error while trying to acquire exclusive lock: " << error; } return -1; } } if (parser.isSet("keyring")) { auto keyringDict = parser.value("keyring"); auto json = QJsonDocument::fromJson(keyringDict.toUtf8()); if (!json.isObject()) { qWarning() << "Not a valid keyring dict " << keyringDict; return -1; } auto object = json.object(); for (const auto accountId : object.keys()) { auto dict = object.value(accountId).toObject(); for (const auto resourceId : dict.keys()) { Kube::AccountKeyring{accountId.toUtf8()}.addPassword(resourceId.toUtf8(), dict.value(resourceId).toString().toUtf8()); } } } { QQmlContext *rootContext = nullptr; bool upgradeComplete = false; Sink::Store::upgrade().then([&] (Sink::Store::UpgradeResult upgradeExecuted) { upgradeComplete = !upgradeExecuted.upgradeExecuted; if (rootContext) { rootContext->setContextProperty("upgradeComplete", true); } }).exec(); if (!upgradeComplete) { QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("upgradeComplete", false); rootContext = engine.rootContext(); engine.load(QUrl::fromLocalFile(findFile("/org/kube/components/kube/upgrade.qml", engine.importPathList()))); return app.exec(); } } QQmlApplicationEngine engine; //For windows engine.addImportPath(QCoreApplication::applicationDirPath() + QStringLiteral("/../qml")); const auto file = "/org/kube/components/kube/main.qml"; const auto mainFile = findFile(file, engine.importPathList()); if (mainFile.isEmpty()) { qWarning() << "Failed to find " << file; qWarning() << "Searched: " << engine.importPathList(); return -1; } engine.load(QUrl::fromLocalFile(mainFile)); return app.exec(); } diff --git a/framework/qml/Icon.qml b/framework/qml/Icon.qml index fa2761fc..5c1db13d 100644 --- a/framework/qml/Icon.qml +++ b/framework/qml/Icon.qml @@ -1,49 +1,50 @@ /* * Copyright (C) 2017 Christian Mollekopf, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.7 Item { id: root property string iconName property url iconSource property alias status: image.status implicitWidth: image.implicitWidth implicitHeight: image.implicitHeight onIconNameChanged: setImageSource() function setImageSource() { if (root.iconName != "") image.source = "image://kube/" + root.iconName; else image.source = ""; } Image { id: image anchors.centerIn: parent width: image.implicitWidth height: image.implicitWidth sourceSize.width: root.width sourceSize.height: root.height cache: true smooth: true + objectName: "image" fillMode: Image.Pad } } diff --git a/framework/qml/tests/tst_icon.qml b/framework/qml/tests/tst_icon.qml new file mode 100644 index 00000000..4eb41281 --- /dev/null +++ b/framework/qml/tests/tst_icon.qml @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Christian Mollekopf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.7 +import QtTest 1.0 +import org.kube.framework 1.0 as Kube + + +TestCase { + id: testCase + width: 400 + height: 400 + name: "Icon" + + Component { + id: iconComponent + Kube.Icon {} + } + + function test_1iconSize() { + var icon = createTemporaryObject(iconComponent, testCase, {iconName: Kube.Icons.mail_inverted, width: 48, height: 48}) + var image = findChild(icon, "image"); + verify(image) + compare(image.status, Image.Ready) + compare(image.paintedWidth, 22) + compare(image.paintedHeight, 22) + } +} diff --git a/tests/kubetestrunner.cpp b/tests/kubetestrunner.cpp index b3b8b295..153acedb 100644 --- a/tests/kubetestrunner.cpp +++ b/tests/kubetestrunner.cpp @@ -1,31 +1,33 @@ /* Copyright (c) 2018 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include int main(int argc, char **argv) { - QApplication app(argc, argv); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); + QApplication app(argc, argv); + qInfo() << "Device pixel ratio" << app.devicePixelRatio(); QTEST_ADD_GPU_BLACKLIST_SUPPORT QTEST_SET_MAIN_SOURCE_PATH return quick_test_main(argc, argv, "kubetest", 0); }