Replies: 7 comments 2 replies
-
Thanks for taking the time to write this. There are somethings in here I really really like which I will highlight below. However, I don't think this is generally the correct direction. It feels like if we were to go that far we might as well do a rewrite in python. Stated Goals of plugins (IMO)
Concerns
Things I liked
Other considerations
|
Beta Was this translation helpful? Give feedback.
-
This thread has so far been very enlightening. I learnt few things 🤗 I don't pretend that I've understood everything, but I'm pretty sure I have a solid picture of the proposal and the counter/complementary proposal. The following are few points that I thought I should share my opinion:
Imho, plugins should be shown like other tools, but with some button texture to show that they are plugins. This would also help new users to know that what they see in screenshots are Flameshot tools and which ones are plugins.
I haven't done this before, but based on what I searched, it is fairly easy to do with most languages. That said, I think we should then provide some tangible examples in some popular languages to help people like me get into writing and maintaining plugins. In general imho the idea is good, and Flameshot can really use it to it's advantage. |
Beta Was this translation helpful? Give feedback.
-
If a plugin system gets implemented, I think it should be made very easy for users to add plugins. I think there should be a plugins section where a user can simply enable a plugin instead of having to find plugins on the internet and then downloading them and adding them manually. Perhaps an official plugins repository or something. One-click add plugin. |
Beta Was this translation helpful? Give feedback.
-
The core of a plugin is the plugin manager, whose design determines how a plugin is implemented and the specifications that the plugin should follow! |
Beta Was this translation helpful? Give feedback.
-
@veracioux The first plugin RFC initial implementation will only support the C++ Qt plugin framework, but will leave room for full extensibility. |
Beta Was this translation helpful? Give feedback.
-
PR #3661 |
Beta Was this translation helpful? Give feedback.
-
There are some features which could be useful to a lot of people, but we refused to implement because it is out of the scope of the project. Notably, those issues labeled as
Plugin
. I propose here a plugin system comprising:Project structure changes
libflameshot
, containing basically everything except main.cpp. This requires no major structure changes, just inserting a bunch ofFLAMESHOT_EXPORT
macros and some tweaks to the build process. The library will reside in this repository.libflameshot
.libpyflameshot
C++ library that will serve as a bridge from C++ to python, defining thin wrapper classes that are adapted to match the python API. This library may even prove as unnecessary as we delve deep into the implementation.pyflameshot
that will house the officialflameshot
python package that is the python API used by plugins.plugins
repository that hosts official plugins and/or verified user plugins.NOTE: There is not much to be said about the C++ API besides just exposing it. I think the python API is a promising especially since we can make use of the officially supported Qt bindings and allow plugin creators to extend flameshot even beyond what the flameshot library API by itself can provision for. I explore the python API in the ensuing sections. Please keep in mind that these ideas are just a brief preliminary taste and an actual implementation will be much more convincing (and I've started working on it).
Loading python plugins
We can divide plugins into two groups:
/usr/share/flameshot/vendor-plugins/
or the like$CONFIG_DIRECTORY/plugins/
In each case, a plugin is a python package that resides in one of the aforementioned directories. When flameshot starts, it shall load all plugins from those directories, starting with system plugins first. A plugin is loaded by executing its
__init__.py
file. The rest is taken care of by the plugin itself.Plugins can be configured in a "proprietary" way, i.e. each plugin can use its own configuration format and file located where ever the plugin deems fit.
Alternatively, plugins can take their configuration from the usual
.ini
file, where each plugin gets its config from its own section in the format[plugin.<plugin_name>]
.In order to loosen the coupling, improve the landscape for users who version control their configs, and keep things standard, we can decide to have separate files in the
$CONFIG_DIRECTORY
named as<plugin_name>.ini
. If a plugin uses a different config format, a different suffix would be used. (This is my strategy of choice)Python plugin functionality
High-level commands
All flameshot sub-commands should be available as functions in a pythonic
Flameshot
class. These functions should have positional args and keyword args (mimicking options). If the flameshot instance is a daemon, the sub-commands should be run as part of the current program. Otherwise, we can make it so that a new flameshot instance is run as a subprocess. One use case is to enable periodic auto-screenshots.Custom tools
Define a
Tool
class that plugins can subclass to create their own tools. Tools should have:draw
function that maps the underlying pixmap to the screenshot that is obtained by applying the tool over itCustom final actions
Add an
Action
class that plugin creators can subclass and define their own behavior. For example, this can be used to define custom upload procedures.Events
Key events should be available for python plugins to "hook into". We can implement this using sigslots or even as python decorators.
on_start_capture(pixmap: QPixmap, capture_widget: QWidget)
We can discuss the function arguments, which are not that important since they can be queried from the current context.
on_final_action(actions: Actions, pixmap: QPixmap = None)
Called when the capture has finished. Callbacks receive a list of "final actions" that were performed and can selectively cancel some of those actions. They can also modify the
pixmap
before the actions are executed.on_capture_finished(success: bool)
Called after the final actions have been performed.
Other events like on_click, etc that may or may not be context specific
Context
The plugins should have a context available which they can use to query the current state of affairs. We can even utilize the recent python
ContextVar
class that provides a thread-safe context for global variables.context.py
flameshot
- the current flameshot instance the plugin is loaded intocapture_context
- Mimics the CaptureContext we currently have implemented in C++. Contains information about the original screenshot that is being edited, the active tool, applied tool layers, etc.Notification API and logger
A thin python wrapper around the notification API and AbstractLogger that we have in C++.
Simple bindings to widgets exposed
The config window, flameshot launcher, and other widgets should be available as QWidgets in the python API so that the plugins can modify them at will. This is made possible by the PySide2 API.
Beta Was this translation helpful? Give feedback.
All reactions