Extending Albert using C++
This page focuses on the practical aspects of extending Albert using C++ and its peculiarities. To get a high level overview of common concepts of the API refer to the general section.
A native plugin is a Qt Plugin, i.e. a shared library providing an instance of the class PluginInstance
.
Albert provides C
and CMake
macros that implement conventions to streamline the plugin development process and to reduce the considerable amount of boilerplate code required to a few lines of code.
CMake
Having a standardized plugin project structure the albert_plugin
macro takes care of most of the CMake boilerplate code. It is part of the albert
CMake module and can be included using find_package(Albert REQUIRED)
. Read its documentation in the header of the CMake module before you proceed.
A minimal working CMakeLists.txt (See also the CMakeLists.txt files of the official plugins):
project(my_plugin VERSION 1.0)
find_package(Albert REQUIRED)
albert_plugin()
This is the standard plugin directory structure of a plugin:
─┬─ my_plugin
├── CMakeLists.txt
├── metadata.json
├─┬─ src
│ └── …
└─┬─ i18n
└── …
A basic metadata file looks like this (See also the metadata.json files of the official plugins):
{
"name": "My Plugin",
"description": "Do useful stuff",
"authors": ["@myname"],
"license": "MIT",
"url": "https://github.com/myusername/my-albert-plugin",
}
C++
Albert plugins ultimately have to inherit the QObject
and PluginInstance
class and contain the ALBERT_PLUGIN
macro in the declaration body.
A basic plugin looks like this (See also the plugin header files of the official plugins):
#pragma once
#include <albert/extensionplugin.h>
#include <albert/triggerqueryhandler.h>
class Plugin : public QObject, public albert::PluginInstance
{
ALBERT_PLUGIN
};
Usually you dont want to subclass PluginInstance
directly but rather ExtensionPlugin
which implements the Extension
interface using the metadata of the plugin instance.
#pragma once
#include <albert/extensionplugin.h>
#include <albert/triggerqueryhandler.h>
class Plugin : public albert::ExtensionPlugin,
public albert::TriggerQueryHandler
{
ALBERT_PLUGIN
void handleTriggerQuery(albert::Query &) override {}
};
From here on it depends on the interface you want to implement. Read through the albert namespace reference. See the official native plugins as a reference. Concise examples to start with are: debug
, timezones
, hash
or urlhandler
.
Plugin directories
The plugin directories depends on the platform and the build type.
- Linux:
~/.local/{lib,lib64}/albert
/usr/local/{lib,lib64}/albert
/usr/lib/${MULTIARCH_TUPLE}/albert
/usr/{lib,lib64}/albert
- macOS:
$BUNDLE_PATH/Contents/PlugIns
~/Library/Application Support/Albert/plugins
The plugin directories are scanned in the order of the above list. On start Albert scans the plugin directories for available plugins. Since identifiers have to be unique, duplicate plugins with the same identifier (project name) are skipped.