From 94bed6baf5e73b0dbfb8f23d5f555fa7b8b32fdb Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sat, 10 Dec 2022 04:59:16 +0200 Subject: [PATCH] kwin: drop support for effect plugins, fix crash completing what I started when I made the effects builtin, the configuration modules for the effects are (and will probably remain) plugins tho Signed-off-by: Ivailo Monev --- kwin/effects.cpp | 165 +++++++----------------------- kwin/effects.h | 2 - kwin/libkwineffects/kwineffects.h | 43 -------- 3 files changed, 36 insertions(+), 174 deletions(-) diff --git a/kwin/effects.cpp b/kwin/effects.cpp index 1cc1ed26..f042ae55 100644 --- a/kwin/effects.cpp +++ b/kwin/effects.cpp @@ -246,8 +246,12 @@ EffectsHandlerImpl::~EffectsHandlerImpl() if (keyboard_grab_effect != NULL) { ungrabKeyboard(); } - foreach (const EffectPair & ep, loaded_effects) { - unloadEffect(ep.first); + QStringList loaded_names; + foreach (const EffectPair &ep, loaded_effects) { + loaded_names.append(ep.first); + } + foreach (const QString &en, loaded_names) { + unloadEffect(en); } } @@ -1245,18 +1249,6 @@ unsigned long EffectsHandlerImpl::xrenderBufferPicture() return None; } -QLibrary* EffectsHandlerImpl::findEffectLibrary(KService* service) -{ - QLibrary* library = new QLibrary(service->library()); - if (!library) { - kError(1212) << "couldn't open library for effect '" << - service->name() << "'"; - return 0; - } - - return library; -} - void EffectsHandlerImpl::toggleEffect(const QString& name) { if (isEffectLoaded(name)) @@ -1361,128 +1353,47 @@ bool EffectsHandlerImpl::loadEffect(const QString& name, bool checkDefault) } if (effect) { - kDebug(1212) << "Effect is internal" << name; bool enabledByDefault = service->property("X-KDE-PluginInfo-EnabledByDefault").toBool(); if (checkDefault && !enabledByDefault) { + kDebug(1212) << "Disabled internal effect" << name; delete effect; return false; } - // external second - } else { - kDebug(1212) << "Effect is external" << name; - library = findEffectLibrary(service.data()); - if (!library) { - return false; - } - QString version_symbol = "effect_version_" + name; - void *version_func = library->resolve(version_symbol.toAscii()); - if (version_func == NULL) { - kWarning(1212) << "Effect " << name << " does not provide required API version, ignoring."; - delete library; - return false; - } - typedef int (*t_versionfunc)(); - int version = reinterpret_cast< t_versionfunc >(version_func)(); // call it - // Version must be the same or less, but major must be the same. - // With major 0 minor must match exactly. - if (version > KWIN_EFFECT_API_VERSION - || (version >> 8) != KWIN_EFFECT_API_VERSION_MAJOR - || (KWIN_EFFECT_API_VERSION_MAJOR == 0 && version != KWIN_EFFECT_API_VERSION)) { - kWarning(1212) << "Effect " << name << " requires unsupported API version " << version; - delete library; - return false; - } - - const QString enabledByDefault_symbol = "effect_enabledbydefault_" + name; - void *enabledByDefault_func = library->resolve(enabledByDefault_symbol.toAscii().data()); - - const QString supported_symbol = "effect_supported_" + name; - void *supported_func = library->resolve(supported_symbol.toAscii().data()); - - const QString create_symbol = "effect_create_" + name; - void *create_func = library->resolve(create_symbol.toAscii().data()); - - if (supported_func) { - typedef bool (*t_supportedfunc)(); - t_supportedfunc supported = reinterpret_cast(supported_func); - if (!supported()) { - kWarning(1212) << "EffectsHandler::loadEffect : Effect " << name << " is not supported" ; - library->unload(); - return false; - } - } - - if (checkDefault && enabledByDefault_func) { - typedef bool (*t_enabledByDefaultfunc)(); - t_enabledByDefaultfunc enabledByDefault = reinterpret_cast(enabledByDefault_func); - - if (!enabledByDefault()) { - library->unload(); - return false; - } - } - - if (!create_func) { - kError(1212) << "EffectsHandler::loadEffect : effect_create function not found"; - library->unload(); - return false; - } - - typedef Effect*(*t_createfunc)(); - t_createfunc create = reinterpret_cast(create_func); - - // Make sure all depenedencies have been loaded - // TODO: detect circular deps - KPluginInfo plugininfo(service); - foreach (const QString & depName, plugininfo.dependencies()) { - if (!loadEffect(depName)) { - kError(1212) << "EffectsHandler::loadEffect : Couldn't load dependencies for effect " << name; - library->unload(); - return false; - } - } - - effect = create(); - } - - effect_order.insert(service->property("X-KDE-Ordering").toInt(), EffectPair(name, effect)); - effectsChanged(); - if (effect) { kDebug(1212) << "Internal effect has been loaded" << name; - effect_factories[ name ] = effect; - } else if (library) { - kDebug(1212) << "External effect has been loaded" << name; - effect_libraries[ name ] = library; + + // order does not matter really + loaded_effects.append(EffectPair(name, effect)); + effectsChanged(); + return true; } - return true; + kWarning() << "Invalid effect" << name; + return false; } void EffectsHandlerImpl::unloadEffect(const QString& name) { m_compositor->addRepaintFull(); - for (QMap< int, EffectPair >::iterator it = effect_order.begin(); it != effect_order.end(); ++it) { - if (it.value().first == name) { + QMutableVectorIterator it(loaded_effects); + while (it.hasNext()) { + const EffectPair &effect = it.next(); + if (effect.first == name) { + Effect* effectptr = effect.second; kDebug(1212) << "EffectsHandler::unloadEffect : Unloading Effect : " << name; - if (activeFullScreenEffect() == it.value().second) { + if (activeFullScreenEffect() == effectptr) { setActiveFullScreenEffect(0); } - stopMouseInterception(it.value().second); + stopMouseInterception(effectptr); // remove support properties for the effect const QList properties = m_propertiesForEffects.keys(); foreach (const QByteArray &property, properties) { - removeSupportProperty(property, it.value().second); + removeSupportProperty(property, effectptr); } - delete it.value().second; - effect_order.remove(it.key()); + it.remove(); + delete effectptr; effectsChanged(); - if (effect_factories.contains(name)) { - delete effect_libraries[ name ]; - } else if (effect_libraries.contains(name)) { - effect_libraries[ name ]->unload(); - } return; } } @@ -1492,11 +1403,12 @@ void EffectsHandlerImpl::unloadEffect(const QString& name) void EffectsHandlerImpl::reconfigureEffect(const QString& name) { - for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) - if ((*it).first == name) { - (*it).second->reconfigure(Effect::ReconfigureAll); - return; + foreach (EffectPair &it, loaded_effects) { + if (it.first == name) { + it.second->reconfigure(Effect::ReconfigureAll); + break; } + } } bool EffectsHandlerImpl::isEffectLoaded(const QString& name) const @@ -1511,13 +1423,13 @@ bool EffectsHandlerImpl::isEffectLoaded(const QString& name) const void EffectsHandlerImpl::reloadEffect(Effect *effect) { QString effectName; - for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) { - if ((*it).second == effect) { - effectName = (*it).first; + foreach (const EffectPair &it, loaded_effects) { + if (it.second == effect) { + effectName = it.first; break; } } - if (!effectName.isNull()) { + if (!effectName.isEmpty()) { unloadEffect(effectName); loadEffect(effectName); } @@ -1525,20 +1437,15 @@ void EffectsHandlerImpl::reloadEffect(Effect *effect) void EffectsHandlerImpl::effectsChanged() { - loaded_effects.clear(); - m_activeEffects.clear(); // it's possible to have a reconfigure and a quad rebuild between two paint cycles - bug #308201 -// kDebug(1212) << "Recreating effects' list:"; - foreach (const EffectPair & effect, effect_order) { -// kDebug(1212) << effect.first; - loaded_effects.append(effect); - } + // it's possible to have a reconfigure and a quad rebuild between two paint cycles - bug #308201 + m_activeEffects.clear(); m_activeEffects.reserve(loaded_effects.count()); } QStringList EffectsHandlerImpl::activeEffects() const { QStringList ret; - foreach(const KWin::EffectPair it, loaded_effects) { + foreach (const EffectPair &it, loaded_effects) { if (it.second->isActive()) { ret << it.first; } diff --git a/kwin/effects.h b/kwin/effects.h index 54a6a070..2cfe2b7b 100644 --- a/kwin/effects.h +++ b/kwin/effects.h @@ -231,7 +231,6 @@ protected Q_SLOTS: void slotPropertyNotify(long atom); protected: - QLibrary* findEffectLibrary(KService* service); void effectsChanged(); void setupClientConnections(const KWin::Client *c); void setupUnmanagedConnections(const KWin::Unmanaged *u); @@ -239,7 +238,6 @@ protected: Effect* keyboard_grab_effect; Effect* fullscreen_effect; QList elevated_windows; - QMultiMap< int, EffectPair > effect_order; QHash< long, int > registered_atoms; int next_window_quad_type; diff --git a/kwin/libkwineffects/kwineffects.h b/kwin/libkwineffects/kwineffects.h index 1033a425..e6adce4b 100644 --- a/kwin/libkwineffects/kwineffects.h +++ b/kwin/libkwineffects/kwineffects.h @@ -493,49 +493,6 @@ public Q_SLOTS: virtual bool borderActivated(ElectricBorder border); }; - -/** - * Defines the class to be used for effect with given name. - * The name must be same as effect's X-KDE-PluginInfo-Name values in .desktop - * file, but without the "kwin4_effect_" prefix. - * E.g. KWIN_EFFECT( flames, MyFlameEffect ) - * In this case object of MyFlameEffect class would be created when effect - * "flames" (which has X-KDE-PluginInfo-Name=kwin4_effect_flames in .desktop - * file) is loaded. - **/ -#define KWIN_EFFECT( name, classname ) \ - extern "C" { \ - KWIN_EXPORT Effect* effect_create_kwin4_effect_##name() { return new classname; } \ - KWIN_EXPORT int effect_version_kwin4_effect_##name() { return KWIN_EFFECT_API_VERSION; } \ - } - -/** - * Defines the function used to check whether an effect is supported - * E.g. KWIN_EFFECT_SUPPORTED( flames, MyFlameEffect::supported() ) - **/ -#define KWIN_EFFECT_SUPPORTED( name, function ) \ - extern "C" { \ - KWIN_EXPORT bool effect_supported_kwin4_effect_##name() { return function; } \ - } - -/** - * Defines the function used to check whether an effect should be enabled by default - * - * This function provides a way for an effect to override the default at runtime, - * e.g. based on the capabilities of the hardware. - * - * This function is optional; the effect doesn't have to provide it. - * - * Note that this function is only called if the supported() function returns true, - * and if X-KDE-PluginInfo-EnabledByDefault is set to true in the .desktop file. - * - * Example: KWIN_EFFECT_ENABLEDBYDEFAULT(flames, MyFlameEffect::enabledByDefault()) - **/ -#define KWIN_EFFECT_ENABLEDBYDEFAULT(name, function) \ - extern "C" { \ - KWIN_EXPORT bool effect_enabledbydefault_kwin4_effect_##name() { return function; } \ - } - /** * Defines the function used to retrieve an effect's config widget * E.g. KWIN_EFFECT_CONFIG( flames, MyFlameEffectConfig )