TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

autostart.cpp 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. *
  3. * This file is part of the KDE libraries
  4. * Copyright (c) 2001 Waldo Bastian <bastian@kde.org>
  5. *
  6. * $Id$
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Library General Public
  10. * License version 2 as published by the Free Software Foundation.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Library General Public License
  18. * along with this library; see the file COPYING.LIB. If not, write to
  19. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  20. * Boston, MA 02110-1301, USA.
  21. **/
  22. #include "autostart.h"
  23. #include <tdeconfig.h>
  24. #include <kdesktopfile.h>
  25. #include <tdeglobal.h>
  26. #include <kstandarddirs.h>
  27. #include <stdlib.h>
  28. class AutoStartItem
  29. {
  30. public:
  31. TQString name;
  32. TQString service;
  33. TQString startAfter;
  34. int phase;
  35. };
  36. class AutoStartList: public TQPtrList<AutoStartItem>
  37. {
  38. public:
  39. AutoStartList() { }
  40. };
  41. AutoStart::AutoStart( bool new_startup )
  42. : m_newStartup( new_startup ), m_phase( new_startup ? -1 : 0), m_phasedone(false)
  43. {
  44. m_startList = new AutoStartList;
  45. m_startList->setAutoDelete(true);
  46. TDEGlobal::dirs()->addResourceType("autostart", "share/autostart");
  47. TQString xdgdirs = getenv("XDG_CONFIG_DIRS");
  48. if (xdgdirs.isEmpty())
  49. xdgdirs = "/etc/xdg";
  50. TQStringList xdgdirslist = TQStringList::split( ':', xdgdirs );
  51. for ( TQStringList::Iterator itr = xdgdirslist.begin(); itr != xdgdirslist.end(); ++itr ) {
  52. TDEGlobal::dirs()->addResourceDir("autostart", (*itr) +"/autostart");
  53. }
  54. }
  55. AutoStart::~AutoStart()
  56. {
  57. delete m_startList;
  58. }
  59. void
  60. AutoStart::setPhase(int phase)
  61. {
  62. if (phase > m_phase)
  63. {
  64. m_phase = phase;
  65. m_phasedone = false;
  66. }
  67. }
  68. void AutoStart::setPhaseDone()
  69. {
  70. m_phasedone = true;
  71. }
  72. static TQString extractName(TQString path)
  73. {
  74. int i = path.findRev('/');
  75. if (i >= 0)
  76. path = path.mid(i+1);
  77. i = path.findRev('.');
  78. if (i >= 0)
  79. path = path.left(i);
  80. return path;
  81. }
  82. static bool startCondition(const TQString &condition)
  83. {
  84. if (condition.isEmpty())
  85. return true;
  86. TQStringList list = TQStringList::split(':', condition, true);
  87. if (list.count() < 4)
  88. return true;
  89. if (list[0].isEmpty() || list[2].isEmpty())
  90. return true;
  91. TDEConfig config(list[0], true, false);
  92. if (!list[1].isEmpty())
  93. config.setGroup(list[1]);
  94. bool defaultValue = (list[3].lower() == "true");
  95. return config.readBoolEntry(list[2], defaultValue);
  96. }
  97. void
  98. AutoStart::loadAutoStartList()
  99. {
  100. TQStringList files = TDEGlobal::dirs()->findAllResources("xdgconf-autostart", "*.desktop", false, true);
  101. TQStringList kdefiles = TDEGlobal::dirs()->findAllResources("autostart", "*.desktop", false, true);
  102. files += kdefiles;
  103. for(TQStringList::ConstIterator it = files.begin();
  104. it != files.end();
  105. ++it)
  106. {
  107. KDesktopFile config(*it, true);
  108. if (config.hasKey("X-TDE-autostart-condition")) {
  109. if (!startCondition(config.readEntry("X-TDE-autostart-condition")))
  110. continue;
  111. }
  112. else {
  113. if (!startCondition(config.readEntry("X-TDE-autostart-condition")))
  114. continue;
  115. }
  116. if (!config.tryExec())
  117. continue;
  118. if (config.readBoolEntry("Hidden", false))
  119. continue;
  120. // Check to see if the most important ( usually ~/.config/autostart or ~/.trinity/Autostart) XDG directory
  121. // has overridden the Hidden directive and honor it if set to True
  122. bool autostartOverriddenAndDisabled = false;
  123. for(TQStringList::ConstIterator localit = files.begin();
  124. localit != files.end();
  125. ++localit)
  126. {
  127. if (((*localit).startsWith(TDEGlobal::dirs()->localxdgconfdir()) == true) || ((*localit).startsWith(TDEGlobal::dirs()->localtdedir()) == true)) {
  128. // Same local file name?
  129. TQString localOuter;
  130. TQString localInner;
  131. int slashPos = (*it).findRev( '/', -1, TRUE );
  132. if (slashPos == -1) {
  133. localOuter = (*it);
  134. }
  135. else {
  136. localOuter = (*it).mid(slashPos+1);
  137. }
  138. slashPos = (*localit).findRev( '/', -1, TRUE );
  139. if (slashPos == -1) {
  140. localInner = (*localit);
  141. }
  142. else {
  143. localInner = (*localit).mid(slashPos+1);
  144. }
  145. if (localOuter == localInner) {
  146. // Overridden!
  147. // But is Hidden == True?
  148. KDesktopFile innerConfig(*localit, true);
  149. if (innerConfig.readBoolEntry("Hidden", false)) {
  150. // Override confirmed; exit speedily without autostarting
  151. autostartOverriddenAndDisabled = true;
  152. }
  153. }
  154. }
  155. }
  156. if (autostartOverriddenAndDisabled == true)
  157. continue;
  158. if (config.hasKey("OnlyShowIn"))
  159. {
  160. if ((!config.readListEntry("OnlyShowIn", ';').contains("TDE")) && (!config.readListEntry("OnlyShowIn", ';').contains("KDE")))
  161. continue;
  162. }
  163. if (config.hasKey("NotShowIn"))
  164. {
  165. if ((config.readListEntry("NotShowIn", ';').contains("TDE")) || (config.readListEntry("NotShowIn", ';').contains("KDE")))
  166. continue;
  167. }
  168. AutoStartItem *item = new AutoStartItem;
  169. item->name = extractName(*it);
  170. item->service = *it;
  171. if (config.hasKey("X-TDE-autostart-after"))
  172. item->startAfter = config.readEntry("X-TDE-autostart-after");
  173. else
  174. item->startAfter = config.readEntry("X-TDE-autostart-after");
  175. if( m_newStartup )
  176. {
  177. if (config.hasKey("X-TDE-autostart-phase"))
  178. item->phase = config.readNumEntry("X-TDE-autostart-phase", 2);
  179. else
  180. item->phase = config.readNumEntry("X-TDE-autostart-phase", 2);
  181. if (item->phase < 0)
  182. item->phase = 0;
  183. }
  184. else
  185. {
  186. if (config.hasKey("X-TDE-autostart-phase"))
  187. item->phase = config.readNumEntry("X-TDE-autostart-phase", 1);
  188. else
  189. item->phase = config.readNumEntry("X-TDE-autostart-phase", 1);
  190. if (item->phase < 1)
  191. item->phase = 1;
  192. }
  193. m_startList->append(item);
  194. }
  195. // Check for duplicate entries and remove if found
  196. TQPtrListIterator<AutoStartItem> it1(*m_startList);
  197. TQPtrListIterator<AutoStartItem> it2(*m_startList);
  198. AutoStartItem *item1;
  199. AutoStartItem *item2;
  200. while ((item1 = it1.current()) != 0) {
  201. bool dupfound1 = false;
  202. it2.toFirst();
  203. while ((item2 = it2.current()) != 0) {
  204. bool dupfound2 = false;
  205. if (item2 != item1) {
  206. if (item1->service == item2->service) {
  207. m_startList->removeRef(item2);
  208. dupfound1 = true;
  209. dupfound2 = true;
  210. }
  211. }
  212. if (!dupfound2) {
  213. ++it2;
  214. }
  215. }
  216. if (!dupfound1) {
  217. ++it1;
  218. }
  219. }
  220. }
  221. TQString
  222. AutoStart::startService()
  223. {
  224. if (m_startList->isEmpty())
  225. return 0;
  226. while(!m_started.isEmpty())
  227. {
  228. // Check for items that depend on previously started items
  229. TQString lastItem = m_started[0];
  230. for(AutoStartItem *item = m_startList->first();
  231. item; item = m_startList->next())
  232. {
  233. if (item->phase == m_phase
  234. && item->startAfter == lastItem)
  235. {
  236. m_started.prepend(item->name);
  237. TQString service = item->service;
  238. m_startList->remove();
  239. return service;
  240. }
  241. }
  242. m_started.remove(m_started.begin());
  243. }
  244. // Check for items that don't depend on anything
  245. AutoStartItem *item;
  246. for(item = m_startList->first();
  247. item; item = m_startList->next())
  248. {
  249. if (item->phase == m_phase
  250. && item->startAfter.isEmpty())
  251. {
  252. m_started.prepend(item->name);
  253. TQString service = item->service;
  254. m_startList->remove();
  255. return service;
  256. }
  257. }
  258. // Just start something in this phase
  259. for(item = m_startList->first();
  260. item; item = m_startList->next())
  261. {
  262. if (item->phase == m_phase)
  263. {
  264. m_started.prepend(item->name);
  265. TQString service = item->service;
  266. m_startList->remove();
  267. return service;
  268. }
  269. }
  270. return 0;
  271. }