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

KDED

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