1/****************************************************************************
2**
3**
4** KRDB - puts current KDE color scheme into preprocessor statements
5** cats specially written application default files and uses xrdb -merge to
6** write to RESOURCE_MANAGER. Thus it gives a simple way to make non-KDE
7** applications fit in with the desktop
8**
9** Copyright (C) 1998 by Mark Donohoe
10** Copyright (C) 1999 by Dirk A. Mueller (reworked for KDE 2.0)
11** Copyright (C) 2001 by Matthias Ettrich (add support for GTK applications )
12** Copyright (C) 2001 by Waldo Bastian <bastian@kde.org>
13** Copyright (C) 2002 by Karol Szwed <gallium@kde.org>
14** This application is freely distributable under the GNU Public License.
15**
16*****************************************************************************/
17
18#include <config-workspace.h>
19#include <limits.h>
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23
24#undef Unsorted
25#include <QBuffer>
26#include <QDir>
27#include <QtCore/QSettings>
28#include <QtCore/QTextCodec>
29#include <QToolTip>
30//Added by qt3to4:
31#include <QPixmap>
32#include <QByteArray>
33#include <QTextStream>
34#include <QDateTime>
35#include <QtDBus/QtDBus>
36#include <ktoolinvocation.h>
37#include <klauncher_iface.h>
38
39#include <kapplication.h>
40#include <kconfig.h>
41#include <kconfiggroup.h>
42#include <kdebug.h>
43#include <kglobalsettings.h>
44#include <kstandarddirs.h>
45#include <kprocess.h>
46#include <ksavefile.h>
47#include <ktemporaryfile.h>
48#include <klocale.h>
49#include <kstyle.h>
50
51#include "krdb.h"
52#ifdef Q_WS_X11
53#include <X11/Xlib.h>
54#include <QX11Info>
55#endif
56inline const char * gtkEnvVar(int version)
57{
58 return 2==version ? "GTK2_RC_FILES" : "GTK_RC_FILES";
59}
60
61inline const char * sysGtkrc(int version)
62{
63 if(2==version)
64 {
65 if(access("/etc/opt/gnome/gtk-2.0", F_OK) == 0)
66 return "/etc/opt/gnome/gtk-2.0/gtkrc";
67 else
68 return "/etc/gtk-2.0/gtkrc";
69 }
70 else
71 {
72 if(access("/etc/opt/gnome/gtk", F_OK) == 0)
73 return "/etc/opt/gnome/gtk/gtkrc";
74 else
75 return "/etc/gtk/gtkrc";
76 }
77}
78
79inline const char * userGtkrc(int version)
80{
81 return 2==version ? "/.gtkrc-2.0" : "/.gtkrc";
82}
83
84// -----------------------------------------------------------------------------
85static void applyGtkStyles(bool active, int version)
86{
87 QString gtkkde = KStandardDirs::locateLocal("config", 2==version?"gtkrc-2.0":"gtkrc");
88 QByteArray gtkrc = getenv(gtkEnvVar(version));
89 QStringList list = QFile::decodeName(gtkrc).split( ':');
90 QString userHomeGtkrc = QDir::homePath()+userGtkrc(version);
91 if (!list.contains(userHomeGtkrc))
92 list.prepend(userHomeGtkrc);
93 QLatin1String systemGtkrc = QLatin1String(sysGtkrc(version));
94 if (!list.contains(systemGtkrc))
95 list.prepend(systemGtkrc);
96 list.removeAll("");
97 list.removeAll(gtkkde);
98 list.append(gtkkde);
99
100 // Pass env. var to kdeinit.
101 QString name = gtkEnvVar(version);
102 QString value = list.join(":");
103 KToolInvocation::klauncher()->setLaunchEnv(name, value);
104}
105
106// -----------------------------------------------------------------------------
107
108static void applyQtColors( KSharedConfigPtr kglobalcfg, QSettings& settings, QPalette& newPal )
109{
110 QStringList actcg, inactcg, discg;
111 /* export kde color settings */
112 int i;
113 for (i = 0; i < QPalette::NColorRoles; i++)
114 actcg << newPal.color(QPalette::Active,
115 (QPalette::ColorRole) i).name();
116 for (i = 0; i < QPalette::NColorRoles; i++)
117 inactcg << newPal.color(QPalette::Inactive,
118 (QPalette::ColorRole) i).name();
119 for (i = 0; i < QPalette::NColorRoles; i++)
120 discg << newPal.color(QPalette::Disabled,
121 (QPalette::ColorRole) i).name();
122
123 settings.setValue("/qt/Palette/active", actcg);
124 settings.setValue("/qt/Palette/inactive", inactcg);
125 settings.setValue("/qt/Palette/disabled", discg);
126
127 // export kwin's colors to qtrc for kstyle to use
128 KConfigGroup wmCfgGroup(kglobalcfg, "WM");
129
130 // active colors
131 QColor clr = newPal.color( QPalette::Active, QPalette::Background );
132 clr = wmCfgGroup.readEntry("activeBackground", clr);
133 settings.setValue("/qt/KWinPalette/activeBackground", clr.name());
134 if (QPixmap::defaultDepth() > 8)
135 clr = clr.dark(110);
136 clr = wmCfgGroup.readEntry("activeBlend", clr);
137 settings.setValue("/qt/KWinPalette/activeBlend", clr.name());
138 clr = newPal.color( QPalette::Active, QPalette::HighlightedText );
139 clr = wmCfgGroup.readEntry("activeForeground", clr);
140 settings.setValue("/qt/KWinPalette/activeForeground", clr.name());
141 clr = newPal.color( QPalette::Active,QPalette::Background );
142 clr = wmCfgGroup.readEntry("frame", clr);
143 settings.setValue("/qt/KWinPalette/frame", clr.name());
144 clr = wmCfgGroup.readEntry("activeTitleBtnBg", clr);
145 settings.setValue("/qt/KWinPalette/activeTitleBtnBg", clr.name());
146
147 // inactive colors
148 clr = newPal.color(QPalette::Inactive, QPalette::Background);
149 clr = wmCfgGroup.readEntry("inactiveBackground", clr);
150 settings.setValue("/qt/KWinPalette/inactiveBackground", clr.name());
151 if (QPixmap::defaultDepth() > 8)
152 clr = clr.dark(110);
153 clr = wmCfgGroup.readEntry("inactiveBlend", clr);
154 settings.setValue("/qt/KWinPalette/inactiveBlend", clr.name());
155 clr = newPal.color(QPalette::Inactive, QPalette::Background).dark();
156 clr = wmCfgGroup.readEntry("inactiveForeground", clr);
157 settings.setValue("/qt/KWinPalette/inactiveForeground", clr.name());
158 clr = newPal.color(QPalette::Inactive, QPalette::Background);
159 clr = wmCfgGroup.readEntry("inactiveFrame", clr);
160 settings.setValue("/qt/KWinPalette/inactiveFrame", clr.name());
161 clr = wmCfgGroup.readEntry("inactiveTitleBtnBg", clr);
162 settings.setValue("/qt/KWinPalette/inactiveTitleBtnBg", clr.name());
163
164 KConfigGroup kdeCfgGroup(kglobalcfg, "KDE");
165 settings.setValue("/qt/KDE/contrast", kdeCfgGroup.readEntry("contrast", 7));
166}
167
168// -----------------------------------------------------------------------------
169
170static void applyQtSettings( KSharedConfigPtr kglobalcfg, QSettings& settings )
171{
172 /* export font settings */
173 settings.setValue("/qt/font", KGlobalSettings::generalFont().toString());
174
175 /* export effects settings */
176 KConfigGroup kdeCfgGroup(kglobalcfg, "General");
177 bool effectsEnabled = kdeCfgGroup.readEntry("EffectsEnabled", false);
178 bool fadeMenus = kdeCfgGroup.readEntry("EffectFadeMenu", false);
179 bool fadeTooltips = kdeCfgGroup.readEntry("EffectFadeTooltip", false);
180 bool animateCombobox = kdeCfgGroup.readEntry("EffectAnimateCombo", false);
181
182 QStringList guieffects;
183 if (effectsEnabled) {
184 guieffects << QString("general");
185 if (fadeMenus)
186 guieffects << QString("fademenu");
187 if (animateCombobox)
188 guieffects << QString("animatecombo");
189 if (fadeTooltips)
190 guieffects << QString("fadetooltip");
191 }
192 else
193 guieffects << QString("none");
194
195 settings.setValue("/qt/GUIEffects", guieffects);
196}
197
198// -----------------------------------------------------------------------------
199
200static void addColorDef(QString& s, const char* n, const QColor& col)
201{
202 QString tmp;
203
204 tmp.sprintf("#define %s #%02x%02x%02x\n",
205 n, col.red(), col.green(), col.blue());
206
207 s += tmp;
208}
209
210
211// -----------------------------------------------------------------------------
212
213static void copyFile(QFile& tmp, QString const& filename, bool )
214{
215 QFile f( filename );
216 if ( f.open(QIODevice::ReadOnly) ) {
217 QByteArray buf( 8192, ' ' );
218 while ( !f.atEnd() ) {
219 int read = f.read( buf.data(), buf.size() );
220 if ( read > 0 )
221 tmp.write( buf.data(), read );
222 }
223 }
224}
225
226
227// -----------------------------------------------------------------------------
228
229static QString item( int i ) {
230 return QString::number( i / 255.0, 'f', 3 );
231}
232
233static QString color( const QColor& col )
234{
235 return QString( "{ %1, %2, %3 }" ).arg( item( col.red() ) ).arg( item( col.green() ) ).arg( item( col.blue() ) );
236}
237
238static void createGtkrc( bool exportColors, const QPalette& cg, bool exportGtkTheme, const QString& gtkTheme, int version )
239{
240 // lukas: why does it create in ~/.kde/share/config ???
241 // pfeiffer: so that we don't overwrite the user's gtkrc.
242 // it is found via the GTK_RC_FILES environment variable.
243 KSaveFile saveFile( KStandardDirs::locateLocal( "config", 2==version?"gtkrc-2.0":"gtkrc" ) );
244 if ( !saveFile.open() )
245 return;
246
247 QTextStream t ( &saveFile );
248 t.setCodec( QTextCodec::codecForLocale () );
249
250 t << i18n(
251 "# created by KDE, %1\n"
252 "#\n"
253 "# If you do not want KDE to override your GTK settings, select\n"
254 "# Appearance -> Colors in the System Settings and disable the checkbox\n"
255 "# \"Apply colors to non-KDE4 applications\"\n"
256 "#\n"
257 "#\n", QDateTime::currentDateTime().toString());
258
259 if ( 2==version ) { // we should maybe check for MacOS settings here
260 t << endl;
261 t << "gtk-alternative-button-order = 1" << endl;
262 t << endl;
263 }
264
265 if (exportGtkTheme)
266 {
267 QString gtkStyle;
268 if (gtkTheme.toLower() == "oxygen")
269 gtkStyle = QString("oxygen-gtk");
270 else
271 gtkStyle = gtkTheme;
272
273 bool exist_gtkrc = false;
274 QByteArray gtkrc = getenv(gtkEnvVar(version));
275 QStringList listGtkrc = QFile::decodeName(gtkrc).split(":");
276 if (listGtkrc.contains(saveFile.fileName()))
277 listGtkrc.removeAll(saveFile.fileName());
278 listGtkrc.append(QDir::homePath() + userGtkrc(version));
279 listGtkrc.append(QDir::homePath() + "/.gtkrc-2.0-kde");
280 listGtkrc.append(QDir::homePath() + "/.gtkrc-2.0-kde4");
281 listGtkrc.removeAll("");
282 listGtkrc.removeDuplicates();
283 for (int i = 0; i < listGtkrc.size(); ++i)
284 {
285 if ((exist_gtkrc = QFile::exists(listGtkrc.at(i))))
286 break;
287 }
288
289 if (!exist_gtkrc)
290 {
291 QString gtk2ThemeFilename;
292 gtk2ThemeFilename = QString("%1/.themes/%2/gtk-2.0/gtkrc").arg(QDir::homePath()).arg(gtkStyle);
293 if (!QFile::exists(gtk2ThemeFilename)) {
294 QStringList gtk2ThemePath;
295 gtk2ThemeFilename.clear();
296 QByteArray xdgDataDirs = getenv("XDG_DATA_DIRS");
297 gtk2ThemePath.append(QDir::homePath() + "/.local");
298 gtk2ThemePath.append(QFile::decodeName(xdgDataDirs).split(":"));
299 gtk2ThemePath.removeDuplicates();
300 for (int i = 0; i < gtk2ThemePath.size(); ++i)
301 {
302 gtk2ThemeFilename = QString("%1/themes/%2/gtk-2.0/gtkrc").arg(gtk2ThemePath.at(i)).arg(gtkStyle);
303 if (QFile::exists(gtk2ThemeFilename))
304 break;
305 else
306 gtk2ThemeFilename.clear();
307 }
308 }
309
310 if (!gtk2ThemeFilename.isEmpty())
311 {
312 t << "include \"" << gtk2ThemeFilename << "\"" << endl;
313 t << endl;
314 t << "gtk-theme-name=\"" << gtkStyle << "\"" << endl;
315 t << endl;
316 if (gtkStyle == "oxygen-gtk")
317 exportColors = false;
318 }
319 }
320
321 }
322
323 if (exportColors)
324 {
325 t << "style \"default\"" << endl;
326 t << "{" << endl;
327 t << " bg[NORMAL] = " << color( cg.color( QPalette::Active, QPalette::Background ) ) << endl;
328 t << " bg[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
329 t << " bg[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Background ) ) << endl;
330 t << " bg[ACTIVE] = " << color( cg.color( QPalette::Active, QPalette::Mid ) ) << endl;
331 t << " bg[PRELIGHT] = " << color( cg.color( QPalette::Active, QPalette::Background ) ) << endl;
332 t << endl;
333 t << " base[NORMAL] = " << color( cg.color( QPalette::Active, QPalette::Base ) ) << endl;
334 t << " base[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
335 t << " base[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Background ) ) << endl;
336 t << " base[ACTIVE] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
337 t << " base[PRELIGHT] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
338 t << endl;
339 t << " text[NORMAL] = " << color( cg.color(QPalette::Active, QPalette::Text) ) << endl;
340 t << " text[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
341 t << " text[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Mid ) ) << endl;
342 t << " text[ACTIVE] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
343 t << " text[PRELIGHT] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
344 t << endl;
345 t << " fg[NORMAL] = " << color ( cg.color( QPalette::Active, QPalette::Foreground ) ) << endl;
346 t << " fg[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
347 t << " fg[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Mid ) ) << endl;
348 t << " fg[ACTIVE] = " << color( cg.color( QPalette::Active, QPalette::Foreground ) ) << endl;
349 t << " fg[PRELIGHT] = " << color( cg.color( QPalette::Active, QPalette::Foreground ) ) << endl;
350 t << "}" << endl;
351 t << endl;
352 t << "class \"*\" style \"default\"" << endl;
353 t << endl;
354
355 // tooltips don't have the standard background color
356 t << "style \"ToolTip\"" << endl;
357 t << "{" << endl;
358 QPalette group = QToolTip::palette();
359 t << " bg[NORMAL] = " << color( group.color( QPalette::Active, QPalette::Background ) ) << endl;
360 t << " base[NORMAL] = " << color( group.color( QPalette::Active, QPalette::Base ) ) << endl;
361 t << " text[NORMAL] = " << color( group.color( QPalette::Active, QPalette::Text ) ) << endl;
362 t << " fg[NORMAL] = " << color( group.color( QPalette::Active, QPalette::Foreground ) ) << endl;
363 t << "}" << endl;
364 t << endl;
365 t << "widget \"gtk-tooltip\" style \"ToolTip\"" << endl;
366 t << "widget \"gtk-tooltips\" style \"ToolTip\"" << endl;
367 t << endl;
368
369
370 // highlight the current (mouse-hovered) menu-item
371 // not every button, checkbox, etc.
372 t << "style \"MenuItem\"" << endl;
373 t << "{" << endl;
374 t << " bg[PRELIGHT] = " << color( cg.color(QPalette::Highlight) ) << endl;
375 t << "}" << endl;
376 t << endl;
377 t << "class \"*MenuItem\" style \"MenuItem\"" << endl;
378 t << endl;
379 }
380
381}
382
383// -----------------------------------------------------------------------------
384
385void runRdb( uint flags )
386{
387 // Obtain the application palette that is about to be set.
388 bool exportColors = flags & KRdbExportColors;
389 bool exportQtColors = flags & KRdbExportQtColors;
390 bool exportQtSettings = flags & KRdbExportQtSettings;
391 bool exportXftSettings = flags & KRdbExportXftSettings;
392 bool exportGtkTheme = flags & KRdbExportGtkTheme;
393
394 KSharedConfigPtr kglobalcfg = KSharedConfig::openConfig( "kdeglobals" );
395 KConfigGroup kglobals(kglobalcfg, "KDE");
396 QPalette newPal = KGlobalSettings::createApplicationPalette(kglobalcfg);
397
398 KTemporaryFile tmpFile;
399 if (!tmpFile.open())
400 {
401 kDebug() << "Couldn't open temp file";
402 exit(0);
403 }
404
405
406 KConfigGroup generalCfgGroup(kglobalcfg, "General");
407
408 QString gtkTheme;
409 if (generalCfgGroup.hasKey("widgetStyle"))
410 gtkTheme = generalCfgGroup.readEntry("widgetStyle");
411 else
412 gtkTheme = "oxygen";
413
414 createGtkrc( exportColors, newPal, exportGtkTheme, gtkTheme, 1 );
415 createGtkrc( exportColors, newPal, exportGtkTheme, gtkTheme, 2 );
416
417 // Export colors to non-(KDE/Qt) apps (e.g. Motif, GTK+ apps)
418 if (exportColors)
419 {
420 KGlobal::dirs()->addResourceType("appdefaults", "data", "kdisplay/app-defaults/");
421 KGlobal::locale()->insertCatalog("krdb");
422
423 QString preproc;
424 QColor backCol = newPal.color( QPalette::Active, QPalette::Background );
425 addColorDef(preproc, "FOREGROUND" , newPal.color( QPalette::Active, QPalette::Foreground ) );
426 addColorDef(preproc, "BACKGROUND" , backCol);
427 addColorDef(preproc, "HIGHLIGHT" , backCol.light(100+(2*KGlobalSettings::contrast()+4)*16/1));
428 addColorDef(preproc, "LOWLIGHT" , backCol.dark(100+(2*KGlobalSettings::contrast()+4)*10));
429 addColorDef(preproc, "SELECT_BACKGROUND" , newPal.color( QPalette::Active, QPalette::Highlight));
430 addColorDef(preproc, "SELECT_FOREGROUND" , newPal.color( QPalette::Active, QPalette::HighlightedText));
431 addColorDef(preproc, "WINDOW_BACKGROUND" , newPal.color( QPalette::Active, QPalette::Base ) );
432 addColorDef(preproc, "WINDOW_FOREGROUND" , newPal.color( QPalette::Active, QPalette::Foreground ) );
433 addColorDef(preproc, "INACTIVE_BACKGROUND", KGlobalSettings::inactiveTitleColor());
434 addColorDef(preproc, "INACTIVE_FOREGROUND", KGlobalSettings::inactiveTitleColor());
435 addColorDef(preproc, "ACTIVE_BACKGROUND" , KGlobalSettings::activeTitleColor());
436 addColorDef(preproc, "ACTIVE_FOREGROUND" , KGlobalSettings::activeTitleColor());
437 //---------------------------------------------------------------
438
439 tmpFile.write( preproc.toLatin1(), preproc.length() );
440
441 QStringList list;
442
443 const QStringList adPaths = KGlobal::dirs()->findDirs("appdefaults", "");
444 for (QStringList::ConstIterator it = adPaths.constBegin(); it != adPaths.constEnd(); ++it) {
445 QDir dSys( *it );
446
447 if ( dSys.exists() ) {
448 dSys.setFilter( QDir::Files );
449 dSys.setSorting( QDir::Name );
450 dSys.setNameFilters(QStringList("*.ad"));
451 list += dSys.entryList();
452 }
453 }
454
455 for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
456 copyFile(tmpFile, KStandardDirs::locate("appdefaults", *it ), true);
457 }
458
459 // Merge ~/.Xresources or fallback to ~/.Xdefaults
460 QString homeDir = QDir::homePath();
461 QString xResources = homeDir + "/.Xresources";
462
463 // very primitive support for ~/.Xresources by appending it
464 if ( QFile::exists( xResources ) )
465 copyFile(tmpFile, xResources, true);
466 else
467 copyFile(tmpFile, homeDir + "/.Xdefaults", true);
468
469 // Export the Xcursor theme & size settings
470 KConfigGroup mousecfg(KSharedConfig::openConfig( "kcminputrc" ), "Mouse" );
471 QString theme = mousecfg.readEntry("cursorTheme", QString());
472 QString size = mousecfg.readEntry("cursorSize", QString());
473 QString contents;
474
475 if (!theme.isNull())
476 contents = "Xcursor.theme: " + theme + '\n';
477
478 if (!size.isNull())
479 contents += "Xcursor.size: " + size + '\n';
480
481 if (exportXftSettings)
482 {
483 if (generalCfgGroup.hasKey("XftAntialias"))
484 {
485 contents += "Xft.antialias: ";
486 if(generalCfgGroup.readEntry("XftAntialias", true))
487 contents += "1\n";
488 else
489 contents += "0\n";
490 }
491
492 if (generalCfgGroup.hasKey("XftHintStyle"))
493 {
494 QString hintStyle = generalCfgGroup.readEntry("XftHintStyle", "hintmedium");
495 contents += "Xft.hinting: ";
496 if(hintStyle.isEmpty())
497 contents += "-1\n";
498 else
499 {
500 if(hintStyle!="hintnone")
501 contents += "1\n";
502 else
503 contents += "0\n";
504 contents += "Xft.hintstyle: " + hintStyle + '\n';
505 }
506 }
507
508 if (generalCfgGroup.hasKey("XftSubPixel"))
509 {
510 QString subPixel = generalCfgGroup.readEntry("XftSubPixel");
511 if(!subPixel.isEmpty())
512 contents += "Xft.rgba: " + subPixel + '\n';
513 }
514
515 KConfig _cfgfonts( "kcmfonts" );
516 KConfigGroup cfgfonts(&_cfgfonts, "General");
517
518 if( cfgfonts.readEntry( "forceFontDPI", 0 ) != 0 )
519 contents += "Xft.dpi: " + cfgfonts.readEntry( "forceFontDPI" ) + '\n';
520 else
521 {
522 KProcess proc;
523 proc << "xrdb" << "-quiet" << "-remove" << "-nocpp";
524 proc.start();
525 if (proc.waitForStarted())
526 {
527 proc.write( QByteArray( "Xft.dpi\n" ) );
528 proc.closeWriteChannel();
529 proc.waitForFinished();
530 }
531 }
532 }
533
534 if (contents.length() > 0)
535 tmpFile.write( contents.toLatin1(), contents.length() );
536
537 tmpFile.flush();
538
539 KProcess proc;
540#ifndef NDEBUG
541 proc << "xrdb" << "-merge" << tmpFile.fileName();
542#else
543 proc << "xrdb" << "-quiet" << "-merge" << tmpFile.fileName();
544#endif
545 proc.execute();
546
547 applyGtkStyles(exportColors, 1);
548 applyGtkStyles(exportColors, 2);
549
550 /* Qt exports */
551 if ( exportQtColors || exportQtSettings )
552 {
553 QSettings* settings = new QSettings(QLatin1String("Trolltech"));
554
555 if ( exportQtColors )
556 applyQtColors( kglobalcfg, *settings, newPal ); // For kcmcolors
557
558 if ( exportQtSettings )
559 applyQtSettings( kglobalcfg, *settings ); // For kcmstyle
560
561 delete settings;
562 QApplication::flush();
563#ifdef Q_WS_X11
564 // We let KIPC take care of ourselves, as we are in a KDE app with
565 // QApp::setDesktopSettingsAware(false);
566 // Instead of calling QApp::x11_apply_settings() directly, we instead
567 // modify the timestamp which propagates the settings changes onto
568 // Qt-only apps without adversely affecting ourselves.
569
570 // Cheat and use the current timestamp, since we just saved to qtrc.
571 QDateTime settingsstamp = QDateTime::currentDateTime();
572
573 static Atom qt_settings_timestamp = 0;
574 if (!qt_settings_timestamp) {
575 QString atomname("_QT_SETTINGS_TIMESTAMP_");
576 atomname += XDisplayName( 0 ); // Use the $DISPLAY envvar.
577 qt_settings_timestamp = XInternAtom( QX11Info::display(), atomname.toLatin1(), False);
578 }
579
580 QBuffer stamp;
581 QDataStream s(&stamp.buffer(), QIODevice::WriteOnly);
582 s << settingsstamp;
583 XChangeProperty( QX11Info::display(), QX11Info::appRootWindow(), qt_settings_timestamp,
584 qt_settings_timestamp, 8, PropModeReplace,
585 (unsigned char*) stamp.buffer().data(),
586 stamp.buffer().size() );
587 QApplication::flush();
588#endif
589 }
590}
591
592