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.
tdelibs/tdeinit/autostart.cpp

305 lines
8.7 KiB

/*
*
* This file is part of the KDE libraries
* Copyright (c) 2001 Waldo Bastian <bastian@kde.org>
*
* $Id$
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
**/
#include "autostart.h"
#include <tdeconfig.h>
#include <kdesktopfile.h>
#include <tdeglobal.h>
#include <kstandarddirs.h>
#include <stdlib.h>
class AutoStartItem
{
public:
TQString name;
TQString service;
TQString startAfter;
int phase;
};
class AutoStartList: public TQPtrList<AutoStartItem>
{
public:
AutoStartList() { }
};
AutoStart::AutoStart( bool new_startup )
: m_newStartup( new_startup ), m_phase( new_startup ? -1 : 0), m_phasedone(false)
{
m_startList = new AutoStartList;
m_startList->setAutoDelete(true);
TDEGlobal::dirs()->addResourceType("autostart", "share/autostart");
TQString xdgdirs = getenv("XDG_CONFIG_DIRS");
if (xdgdirs.isEmpty())
xdgdirs = "/etc/xdg";
TQStringList xdgdirslist = TQStringList::split( ':', xdgdirs );
for ( TQStringList::Iterator itr = xdgdirslist.begin(); itr != xdgdirslist.end(); ++itr ) {
TDEGlobal::dirs()->addResourceDir("autostart", (*itr) +"/autostart");
}
}
AutoStart::~AutoStart()
{
delete m_startList;
}
void
AutoStart::setPhase(int phase)
{
if (phase > m_phase)
{
m_phase = phase;
m_phasedone = false;
}
}
void AutoStart::setPhaseDone()
{
m_phasedone = true;
}
static TQString extractName(TQString path)
{
int i = path.findRev('/');
if (i >= 0)
path = path.mid(i+1);
i = path.findRev('.');
if (i >= 0)
path = path.left(i);
return path;
}
static bool startCondition(const TQString &condition)
{
if (condition.isEmpty())
return true;
TQStringList list = TQStringList::split(':', condition, true);
if (list.count() < 4)
return true;
if (list[0].isEmpty() || list[2].isEmpty())
return true;
TDEConfig config(list[0], true, false);
if (!list[1].isEmpty())
config.setGroup(list[1]);
bool defaultValue = (list[3].lower() == "true");
return config.readBoolEntry(list[2], defaultValue);
}
void
AutoStart::loadAutoStartList()
{
TQStringList files = TDEGlobal::dirs()->findAllResources("xdgconf-autostart", "*.desktop", false, true);
TQStringList kdefiles = TDEGlobal::dirs()->findAllResources("autostart", "*.desktop", false, true);
files += kdefiles;
for(TQStringList::ConstIterator it = files.begin(); it != files.end(); ++it)
{
// Explicitly skip autostart files from KDE
if ((*it).contains("org.kde") || (*it).startsWith("/etc/kde/xdg/autostart"))
{
continue;
}
KDesktopFile config(*it, true);
if (config.hasKey("X-TDE-autostart-condition")) {
if (!startCondition(config.readEntry("X-TDE-autostart-condition")))
continue;
}
else if (config.hasKey("X-KDE-autostart-condition")) {
if (!startCondition(config.readEntry("X-KDE-autostart-condition")))
continue;
}
if (!config.tryExec())
continue;
if (config.readBoolEntry("Hidden", false))
continue;
// Check to see if the most important ( usually ~/.config/autostart or ~/.trinity/Autostart) XDG directory
// has overridden the Hidden directive and honor it if set to True
bool autostartOverriddenAndDisabled = false;
for(TQStringList::ConstIterator localit = files.begin();
localit != files.end();
++localit)
{
if (((*localit).startsWith(TDEGlobal::dirs()->localxdgconfdir()) == true) || ((*localit).startsWith(TDEGlobal::dirs()->localtdedir()) == true)) {
// Same local file name?
TQString localOuter;
TQString localInner;
int slashPos = (*it).findRev( '/', -1, TRUE );
if (slashPos == -1) {
localOuter = (*it);
}
else {
localOuter = (*it).mid(slashPos+1);
}
slashPos = (*localit).findRev( '/', -1, TRUE );
if (slashPos == -1) {
localInner = (*localit);
}
else {
localInner = (*localit).mid(slashPos+1);
}
if (localOuter == localInner) {
// Overridden!
// But is Hidden == True?
KDesktopFile innerConfig(*localit, true);
if (innerConfig.readBoolEntry("Hidden", false)) {
// Override confirmed; exit speedily without autostarting
autostartOverriddenAndDisabled = true;
}
}
}
}
if (autostartOverriddenAndDisabled == true)
continue;
if (config.hasKey("OnlyShowIn"))
{
if (!config.readListEntry("OnlyShowIn", ';').contains("TDE"))
continue;
}
if (config.hasKey("NotShowIn"))
{
if (config.readListEntry("NotShowIn", ';').contains("TDE") ||
config.readListEntry("NotShowIn", ';').contains("KDE"))
continue;
}
AutoStartItem *item = new AutoStartItem;
item->name = extractName(*it);
item->service = *it;
if (config.hasKey("X-TDE-autostart-after"))
item->startAfter = config.readEntry("X-TDE-autostart-after");
else
item->startAfter = config.readEntry("X-KDE-autostart-after");
if( m_newStartup )
{
if (config.hasKey("X-TDE-autostart-phase"))
item->phase = config.readNumEntry("X-TDE-autostart-phase", 2);
else
item->phase = config.readNumEntry("X-KDE-autostart-phase", 2);
if (item->phase < 0)
item->phase = 0;
}
else
{
if (config.hasKey("X-TDE-autostart-phase"))
item->phase = config.readNumEntry("X-TDE-autostart-phase", 1);
else
item->phase = config.readNumEntry("X-KDE-autostart-phase", 1);
if (item->phase < 1)
item->phase = 1;
}
m_startList->append(item);
}
// Check for duplicate entries and remove if found
TQPtrListIterator<AutoStartItem> it1(*m_startList);
TQPtrListIterator<AutoStartItem> it2(*m_startList);
AutoStartItem *item1;
AutoStartItem *item2;
while ((item1 = it1.current()) != 0) {
bool dupfound1 = false;
it2.toFirst();
while ((item2 = it2.current()) != 0) {
bool dupfound2 = false;
if (item2 != item1) {
if (item1->service == item2->service) {
m_startList->removeRef(item2);
dupfound1 = true;
dupfound2 = true;
}
}
if (!dupfound2) {
++it2;
}
}
if (!dupfound1) {
++it1;
}
}
}
TQString
AutoStart::startService()
{
if (m_startList->isEmpty())
return 0;
while(!m_started.isEmpty())
{
// Check for items that depend on previously started items
TQString lastItem = m_started[0];
for(AutoStartItem *item = m_startList->first();
item; item = m_startList->next())
{
if (item->phase == m_phase
&& item->startAfter == lastItem)
{
m_started.prepend(item->name);
TQString service = item->service;
m_startList->remove();
return service;
}
}
m_started.remove(m_started.begin());
}
// Check for items that don't depend on anything
AutoStartItem *item;
for(item = m_startList->first();
item; item = m_startList->next())
{
if (item->phase == m_phase
&& item->startAfter.isEmpty())
{
m_started.prepend(item->name);
TQString service = item->service;
m_startList->remove();
return service;
}
}
// Just start something in this phase
for(item = m_startList->first();
item; item = m_startList->next())
{
if (item->phase == m_phase)
{
m_started.prepend(item->name);
TQString service = item->service;
m_startList->remove();
return service;
}
}
return 0;
}