File indexing completed on 2024-05-05 17:42:25
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2013 Kevin Ottens <ervin+bluesystems@kde.org> 0003 SPDX-FileCopyrightText: 2013 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0004 SPDX-FileCopyrightText: 2013 Alejandro Fiestas Olivares <afiestas@kde.org> 0005 SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0008 */ 0009 0010 #include "khintssettings.h" 0011 0012 #include <QApplication> 0013 #include <QDebug> 0014 #include <QDialogButtonBox> 0015 #include <QDir> 0016 #include <QFileInfo> 0017 #include <QGuiApplication> 0018 #include <QMainWindow> 0019 #include <QPalette> 0020 #include <QScreen> 0021 #include <QStandardPaths> 0022 #include <QString> 0023 #include <QTemporaryFile> 0024 #include <QToolBar> 0025 #include <QToolButton> 0026 0027 #include <QDBusArgument> 0028 #include <QDBusConnection> 0029 #include <QDBusInterface> 0030 0031 #include <KSandbox> 0032 #include <kcolorscheme.h> 0033 #include <kconfiggroup.h> 0034 #include <kiconloader.h> 0035 0036 #include <config-platformtheme.h> 0037 #ifdef UNIT_TEST 0038 #undef HAVE_X11 0039 #define HAVE_X11 0 0040 #endif 0041 #if HAVE_X11 0042 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0043 #include <private/qtx11extras_p.h> 0044 #else 0045 #include <QX11Info> 0046 #endif 0047 #include <X11/Xcursor/Xcursor.h> 0048 #endif 0049 0050 static const QString defaultLookAndFeelPackage = QStringLiteral("org.kde.breeze.desktop"); 0051 0052 const QDBusArgument &operator>>(const QDBusArgument &argument, QMap<QString, QVariantMap> &map) 0053 { 0054 argument.beginMap(); 0055 map.clear(); 0056 0057 while (!argument.atEnd()) { 0058 QString key; 0059 QVariantMap value; 0060 argument.beginMapEntry(); 0061 argument >> key >> value; 0062 argument.endMapEntry(); 0063 map.insert(key, value); 0064 } 0065 0066 argument.endMap(); 0067 return argument; 0068 } 0069 0070 KHintsSettings::KHintsSettings(const KSharedConfig::Ptr &kdeglobals) 0071 : QObject(nullptr) 0072 , mKdeGlobals(kdeglobals) 0073 , mUsePortal(KSandbox::isInside()) 0074 { 0075 if (!mKdeGlobals) { 0076 mKdeGlobals = KSharedConfig::openConfig(); 0077 } 0078 KConfigGroup cg(mKdeGlobals, "KDE"); 0079 0080 if (mUsePortal) { 0081 updatePortalSetting(); 0082 } 0083 0084 const auto cursorBlinkRate = readConfigValue(cg, QStringLiteral("CursorBlinkRate"), 1000).toInt(); 0085 m_hints[QPlatformTheme::CursorFlashTime] = cursorBlinkRate > 0 ? qBound(200, cursorBlinkRate, 2000) : 0; // 0 => no blinking 0086 m_hints[QPlatformTheme::MouseDoubleClickInterval] = readConfigValue(cg, QStringLiteral("DoubleClickInterval"), 400); 0087 m_hints[QPlatformTheme::StartDragDistance] = readConfigValue(cg, QStringLiteral("StartDragDist"), 10); 0088 m_hints[QPlatformTheme::StartDragTime] = readConfigValue(cg, QStringLiteral("StartDragTime"), 500); 0089 0090 KConfigGroup cgToolbar(mKdeGlobals, "Toolbar style"); 0091 m_hints[QPlatformTheme::ToolButtonStyle] = toolButtonStyle(cgToolbar); 0092 0093 KConfigGroup cgToolbarIcon(mKdeGlobals, "MainToolbarIcons"); 0094 m_hints[QPlatformTheme::ToolBarIconSize] = readConfigValue(cgToolbarIcon, QStringLiteral("Size"), 22); 0095 0096 m_hints[QPlatformTheme::ItemViewActivateItemOnSingleClick] = readConfigValue(cg, QStringLiteral("SingleClick"), true); 0097 0098 m_hints[QPlatformTheme::SystemIconThemeName] = readConfigValue(QStringLiteral("Icons"), QStringLiteral("Theme"), QStringLiteral("breeze")); 0099 0100 m_hints[QPlatformTheme::SystemIconFallbackThemeName] = QStringLiteral("hicolor"); 0101 m_hints[QPlatformTheme::IconThemeSearchPaths] = xdgIconThemePaths(); 0102 0103 QStringList styleNames{ 0104 QStringLiteral(BREEZE_STYLE_NAME), 0105 QStringLiteral("oxygen"), 0106 QStringLiteral("fusion"), 0107 QStringLiteral("windows"), 0108 }; 0109 const QString configuredStyle = readConfigValue(cg, QStringLiteral("widgetStyle"), QString()).toString(); 0110 if (!configuredStyle.isEmpty()) { 0111 styleNames.removeOne(configuredStyle); 0112 styleNames.prepend(configuredStyle); 0113 } 0114 const QString lnfStyle = readConfigValue(QStringLiteral("KDE"), QStringLiteral("widgetStyle"), QString()).toString(); 0115 if (!lnfStyle.isEmpty()) { 0116 styleNames.removeOne(lnfStyle); 0117 styleNames.prepend(lnfStyle); 0118 } 0119 m_hints[QPlatformTheme::StyleNames] = styleNames; 0120 0121 m_hints[QPlatformTheme::DialogButtonBoxLayout] = QDialogButtonBox::KdeLayout; 0122 m_hints[QPlatformTheme::DialogButtonBoxButtonsHaveIcons] = readConfigValue(cg, QStringLiteral("ShowIconsOnPushButtons"), true); 0123 m_hints[QPlatformTheme::UseFullScreenForPopupMenu] = true; 0124 m_hints[QPlatformTheme::KeyboardScheme] = QPlatformTheme::KdeKeyboardScheme; 0125 0126 int uiEffectsFlags = readConfigValue(cg, QStringLiteral("GraphicEffectsLevel"), 0) != 0 ? QPlatformTheme::GeneralUiEffect : 0; 0127 uiEffectsFlags |= QPlatformTheme::HoverEffect; 0128 m_hints[QPlatformTheme::UiEffects] = uiEffectsFlags; 0129 0130 m_hints[QPlatformTheme::IconPixmapSizes] = QVariant::fromValue(QList<int>() << 512 << 256 << 128 << 64 << 32 << 22 << 16 << 8); 0131 0132 m_hints[QPlatformTheme::WheelScrollLines] = readConfigValue(cg, QStringLiteral("WheelScrollLines"), 3); 0133 if (qobject_cast<QApplication *>(QCoreApplication::instance())) { 0134 QApplication::setWheelScrollLines(readConfigValue(cg, QStringLiteral("WheelScrollLines"), 3).toInt()); 0135 } 0136 0137 updateShowIconsInMenuItems(cg); 0138 0139 m_hints[QPlatformTheme::ShowShortcutsInContextMenus] = true; 0140 0141 QMetaObject::invokeMethod(this, "delayedDBusConnects", Qt::QueuedConnection); 0142 QMetaObject::invokeMethod(this, "setupIconLoader", Qt::QueuedConnection); 0143 0144 loadPalettes(); 0145 } 0146 0147 KHintsSettings::~KHintsSettings() 0148 { 0149 qDeleteAll(m_palettes); 0150 } 0151 0152 QVariant KHintsSettings::readConfigValue(const QString &group, const QString &key, const QVariant &defaultValue) 0153 { 0154 KConfigGroup userCg(mKdeGlobals, group); 0155 return readConfigValue(userCg, key, defaultValue); 0156 } 0157 0158 QVariant KHintsSettings::readConfigValue(const KConfigGroup &cg, const QString &key, const QVariant &defaultValue) const 0159 { 0160 if (mUsePortal) { 0161 const QString settingName = QStringLiteral("org.kde.kdeglobals.%1").arg(cg.name()); 0162 auto groupIt = mKdeGlobalsPortal.constFind(settingName); 0163 if (groupIt != mKdeGlobalsPortal.constEnd()) { 0164 auto valueIt = groupIt.value().constFind(key); 0165 if (valueIt != groupIt.value().constEnd()) { 0166 return valueIt.value(); 0167 } 0168 } 0169 } 0170 0171 return cg.readEntry(key, defaultValue); 0172 } 0173 0174 QStringList KHintsSettings::xdgIconThemePaths() const 0175 { 0176 QStringList paths; 0177 0178 // make sure we have ~/.local/share/icons in paths if it exists 0179 paths << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("icons"), QStandardPaths::LocateDirectory); 0180 0181 const QFileInfo homeIconDir(QDir::homePath() + QStringLiteral("/.icons")); 0182 if (homeIconDir.isDir()) { 0183 paths << homeIconDir.absoluteFilePath(); 0184 } 0185 0186 return paths; 0187 } 0188 0189 void KHintsSettings::delayedDBusConnects() 0190 { 0191 QDBusConnection::sessionBus() 0192 .connect(QString(), QStringLiteral("/KToolBar"), QStringLiteral("org.kde.KToolBar"), QStringLiteral("styleChanged"), this, SLOT(toolbarStyleChanged())); 0193 QDBusConnection::sessionBus().connect(QString(), 0194 QStringLiteral("/KGlobalSettings"), 0195 QStringLiteral("org.kde.KGlobalSettings"), 0196 QStringLiteral("notifyChange"), 0197 this, 0198 SLOT(slotNotifyChange(int, int))); 0199 if (mUsePortal) { 0200 QDBusConnection::sessionBus().connect(QString(), 0201 QStringLiteral("/org/freedesktop/portal/desktop"), 0202 QStringLiteral("org.freedesktop.portal.Settings"), 0203 QStringLiteral("SettingChanged"), 0204 this, 0205 SLOT(slotPortalSettingChanged(QString, QString, QDBusVariant))); 0206 } 0207 } 0208 0209 void KHintsSettings::setupIconLoader() 0210 { 0211 connect(KIconLoader::global(), &KIconLoader::iconChanged, this, &KHintsSettings::iconChanged); 0212 } 0213 0214 void KHintsSettings::toolbarStyleChanged() 0215 { 0216 mKdeGlobals->reparseConfiguration(); 0217 KConfigGroup cg(mKdeGlobals, "Toolbar style"); 0218 0219 m_hints[QPlatformTheme::ToolButtonStyle] = toolButtonStyle(cg); 0220 // from gtksymbol.cpp 0221 QWidgetList widgets = QApplication::allWidgets(); 0222 for (int i = 0; i < widgets.size(); ++i) { 0223 QWidget *widget = widgets.at(i); 0224 if (qobject_cast<QToolButton *>(widget)) { 0225 QEvent event(QEvent::StyleChange); 0226 QApplication::sendEvent(widget, &event); 0227 } 0228 } 0229 } 0230 0231 void KHintsSettings::slotNotifyChange(int type, int arg) 0232 { 0233 mKdeGlobals->reparseConfiguration(); 0234 KConfigGroup cg(mKdeGlobals, "KDE"); 0235 0236 switch (type) { 0237 case PaletteChanged: { 0238 // Don't change the palette if the application has a custom one set 0239 if (!qApp->property("KDE_COLOR_SCHEME_PATH").toString().isEmpty()) { 0240 break; 0241 } 0242 loadPalettes(); 0243 0244 // QApplication::setPalette and QGuiApplication::setPalette are different functions 0245 // and non virtual. Call the correct one 0246 if (qobject_cast<QApplication *>(QCoreApplication::instance())) { 0247 QPalette palette = *m_palettes[QPlatformTheme::SystemPalette]; 0248 QApplication::setPalette(palette); 0249 // QTBUG QGuiApplication::paletteChanged() signal is only emitted by QGuiApplication 0250 // so things like SystemPalette QtQuick item that use it won't notice a palette 0251 // change when a QApplication which causes e.g. QML System Settings modules to not update 0252 Q_EMIT qApp->paletteChanged(palette); 0253 } else if (qobject_cast<QGuiApplication *>(QCoreApplication::instance())) { 0254 QGuiApplication::setPalette(*m_palettes[QPlatformTheme::SystemPalette]); 0255 } 0256 break; 0257 } 0258 case SettingsChanged: { 0259 SettingsCategory category = static_cast<SettingsCategory>(arg); 0260 if (category == SETTINGS_QT || category == SETTINGS_MOUSE) { 0261 updateQtSettings(cg); 0262 } else if (category == SETTINGS_STYLE) { 0263 m_hints[QPlatformTheme::DialogButtonBoxButtonsHaveIcons] = cg.readEntry("ShowIconsOnPushButtons", true); 0264 m_hints[QPlatformTheme::UiEffects] = cg.readEntry("GraphicEffectsLevel", 0) != 0 ? QPlatformTheme::GeneralUiEffect : 0; 0265 0266 updateShowIconsInMenuItems(cg); 0267 } 0268 break; 0269 } 0270 case ToolbarStyleChanged: { 0271 toolbarStyleChanged(); 0272 break; 0273 } 0274 case IconChanged: 0275 iconChanged(arg); // Once the KCM is ported to use IconChanged, this should not be needed 0276 break; 0277 case CursorChanged: 0278 updateCursorTheme(); 0279 break; 0280 case StyleChanged: { 0281 QApplication *app = qobject_cast<QApplication *>(QCoreApplication::instance()); 0282 if (!app) { 0283 return; 0284 } 0285 0286 // HOTFIX here. Hardcoded default value is duplicated and may be inconsistent with the one actually defined in kcm_style kcfg 0287 const QString theme = readConfigValue(cg, QStringLiteral("widgetStyle"), QStringLiteral(BREEZE_STYLE_NAME)).toString(); 0288 0289 QStringList styleNames; 0290 if (theme != QStringLiteral(BREEZE_STYLE_NAME)) { 0291 styleNames << theme; 0292 } 0293 styleNames << QStringLiteral(BREEZE_STYLE_NAME) << QStringLiteral("oxygen") << QStringLiteral("fusion") << QStringLiteral("windows"); 0294 const QString lnfStyle = readConfigValue(QStringLiteral("KDE"), QStringLiteral("widgetStyle"), QString()).toString(); 0295 if (!lnfStyle.isEmpty() && !styleNames.contains(lnfStyle)) { 0296 styleNames.prepend(lnfStyle); 0297 } 0298 m_hints[QPlatformTheme::StyleNames] = styleNames; 0299 0300 app->setStyle(theme); 0301 loadPalettes(); 0302 break; 0303 } 0304 default: 0305 qWarning() << "Unknown type of change in KGlobalSettings::slotNotifyChange: " << type; 0306 } 0307 } 0308 0309 void KHintsSettings::slotPortalSettingChanged(const QString &group, const QString &key, const QDBusVariant &value) 0310 { 0311 if (group == QLatin1String("org.kde.kdeglobals.General") && key == QLatin1String("ColorScheme")) { 0312 // For colors obtain complete configuration again 0313 updatePortalSetting(); 0314 slotNotifyChange(PaletteChanged, 0); 0315 } else if (group == QLatin1String("org.kde.kdeglobals.KDE") && key == QLatin1String("widgetStyle")) { 0316 mKdeGlobalsPortal[group][key] = value.variant().toString(); 0317 slotNotifyChange(StyleChanged, 0); 0318 } else if (group == QLatin1String("org.kde.kdeglobals.Icons") && key == QLatin1String("Theme")) { 0319 mKdeGlobalsPortal[group][key] = value.variant().toString(); 0320 // Change icons for each group 0321 for (int i = 0; i <= 5; ++i) { 0322 iconChanged(i); 0323 } 0324 } else if (group == QLatin1String("org.kde.kdeglobals.Toolbar style") && key == QLatin1String("ToolButtonStyle")) { 0325 mKdeGlobalsPortal[group][key] = value.variant().toString(); 0326 toolbarStyleChanged(); 0327 } 0328 } 0329 0330 void KHintsSettings::iconChanged(int group) 0331 { 0332 KIconLoader::Group iconGroup = (KIconLoader::Group)group; 0333 if (iconGroup != KIconLoader::MainToolbar) { 0334 m_hints[QPlatformTheme::SystemIconThemeName] = readConfigValue(QStringLiteral("Icons"), QStringLiteral("Theme"), QStringLiteral("breeze")); 0335 return; 0336 } 0337 0338 const int currentSize = KIconLoader::global()->currentSize(KIconLoader::MainToolbar); 0339 if (m_hints[QPlatformTheme::ToolBarIconSize] == currentSize) { 0340 return; 0341 } 0342 0343 m_hints[QPlatformTheme::ToolBarIconSize] = currentSize; 0344 0345 // If we are not a QApplication, means that we are a QGuiApplication, then we do nothing. 0346 if (!qobject_cast<QApplication *>(QCoreApplication::instance())) { 0347 return; 0348 } 0349 0350 const QWidgetList widgets = QApplication::allWidgets(); 0351 for (QWidget *widget : widgets) { 0352 if (qobject_cast<QToolBar *>(widget) || qobject_cast<QMainWindow *>(widget)) { 0353 QEvent event(QEvent::StyleChange); 0354 QApplication::sendEvent(widget, &event); 0355 } 0356 } 0357 } 0358 0359 void KHintsSettings::updateQtSettings(KConfigGroup &cg) 0360 { 0361 int flash = qBound(200, cg.readEntry("CursorBlinkRate", 1000), 2000); 0362 m_hints[QPlatformTheme::CursorFlashTime] = flash; 0363 0364 int doubleClickInterval = cg.readEntry("DoubleClickInterval", 400); 0365 m_hints[QPlatformTheme::MouseDoubleClickInterval] = doubleClickInterval; 0366 0367 int startDragDistance = cg.readEntry("StartDragDist", 10); 0368 m_hints[QPlatformTheme::StartDragDistance] = startDragDistance; 0369 0370 int startDragTime = cg.readEntry("StartDragTime", 500); 0371 m_hints[QPlatformTheme::StartDragTime] = startDragTime; 0372 0373 m_hints[QPlatformTheme::ItemViewActivateItemOnSingleClick] = cg.readEntry("SingleClick", true); 0374 0375 updateShowIconsInMenuItems(cg); 0376 0377 int wheelScrollLines = cg.readEntry("WheelScrollLines", 3); 0378 m_hints[QPlatformTheme::WheelScrollLines] = wheelScrollLines; 0379 QApplication *app = qobject_cast<QApplication *>(QCoreApplication::instance()); 0380 if (app) { 0381 QApplication::setWheelScrollLines(cg.readEntry("WheelScrollLines", 3)); 0382 } 0383 } 0384 0385 void KHintsSettings::updateShowIconsInMenuItems(KConfigGroup &cg) 0386 { 0387 bool showIcons = readConfigValue(cg, QStringLiteral("ShowIconsInMenuItems"), true).toBool(); 0388 QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !showIcons); 0389 } 0390 0391 Qt::ToolButtonStyle KHintsSettings::toolButtonStyle(const KConfigGroup &cg) 0392 { 0393 const QString buttonStyle = readConfigValue(cg, QStringLiteral("ToolButtonStyle"), QStringLiteral("TextBesideIcon")).toString().toLower(); 0394 return buttonStyle == QLatin1String("textbesideicon") ? Qt::ToolButtonTextBesideIcon 0395 : buttonStyle == QLatin1String("icontextright") ? Qt::ToolButtonTextBesideIcon 0396 : buttonStyle == QLatin1String("textundericon") ? Qt::ToolButtonTextUnderIcon 0397 : buttonStyle == QLatin1String("icontextbottom") ? Qt::ToolButtonTextUnderIcon 0398 : buttonStyle == QLatin1String("textonly") ? Qt::ToolButtonTextOnly 0399 : Qt::ToolButtonIconOnly; 0400 } 0401 0402 void KHintsSettings::loadPalettes() 0403 { 0404 qDeleteAll(m_palettes); 0405 m_palettes.clear(); 0406 0407 if (mUsePortal && mKdeGlobalsPortal.contains(QStringLiteral("org.kde.kdeglobals.Colors:View"))) { 0408 // Construct a temporary KConfig file containing color setting so we can create a KColorScheme from it 0409 QTemporaryFile file; 0410 file.open(); 0411 0412 KSharedConfigPtr tempConfig = KSharedConfig::openConfig(file.fileName(), KConfig::SimpleConfig); 0413 for (auto groupIt = mKdeGlobalsPortal.constBegin(); groupIt != mKdeGlobalsPortal.constEnd(); ++groupIt) { 0414 if (groupIt.key().startsWith(QStringLiteral("org.kde.kdeglobals.Colors:"))) { 0415 KConfigGroup tempGroup(tempConfig, groupIt.key().right(groupIt.key().length() - QStringLiteral("org.kde.kdeglobals.").length())); 0416 for (auto valueIt = groupIt.value().constBegin(); valueIt != groupIt.value().constEnd(); ++valueIt) { 0417 tempGroup.writeEntry(valueIt.key(), valueIt.value()); 0418 } 0419 } 0420 } 0421 m_palettes[QPlatformTheme::SystemPalette] = new QPalette(KColorScheme::createApplicationPalette(tempConfig)); 0422 } else if (mKdeGlobals->hasGroup("Colors:View")) { 0423 m_palettes[QPlatformTheme::SystemPalette] = new QPalette(KColorScheme::createApplicationPalette(mKdeGlobals)); 0424 } else { 0425 KConfigGroup cg(mKdeGlobals, "KDE"); 0426 const QString looknfeel = readConfigValue(cg, QStringLiteral("LookAndFeelPackage"), defaultLookAndFeelPackage).toString(); 0427 QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0428 QStringLiteral("plasma/look-and-feel/") + looknfeel + QStringLiteral("/contents/colors")); 0429 if (!path.isEmpty()) { 0430 m_palettes[QPlatformTheme::SystemPalette] = new QPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(path))); 0431 return; 0432 } 0433 0434 const QString scheme = readConfigValue(QStringLiteral("General"), QStringLiteral("ColorScheme"), QStringLiteral("BreezeLight")).toString(); 0435 path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("color-schemes/") + scheme + QStringLiteral(".colors")); 0436 0437 if (path.isEmpty()) { 0438 qWarning() << "Could not find color scheme" << scheme << "falling back to BreezeLight"; 0439 path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("color-schemes/BreezeLight.colors")); 0440 } 0441 0442 m_palettes[QPlatformTheme::SystemPalette] = new QPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(path))); 0443 } 0444 } 0445 0446 void KHintsSettings::updateCursorTheme() 0447 { 0448 #if HAVE_X11 0449 if (QX11Info::isPlatformX11()) { 0450 KConfig config(QStringLiteral("kcminputrc")); 0451 KConfigGroup g(&config, "Mouse"); 0452 0453 int size = g.readEntry("cursorSize", 24); 0454 const QString theme = g.readEntry("cursorTheme", QString()); 0455 // Note that in X11R7.1 and earlier, calling XcursorSetTheme() 0456 // with a NULL theme would cause Xcursor to use "default", but 0457 // in 7.2 and later it will cause it to revert to the theme that 0458 // was configured when the application was started. 0459 XcursorSetTheme(QX11Info::display(), theme.isNull() ? "default" : QFile::encodeName(theme).constData()); 0460 XcursorSetDefaultSize(QX11Info::display(), size); 0461 } 0462 #endif 0463 } 0464 0465 void KHintsSettings::updatePortalSetting() 0466 { 0467 mKdeGlobalsPortal.clear(); 0468 0469 QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.portal.Desktop"), 0470 QStringLiteral("/org/freedesktop/portal/desktop"), 0471 QStringLiteral("org.freedesktop.portal.Settings"), 0472 QStringLiteral("ReadAll")); 0473 message << QStringList{QStringLiteral("org.kde.kdeglobals.*")}; 0474 0475 // FIXME: async? 0476 QDBusMessage resultMessage = QDBusConnection::sessionBus().call(message); 0477 if (resultMessage.type() == QDBusMessage::ReplyMessage) { 0478 QDBusArgument dbusArgument = resultMessage.arguments().at(0).value<QDBusArgument>(); 0479 dbusArgument >> mKdeGlobalsPortal; 0480 } 0481 }