File indexing completed on 2024-04-21 14:55:54
0001 /* This file is part of the KDE libraries 0002 Copyright (C) 2000, 2006 David Faure <faure@kde.org> 0003 Copyright 2008 Friedrich W. H. Kossebau <kossebau@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License version 2 as published by the Free Software Foundation. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kglobalsettings.h" 0021 0022 #include <ktoolbar.h> 0023 #include <kconfig.h> 0024 #include <kcolorscheme.h> 0025 0026 //#include <kstyle.h> 0027 0028 #include <QColor> 0029 #include <QCursor> 0030 #include <QDesktopWidget> 0031 #include <QDir> 0032 #include <QFont> 0033 #include <QFontDatabase> 0034 #include <QFontInfo> 0035 #include <QKeySequence> 0036 #include <QPixmap> 0037 #include <QPixmapCache> 0038 #include <QApplication> 0039 #include <QDBusConnection> 0040 #include <QStyleFactory> 0041 #include <QDebug> 0042 #include <qstandardpaths.h> 0043 0044 // next two needed so we can set their palettes 0045 #include <QDBusMessage> 0046 #include <QToolTip> 0047 #include <QUrl> 0048 #include <QWhatsThis> 0049 0050 #ifdef Q_OS_WIN 0051 #include <windows.h> 0052 0053 static QRgb qt_colorref2qrgb(COLORREF col) 0054 { 0055 return qRgb(GetRValue(col), GetGValue(col), GetBValue(col)); 0056 } 0057 #endif 0058 #include <config-kdelibs4support.h> 0059 #if HAVE_X11 0060 #include <X11/Xlib.h> 0061 #ifdef HAVE_XCURSOR // TODO NOT DEFINED ANYMORE. Can we drop X cursor themes? 0062 #include <X11/Xcursor/Xcursor.h> 0063 #endif 0064 //#include "fixx11h.h" 0065 #include <QX11Info> 0066 #endif 0067 0068 #include <stdlib.h> 0069 #include <kconfiggroup.h> 0070 #include <kiconloader.h> 0071 0072 //static QColor *_buttonBackground = 0; 0073 static KGlobalSettings::GraphicEffects _graphicEffects = KGlobalSettings::NoEffects; 0074 0075 class Q_DECL_HIDDEN KGlobalSettings::Private 0076 { 0077 public: 0078 Private(KGlobalSettings *q) 0079 : q(q), activated(false), paletteCreated(false), mMouseSettings(nullptr), mLargeFont(nullptr) 0080 #if HAVE_X11 0081 , isX11(QX11Info::isPlatformX11()) 0082 #endif 0083 { 0084 kdeFullSession = !qgetenv("KDE_FULL_SESSION").isEmpty(); 0085 } 0086 0087 QPalette createApplicationPalette(const KSharedConfigPtr &config); 0088 QPalette createNewApplicationPalette(const KSharedConfigPtr &config); 0089 void _k_slotNotifyChange(int, int); 0090 void _k_slotIconChange(int); 0091 0092 void propagateQtSettings(); 0093 void kdisplaySetPalette(); 0094 void kdisplaySetStyle(); 0095 void kdisplaySetFont(); 0096 void applyGUIStyle(); 0097 void dropMouseSettingsCache(); 0098 KGlobalSettings::KMouseSettings &mouseSettings(); 0099 0100 /** 0101 * @internal 0102 * 0103 * Ensures that cursors are loaded from the theme KDE is configured 0104 * to use. Note that calling this function doesn't cause existing 0105 * cursors to be reloaded. Reloading already created cursors is 0106 * handled by the KCM when a cursor theme is applied. 0107 * 0108 * It is not necessary to call this function when KGlobalSettings 0109 * is initialized. 0110 */ 0111 void applyCursorTheme(); 0112 0113 static void reloadStyleSettings(); 0114 0115 QFont largeFont(const QString &text); 0116 0117 KGlobalSettings *q; 0118 bool activated; 0119 bool paletteCreated; 0120 bool kdeFullSession; 0121 QPalette applicationPalette; 0122 KGlobalSettings::KMouseSettings *mMouseSettings; 0123 QFont *mLargeFont; 0124 #if HAVE_X11 0125 bool isX11; 0126 #endif 0127 }; 0128 0129 // class for access to KGlobalSettings constructor 0130 class KGlobalSettingsSingleton 0131 { 0132 public: 0133 KGlobalSettings object; 0134 }; 0135 0136 Q_GLOBAL_STATIC(KGlobalSettingsSingleton, s_self) 0137 0138 KGlobalSettings *KGlobalSettings::self() 0139 { 0140 return &s_self()->object; 0141 } 0142 0143 KGlobalSettings::KGlobalSettings() 0144 : QObject(nullptr), d(new Private(this)) 0145 { 0146 connect(this, SIGNAL(kdisplayFontChanged()), SIGNAL(appearanceChanged())); 0147 } 0148 0149 KGlobalSettings::~KGlobalSettings() 0150 { 0151 delete d; 0152 } 0153 0154 void KGlobalSettings::activate() 0155 { 0156 activate(ApplySettings | ListenForChanges); 0157 } 0158 0159 void KGlobalSettings::activate(ActivateOptions options) 0160 { 0161 if (!d->activated) { 0162 d->activated = true; 0163 0164 if (options & ListenForChanges) { 0165 QDBusConnection::sessionBus().connect(QString(), "/KGlobalSettings", "org.kde.KGlobalSettings", 0166 "notifyChange", this, SLOT(_k_slotNotifyChange(int,int))); 0167 QDBusConnection::sessionBus().connect(QString(), "/KIconLoader", "org.kde.KIconLoader", 0168 "iconChanged", this, SLOT(_k_slotIconChange(int))); 0169 QDBusConnection::sessionBus().connect(QString(), "/KDEPlatformTheme", "org.kde.KDEPlatformTheme", 0170 "refreshFonts", this, SLOT(kdisplayFontChanged())); 0171 } 0172 0173 if (options & ApplySettings) { 0174 d->kdisplaySetStyle(); // implies palette setup 0175 d->propagateQtSettings(); 0176 } 0177 } 0178 } 0179 0180 // Qt5 TODO: implement QPlatformIntegration::styleHint so that it reads a Qt or KDE setting, 0181 // so that apps can just use QApplication::startDragDistance(). 0182 int KGlobalSettings::dndEventDelay() 0183 { 0184 KConfigGroup g(KSharedConfig::openConfig(), "General"); 0185 return g.readEntry("StartDragDist", QApplication::startDragDistance()); 0186 } 0187 0188 bool KGlobalSettings::singleClick() 0189 { 0190 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0191 return g.readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK); 0192 } 0193 0194 bool KGlobalSettings::changeCursorOverIcon() 0195 { 0196 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0197 return g.readEntry("ChangeCursor", KDE_DEFAULT_CHANGECURSOR); 0198 } 0199 0200 int KGlobalSettings::autoSelectDelay() 0201 { 0202 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0203 return g.readEntry("AutoSelectDelay", KDE_DEFAULT_AUTOSELECTDELAY); 0204 } 0205 0206 KGlobalSettings::Completion KGlobalSettings::completionMode() 0207 { 0208 int completion; 0209 KConfigGroup g(KSharedConfig::openConfig(), "General"); 0210 completion = g.readEntry("completionMode", -1); 0211 if ((completion < (int) CompletionNone) || 0212 (completion > (int) CompletionPopupAuto)) { 0213 completion = (int) CompletionPopup; // Default 0214 } 0215 return (Completion) completion; 0216 } 0217 0218 bool KGlobalSettings::showContextMenusOnPress() 0219 { 0220 KConfigGroup g(KSharedConfig::openConfig(), "ContextMenus"); 0221 return g.readEntry("ShowOnPress", true); 0222 } 0223 0224 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 0225 QColor KGlobalSettings::inactiveTitleColor() 0226 { 0227 #ifdef Q_OS_WIN 0228 return qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)); 0229 #else 0230 KConfigGroup g(KSharedConfig::openConfig(), "WM"); 0231 return g.readEntry("inactiveBackground", QColor(224, 223, 222)); 0232 #endif 0233 } 0234 0235 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 0236 QColor KGlobalSettings::inactiveTextColor() 0237 { 0238 #ifdef Q_OS_WIN 0239 return qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)); 0240 #else 0241 KConfigGroup g(KSharedConfig::openConfig(), "WM"); 0242 return g.readEntry("inactiveForeground", QColor(75, 71, 67)); 0243 #endif 0244 } 0245 0246 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 0247 QColor KGlobalSettings::activeTitleColor() 0248 { 0249 #ifdef Q_OS_WIN 0250 return qt_colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)); 0251 #else 0252 KConfigGroup g(KSharedConfig::openConfig(), "WM"); 0253 return g.readEntry("activeBackground", QColor(48, 174, 232)); 0254 #endif 0255 } 0256 0257 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 0258 QColor KGlobalSettings::activeTextColor() 0259 { 0260 #ifdef Q_OS_WIN 0261 return qt_colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)); 0262 #else 0263 KConfigGroup g(KSharedConfig::openConfig(), "WM"); 0264 return g.readEntry("activeForeground", QColor(255, 255, 255)); 0265 #endif 0266 } 0267 0268 int KGlobalSettings::contrast() 0269 { 0270 return KColorScheme::contrast(); 0271 } 0272 0273 qreal KGlobalSettings::contrastF(const KSharedConfigPtr &config) 0274 { 0275 return KColorScheme::contrastF(config); 0276 } 0277 0278 bool KGlobalSettings::shadeSortColumn() 0279 { 0280 KConfigGroup g(KSharedConfig::openConfig(), "General"); 0281 return g.readEntry("shadeSortColumn", KDE_DEFAULT_SHADE_SORT_COLUMN); 0282 } 0283 0284 bool KGlobalSettings::allowDefaultBackgroundImages() 0285 { 0286 KConfigGroup g(KSharedConfig::openConfig(), "General"); 0287 return g.readEntry("allowDefaultBackgroundImages", KDE_DEFAULT_ALLOW_DEFAULT_BACKGROUND_IMAGES); 0288 } 0289 0290 //inspired in old KGlobalSettingsData code 0291 QFont constructFontFromConfig(const char *groupKey, const char *configKey) 0292 { 0293 const KConfigGroup configGroup(KSharedConfig::openConfig(), groupKey); 0294 QFont ret; 0295 ret.setStyleHint(QFont::SansSerif); 0296 ret = configGroup.readEntry(configKey, ret); 0297 return ret; 0298 } 0299 0300 QFont KGlobalSettings::generalFont() 0301 { 0302 return QFontDatabase::systemFont(QFontDatabase::GeneralFont); 0303 } 0304 QFont KGlobalSettings::fixedFont() 0305 { 0306 return QFontDatabase::systemFont(QFontDatabase::FixedFont); 0307 } 0308 QFont KGlobalSettings::windowTitleFont() 0309 { 0310 return QFontDatabase::systemFont(QFontDatabase::TitleFont); 0311 } 0312 QFont KGlobalSettings::smallestReadableFont() 0313 { 0314 return QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont); 0315 } 0316 QFont KGlobalSettings::toolBarFont() 0317 { 0318 return constructFontFromConfig("General", "toolBarFont"); 0319 } 0320 QFont KGlobalSettings::menuFont() 0321 { 0322 return constructFontFromConfig("General", "menuFont"); 0323 } 0324 QFont KGlobalSettings::taskbarFont() 0325 { 0326 return constructFontFromConfig("General", "taskbarFont"); 0327 } 0328 0329 QFont KGlobalSettings::Private::largeFont(const QString &text) 0330 { 0331 QFontDatabase db; 0332 QStringList fam = db.families(); 0333 0334 // Move a bunch of preferred fonts to the front. 0335 // most preferred last 0336 static const char *const PreferredFontNames[] = { 0337 "Arial", 0338 "Sans Serif", 0339 "Verdana", 0340 "Tahoma", 0341 "Lucida Sans", 0342 "Lucidux Sans", 0343 "Nimbus Sans", 0344 "Gothic I" 0345 }; 0346 static const unsigned int PreferredFontNamesCount = sizeof(PreferredFontNames) / sizeof(const char *); 0347 for (unsigned int i = 0; i < PreferredFontNamesCount; ++i) { 0348 const QString fontName(PreferredFontNames[i]); 0349 if (fam.removeAll(fontName) > 0) { 0350 fam.prepend(fontName); 0351 } 0352 } 0353 0354 if (mLargeFont) { 0355 fam.prepend(mLargeFont->family()); 0356 delete mLargeFont; 0357 } 0358 0359 for (QStringList::ConstIterator it = fam.constBegin(); 0360 it != fam.constEnd(); ++it) { 0361 if (db.isSmoothlyScalable(*it) && !db.isFixedPitch(*it)) { 0362 QFont font(*it); 0363 font.setPixelSize(75); 0364 QFontMetrics metrics(font); 0365 int h = metrics.height(); 0366 if ((h < 60) || (h > 90)) { 0367 continue; 0368 } 0369 0370 bool ok = true; 0371 for (int i = 0; i < text.length(); i++) { 0372 if (!metrics.inFont(text[i])) { 0373 ok = false; 0374 break; 0375 } 0376 } 0377 if (!ok) { 0378 continue; 0379 } 0380 0381 font.setPointSize(48); 0382 mLargeFont = new QFont(font); 0383 return *mLargeFont; 0384 } 0385 } 0386 mLargeFont = new QFont(q->generalFont()); 0387 mLargeFont->setPointSize(48); 0388 return *mLargeFont; 0389 } 0390 0391 QFont KGlobalSettings::largeFont(const QString &text) 0392 { 0393 return self()->d->largeFont(text); 0394 } 0395 0396 KGlobalSettings::KMouseSettings &KGlobalSettings::Private::mouseSettings() 0397 { 0398 if (!mMouseSettings) { 0399 mMouseSettings = new KGlobalSettings::KMouseSettings; 0400 KGlobalSettings::KMouseSettings &s = *mMouseSettings; // for convenience 0401 0402 #ifndef Q_OS_WIN 0403 KConfigGroup g(KSharedConfig::openConfig(), "Mouse"); 0404 QString setting = g.readEntry("MouseButtonMapping"); 0405 if (setting == "RightHanded") { 0406 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 0407 } else if (setting == "LeftHanded") { 0408 s.handed = KGlobalSettings::KMouseSettings::LeftHanded; 0409 } else { 0410 #if HAVE_X11 0411 if (isX11) { 0412 // get settings from X server 0413 // This is a simplified version of the code in input/mouse.cpp 0414 // Keep in sync ! 0415 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 0416 unsigned char map[20]; 0417 int num_buttons = XGetPointerMapping(QX11Info::display(), map, 20); 0418 if (num_buttons == 2) { 0419 if ((int)map[0] == 1 && (int)map[1] == 2) { 0420 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 0421 } else if ((int)map[0] == 2 && (int)map[1] == 1) { 0422 s.handed = KGlobalSettings::KMouseSettings::LeftHanded; 0423 } 0424 } else if (num_buttons >= 3) { 0425 if ((int)map[0] == 1 && (int)map[2] == 3) { 0426 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 0427 } else if ((int)map[0] == 3 && (int)map[2] == 1) { 0428 s.handed = KGlobalSettings::KMouseSettings::LeftHanded; 0429 } 0430 } 0431 } 0432 #else 0433 // FIXME: Implement on other platforms 0434 #endif 0435 } 0436 #endif //Q_OS_WIN 0437 } 0438 #ifdef Q_OS_WIN 0439 //not cached 0440 #ifndef _WIN32_WCE 0441 mMouseSettings->handed = (GetSystemMetrics(SM_SWAPBUTTON) ? 0442 KGlobalSettings::KMouseSettings::LeftHanded : 0443 KGlobalSettings::KMouseSettings::RightHanded); 0444 #else 0445 // There is no mice under wince 0446 mMouseSettings->handed = KGlobalSettings::KMouseSettings::RightHanded; 0447 #endif 0448 #endif 0449 return *mMouseSettings; 0450 } 0451 // KDE5: make this a const return? 0452 KGlobalSettings::KMouseSettings &KGlobalSettings::mouseSettings() 0453 { 0454 return self()->d->mouseSettings(); 0455 } 0456 0457 QString KGlobalSettings::desktopPath() 0458 { 0459 QString path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); 0460 return path.isEmpty() ? QDir::homePath() : path; 0461 } 0462 0463 // This was the KDE-specific autostart folder in KDEHOME. 0464 // KDE 5 : re-evaluate this, I'd say the xdg autostart spec supersedes this, and is sufficient 0465 // (since there's a GUI for creating the necessary desktop files) 0466 #if 0 0467 QString KGlobalSettings::autostartPath() 0468 { 0469 QString s_autostartPath; 0470 KConfigGroup g(KSharedConfig::openConfig(), "Paths"); 0471 s_autostartPath = KGlobal::dirs()->localkdedir() + "Autostart/"; 0472 s_autostartPath = g.readPathEntry("Autostart", s_autostartPath); 0473 s_autostartPath = QDir::cleanPath(s_autostartPath); 0474 if (!s_autostartPath.endsWith('/')) { 0475 s_autostartPath.append(QLatin1Char('/')); 0476 } 0477 return s_autostartPath; 0478 } 0479 #endif 0480 0481 QString KGlobalSettings::documentPath() 0482 { 0483 QString path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); 0484 return path.isEmpty() ? QDir::homePath() : path; 0485 } 0486 0487 QString KGlobalSettings::downloadPath() 0488 { 0489 QString path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); 0490 return path.isEmpty() ? QDir::homePath() : path; 0491 } 0492 0493 QString KGlobalSettings::videosPath() 0494 { 0495 QString path = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); 0496 return path.isEmpty() ? QDir::homePath() : path; 0497 } 0498 0499 QString KGlobalSettings::picturesPath() 0500 { 0501 QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); 0502 return path.isEmpty() ? QDir::homePath() : path; 0503 } 0504 0505 QString KGlobalSettings::musicPath() 0506 { 0507 QString path = QStandardPaths::writableLocation(QStandardPaths::MusicLocation); 0508 return path.isEmpty() ? QDir::homePath() : path; 0509 } 0510 0511 bool KGlobalSettings::isMultiHead() 0512 { 0513 #ifdef Q_OS_WIN 0514 return GetSystemMetrics(SM_CMONITORS) > 1; 0515 #else 0516 QByteArray multiHead = qgetenv("KDE_MULTIHEAD"); 0517 if (!multiHead.isEmpty()) { 0518 return (multiHead.toLower() == "true"); 0519 } 0520 return false; 0521 #endif 0522 } 0523 0524 bool KGlobalSettings::wheelMouseZooms() 0525 { 0526 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0527 return g.readEntry("WheelMouseZooms", KDE_DEFAULT_WHEEL_ZOOM); 0528 } 0529 0530 QRect KGlobalSettings::splashScreenDesktopGeometry() 0531 { 0532 return QApplication::desktop()->screenGeometry(QCursor::pos()); 0533 } 0534 0535 QRect KGlobalSettings::desktopGeometry(const QPoint &point) 0536 { 0537 return QApplication::desktop()->screenGeometry(point); 0538 } 0539 0540 QRect KGlobalSettings::desktopGeometry(const QWidget *w) 0541 { 0542 return QApplication::desktop()->screenGeometry(w); 0543 } 0544 0545 bool KGlobalSettings::showIconsOnPushButtons() 0546 { 0547 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0548 return g.readEntry("ShowIconsOnPushButtons", 0549 KDE_DEFAULT_ICON_ON_PUSHBUTTON); 0550 } 0551 0552 bool KGlobalSettings::naturalSorting() 0553 { 0554 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0555 return g.readEntry("NaturalSorting", 0556 KDE_DEFAULT_NATURAL_SORTING); 0557 } 0558 0559 KGlobalSettings::GraphicEffects KGlobalSettings::graphicEffectsLevel() 0560 { 0561 // This variable stores whether _graphicEffects has the default value because it has not been 0562 // loaded yet, or if it has been loaded from the user settings or defaults and contains a valid 0563 // value. 0564 static bool _graphicEffectsInitialized = false; 0565 0566 if (!_graphicEffectsInitialized) { 0567 _graphicEffectsInitialized = true; 0568 Private::reloadStyleSettings(); 0569 } 0570 0571 return _graphicEffects; 0572 } 0573 0574 KGlobalSettings::GraphicEffects KGlobalSettings::graphicEffectsLevelDefault() 0575 { 0576 // For now, let always enable animations by default. The plan is to make 0577 // this code a bit smarter. (ereslibre) 0578 0579 return ComplexAnimationEffects; 0580 } 0581 0582 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED 0583 bool KGlobalSettings::showFilePreview(const QUrl &url) 0584 { 0585 KConfigGroup g(KSharedConfig::openConfig(), "PreviewSettings"); 0586 bool defaultSetting = url.isLocalFile(); // ## incorrect, use KProtocolInfo::showFilePreview instead 0587 return g.readEntry(url.scheme(), defaultSetting); 0588 } 0589 #endif 0590 0591 bool KGlobalSettings::opaqueResize() 0592 { 0593 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0594 return g.readEntry("OpaqueResize", KDE_DEFAULT_OPAQUE_RESIZE); 0595 } 0596 0597 int KGlobalSettings::buttonLayout() 0598 { 0599 KConfigGroup g(KSharedConfig::openConfig(), "KDE"); 0600 return g.readEntry("ButtonLayout", KDE_DEFAULT_BUTTON_LAYOUT); 0601 } 0602 0603 #if 0 // HAVE_X11 && QT_VERSION >= QT_VERSION_CHECK(5,0,0) 0604 // Taken from Qt-4.x qt_x11_apply_settings_in_all_apps since Qt5 doesn't have it anymore. 0605 // TODO: evaluate if this is still needed 0606 // TODO: if yes, this code should be an invokable method of the qxcb platform plugin? 0607 // TODO: it looks like the handling code for this in QPA is missing, too... 0608 static void x11_apply_settings_in_all_apps() 0609 { 0610 QByteArray stamp; 0611 QDataStream s(&stamp, QIODevice::WriteOnly); 0612 s << QDateTime::currentDateTime(); 0613 0614 QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_"); 0615 settings_atom_name += XDisplayString(QX11Info::display()); 0616 0617 xcb_connection_t *xcb_conn = QX11Info::connection(); 0618 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_conn, false, settings_atom_name.size(), settings_atom_name.constData()); 0619 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_conn, cookie, 0); 0620 xcb_atom_t atom = reply->atom; 0621 free(reply); 0622 0623 xcb_change_property(xcb_conn, XCB_PROP_MODE_REPLACE, QX11Info::appRootWindow(), atom, XCB_ATOM_ATOM, 0624 8, stamp.size(), (const void *)stamp.constData()); 0625 0626 //XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0), 0627 //ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8, 0628 //PropModeReplace, (unsigned char *)stamp.data(), stamp.size()); 0629 } 0630 #endif 0631 0632 void KGlobalSettings::emitChange(ChangeType changeType, int arg) 0633 { 0634 switch (changeType) { 0635 case IconChanged: 0636 KIconLoader::emitChange(KIconLoader::Group(arg)); 0637 break; 0638 case ToolbarStyleChanged: 0639 KToolBar::emitToolbarStyleChanged(); 0640 break; 0641 case FontChanged: 0642 self()->d->kdisplaySetFont(); 0643 break; 0644 default: { 0645 QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange"); 0646 QList<QVariant> args; 0647 args.append(static_cast<int>(changeType)); 0648 args.append(arg); 0649 message.setArguments(args); 0650 QDBusConnection::sessionBus().send(message); 0651 } break; 0652 0653 } 0654 } 0655 0656 void KGlobalSettings::Private::_k_slotIconChange(int arg) 0657 { 0658 _k_slotNotifyChange(IconChanged, arg); 0659 } 0660 0661 void KGlobalSettings::Private::_k_slotNotifyChange(int changeType, int arg) 0662 { 0663 switch (changeType) { 0664 case StyleChanged: 0665 if (activated) { 0666 KSharedConfig::openConfig()->reparseConfiguration(); 0667 kdisplaySetStyle(); 0668 } 0669 break; 0670 0671 case ToolbarStyleChanged: 0672 KSharedConfig::openConfig()->reparseConfiguration(); 0673 emit q->toolbarAppearanceChanged(arg); 0674 break; 0675 0676 case PaletteChanged: 0677 if (activated) { 0678 KSharedConfig::openConfig()->reparseConfiguration(); 0679 paletteCreated = false; 0680 kdisplaySetPalette(); 0681 } 0682 break; 0683 0684 case FontChanged: 0685 Q_ASSERT(false && "shouldn't get here now..."); 0686 break; 0687 0688 case SettingsChanged: { 0689 KSharedConfig::openConfig()->reparseConfiguration(); 0690 SettingsCategory category = static_cast<SettingsCategory>(arg); 0691 if (category == SETTINGS_QT) { 0692 if (activated) { 0693 propagateQtSettings(); 0694 } 0695 } else { 0696 switch (category) { 0697 case SETTINGS_STYLE: 0698 reloadStyleSettings(); 0699 break; 0700 case SETTINGS_MOUSE: 0701 self()->d->dropMouseSettingsCache(); 0702 break; 0703 case SETTINGS_LOCALE: 0704 // QT5 TODO REPLACEMENT ? KLocale::global()->reparseConfiguration(); 0705 break; 0706 default: 0707 break; 0708 } 0709 emit q->settingsChanged(category); 0710 } 0711 break; 0712 } 0713 case IconChanged: 0714 QPixmapCache::clear(); 0715 KSharedConfig::openConfig()->reparseConfiguration(); 0716 emit q->iconChanged(arg); 0717 break; 0718 0719 case CursorChanged: 0720 applyCursorTheme(); 0721 break; 0722 0723 case BlockShortcuts: 0724 // FIXME KAccel port 0725 //KGlobalAccel::blockShortcuts(arg); 0726 emit q->blockShortcuts(arg); // see kwin 0727 break; 0728 0729 case NaturalSortingChanged: 0730 emit q->naturalSortingChanged(); 0731 break; 0732 0733 default: 0734 qWarning() << "Unknown type of change in KGlobalSettings::slotNotifyChange: " << changeType; 0735 } 0736 } 0737 0738 // Set by KApplication 0739 QString kde_overrideStyle; 0740 0741 void KGlobalSettings::Private::applyGUIStyle() 0742 { 0743 #if 0 // Disabled for KF5. TODO Qt5: check that the KDE style is correctly applied. 0744 //Platform plugin only loaded on X11 systems 0745 #if HAVE_X11 0746 if (!kde_overrideStyle.isEmpty()) { 0747 const QLatin1String currentStyleName(qApp->style()->metaObject()->className()); 0748 if (0 != kde_overrideStyle.compare(currentStyleName, Qt::CaseInsensitive) && 0749 0 != (QString(kde_overrideStyle + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive)) { 0750 qApp->setStyle(kde_overrideStyle); 0751 } 0752 } else { 0753 emit q->kdisplayStyleChanged(); 0754 } 0755 #else 0756 const QLatin1String currentStyleName(qApp->style()->metaObject()->className()); 0757 0758 if (kde_overrideStyle.isEmpty()) { 0759 const QString &defaultStyle = KStyle::defaultStyle(); 0760 const KConfigGroup pConfig(KSharedConfig::openConfig(), "General"); 0761 const QString &styleStr = pConfig.readEntry("widgetStyle", defaultStyle); 0762 0763 if (styleStr.isEmpty() || 0764 // check whether we already use the correct style to return then 0765 // (workaround for Qt misbehavior to avoid double style initialization) 0766 0 == (QString(styleStr + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive) || 0767 0 == styleStr.compare(currentStyleName, Qt::CaseInsensitive)) { 0768 return; 0769 } 0770 0771 QStyle *sp = QStyleFactory::create(styleStr); 0772 if (sp && currentStyleName == sp->metaObject()->className()) { 0773 delete sp; 0774 return; 0775 } 0776 0777 // If there is no default style available, try falling back any available style 0778 if (!sp && styleStr != defaultStyle) { 0779 sp = QStyleFactory::create(defaultStyle); 0780 } 0781 if (!sp) { 0782 sp = QStyleFactory::create(QStyleFactory::keys().first()); 0783 } 0784 qApp->setStyle(sp); 0785 } else if (0 != kde_overrideStyle.compare(currentStyleName, Qt::CaseInsensitive) && 0786 0 != (QString(kde_overrideStyle + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive)) { 0787 qApp->setStyle(kde_overrideStyle); 0788 } 0789 emit q->kdisplayStyleChanged(); 0790 #endif //HAVE_X11 0791 #endif 0792 } 0793 0794 QPalette KGlobalSettings::createApplicationPalette(const KSharedConfigPtr &config) 0795 { 0796 return self()->d->createApplicationPalette(config); 0797 } 0798 0799 QPalette KGlobalSettings::createNewApplicationPalette(const KSharedConfigPtr &config) 0800 { 0801 return self()->d->createNewApplicationPalette(config); 0802 } 0803 0804 QPalette KGlobalSettings::Private::createApplicationPalette(const KSharedConfigPtr &config) 0805 { 0806 // This method is typically called once by KQGuiPlatformPlugin::palette and once again 0807 // by kdisplaySetPalette(), so we cache the palette to save time. 0808 if (config == KSharedConfig::openConfig() && paletteCreated) { 0809 return applicationPalette; 0810 } 0811 return createNewApplicationPalette(config); 0812 } 0813 0814 QPalette KGlobalSettings::Private::createNewApplicationPalette(const KSharedConfigPtr &config) 0815 { 0816 QPalette palette = KColorScheme::createApplicationPalette(config); 0817 0818 if (config == KSharedConfig::openConfig()) { 0819 paletteCreated = true; 0820 applicationPalette = palette; 0821 } 0822 0823 return palette; 0824 } 0825 0826 void KGlobalSettings::Private::kdisplaySetPalette() 0827 { 0828 #if !defined(Q_OS_WINCE) 0829 if (!kdeFullSession) { 0830 return; 0831 } 0832 0833 QApplication::setPalette(q->createApplicationPalette()); 0834 emit q->kdisplayPaletteChanged(); 0835 emit q->appearanceChanged(); 0836 #endif 0837 } 0838 0839 void KGlobalSettings::Private::kdisplaySetFont() 0840 { 0841 #if !defined(Q_OS_WINCE) 0842 if (!kdeFullSession) { 0843 return; 0844 } 0845 0846 QDBusMessage message = QDBusMessage::createSignal("/KDEPlatformTheme", "org.kde.KDEPlatformTheme", "refreshFonts"); 0847 QDBusConnection::sessionBus().send(message); 0848 emit q->kdisplayFontChanged(); 0849 #endif 0850 } 0851 0852 void KGlobalSettings::Private::kdisplaySetStyle() 0853 { 0854 applyGUIStyle(); 0855 0856 // Reread palette from config file. 0857 kdisplaySetPalette(); 0858 } 0859 0860 void KGlobalSettings::Private::reloadStyleSettings() 0861 { 0862 KConfigGroup g(KSharedConfig::openConfig(), "KDE-Global GUI Settings"); 0863 0864 // Asking for hasKey we do not ask for graphicEffectsLevelDefault() that can 0865 // contain some very slow code. If we can save that time, do it. (ereslibre) 0866 0867 if (g.hasKey("GraphicEffectsLevel")) { 0868 _graphicEffects = ((GraphicEffects) g.readEntry("GraphicEffectsLevel", QVariant((int) NoEffects)).toInt()); 0869 0870 return; 0871 } 0872 0873 _graphicEffects = KGlobalSettings::graphicEffectsLevelDefault(); 0874 } 0875 0876 void KGlobalSettings::Private::applyCursorTheme() 0877 { 0878 #if HAVE_X11 && defined(HAVE_XCURSOR) 0879 if (!isX11) { 0880 return; 0881 } 0882 KConfig config("kcminputrc"); 0883 KConfigGroup g(&config, "Mouse"); 0884 0885 QString theme = g.readEntry("cursorTheme", QString()); 0886 int size = g.readEntry("cursorSize", -1); 0887 0888 // Default cursor size is 16 points 0889 if (size == -1) { 0890 QApplication *app = static_cast<QApplication *>(QApplication::instance()); 0891 size = app->desktop()->screen(0)->logicalDpiY() * 16 / 72; 0892 } 0893 0894 // Note that in X11R7.1 and earlier, calling XcursorSetTheme() 0895 // with a NULL theme would cause Xcursor to use "default", but 0896 // in 7.2 and later it will cause it to revert to the theme that 0897 // was configured when the application was started. 0898 XcursorSetTheme(QX11Info::display(), theme.isNull() ? 0899 "default" : QFile::encodeName(theme)); 0900 XcursorSetDefaultSize(QX11Info::display(), size); 0901 0902 emit q->cursorChanged(); 0903 #endif 0904 } 0905 0906 void KGlobalSettings::Private::propagateQtSettings() 0907 { 0908 KConfigGroup cg(KSharedConfig::openConfig(), "KDE"); 0909 0910 #ifndef Q_OS_WIN 0911 int num = cg.readEntry("CursorBlinkRate", QApplication::cursorFlashTime()); 0912 if ((num != 0) && (num < 200)) { 0913 num = 200; 0914 } 0915 if (num > 2000) { 0916 num = 2000; 0917 } 0918 QApplication::setCursorFlashTime(num); 0919 #else 0920 int num; 0921 #endif 0922 num = cg.readEntry("DoubleClickInterval", QApplication::doubleClickInterval()); 0923 QApplication::setDoubleClickInterval(num); 0924 num = cg.readEntry("StartDragTime", QApplication::startDragTime()); 0925 QApplication::setStartDragTime(num); 0926 num = cg.readEntry("StartDragDist", QApplication::startDragDistance()); 0927 QApplication::setStartDragDistance(num); 0928 num = cg.readEntry("WheelScrollLines", QApplication::wheelScrollLines()); 0929 QApplication::setWheelScrollLines(num); 0930 bool showIcons = cg.readEntry("ShowIconsInMenuItems", !QApplication::testAttribute(Qt::AA_DontShowIconsInMenus)); 0931 QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !showIcons); 0932 0933 // KDE5: this seems fairly pointless 0934 emit q->settingsChanged(SETTINGS_QT); 0935 } 0936 0937 void KGlobalSettings::Private::dropMouseSettingsCache() 0938 { 0939 #ifndef Q_OS_WIN 0940 delete self()->d->mMouseSettings; 0941 self()->d->mMouseSettings = nullptr; 0942 #endif 0943 } 0944 0945 #include "moc_kglobalsettings.cpp"