Flameshot developer docs#
Thank you for your interest in developing flameshot. This developer documentation (hopefully) has an intuitive structure. It tries to describe what code is run when a user performs an action in Flameshot.
**Please read this entire page. It will make your life a whole lot easier when contributing to Flameshot. If you know exactly what you want to work on, you should look at FAQ **
Flameshot is built on C++/Qt5 with CMake as its build system. The source code is
src/. The entrypoint is
Flameshot provides both a GUI and a CLI (the latter currently works only on Linux and macOS).
The main cmake file is
CMakeLists.txt in the project root. It
files from the
cmake/ directory as well. These files together control some
more general aspects of the build process, like project information, packaging,
There is also the file
src/CMakeLists.txt. It mostly defines how the source
files are compiled into targets and how the external libraries are linked. It
does some other stuff too. Currently, there isn't a clear separation of concerns
src/CMakeLists.txt. In the future we should
refactor these files to make it more clear why each of them exists.
What happens when I launch flameshot?#
There are two ways to launch flameshot: daemon mode and single-action mode. In
both modes, an instance of
Flameshot is created via
Flameshot provides the
high level API for interacting with flameshot; and its methods mimic the CLI
subcommands a great deal. This object is a singleton, so it can only be created
once. It is accessed as
On Windows, only daemon mode is currently supported.
Single-action mode (via command line interface)#
Single-action mode (also called one-off mode) is triggered when flameshot is
launched with a command line argument - for example as
flameshot gui. As its
name implies, it performs a single action, such as "take a screenshot
interactively by opening a GUI" or "take a screenshot of the entire screen",
etc. Afterwards, Flameshot quits.
This mode is triggered when the
flameshot command is launched. In this mode, a
flameshot process is started in the background. A system tray is displayed if
the user hasn't disabled it in the config. In addition to
if the current process is the daemon, it also calls
The daemon has the following purposes:
Run in the background, wait for the user to press a hotkey, and perform corresponding action.
This is true for Windows and macOS, but not for Linux. On Linux, hotkeys are meant to be handled by the desktop environment or equivalent.
Provide a system tray that the user can click to initiate actions via context menu
Periodically check for updates and notify the user
Act as a host for persistent phenomena. Example: On X11 (linux), when a program inserts content into the clipboard, it must keep running so the content persists in the clipboard.
All of the above are user-configurable.
FlameshotDaemon handles all communication with
the daemon. The class provides public static methods that are designed so that
the caller does not need to know if the current process is a flameshot daemon or
a single-action invocation of Flameshot. If the current process is the daemon,
then the static methods of
FlameshotDaemon will call the
corresponding instance methods of the singleton. If not, the current process
will communicate with the daemon process via D-Bus. Then, within the daemon
process, those D-Bus calls will be translated into
FlameshotDaemon instance method calls.
The configuration is handled by
ConfigHandler. It is
decoupled from any user interface, so it serves the configuration for both the
GUI and CLI. All configuration settings recognized by the config files are
defined as getters in this class. There are also setters for each setting, named
as per the usual convention. For example, the setting
savePath has a getter
savePath and a setter named
setSavePath. Before working on a new
config setting for flameshot, please read this FAQ
ConfigHandleris based on
- The configuration uses the
- The configuration is automatically reloaded when the config file changes
- Always use
SLOT(slot()). This usually provides better code introspection and makes refactoring easier and less error-prone.