Jump to content

Krita/PluginMechanics

From KDE Community Wiki

Mechanics of how plugin loading happens in Krita

Loading plugins is one of the more annoying parts of a build since it is very finicky. Here is a list of instructions explaining the chain of communication that needs to happen for a successful load.


We will consider rotateimage.cc, since the KisViewPlugins can be finicky. We will explain what needs to happen to ensure the ViewManager m_view is non-zero.

The ViewManager plugins are supposed to be loaded in around line 350 in KisMainWindow:

KoPluginLoader::instance()->load("Krita/ViewPlugin", "Type == 'Service' and ([X-Krita-Version] == 28)", KoPluginLoader::PluginsConfig(), viewManager());

The PluginLoader will run a search for .so or .dll plugin files with embedded JSON, which should be embedded in the build step. The last argument, viewManager(), is what will eventually be m_view in KisViewPlugin. Make sure it is nonzero. viewManager() becomes the argument "owner" in the KoPluginLoader::load(), which will be passed in the factory->create() method in KoPluginLoader, around line 127. That is passed as parent to the constructor for a plugin like rotateimage.cc around line 43. That is passed to the base class constructor KisViewPlugin, with the name parent as well, line 28. At that point, the Q_ASSERT should slam on the brakes if something went wrong.


Q: I have noticed that owner is not given as a parameter when calling the load function on some components, and the plugin gets deleted.

A: That should be OK too. The plugin might do something like, add a bunch of brushes to the registry, then quit, so it's OK to delete it when it's finished. These KisViewPlugins are things that live in the main menu though, they are long lived., so you definitely don't want to be getting to line 134 with any of the KisViewPlugins.


Q: What about the order the plugins are loaded? Is multithreading a concern?

A: It should not matter. The plugins themselves are intended to be self-contained, the two arguments (one QObject and one QVariantList) are intended to be the only necessary communication between the plugin and the rest of the program. I believe there are other safeguards.