kded: rework phases logic to take any desktop session into account

much like XDG autostart except for KDED modules, requires adjustments to
modules that are automatically loaded in phase-1

in the future the logic may apply not only to modules during startup but
also when attempting to load a module in general

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-08-31 22:56:41 +03:00
parent 387bdaa93f
commit e482da9067
5 changed files with 43 additions and 27 deletions

View file

@ -26,11 +26,11 @@ is not running (i.e. when running a KDE application in another environment).
[The following paragraph was copied from kdebase/workspace/ksmserver/README]
The exact way autoloading works is controlled by X-KDE-Kded-phase=,
which may be 0, 1 or 2 (the default). Kded phase 0 means the module is
always loaded by kded, even outside of KDE session. It should used only
by kded modules which must be always running. Kded phase 1 modules are
loaded right after kded startup, but only during KDE startup, i.e. it is
for modules that are always needed by the KDE session. Phase 2 modules
will be loaded later.
always loaded by kded, even outside of the current desktop session. It should
used only by kded modules which must be always running. Kded phase 1 modules are
loaded right after kded startup and is for modules that must be loaded for
specific desktop session. Phase 2 modules will be loaded later by ksmserver
and only for KDE session.
Normally KDED modules are loaded whenever they are accessed, so you don't
need autoloading enabled. On demand loading can be disabled by putting

View file

@ -203,26 +203,38 @@ static int phaseForModule(const KService::Ptr& service)
return (phasev.isValid() ? phasev.toInt() : 2);
}
static bool allowedForDesktop(const KService::Ptr &service, const QString &desktop)
{
const QString only_show_in = service->property("OnlyShowIn", QVariant::String).toString();
kDebug(7020) << "only_show_in" << service->entryPath() << only_show_in;
if (only_show_in.isEmpty()) {
return true;
}
const QStringList only_show_in_list = only_show_in.split(QLatin1Char(';'));
return only_show_in_list.contains(desktop);
}
static bool excludedForDesktop(const KService::Ptr &service, const QString &desktop)
{
const QString not_show_in = service->property("NotShowIn", QVariant::String).toString();
kDebug(7020) << "not_show_in" << service->entryPath() << not_show_in;
if (not_show_in.isEmpty()) {
return false;
}
const QStringList not_show_in_list = not_show_in.split(QLatin1Char(';'));
return !not_show_in_list.contains(desktop);
}
void Kded::initModules()
{
m_dontLoad.clear();
bool kde_running = !qgetenv("KDE_FULL_SESSION").isEmpty();
if (!kde_running) {
kde_running = (QProcess::execute(QString::fromLatin1("kcheckrunning")) == 0);
}
if (kde_running) {
// not the same user like the one running the session (most likely we're run via sudo or something)
const QByteArray sessionUID = qgetenv("KDE_SESSION_UID");
if (!sessionUID.isEmpty() && uid_t(sessionUID.toInt()) != ::getuid()) {
kde_running = false;
}
}
kDebug(7020) << "kde_running" << kde_running;
const QString current_desktop = QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP"));
kDebug(7020) << "current_desktop" << current_desktop;
// Preload kded modules.
const KService::List kdedModules = KServiceTypeTrader::self()->query("KDEDModule");
for (int phase = 0; phase < 2; phase++) {
foreach (KService::Ptr service, kdedModules) {
foreach (const KService::Ptr service, kdedModules) {
const int module_phase = phaseForModule(service);
// Should the service be loaded in this phase or later?
if (module_phase != phase) {
@ -231,8 +243,6 @@ void Kded::initModules()
// Should the service load on startup?
const bool autoload = isModuleAutoloaded(service);
// see ksmserver's README for description of the phases
bool prevent_autoload = false;
switch( module_phase ) {
case 0: {
@ -240,8 +250,17 @@ void Kded::initModules()
break;
}
case 1: {
// autoload only in KDE
if (!kde_running) {
// autoload only in the current desktop?
if (current_desktop.isEmpty()) {
prevent_autoload = true;
break;
}
if (!prevent_autoload && !allowedForDesktop(service, current_desktop)) {
prevent_autoload = true;
}
if (!prevent_autoload && excludedForDesktop(service, current_desktop)) {
prevent_autoload = true;
}
break;

View file

@ -9,4 +9,3 @@ X-KDE-DBus-ModuleName=kaudioplayer
X-KDE-Kded-autoload=false
X-KDE-Kded-load-on-demand=true
X-KDE-MediaPlayer=kded_kaudioplayer
OnlyShowIn=KDE;

View file

@ -8,4 +8,3 @@ X-KDE-Library=knetworkmanager
X-KDE-DBus-ModuleName=knetworkmanager
X-KDE-Kded-autoload=true
X-KDE-Kded-load-on-demand=true
OnlyShowIn=KDE;

View file

@ -9,4 +9,3 @@ X-KDE-DBus-ModuleName=kpasswdstore
X-KDE-Kded-autoload=true
X-KDE-Kded-load-on-demand=true
X-KDE-Kded-phase=1
OnlyShowIn=KDE;