diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a2a237..93569d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,85 +1,85 @@ cmake_minimum_required(VERSION 2.8.12) project(PlasmaIntegration) set(PROJECT_VERSION "5.10.95") set(PROJECT_VERSION_MAJOR 5) include(FeatureSummary) find_package(ECM 5.17.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(GenerateExportHeader) include(ECMPackageConfigHelpers) include(ECMSetupVersion) include(ECMGenerateHeaders) include(KDEInstallDirs) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(KDECMakeSettings) set(REQUIRED_QT_VERSION 5.5.0) -find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets DBus X11Extras) +find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets DBus X11Extras QuickControls2) set(KF5_DEP_VERSION "5.33.0") find_package(KF5 ${KF5_DEP_VERSION} REQUIRED COMPONENTS Config ConfigWidgets I18n IconThemes KIO Notifications Wayland WidgetsAddons WindowSystem ) find_package(XCB COMPONENTS XCB) set_package_properties(XCB PROPERTIES DESCRIPTION "X protocol C-language Binding" URL "http://xcb.freedesktop.org" TYPE REQUIRED PURPOSE "Required to pass style properties to native Windows on X11 Platform" ) find_package(Breeze ${PROJECT_VERSION} CONFIG) set_package_properties(Breeze PROPERTIES TYPE REQUIRED PURPOSE "For setting the default QStyle name") # dependencies for QPA plugin if(Qt5Core_VERSION VERSION_LESS "5.8.0") find_package(Qt5PlatformSupport REQUIRED) else() find_package(Qt5ThemeSupport REQUIRED) endif() if(Qt5Core_VERSION VERSION_LESS "5.8.0") add_definitions(-DQ_FONTCONFIGDATABASE) set(QT5PLATFORMSUPPORT_LIBS Qt5PlatformSupport::Qt5PlatformSupport) else() set(QT5PLATFORMSUPPORT_LIBS Qt5ThemeSupport::Qt5ThemeSupport ) endif() add_definitions(-DTRANSLATION_DOMAIN=\"plasmaintegration5\") if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ki18n_install(po) endif() add_subdirectory(src) add_subdirectory(autotests) add_subdirectory(tests) find_package(FontNotoSans) set_package_properties(FontNotoSans PROPERTIES PURPOSE "Default sans-serif font -- this is not detected automatically, pass -DCMAKE_DISABLE_FIND_PACKAGE_FontNotoSans=true to mark it ignored." URL "https://www.google.com/get/noto/" TYPE RUNTIME ) find_package(FontHack) set_package_properties(FontHack PROPERTIES PURPOSE "Default monospace font -- this is not detected automatically, pass -DCMAKE_DISABLE_FIND_PACKAGE_FontHack=true to mark it ignored." URL "http://sourcefoundry.org/hack/" TYPE RUNTIME ) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/platformtheme/CMakeLists.txt b/src/platformtheme/CMakeLists.txt index 63a1b95..dbb117f 100644 --- a/src/platformtheme/CMakeLists.txt +++ b/src/platformtheme/CMakeLists.txt @@ -1,72 +1,73 @@ find_package(X11) set_package_properties(X11 PROPERTIES DESCRIPTION "Required for updating the Cursor theme on X11" URL "http://www.x.org" TYPE REQUIRED ) set(HAVE_X11 ${X11_FOUND}) if(HAVE_X11) find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED X11Extras) find_package(XCB COMPONENTS XCB) set_package_properties(XCB PROPERTIES TYPE REQUIRED) endif() configure_file(config-platformtheme.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-platformtheme.h ) # qdbusmenubar uses them remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS) include_directories(${Qt5Core_PRIVATE_INCLUDE_DIRS}) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) set(platformtheme_SRCS kdeplatformtheme.cpp kfontsettingsdata.cpp khintssettings.cpp kdeplatformfiledialoghelper.cpp kdeplatformfiledialogbase.cpp kdeplatformsystemtrayicon.cpp kfiletreeview.cpp kdirselectdialog.cpp kwaylandintegration.cpp x11integration.cpp main.cpp ) if(Qt5Core_VERSION VERSION_EQUAL "5.7.0" OR Qt5Core_VERSION VERSION_GREATER "5.7.0") set(platformtheme_SRCS qdbusmenubar.cpp # fork of Qt's qdbusmenubar with some added setters for our convenience ${platformtheme_SRCS} ) endif() add_library(KDEPlasmaPlatformTheme MODULE ${platformtheme_SRCS}) target_link_libraries(KDEPlasmaPlatformTheme PRIVATE Qt5::DBus Qt5::X11Extras + Qt5::QuickControls2 KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets # KFileFilterCombo, KDirSortFilterProxyModel, KRecentDirs KF5::KIOWidgets KF5::XmlGui KF5::I18n KF5::Notifications KF5::WindowSystem KF5::WaylandClient XCB::XCB ${QT5PLATFORMSUPPORT_LIBS} ) if(HAVE_X11) target_link_libraries(KDEPlasmaPlatformTheme PRIVATE Qt5::X11Extras ${X11_Xcursor_LIB} ${XCB_XCB_LIBRARY}) endif() install(TARGETS KDEPlasmaPlatformTheme DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/platformthemes) install(FILES fonts_global_toolbar.upd fonts_global.upd fonts_akregator.upd fonts_kate.upd DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) install(PROGRAMS fonts_global.pl fonts_akregator.pl fonts_kate.pl DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) diff --git a/src/platformtheme/kdeplatformtheme.cpp b/src/platformtheme/kdeplatformtheme.cpp index e94e907..44a3146 100644 --- a/src/platformtheme/kdeplatformtheme.cpp +++ b/src/platformtheme/kdeplatformtheme.cpp @@ -1,408 +1,413 @@ /* This file is part of the KDE libraries * Copyright 2013 Kevin Ottens * Copyright 2013 Aleix Pol Gonzalez * Copyright 2014 Lukáš Tinkl * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License or ( at * your option ) version 3 or, at the discretion of KDE e.V. ( which shall * act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 "kdeplatformtheme.h" #include "kfontsettingsdata.h" #include "khintssettings.h" #include "kdeplatformfiledialoghelper.h" #include "kdeplatformsystemtrayicon.h" #include "kwaylandintegration.h" #include "x11integration.h" #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(5,7,0) #include "qdbusmenubar_p.h" #endif static const QByteArray s_x11AppMenuServiceNamePropertyName = QByteArrayLiteral("_KDE_NET_WM_APPMENU_SERVICE_NAME"); static const QByteArray s_x11AppMenuObjectPathPropertyName = QByteArrayLiteral("_KDE_NET_WM_APPMENU_OBJECT_PATH"); static const QByteArray s_waylandAppMenuServiceNamePropertyName = QByteArrayLiteral("KDE_APPMENU_SERVICE_NAME"); static const QByteArray s_waylandAppMenuObjectPathPropertyName = QByteArrayLiteral("KDE_APPMENU_OBJECT_PATH"); static bool checkDBusGlobalMenuAvailable() { if (qEnvironmentVariableIsSet("KDE_NO_GLOBAL_MENU")) { return false; } QDBusConnection connection = QDBusConnection::sessionBus(); QString registrarService = QStringLiteral("com.canonical.AppMenu.Registrar"); return connection.interface()->isServiceRegistered(registrarService); } static bool isDBusGlobalMenuAvailable() { static bool dbusGlobalMenuAvailable = checkDBusGlobalMenuAvailable(); return dbusGlobalMenuAvailable; } KdePlatformTheme::KdePlatformTheme() { loadSettings(); if (KWindowSystem::isPlatformWayland()) { m_kwaylandIntegration.reset(new KWaylandIntegration()); m_kwaylandIntegration->init(); } #if HAVE_X11 if (KWindowSystem::isPlatformX11()) { m_x11Integration.reset(new X11Integration()); m_x11Integration->init(); } #endif QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, false); setQtQuickControlsTheme(); } KdePlatformTheme::~KdePlatformTheme() { delete m_fontsData; delete m_hints; } QVariant KdePlatformTheme::themeHint(QPlatformTheme::ThemeHint hintType) const { QVariant hint = m_hints->hint(hintType); if (hint.isValid()) { return hint; } else { return QPlatformTheme::themeHint(hintType); } } QIcon KdePlatformTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const { if (iconOptions.testFlag(DontUseCustomDirectoryIcons) && fileInfo.isDir()) { return QIcon::fromTheme(QLatin1String("inode-directory")); } return QIcon::fromTheme(KIO::iconNameForUrl(QUrl::fromLocalFile(fileInfo.absoluteFilePath()))); } #if QT_VERSION < QT_VERSION_CHECK(5, 8, 0) QPixmap KdePlatformTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, QPlatformTheme::IconOptions iconOptions) const { return fileIcon(fileInfo, iconOptions).pixmap(size.toSize(), QIcon::Normal); } #endif const QPalette *KdePlatformTheme::palette(Palette type) const { QPalette *palette = m_hints->palette(type); if (palette) { return palette; } else { return QPlatformTheme::palette(type); } } const QFont *KdePlatformTheme::font(Font type) const { KFontSettingsData::FontTypes fdtype; switch (type) { case SystemFont: fdtype = KFontSettingsData::GeneralFont; break; case MenuFont: case MenuBarFont: case MenuItemFont: fdtype = KFontSettingsData::MenuFont; break; case MessageBoxFont: case LabelFont: case TipLabelFont: case StatusBarFont: case PushButtonFont: case ItemViewFont: case ListViewFont: case HeaderViewFont: case ListBoxFont: case ComboMenuItemFont: case ComboLineEditFont: fdtype = KFontSettingsData::GeneralFont; break; case TitleBarFont: case MdiSubWindowTitleFont: case DockWidgetTitleFont: fdtype = KFontSettingsData::WindowTitleFont; break; case SmallFont: case MiniFont: fdtype = KFontSettingsData::SmallestReadableFont; break; case FixedFont: fdtype = KFontSettingsData::FixedFont; break; case ToolButtonFont: fdtype = KFontSettingsData::ToolbarFont; break; default: fdtype = KFontSettingsData::GeneralFont; break; } return m_fontsData->font(fdtype); } QIconEngine *KdePlatformTheme::createIconEngine(const QString &iconName) const { return new KIconEngine(iconName, KIconLoader::global()); } void KdePlatformTheme::loadSettings() { m_fontsData = new KFontSettingsData; m_hints = new KHintsSettings; } QList KdePlatformTheme::keyBindings(QKeySequence::StandardKey key) const { switch (key) { case QKeySequence::HelpContents: return KStandardShortcut::shortcut(KStandardShortcut::Help); case QKeySequence::WhatsThis: return KStandardShortcut::shortcut(KStandardShortcut::WhatsThis); case QKeySequence::Open: return KStandardShortcut::shortcut(KStandardShortcut::Open); case QKeySequence::Close: return KStandardShortcut::shortcut(KStandardShortcut::Close); case QKeySequence::Save: return KStandardShortcut::shortcut(KStandardShortcut::Save); case QKeySequence::New: return KStandardShortcut::shortcut(KStandardShortcut::New); case QKeySequence::Cut: return KStandardShortcut::shortcut(KStandardShortcut::Cut); case QKeySequence::Copy: return KStandardShortcut::shortcut(KStandardShortcut::Copy); case QKeySequence::Paste: return KStandardShortcut::shortcut(KStandardShortcut::Paste); case QKeySequence::Undo: return KStandardShortcut::shortcut(KStandardShortcut::Undo); case QKeySequence::Redo: return KStandardShortcut::shortcut(KStandardShortcut::Redo); case QKeySequence::Back: return KStandardShortcut::shortcut(KStandardShortcut::Back); case QKeySequence::Forward: return KStandardShortcut::shortcut(KStandardShortcut::Forward); case QKeySequence::Refresh: return KStandardShortcut::shortcut(KStandardShortcut::Reload); case QKeySequence::ZoomIn: return KStandardShortcut::shortcut(KStandardShortcut::ZoomIn); case QKeySequence::ZoomOut: return KStandardShortcut::shortcut(KStandardShortcut::ZoomOut); case QKeySequence::Print: return KStandardShortcut::shortcut(KStandardShortcut::Print); case QKeySequence::Find: return KStandardShortcut::shortcut(KStandardShortcut::Find); case QKeySequence::FindNext: return KStandardShortcut::shortcut(KStandardShortcut::FindNext); case QKeySequence::FindPrevious: return KStandardShortcut::shortcut(KStandardShortcut::FindPrev); case QKeySequence::Replace: return KStandardShortcut::shortcut(KStandardShortcut::Replace); case QKeySequence::SelectAll: return KStandardShortcut::shortcut(KStandardShortcut::SelectAll); case QKeySequence::MoveToNextWord: return KStandardShortcut::shortcut(KStandardShortcut::ForwardWord); case QKeySequence::MoveToPreviousWord: return KStandardShortcut::shortcut(KStandardShortcut::BackwardWord); case QKeySequence::MoveToNextPage: return KStandardShortcut::shortcut(KStandardShortcut::Next); case QKeySequence::MoveToPreviousPage: return KStandardShortcut::shortcut(KStandardShortcut::Prior); case QKeySequence::MoveToStartOfLine: return KStandardShortcut::shortcut(KStandardShortcut::BeginningOfLine); case QKeySequence::MoveToEndOfLine: return KStandardShortcut::shortcut(KStandardShortcut::EndOfLine); case QKeySequence::MoveToStartOfDocument: return KStandardShortcut::shortcut(KStandardShortcut::Begin); case QKeySequence::MoveToEndOfDocument: return KStandardShortcut::shortcut(KStandardShortcut::End); case QKeySequence::SaveAs: return KStandardShortcut::shortcut(KStandardShortcut::SaveAs); case QKeySequence::Preferences: return KStandardShortcut::shortcut(KStandardShortcut::Preferences); case QKeySequence::Quit: return KStandardShortcut::shortcut(KStandardShortcut::Quit); case QKeySequence::FullScreen: return KStandardShortcut::shortcut(KStandardShortcut::FullScreen); case QKeySequence::Deselect: return KStandardShortcut::shortcut(KStandardShortcut::Deselect); case QKeySequence::DeleteStartOfWord: return KStandardShortcut::shortcut(KStandardShortcut::DeleteWordBack); case QKeySequence::DeleteEndOfWord: return KStandardShortcut::shortcut(KStandardShortcut::DeleteWordForward); case QKeySequence::NextChild: return KStandardShortcut::shortcut(KStandardShortcut::TabNext); case QKeySequence::PreviousChild: return KStandardShortcut::shortcut(KStandardShortcut::TabPrev); default: return QPlatformTheme::keyBindings(key); } } bool KdePlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const { return type == QPlatformTheme::FileDialog && qobject_cast(QCoreApplication::instance()); } QString KdePlatformTheme::standardButtonText(int button) const { switch (static_cast(button)) { case QPlatformDialogHelper::NoButton: qWarning() << Q_FUNC_INFO << "Unsupported standard button:" << button; return QString(); case QPlatformDialogHelper::Ok: return KStandardGuiItem::ok().text(); case QPlatformDialogHelper::Save: return KStandardGuiItem::save().text(); case QPlatformDialogHelper::SaveAll: return i18nc("@action:button", "Save All"); case QPlatformDialogHelper::Open: return KStandardGuiItem::open().text(); case QPlatformDialogHelper::Yes: return KStandardGuiItem::yes().text(); case QPlatformDialogHelper::YesToAll: return i18nc("@action:button", "Yes to All"); case QPlatformDialogHelper::No: return KStandardGuiItem::no().text(); case QPlatformDialogHelper::NoToAll: return i18nc("@action:button", "No to All"); case QPlatformDialogHelper::Abort: // FIXME KStandardGuiItem::stop() doesn't seem right here return i18nc("@action:button", "Abort"); case QPlatformDialogHelper::Retry: return i18nc("@action:button", "Retry"); case QPlatformDialogHelper::Ignore: return i18nc("@action:button", "Ignore"); case QPlatformDialogHelper::Close: return KStandardGuiItem::close().text(); case QPlatformDialogHelper::Cancel: return KStandardGuiItem::cancel().text(); case QPlatformDialogHelper::Discard: return KStandardGuiItem::discard().text(); case QPlatformDialogHelper::Help: return KStandardGuiItem::help().text(); case QPlatformDialogHelper::Apply: return KStandardGuiItem::apply().text(); case QPlatformDialogHelper::Reset: return KStandardGuiItem::reset().text(); case QPlatformDialogHelper::RestoreDefaults: return KStandardGuiItem::defaults().text(); default: return QPlatformTheme::defaultStandardButtonText(button); } } QPlatformDialogHelper *KdePlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const { switch (type) { case QPlatformTheme::FileDialog: return new KDEPlatformFileDialogHelper; case QPlatformTheme::FontDialog: case QPlatformTheme::ColorDialog: case QPlatformTheme::MessageDialog: default: return 0; } } QPlatformSystemTrayIcon *KdePlatformTheme::createPlatformSystemTrayIcon() const { return new KDEPlatformSystemTrayIcon; } #if QT_VERSION >= QT_VERSION_CHECK(5,7,0) QPlatformMenuBar *KdePlatformTheme::createPlatformMenuBar() const { if (isDBusGlobalMenuAvailable()) { auto *menu = new QDBusMenuBar(); QObject::connect(menu, &QDBusMenuBar::windowChanged, menu, [this, menu](QWindow *newWindow, QWindow *oldWindow) { const QString &serviceName = QDBusConnection::sessionBus().baseService(); const QString &objectPath = menu->objectPath(); if (m_x11Integration) { if (oldWindow) { m_x11Integration->setWindowProperty(oldWindow, s_x11AppMenuServiceNamePropertyName, {}); m_x11Integration->setWindowProperty(oldWindow, s_x11AppMenuObjectPathPropertyName, {}); } if (newWindow) { m_x11Integration->setWindowProperty(newWindow, s_x11AppMenuServiceNamePropertyName, serviceName.toUtf8()); m_x11Integration->setWindowProperty(newWindow, s_x11AppMenuObjectPathPropertyName, objectPath.toUtf8()); } } if (m_kwaylandIntegration) { if (oldWindow) { m_kwaylandIntegration->setWindowProperty(oldWindow, s_waylandAppMenuServiceNamePropertyName, {}); m_kwaylandIntegration->setWindowProperty(oldWindow, s_waylandAppMenuObjectPathPropertyName, {}); } if (newWindow) { m_kwaylandIntegration->setWindowProperty(newWindow, s_waylandAppMenuServiceNamePropertyName, serviceName.toUtf8()); m_kwaylandIntegration->setWindowProperty(newWindow, s_waylandAppMenuObjectPathPropertyName, objectPath.toUtf8()); } } }); return menu; } return nullptr; } #endif //force QtQuickControls2 to use the desktop theme as default void KdePlatformTheme::setQtQuickControlsTheme() { - //if the user has explicitly set something else, don't meddle - if (qEnvironmentVariableIsSet("QT_QUICK_CONTROLS_STYLE")) { + //if the user is running only a QGuiApplication, explicitely unset the QQC1 desktop style and abort + //as this style is all about QWidgets and we know setting this will make it crash + if (!qobject_cast(qApp)) { + if (qgetenv("QT_QUICK_CONTROLS_1_STYLE").right(7) == "Desktop") { + qunsetenv("QT_QUICK_CONTROLS_1_STYLE"); + } return; } - //if the user is running only a QGuiApplication. Abort as this style is all about QWidgets and we know setting this will make it crash - if (!qobject_cast(qApp)) { + //if the user has explicitly set something else, don't meddle + if (!QQuickStyle::name().isEmpty()) { return; } - qputenv("QT_QUICK_CONTROLS_STYLE", "org.kde.desktop"); + QQuickStyle::setStyle(QLatin1String("org.kde.desktop")); } #include "kdeplatformtheme.moc"