diff --git a/CMakeLists.txt b/CMakeLists.txt index 1255d4c3..5c63225c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,100 +1,100 @@ cmake_minimum_required(VERSION 3.0) project(plasma-browser-integration) set(PROJECT_VERSION "5.18.80") set(PROJECT_VERSION_MAJOR 5) set(QT_MIN_VERSION "5.9.0") -set(KF5_MIN_VERSION "5.42.0") +set(KF5_MIN_VERSION "5.70.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(FeatureSummary) include(KDEClangFormat) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Gui DBus Widgets ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS KIO I18n CoreAddons Config Crash DBusAddons Notifications Runner Activities Purpose FileMetaData ) add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) #add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000) # Options option(INSTALL_CHROME_MANIFEST "Whether to install a configuration file that makes Chrome automatically download the extension from the store" FALSE) add_feature_info(INSTALL_CHROME_MANIFEST ${INSTALL_CHROME_MANIFEST} "Install extension from Chrome store automatically") # in ubuntu and derivatives, this should be installed in the chromium-browser/extensions, # but since this is distribution specific path, let's use what upstream uses # ideally ubuntu and derivatives should patch this in their packaging set(CHROMIUM_EXTENSIONS_DIR "chromium" CACHE STRING "Directory name to install Chromium extensions into") add_feature_info(CHROMIUM_EXTENSIONS_DIR On "Directory name to install Chromium extensions into is '${CHROMIUM_EXTENSIONS_DIR}'") option(COPY_MESSAGING_HOST_FILE_HOME "Copy the native messaging hosts json file to user home dir" FALSE) add_feature_info(COPY_MESSAGING_HOST_FILE_HOME ${COPY_MESSAGING_HOST_FILE_HOME} "Enable this option to copy the native messaging hosts json file to home dir if you install plasma-browser-integration to custom prefix (non-/usr)") set(MOZILLA_DIR "${CMAKE_INSTALL_PREFIX}/lib/mozilla" CACHE STRING "Mozilla directory") add_feature_info(MOZILLA_DIR On "Mozilla directory is '${MOZILLA_DIR}'") add_subdirectory(host) add_subdirectory(tabsrunner) add_subdirectory(reminder) if(NOT DEFINED CHROME_EXTENSION_ID) # The extension ID is based on the key used to sign the extension # see https://stackoverflow.com/questions/23873623/obtaining-chrome-extension-id-for-development set(CHROME_EXTENSION_ID "cimiefiiaegbelhefglklhhakcgmhkai") endif() # TODO configure manifest.json configure_file(org.kde.plasma.chrome_integration.json.in org.kde.plasma.chrome_integration.json @ONLY) configure_file(org.kde.plasma.firefox_integration.json.in org.kde.plasma.firefox_integration.json @ONLY) # #chromium install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.plasma.chrome_integration.json DESTINATION ${KDE_INSTALL_FULL_SYSCONFDIR}/chromium/native-messaging-hosts/ RENAME org.kde.plasma.browser_integration.json) # #google-chrome install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.plasma.chrome_integration.json DESTINATION ${KDE_INSTALL_FULL_SYSCONFDIR}/opt/chrome/native-messaging-hosts/ RENAME org.kde.plasma.browser_integration.json) # firefox install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.plasma.firefox_integration.json DESTINATION ${MOZILLA_DIR}/native-messaging-hosts/ RENAME org.kde.plasma.browser_integration.json) if (COPY_MESSAGING_HOST_FILE_HOME) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.plasma.firefox_integration.json DESTINATION $ENV{HOME}/.mozilla/native-messaging-hosts/ RENAME org.kde.plasma.browser_integration.json) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.plasma.chrome_integration.json DESTINATION $ENV{HOME}/.config/chromium/NativeMessagingHosts/ RENAME org.kde.plasma.browser_integration.json) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.plasma.chrome_integration.json DESTINATION $ENV{HOME}/.config/google-chrome/NativeMessagingHosts/ RENAME org.kde.plasma.browser_integration.json) endif() if (INSTALL_CHROME_MANIFEST) # Install a policy to have browsers automatically add the extension # google-chrome install(FILES chrome_install_from_store_policy DESTINATION ${KDE_INSTALL_DATADIR}/google-chrome/extensions RENAME ${CHROME_EXTENSION_ID}.json) # chromium install(FILES chrome_install_from_store_policy DESTINATION ${KDE_INSTALL_DATADIR}/${CHROMIUM_EXTENSIONS_DIR}/extensions RENAME ${CHROME_EXTENSION_ID}.json) endif() # TODO firefox # add clang-format target for all our real source files file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/reminder/browserintegrationreminder.cpp b/reminder/browserintegrationreminder.cpp index 095e1139..a5755b49 100644 --- a/reminder/browserintegrationreminder.cpp +++ b/reminder/browserintegrationreminder.cpp @@ -1,201 +1,204 @@ /*************************************************************************** * Copyright 2018 by David Edmundson * * Copyright 2018 by Eike Hein * * * * 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 . * ***************************************************************************/ #include "browserintegrationreminder.h" #include #include #include #include #include #include #include #include #include #include #include #include +#include #include +#include #include -#include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(BrowserIntegrationReminderFactory, "browserintegrationreminder.json", registerPlugin();) static const QString s_dbusServiceName = QStringLiteral("org.kde.plasma.browser_integration"); #define MAX_SHOW_COUNT 3 BrowserIntegrationReminder::BrowserIntegrationReminder(QObject *parent, const QList&) : KDEDModule(parent) { m_debug = qEnvironmentVariableIsSet("PLASMA_BROWSE_REMIND_FORCE"); auto config = KSharedConfig::openConfig()->group("PlasmaBrowserIntegration"); m_shownCount = config.readEntry("shownCount", 0); if (m_shownCount > MAX_SHOW_COUNT && !m_debug) { disableAutoload(); //safer than it looks it won't be processed till we hit the event loop return; } QUrl firefox(QStringLiteral("https://addons.mozilla.org/en-US/firefox/addon/plasma-integration/")); m_browsers[QStringLiteral("firefox.desktop")] = firefox; m_browsers[QStringLiteral("nightly.desktop")] = firefox; QUrl chrome(QStringLiteral("https://chrome.google.com/webstore/detail/plasma-integration/cimiefiiaegbelhefglklhhakcgmhkai")); m_browsers[QStringLiteral("google-chrome.desktop")] = chrome; m_browsers[QStringLiteral("google-chrome-beta.desktop")] = chrome; m_browsers[QStringLiteral("google-chrome-unstable.desktop")] = chrome; m_browsers[QStringLiteral("chromium-browser.desktop")] = chrome; setModuleName(QStringLiteral("BrowserIntegrationReminder")); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.connect(QStringLiteral("org.kde.ActivityManager"), QStringLiteral("/ActivityManager/Resources/Scoring"), QStringLiteral("org.kde.ActivityManager.ResourcesScoring"), QStringLiteral("ResourceScoreUpdated"), this, SLOT(onResourceScoresChanged(QString,QString,QString,double,unsigned int,unsigned int))); } BrowserIntegrationReminder::~BrowserIntegrationReminder() { } void BrowserIntegrationReminder::onResourceScoresChanged(const QString &activity, const QString &client, const QString &resource, double score, unsigned int lastUpdate, unsigned int firstUpdate) { Q_UNUSED(activity); Q_UNUSED(score); Q_UNUSED(lastUpdate); Q_UNUSED(firstUpdate); Q_UNUSED(client) if (!resource.startsWith(QStringLiteral("applications:"))) { return; } const QString desktopFile = resource.mid(strlen("applications:")); if (!m_browsers.contains(desktopFile)) { return; } //wait a few seconds and then query if the extension is active QTimer::singleShot(10 * 1000, this, [this, desktopFile]() { onBrowserStarted(desktopFile); }); } void BrowserIntegrationReminder::onBrowserStarted(const QString &browser) { QDBusConnection bus = QDBusConnection::sessionBus(); if (m_sni) { return; } if (!KService::serviceByStorageId(browser)) { return; } if (!m_watcher) { m_watcher = new QDBusServiceWatcher(s_dbusServiceName, bus, QDBusServiceWatcher::WatchForRegistration, this); connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, [this](const QString &service) { Q_UNUSED(service); if (m_sni) { m_sni->deleteLater(); disableAutoload(); } }); } if (!m_debug && bus.interface()->isServiceRegistered(s_dbusServiceName)) { //the user has the extension installed, we don't need to keep checking //env var exists for easier testing disableAutoload(); return; } m_sni = new KStatusNotifierItem(this); m_shownCount++; auto config = KSharedConfig::openConfig()->group("PlasmaBrowserIntegration"); config.writeEntry("shownCount", m_shownCount); m_sni->setTitle(i18n("Get Plasma Browser Integration")); m_sni->setIconByName(QStringLiteral("plasma-browser-integration")); m_sni->setStandardActionsEnabled(false); m_sni->setStatus(KStatusNotifierItem::Active); connect(m_sni, &KStatusNotifierItem::activateRequested, this, [this, browser]() { const KService::Ptr service = KService::serviceByStorageId(browser); if (!service) { unload(); return; } - KRun::runApplication(*service, QList() << m_browsers[browser], nullptr, KRun::RunFlags(), - QString(), nullptr); + KIO::ApplicationLauncherJob *job = new KIO::ApplicationLauncherJob(service); + job->setUrls({m_browsers[browser]}); + job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled)); + job->start(); KActivities::ResourceInstance::notifyAccessed(QUrl(QStringLiteral("applications:") + browser), QStringLiteral("org.kde.plasma.browserintegrationreminder")); //remove for this session. //If the user installed it successfully we won't show anything next session //If they didn't they'll get the link next login unload(); }); auto *menu = new QMenu; auto *action = new QAction(QIcon::fromTheme(QStringLiteral("view-hidden")), i18n("Do not show again")); menu->addAction(action); connect(action, &QAction::triggered, this, [this]() { auto config = KSharedConfig::openConfig()->group("PlasmaBrowserIntegration"); config.writeEntry("shownCount", 100); disableAutoload(); }); m_sni->setContextMenu(menu); } void BrowserIntegrationReminder::unload() { QDBusConnection dbus = QDBusConnection::sessionBus(); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"), QStringLiteral("/kded"), QStringLiteral("org.kde.kded5"), QStringLiteral("unloadModule")); msg.setArguments({QVariant(QStringLiteral("browserintegrationreminder"))}); dbus.call(msg, QDBus::NoBlock); } void BrowserIntegrationReminder::disableAutoload() { QDBusConnection dbus = QDBusConnection::sessionBus(); QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"), QStringLiteral("/kded"), QStringLiteral("org.kde.kded5"), QStringLiteral("setModuleAutoloading")); msg.setArguments({QVariant(QStringLiteral("browserintegrationreminder")), QVariant(false)}); dbus.call(msg, QDBus::NoBlock); unload(); } #include "browserintegrationreminder.moc"