• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDED

  • sources
  • kde-4.14
  • kdelibs
  • kded
kded.cpp
Go to the documentation of this file.
1 // vim: expandtab sw=4 ts=4
2 /* This file is part of the KDE libraries
3  * Copyright (C) 1999 David Faure <faure@kde.org>
4  * Copyright (C) 2000 Waldo Bastian <bastian@kde.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License version 2 as published by the Free Software Foundation;
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  **/
20 
21 #include "kded.h"
22 #include "kdedadaptor.h"
23 #include "kdedmodule.h"
24 
25 #include <kcrash.h>
26 #include <kdeversion.h>
27 
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <signal.h>
31 #include <time.h>
32 
33 #include <QtCore/QDir>
34 #include <QtCore/QFile>
35 #include <QtCore/QTimer>
36 
37 #include <QtDBus/QtDBus>
38 
39 #include <kuniqueapplication.h>
40 #include <kapplication.h>
41 #include <kcmdlineargs.h>
42 #include <kaboutdata.h>
43 #ifndef KDE_NO_DEPRECATED
44 #include <klibloader.h>
45 #else
46 #include <klibrary.h>
47 #endif
48 #include <klocale.h>
49 #include <kglobal.h>
50 #include <kconfig.h>
51 #include <kconfiggroup.h>
52 #include <kdebug.h>
53 #include <kdirwatch.h>
54 #include <kstandarddirs.h>
55 #include <kservicetypetrader.h>
56 #include <ktoolinvocation.h>
57 #include <kde_file.h>
58 #include "klauncher_iface.h"
59 
60 #ifdef Q_WS_X11
61 #include <qx11info_x11.h>
62 #include <X11/Xlib.h>
63 #include <fixx11h.h>
64 #endif
65 
66 #define KDED_EXENAME "kded4"
67 
68 #define MODULES_PATH "/modules/"
69 
70 Kded *Kded::_self = 0;
71 
72 static bool checkStamps = true;
73 static bool delayedCheck = false;
74 static int HostnamePollInterval;
75 static bool bCheckSycoca;
76 static bool bCheckUpdates;
77 static bool bCheckHostname;
78 
79 #ifdef Q_DBUS_EXPORT
80 extern Q_DBUS_EXPORT void qDBusAddSpyHook(void (*)(const QDBusMessage&));
81 #else
82 extern QDBUS_EXPORT void qDBusAddSpyHook(void (*)(const QDBusMessage&));
83 #endif
84 
85 static void runBuildSycoca(QObject *callBackObj=0, const char *callBackSlot=0, const char *callBackErrorSlot=0)
86 {
87  const QString exe = KStandardDirs::findExe(KBUILDSYCOCA_EXENAME);
88  Q_ASSERT(!exe.isEmpty());
89  QStringList args;
90  args.append("--incremental");
91  if(checkStamps)
92  args.append("--checkstamps");
93  if(delayedCheck)
94  args.append("--nocheckfiles");
95  else
96  checkStamps = false; // useful only during kded startup
97  if (callBackObj)
98  {
99  QVariantList argList;
100  argList << exe << args << QStringList() << QString();
101  KToolInvocation::klauncher()->callWithCallback("kdeinit_exec_wait", argList, callBackObj, callBackSlot, callBackErrorSlot);
102  }
103  else
104  {
105  KToolInvocation::kdeinitExecWait( exe, args );
106  }
107 }
108 
109 static void runKonfUpdate()
110 {
111  KToolInvocation::kdeinitExecWait( "kconf_update", QStringList(), 0, 0, "0" /*no startup notification*/ );
112 }
113 
114 static void runDontChangeHostname(const QByteArray &oldName, const QByteArray &newName)
115 {
116  QStringList args;
117  args.append(QFile::decodeName(oldName));
118  args.append(QFile::decodeName(newName));
119  KToolInvocation::kdeinitExecWait( "kdontchangethehostname", args );
120 }
121 
122 Kded::Kded()
123  : m_needDelayedCheck(false)
124 {
125  _self = this;
126 
127  m_serviceWatcher = new QDBusServiceWatcher(this);
128  m_serviceWatcher->setConnection(QDBusConnection::sessionBus());
129  m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
130  QObject::connect(m_serviceWatcher, SIGNAL(serviceUnregistered(QString)),
131  this, SLOT(slotApplicationRemoved(QString)));
132 
133  new KBuildsycocaAdaptor(this);
134  new KdedAdaptor(this);
135 
136  QDBusConnection session = QDBusConnection::sessionBus();
137  session.registerObject("/kbuildsycoca", this);
138  session.registerObject("/kded", this);
139 
140  qDBusAddSpyHook(messageFilter);
141 
142  m_pTimer = new QTimer(this);
143  m_pTimer->setSingleShot( true );
144  connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recreate()));
145 
146  m_pDirWatch = 0;
147 
148  m_recreateCount = 0;
149  m_recreateBusy = false;
150 }
151 
152 Kded::~Kded()
153 {
154  _self = 0;
155  m_pTimer->stop();
156  delete m_pTimer;
157  delete m_pDirWatch;
158 
159  for (QHash<QByteArray,KDEDModule*>::iterator
160  it(m_modules.begin()), itEnd(m_modules.end());
161  it != itEnd; ++it)
162  {
163  KDEDModule* module(it.value());
164 
165  // first disconnect otherwise slotKDEDModuleRemoved() is called
166  // and changes m_modules while we're iterating over it
167  disconnect(module, SIGNAL(moduleDeleted(KDEDModule*)),
168  this, SLOT(slotKDEDModuleRemoved(KDEDModule*)));
169 
170  delete module;
171  }
172 }
173 
174 // on-demand module loading
175 // this function is called by the D-Bus message processing function before
176 // calls are delivered to objects
177 void Kded::messageFilter(const QDBusMessage &message)
178 {
179  // This happens when kded goes down and some modules try to clean up.
180  if (!self())
181  return;
182 
183  if (message.type() != QDBusMessage::MethodCallMessage)
184  return;
185 
186  QString obj = message.path();
187  if (!obj.startsWith(MODULES_PATH))
188  return;
189 
190  // Remove the <MODULES_PATH> part
191  obj = obj.mid(strlen(MODULES_PATH));
192  if (obj == "ksycoca")
193  return; // Ignore this one.
194 
195  // Remove the part after the modules name
196  int index = obj.indexOf('/');
197  if (index!=-1) {
198  obj = obj.left(index);
199  }
200 
201  if (self()->m_dontLoad.value(obj, 0))
202  return;
203 
204  KDEDModule *module = self()->loadModule(obj, true);
205  if (!module) {
206  kDebug(7020) << "Failed to load module for " << obj;
207  }
208  Q_UNUSED(module);
209 }
210 
211 static int phaseForModule(const KService::Ptr& service)
212 {
213  const QVariant phasev = service->property("X-KDE-Kded-phase", QVariant::Int );
214  return phasev.isValid() ? phasev.toInt() : 2;
215 }
216 
217 void Kded::initModules()
218 {
219  m_dontLoad.clear();
220  bool kde_running = !qgetenv( "KDE_FULL_SESSION" ).isEmpty();
221  if (kde_running) {
222  // not the same user like the one running the session (most likely we're run via sudo or something)
223  const QByteArray sessionUID = qgetenv( "KDE_SESSION_UID" );
224  if( !sessionUID.isEmpty() && uid_t( sessionUID.toInt() ) != getuid())
225  kde_running = false;
226 
227  // not the same kde version as the current desktop
228  const QByteArray kdeSession = qgetenv("KDE_SESSION_VERSION");
229  if (kdeSession.toInt() != KDE_VERSION_MAJOR)
230  kde_running = false;
231  }
232 
233  // There will be a "phase 2" only if we're in the KDE startup.
234  // If kded is restarted by its crashhandled or by hand,
235  // then there will be no second phase autoload, so load
236  // these modules now, if in a KDE session.
237  const bool loadPhase2Now = (kde_running && qgetenv("KDED_STARTED_BY_KDEINIT").toInt() == 0);
238 
239  // Preload kded modules.
240  const KService::List kdedModules = KServiceTypeTrader::self()->query("KDEDModule");
241  for(KService::List::ConstIterator it = kdedModules.begin(); it != kdedModules.end(); ++it)
242  {
243  KService::Ptr service = *it;
244  // Should the service load on startup?
245  const bool autoload = isModuleAutoloaded(service);
246 
247  // see ksmserver's README for description of the phases
248  bool prevent_autoload = false;
249  switch( phaseForModule(service) )
250  {
251  case 0: // always autoload
252  break;
253  case 1: // autoload only in KDE
254  if (!kde_running) {
255  prevent_autoload = true;
256  }
257  break;
258  case 2: // autoload delayed, only in KDE
259  default:
260  if (!loadPhase2Now) {
261  prevent_autoload = true;
262  }
263  break;
264  }
265 
266  // Load the module if necessary and allowed
267  if (autoload && !prevent_autoload) {
268  if (!loadModule(service, false)) {
269  continue;
270  }
271  }
272 
273  // Remember if the module is allowed to load on demand
274  bool loadOnDemand = isModuleLoadedOnDemand(service);
275  if (!loadOnDemand)
276  noDemandLoad(service->desktopEntryName());
277 
278  // In case of reloading the configuration it is possible for a module
279  // to run even if it is now allowed to. Stop it then.
280  if (!loadOnDemand && !autoload)
281  unloadModule(service->desktopEntryName().toLatin1());
282  }
283 }
284 
285 void Kded::loadSecondPhase()
286 {
287  kDebug(7020) << "Loading second phase autoload";
288  KSharedConfig::Ptr config = KGlobal::config();
289  KService::List kdedModules = KServiceTypeTrader::self()->query("KDEDModule");
290  for(KService::List::ConstIterator it = kdedModules.constBegin(); it != kdedModules.constEnd(); ++it) {
291  const KService::Ptr service = *it;
292  const bool autoload = isModuleAutoloaded(service);
293  if (autoload && phaseForModule(service) == 2) {
294  //kDebug(7020) << "2nd phase: loading" << service->desktopEntryName();
295  loadModule(service, false);
296  }
297  }
298 }
299 
300 void Kded::noDemandLoad(const QString &obj)
301 {
302  m_dontLoad.insert(obj.toLatin1(), this);
303 }
304 
305 void Kded::setModuleAutoloading(const QString &obj, bool autoload)
306 {
307  KSharedConfig::Ptr config = KGlobal::config();
308  // Ensure the service exists.
309  KService::Ptr service = KService::serviceByDesktopPath("kded/"+obj+".desktop");
310  if (!service)
311  return;
312  KConfigGroup cg(config, QString("Module-%1").arg(service->desktopEntryName()));
313  cg.writeEntry("autoload", autoload);
314  cg.sync();
315 }
316 
317 bool Kded::isModuleAutoloaded(const QString &obj) const
318 {
319  KService::Ptr s = KService::serviceByDesktopPath("kded/"+obj+".desktop");
320  if (!s)
321  return false;
322  return isModuleAutoloaded(s);
323 }
324 
325 bool Kded::isModuleAutoloaded(const KService::Ptr &module) const
326 {
327  KSharedConfig::Ptr config = KGlobal::config();
328  bool autoload = module->property("X-KDE-Kded-autoload", QVariant::Bool).toBool();
329  KConfigGroup cg(config, QString("Module-%1").arg(module->desktopEntryName()));
330  autoload = cg.readEntry("autoload", autoload);
331  return autoload;
332 }
333 
334 bool Kded::isModuleLoadedOnDemand(const QString &obj) const
335 {
336  KService::Ptr s = KService::serviceByDesktopPath("kded/"+obj+".desktop");
337  if (!s)
338  return false;
339  return isModuleLoadedOnDemand(s);
340 }
341 
342 bool Kded::isModuleLoadedOnDemand(const KService::Ptr &module) const
343 {
344  KSharedConfig::Ptr config = KGlobal::config();
345  bool loadOnDemand = true;
346  QVariant p = module->property("X-KDE-Kded-load-on-demand", QVariant::Bool);
347  if (p.isValid() && (p.toBool() == false))
348  loadOnDemand = false;
349  return loadOnDemand;
350 }
351 
352 KDEDModule *Kded::loadModule(const QString &obj, bool onDemand)
353 {
354  // Make sure this method is only called with valid module names.
355  Q_ASSERT(obj.indexOf('/')==-1);
356 
357  KDEDModule *module = m_modules.value(obj, 0);
358  if (module)
359  return module;
360  KService::Ptr s = KService::serviceByDesktopPath("kded/"+obj+".desktop");
361  return loadModule(s, onDemand);
362 }
363 
364 KDEDModule *Kded::loadModule(const KService::Ptr& s, bool onDemand)
365 {
366  if (s && !s->library().isEmpty())
367  {
368  QString obj = s->desktopEntryName();
369  KDEDModule *oldModule = m_modules.value(obj, 0);
370  if (oldModule)
371  return oldModule;
372 
373  if (onDemand)
374  {
375  QVariant p = s->property("X-KDE-Kded-load-on-demand", QVariant::Bool);
376  if (p.isValid() && (p.toBool() == false))
377  {
378  noDemandLoad(s->desktopEntryName());
379  return 0;
380  }
381  }
382 
383  KDEDModule *module = 0;
384  QString libname = "kded_"+s->library();
385  KPluginLoader loader(libname);
386 
387  KPluginFactory *factory = loader.factory();
388  if (!factory) {
389  // kde3 compat
390  QString factoryName = s->property("X-KDE-FactoryName", QVariant::String).toString();
391  if (factoryName.isEmpty())
392  factoryName = s->library();
393  factoryName = "create_" + factoryName;
394 #ifndef KDE_NO_DEPRECATED
395  KLibrary* lib = KLibLoader::self()->library(libname);
396  KDEDModule* (*create)();
397  if (lib) {
398  create = (KDEDModule* (*)())lib->resolveFunction(QFile::encodeName(factoryName));
399  if (create)
400  module = create();
401  }
402 #endif
403  if (!module) {
404  kWarning() << "Could not load library" << libname << ". ["
405  << loader.errorString() << "]";
406  }
407  } else {
408  // create the module
409  module = factory->create<KDEDModule>(this);
410  }
411  if (module) {
412  module->setModuleName(obj);
413  m_modules.insert(obj, module);
414  //m_libs.insert(obj, lib);
415  connect(module, SIGNAL(moduleDeleted(KDEDModule*)), SLOT(slotKDEDModuleRemoved(KDEDModule*)));
416  kDebug(7020) << "Successfully loaded module" << obj;
417  return module;
418  } else {
419  kDebug(7020) << "Could not load module" << obj;
420  //loader.unload();
421  }
422  }
423  return 0;
424 }
425 
426 bool Kded::unloadModule(const QString &obj)
427 {
428  KDEDModule *module = m_modules.value(obj, 0);
429  if (!module)
430  return false;
431  kDebug(7020) << "Unloading module" << obj;
432  m_modules.remove(obj);
433  delete module;
434  return true;
435 }
436 
437 QStringList Kded::loadedModules()
438 {
439  return m_modules.keys();
440 }
441 
442 void Kded::slotKDEDModuleRemoved(KDEDModule *module)
443 {
444  m_modules.remove(module->moduleName());
445  //KLibrary *lib = m_libs.take(module->moduleName());
446  //if (lib)
447  // lib->unload();
448 }
449 
450 void Kded::slotApplicationRemoved(const QString &name)
451 {
452 #if 0 // see kdedmodule.cpp (KDED_OBJECTS)
453  foreach( KDEDModule* module, m_modules )
454  {
455  module->removeAll(appId);
456  }
457 #endif
458  m_serviceWatcher->removeWatchedService(name);
459  const QList<qlonglong> windowIds = m_windowIdList.value(name);
460  for( QList<qlonglong>::ConstIterator it = windowIds.begin();
461  it != windowIds.end(); ++it)
462  {
463  qlonglong windowId = *it;
464  m_globalWindowIdList.remove(windowId);
465  foreach( KDEDModule* module, m_modules )
466  {
467  emit module->windowUnregistered(windowId);
468  }
469  }
470  m_windowIdList.remove(name);
471 }
472 
473 void Kded::updateDirWatch()
474 {
475  if (!bCheckUpdates) return;
476 
477  delete m_pDirWatch;
478  m_pDirWatch = new KDirWatch;
479 
480  QObject::connect( m_pDirWatch, SIGNAL(dirty(QString)),
481  this, SLOT(update(QString)));
482  QObject::connect( m_pDirWatch, SIGNAL(created(QString)),
483  this, SLOT(update(QString)));
484  QObject::connect( m_pDirWatch, SIGNAL(deleted(QString)),
485  this, SLOT(dirDeleted(QString)));
486 
487  // For each resource
488  for( QStringList::ConstIterator it = m_allResourceDirs.constBegin();
489  it != m_allResourceDirs.constEnd();
490  ++it )
491  {
492  readDirectory( *it );
493  }
494 }
495 
496 void Kded::updateResourceList()
497 {
498  KSycoca::clearCaches();
499 
500  if (!bCheckUpdates) return;
501 
502  if (delayedCheck) return;
503 
504  const QStringList dirs = KSycoca::self()->allResourceDirs();
505  // For each resource
506  for( QStringList::ConstIterator it = dirs.begin();
507  it != dirs.end();
508  ++it )
509  {
510  if (!m_allResourceDirs.contains(*it))
511  {
512  m_allResourceDirs.append(*it);
513  readDirectory(*it);
514  }
515  }
516 }
517 
518 void Kded::recreate()
519 {
520  recreate(false);
521 }
522 
523 void Kded::runDelayedCheck()
524 {
525  if( m_needDelayedCheck )
526  recreate(false);
527  m_needDelayedCheck = false;
528 }
529 
530 void Kded::recreate(bool initial)
531 {
532  m_recreateBusy = true;
533  // Using KLauncher here is difficult since we might not have a
534  // database
535 
536  if (!initial)
537  {
538  updateDirWatch(); // Update tree first, to be sure to miss nothing.
539  runBuildSycoca(this, SLOT(recreateDone()), SLOT(recreateFailed(QDBusError)));
540  }
541  else
542  {
543  if(!delayedCheck)
544  updateDirWatch(); // this would search all the directories
545  if (bCheckSycoca)
546  runBuildSycoca();
547  recreateDone();
548  if(delayedCheck)
549  {
550  // do a proper ksycoca check after a delay
551  QTimer::singleShot( 60000, this, SLOT(runDelayedCheck()));
552  m_needDelayedCheck = true;
553  delayedCheck = false;
554  }
555  else
556  m_needDelayedCheck = false;
557  }
558 }
559 
560 void Kded::recreateFailed(const QDBusError &error)
561 {
562  kWarning() << error;
563  for(; m_recreateCount; m_recreateCount--)
564  {
565  QDBusMessage msg = m_recreateRequests.takeFirst();
566  QDBusConnection::sessionBus().send(msg.createErrorReply(error));
567  }
568  afterRecreateFinished();
569 }
570 
571 void Kded::recreateDone()
572 {
573  updateResourceList();
574 
575  for(; m_recreateCount; m_recreateCount--)
576  {
577  QDBusMessage msg = m_recreateRequests.takeFirst();
578  QDBusConnection::sessionBus().send(msg.createReply());
579  }
580  afterRecreateFinished();
581 }
582 
583 void Kded::afterRecreateFinished()
584 {
585  m_recreateBusy = false;
586 
587  // Did a new request come in while building?
588  if (!m_recreateRequests.isEmpty())
589  {
590  m_pTimer->start(2000);
591  m_recreateCount = m_recreateRequests.count();
592  } else {
593  initModules();
594  }
595 }
596 
597 void Kded::dirDeleted(const QString& path)
598 {
599  update(path);
600 }
601 
602 void Kded::update(const QString& )
603 {
604  if (!m_recreateBusy)
605  {
606  m_pTimer->start( 10000 );
607  }
608 }
609 
610 void Kded::recreate(const QDBusMessage &msg)
611 {
612  if (!m_recreateBusy)
613  {
614  if (m_recreateRequests.isEmpty())
615  {
616  m_pTimer->start(0);
617  m_recreateCount = 0;
618  }
619  m_recreateCount++;
620  }
621  msg.setDelayedReply(true);
622  m_recreateRequests.append(msg);
623  return;
624 }
625 
626 
627 void Kded::readDirectory( const QString& _path )
628 {
629  QString path( _path );
630  if ( !path.endsWith( '/' ) )
631  path += '/';
632 
633  if ( m_pDirWatch->contains( path ) ) // Already seen this one?
634  return;
635 
636  m_pDirWatch->addDir(path,KDirWatch::WatchFiles|KDirWatch::WatchSubDirs); // add watch on this dir
637  return; // KDirWatch now claims to also support recursive watching
638 #if 0
639  QDir d( _path, QString(), QDir::Unsorted, QDir::Readable | QDir::Executable | QDir::Dirs | QDir::Hidden );
640  // set QDir ...
641 
642 
643  //************************************************************************
644  // Setting dirs
645  //************************************************************************
646 
647  if ( !d.exists() ) // exists&isdir?
648  {
649  kDebug(7020) << "Does not exist:" << _path;
650  return; // return false
651  }
652 
653  // Note: If some directory is gone, dirwatch will delete it from the list.
654 
655  //************************************************************************
656  // Reading
657  //************************************************************************
658  QString file;
659  unsigned int i; // counter and string length.
660  unsigned int count = d.count();
661  for( i = 0; i < count; i++ ) // check all entries
662  {
663  if (d[i] == "." || d[i] == ".." || d[i] == "magic")
664  continue; // discard those ".", "..", "magic"...
665 
666  file = path; // set full path
667  file += d[i]; // and add the file name.
668 
669  readDirectory( file ); // yes, dive into it.
670  }
671 #endif
672 }
673 
674 /*
675 bool Kded::isWindowRegistered(long windowId) const
676 {
677  return m_globalWindowIdList.contains(windowId);
678 
679 }
680 */
681 
682 void Kded::registerWindowId(qlonglong windowId, const QString &sender)
683 {
684  if (!m_windowIdList.contains(sender)) {
685  m_serviceWatcher->addWatchedService(sender);
686  }
687 
688  m_globalWindowIdList.insert(windowId);
689  QList<qlonglong> windowIds = m_windowIdList.value(sender);
690  windowIds.append(windowId);
691  m_windowIdList.insert(sender, windowIds);
692 
693  foreach( KDEDModule* module, m_modules )
694  {
695  //kDebug() << module->moduleName();
696  emit module->windowRegistered(windowId);
697  }
698 }
699 
700 void Kded::unregisterWindowId(qlonglong windowId, const QString &sender)
701 {
702  m_globalWindowIdList.remove(windowId);
703  QList<qlonglong> windowIds = m_windowIdList.value(sender);
704  if (!windowIds.isEmpty())
705  {
706  windowIds.removeAll(windowId);
707  if (windowIds.isEmpty()) {
708  m_serviceWatcher->removeWatchedService(sender);
709  m_windowIdList.remove(sender);
710  } else {
711  m_windowIdList.insert(sender, windowIds);
712  }
713  }
714 
715  foreach( KDEDModule* module, m_modules )
716  {
717  //kDebug() << module->moduleName();
718  emit module->windowUnregistered(windowId);
719  }
720 }
721 
722 
723 static void sighandler(int /*sig*/)
724 {
725  if (qApp)
726  qApp->quit();
727 }
728 
729 KUpdateD::KUpdateD()
730 {
731  m_pDirWatch = new KDirWatch;
732  m_pTimer = new QTimer;
733  m_pTimer->setSingleShot( true );
734  connect(m_pTimer, SIGNAL(timeout()), this, SLOT(runKonfUpdate()));
735  QObject::connect( m_pDirWatch, SIGNAL(dirty(QString)),
736  this, SLOT(slotNewUpdateFile()));
737 
738  const QStringList dirs = KGlobal::dirs()->findDirs("data", "kconf_update");
739  for( QStringList::ConstIterator it = dirs.begin();
740  it != dirs.end();
741  ++it )
742  {
743  QString path = *it;
744  if (path[path.length()-1] != '/')
745  path += '/';
746 
747  if (!m_pDirWatch->contains(path))
748  m_pDirWatch->addDir(path,KDirWatch::WatchFiles|KDirWatch::WatchSubDirs);
749  }
750 }
751 
752 KUpdateD::~KUpdateD()
753 {
754  delete m_pDirWatch;
755  delete m_pTimer;
756 }
757 
758 void KUpdateD::runKonfUpdate()
759 {
760  ::runKonfUpdate();
761 }
762 
763 void KUpdateD::slotNewUpdateFile()
764 {
765  m_pTimer->start( 500 );
766 }
767 
768 KHostnameD::KHostnameD(int pollInterval)
769 {
770  m_Timer.start(pollInterval); // repetitive timer (not single-shot)
771  connect(&m_Timer, SIGNAL(timeout()), this, SLOT(checkHostname()));
772  checkHostname();
773 }
774 
775 KHostnameD::~KHostnameD()
776 {
777  // Empty
778 }
779 
780 void KHostnameD::checkHostname()
781 {
782  char buf[1024+1];
783  if (gethostname(buf, 1024) != 0)
784  return;
785  buf[sizeof(buf)-1] = '\0';
786 
787  if (m_hostname.isEmpty())
788  {
789  m_hostname = buf;
790  return;
791  }
792 
793  if (m_hostname == buf)
794  return;
795 
796  QByteArray newHostname = buf;
797 
798  runDontChangeHostname(m_hostname, newHostname);
799  m_hostname = newHostname;
800 }
801 
802 
803 KBuildsycocaAdaptor::KBuildsycocaAdaptor(QObject *parent)
804  : QDBusAbstractAdaptor(parent)
805 {
806 }
807 
808 void KBuildsycocaAdaptor::recreate(const QDBusMessage &msg)
809 {
810  Kded::self()->recreate(msg);
811 }
812 
813 class KDEDApplication : public KUniqueApplication
814 {
815 public:
816  KDEDApplication() : KUniqueApplication( )
817  {
818  startup = true;
819  }
820 
821  int newInstance()
822  {
823  if (startup) {
824  startup = false;
825 
826  // This long initialization has to be here, not in kdemain.
827  // If it was in main, it would cause a dbus timeout when
828  // our parent from KUniqueApplication tries to call our
829  // newInstance method.
830 
831  Kded *kded = Kded::self();
832 
833  kded->recreate(true); // initial
834 
835  if (bCheckUpdates)
836  (void) new KUpdateD; // Watch for updates
837 
838 #ifdef Q_WS_X11
839  XEvent e;
840  e.xclient.type = ClientMessage;
841  e.xclient.message_type = XInternAtom( QX11Info::display(), "_KDE_SPLASH_PROGRESS", False );
842  e.xclient.display = QX11Info::display();
843  e.xclient.window = QX11Info::appRootWindow();
844  e.xclient.format = 8;
845  strcpy( e.xclient.data.b, "kded" );
846  XSendEvent( QX11Info::display(), QX11Info::appRootWindow(), False, SubstructureNotifyMask, &e );
847 #endif
848 
849  runKonfUpdate(); // Run it once.
850 
851 #ifdef Q_WS_X11
852  e.xclient.type = ClientMessage;
853  e.xclient.message_type = XInternAtom( QX11Info::display(), "_KDE_SPLASH_PROGRESS", False );
854  e.xclient.display = QX11Info::display();
855  e.xclient.window = QX11Info::appRootWindow();
856  e.xclient.format = 8;
857  strcpy( e.xclient.data.b, "confupdate" );
858  XSendEvent( QX11Info::display(), QX11Info::appRootWindow(), False, SubstructureNotifyMask, &e );
859 #endif
860 
861 // if (bCheckHostname)
862 // (void) new KHostnameD(HostnamePollInterval); // Watch for hostname changes
863  } else
864  runBuildSycoca();
865 
866  return 0;
867  }
868 
869  bool startup;
870 };
871 
872 extern "C" KDE_EXPORT int kdemain(int argc, char *argv[])
873 {
874  KAboutData aboutData( "kded" /*don't change this one to kded4! dbus registration should be org.kde.kded etc.*/,
875  "kdelibs4", ki18n("KDE Daemon"),
876  KDE_VERSION_STRING,
877  ki18n("KDE Daemon - triggers Sycoca database updates when needed"));
878 
879  KCmdLineOptions options;
880  options.add("check", ki18n("Check Sycoca database only once"));
881 
882  KCmdLineArgs::init(argc, argv, &aboutData);
883 
884  KUniqueApplication::addCmdLineOptions();
885 
886  KCmdLineArgs::addCmdLineOptions( options );
887 
888  // WABA: Make sure not to enable session management.
889  putenv(qstrdup("SESSION_MANAGER="));
890 
891  // Parse command line before checking DCOP
892  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
893 
894  KComponentData componentData(&aboutData);
895  KSharedConfig::Ptr config = componentData.config(); // Enable translations.
896 
897  KConfigGroup cg(config, "General");
898  if (args->isSet("check"))
899  {
900  // KUniqueApplication not wanted here.
901  KApplication app;
902  checkStamps = cg.readEntry("CheckFileStamps", true);
903  runBuildSycoca();
904  runKonfUpdate();
905  return 0;
906  }
907 
908  if (!KUniqueApplication::start())
909  {
910  fprintf(stderr, "KDE Daemon (kded) already running.\n");
911  return 0;
912  }
913 
914  // Thiago: reenable if such a thing exists in QtDBus in the future
915  //KUniqueApplication::dcopClient()->setQtBridgeEnabled(false);
916 
917  HostnamePollInterval = cg.readEntry("HostnamePollInterval", 5000);
918  bCheckSycoca = cg.readEntry("CheckSycoca", true);
919  bCheckUpdates = cg.readEntry("CheckUpdates", true);
920  bCheckHostname = cg.readEntry("CheckHostname", true);
921  checkStamps = cg.readEntry("CheckFileStamps", true);
922  delayedCheck = cg.readEntry("DelayedCheck", false);
923 
924  Kded *kded = new Kded(); // Build data base
925 
926 #ifndef _WIN32_WCE
927  KDE_signal(SIGTERM, sighandler);
928 #endif
929  KDE_signal(SIGHUP, sighandler);
930  KDEDApplication k;
931  k.setQuitOnLastWindowClosed(false);
932 
933  KCrash::setFlags(KCrash::AutoRestart);
934 
935  // Not sure why kded is created before KDEDApplication
936  // but if it has to be, then it needs to be moved to the main thread
937  // before it can use timers (DF)
938  kded->moveToThread( k.thread() );
939 
940  int result = k.exec(); // keep running
941 
942  delete kded;
943 
944  return result;
945 }
946 
947 #include "kded.moc"
KLibLoader::library
KLibrary * library(const QString &libname, QLibrary::LoadHints loadHint=0)
kdedadaptor.h
kded.h
KSharedPtr< KService >
KApplication
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KCmdLineArgs::addCmdLineOptions
static void addCmdLineOptions(const KCmdLineOptions &options, const KLocalizedString &name=KLocalizedString(), const QByteArray &id=QByteArray(), const QByteArray &afterId=QByteArray())
KUniqueApplication::start
static bool start()
QHash::insert
iterator insert(const Key &key, const T &value)
KUpdateD::runKonfUpdate
void runKonfUpdate()
Definition: kded.cpp:758
kdebug.h
KBuildsycocaAdaptor::recreate
Q_NOREPLY void recreate(const QDBusMessage &)
Definition: kded.cpp:808
QByteArray::toInt
int toInt(bool *ok, int base) const
KUpdateD
Definition: kded.h:230
kapplication.h
Kded::registerWindowId
void registerWindowId(qlonglong windowId, const QString &sender)
Applications can register/unregister their windows with kded modules.
Definition: kded.cpp:682
Kded::setModuleAutoloading
void setModuleAutoloading(const QString &module, bool autoload)
Configure whether a module should be loaded on startup.
Definition: kded.cpp:305
KCmdLineOptions::add
KCmdLineOptions & add(const QByteArray &name, const KLocalizedString &description=KLocalizedString(), const QByteArray &defaultValue=QByteArray())
QDBusMessage::setDelayedReply
void setDelayedReply(bool enable) const
QByteArray
KdedAdaptor
Definition: kdedadaptor.h:26
KServiceTypeTrader::self
static KServiceTypeTrader * self()
KDEDModule
kdirwatch.h
phaseForModule
static int phaseForModule(const KService::Ptr &service)
Definition: kded.cpp:211
ki18n
KLocalizedString ki18n(const char *msg)
Kded::slotApplicationRemoved
void slotApplicationRemoved(const QString &)
An application unregistered itself from DBus.
Definition: kded.cpp:450
timeout
int timeout
QObject::moveToThread
void moveToThread(QThread *targetThread)
QX11Info::appRootWindow
Qt::HANDLE appRootWindow(int screen)
KCmdLineArgs::parsedArgs
static KCmdLineArgs * parsedArgs(const QByteArray &id=QByteArray())
QX11Info::display
Display * display()
KHostnameD::KHostnameD
KHostnameD(int pollInterval)
Definition: kded.cpp:768
KStandardDirs::findDirs
QStringList findDirs(const char *type, const QString &reldir) const
klauncher_iface.h
Kded::recreate
void recreate(const QDBusMessage &)
Definition: kded.cpp:610
kconfig.h
KCmdLineArgs
KService::property
QVariant property(const QString &_name, QVariant::Type t) const
dirs
KStandardDirs * dirs()
QDBusConnection::registerObject
bool registerObject(const QString &path, QObject *object, QFlags< QDBusConnection::RegisterOption > options)
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QByteArray::isEmpty
bool isEmpty() const
delayedCheck
static bool delayedCheck
Definition: kded.cpp:73
KDEDModule::windowUnregistered
void windowUnregistered(qlonglong windowId)
QDBusMessage::type
MessageType type() const
HostnamePollInterval
static int HostnamePollInterval
Definition: kded.cpp:74
Kded::recreateDone
void recreateDone()
Recreating finished.
Definition: kded.cpp:571
Kded::slotKDEDModuleRemoved
void slotKDEDModuleRemoved(KDEDModule *)
A KDEDModule is about to get destroyed.
Definition: kded.cpp:442
QDBusConnection
KConfigGroup::writeEntry
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
QDBusConnection::sessionBus
QDBusConnection sessionBus()
Kded::recreate
void recreate()
Recreate the database file.
Definition: kded.cpp:518
Kded::Kded
Kded()
Definition: kded.cpp:122
QSet::insert
const_iterator insert(const T &value)
Kded::self
static Kded * self()
Definition: kded.h:47
ktoolinvocation.h
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
klocale.h
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
KDE_VERSION_STRING
#define KDE_VERSION_STRING
KDEDModule::setModuleName
void setModuleName(const QString &name)
MODULES_PATH
#define MODULES_PATH
Definition: kded.cpp:68
KCmdLineArgs::isSet
bool isSet(const QByteArray &option) const
config
KSharedConfigPtr config()
Kded::loadedModules
QStringList loadedModules()
Definition: kded.cpp:437
Kded::noDemandLoad
void noDemandLoad(const QString &obj)
Definition: kded.cpp:300
QDBusAbstractAdaptor
QHash::iterator
kservicetypetrader.h
KUpdateD::slotNewUpdateFile
void slotNewUpdateFile()
Definition: kded.cpp:763
kglobal.h
kdedmodule.h
KComponentData::config
const KSharedConfig::Ptr & config() const
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QDBusServiceWatcher::setConnection
void setConnection(const QDBusConnection &connection)
QDBusMessage::createReply
QDBusMessage createReply(const QList< QVariant > &arguments) const
KDEDModule::windowRegistered
void windowRegistered(qlonglong windowId)
KPluginLoader::errorString
QString errorString() const
KPluginLoader
QTimer
QVariant::toInt
int toInt(bool *ok) const
QObject
qDBusAddSpyHook
QDBUS_EXPORT void qDBusAddSpyHook(void(*)(const QDBusMessage &))
QList::isEmpty
bool isEmpty() const
kcmdlineargs.h
Kded::loadModule
KDEDModule * loadModule(const QString &obj, bool onDemand)
Definition: kded.cpp:352
QDBusConnection::send
bool send(const QDBusMessage &message) const
QString::isEmpty
bool isEmpty() const
QList::removeAll
int removeAll(const T &value)
Kded::loadSecondPhase
void loadSecondPhase()
Definition: kded.cpp:285
kuniqueapplication.h
KDEDModule::moduleName
QString moduleName() const
QHash::begin
iterator begin()
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
runDontChangeHostname
static void runDontChangeHostname(const QByteArray &oldName, const QByteArray &newName)
Definition: kded.cpp:114
KLibrary
bCheckUpdates
static bool bCheckUpdates
Definition: kded.cpp:76
runBuildSycoca
static void runBuildSycoca(QObject *callBackObj=0, const char *callBackSlot=0, const char *callBackErrorSlot=0)
Definition: kded.cpp:85
Kded::updateResourceList
void updateResourceList()
Update directories to watch.
Definition: kded.cpp:496
KBuildsycocaAdaptor
Definition: kded.h:218
KAboutData
KUniqueApplication::newInstance
virtual int newInstance()
bCheckHostname
static bool bCheckHostname
Definition: kded.cpp:77
kcrash.h
QString
QList
QHash::remove
int remove(const Key &key)
Kded::isModuleAutoloaded
bool isModuleAutoloaded(const QString &module) const
Check if a module should be loaded on startup.
Definition: kded.cpp:317
QDBusServiceWatcher::removeWatchedService
bool removeWatchedService(const QString &service)
Kded::isModuleLoadedOnDemand
bool isModuleLoadedOnDemand(const QString &module) const
Check if a module should be loaded on demand.
Definition: kded.cpp:334
KService::serviceByDesktopPath
static Ptr serviceByDesktopPath(const QString &_path)
QStringList
Kded::update
void update(const QString &dir)
Definition: kded.cpp:602
QHash::keys
QList< Key > keys() const
QDBusMessage::createErrorReply
QDBusMessage createErrorReply(const QString name, const QString &msg) const
QHash::clear
void clear()
QList::end
iterator end()
QHash::value
const T value(const Key &key) const
Kded::unloadModule
bool unloadModule(const QString &obj)
Definition: kded.cpp:426
fixx11h.h
KService::library
QString library() const
KBuildsycocaAdaptor::KBuildsycocaAdaptor
KBuildsycocaAdaptor(QObject *parent)
Definition: kded.cpp:803
KCrash::AutoRestart
Kded::recreateFailed
void recreateFailed(const QDBusError &error)
Definition: kded.cpp:560
QTimer::stop
void stop()
KDirWatch::WatchFiles
KDirWatch::contains
bool contains(const QString &path) const
Kded::updateDirWatch
void updateDirWatch()
Collect all directories to watch.
Definition: kded.cpp:473
QDir
KPluginLoader::factory
KPluginFactory * factory()
KConfigGroup
KUniqueApplication::addCmdLineOptions
static void addCmdLineOptions()
KLibLoader::self
static KLibLoader * self()
KServiceTypeTrader::query
KService::List query(const QString &servicetype, const QString &constraint=QString()) const
KLibrary::resolveFunction
void_function_ptr resolveFunction(const char *name)
checkStamps
static bool checkStamps
Definition: kded.cpp:72
QString::toLatin1
QByteArray toLatin1() const
KUpdateD::KUpdateD
KUpdateD()
Definition: kded.cpp:729
QString::mid
QString mid(int position, int n) const
QSet::remove
bool remove(const T &value)
QDBusMessage
QList::takeFirst
T takeFirst()
KService::desktopEntryName
QString desktopEntryName() const
kstandarddirs.h
QString::count
int count() const
kdemain
int kdemain(int argc, char *argv[])
Definition: kded.cpp:872
bCheckSycoca
static bool bCheckSycoca
Definition: kded.cpp:75
runKonfUpdate
static void runKonfUpdate()
Definition: kded.cpp:109
QDBusAbstractInterface::callWithCallback
bool callWithCallback(const QString &method, const QList< QVariant > &args, QObject *receiver, const char *returnMethod, const char *errorMethod)
KToolInvocation::kdeinitExecWait
static int kdeinitExecWait(const QString &name, const QStringList &args=QStringList(), QString *error=0, int *pid=0, const QByteArray &startup_id=QByteArray())
KStandardDirs::findExe
static QString findExe(const QString &appname, const QString &pathstr=QString(), SearchOptions options=NoSearchOptions)
QList::ConstIterator
typedef ConstIterator
create
KAction * create(StandardAction id, const QObject *recvr, const char *slot, QObject *parent)
KCmdLineArgs::init
static void init(int argc, char **argv, const QByteArray &appname, const QByteArray &catalog, const KLocalizedString &programName, const QByteArray &version, const KLocalizedString &description=KLocalizedString(), StdCmdLineArgs stdargs=StdCmdLineArgs(CmdLineArgQt|CmdLineArgKDE))
QString::length
int length() const
QVariant::toBool
bool toBool() const
KDE_VERSION_MAJOR
#define KDE_VERSION_MAJOR
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QString::left
QString left(int n) const
QDBusMessage::path
QString path() const
KDirWatch::addDir
void addDir(const QString &path, WatchModes watchModes=WatchDirOnly)
sighandler
static void sighandler(int)
Definition: kded.cpp:723
QTimer::start
void start(int msec)
QVariant::isValid
bool isValid() const
KUpdateD::~KUpdateD
~KUpdateD()
Definition: kded.cpp:752
KUniqueApplication
QHash::contains
bool contains(const Key &key) const
klibloader.h
KCrash::setFlags
void setFlags(CrashFlags flags)
KDirWatch
Kded::~Kded
virtual ~Kded()
Definition: kded.cpp:152
KConfigGroup::sync
void sync()
kaboutdata.h
QHash::end
iterator end()
QList::constEnd
const_iterator constEnd() const
KDirWatch::WatchSubDirs
QList::constBegin
const_iterator constBegin() const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
klibrary.h
QDBusServiceWatcher::setWatchMode
void setWatchMode(QFlags< QDBusServiceWatcher::WatchModeFlag > mode)
KBUILDSYCOCA_EXENAME
#define KBUILDSYCOCA_EXENAME
KCmdLineOptions
QVariant::toString
QString toString() const
KPluginFactory
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
KSycoca::self
static KSycoca * self()
QList::begin
iterator begin()
KSycoca::allResourceDirs
QStringList allResourceDirs()
KHostnameD::checkHostname
void checkHostname()
Definition: kded.cpp:780
KComponentData
Kded::unregisterWindowId
void unregisterWindowId(qlonglong windowId, const QString &sender)
Unregister a window previously registered with KDED.
Definition: kded.cpp:700
QDBusServiceWatcher::addWatchedService
void addWatchedService(const QString &newService)
QFile::encodeName
QByteArray encodeName(const QString &fileName)
QFile::decodeName
QString decodeName(const QByteArray &localFileName)
Kded
Definition: kded.h:40
kconfiggroup.h
Kded::messageFilter
static void messageFilter(const QDBusMessage &)
Definition: kded.cpp:177
QDBusServiceWatcher
KHostnameD::~KHostnameD
~KHostnameD()
Definition: kded.cpp:775
KDE_EXPORT
#define KDE_EXPORT
Kded::runDelayedCheck
void runDelayedCheck()
Definition: kded.cpp:523
QDBusError
Kded::dirDeleted
void dirDeleted(const QString &path)
Definition: kded.cpp:597
QTimer::setSingleShot
void setSingleShot(bool singleShot)
QVariant
KToolInvocation::klauncher
static OrgKdeKLauncherInterface * klauncher()
Kded::initModules
void initModules()
Loads / unloads modules according to config.
Definition: kded.cpp:217
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:26:11 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDED

Skip menu "KDED"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal