Discussion:
DBus service for screenshots.
Emmanuele Bassi
2015-09-24 23:03:33 UTC
Permalink
Hi;

you also want to use xdg-list, not dbus-list, for discussing a shared
DBus interface.

Ciao,
Emmanuele.
Hi;
Hi,
In December we'll be releasing a new screenshot app for KDE. We've
implemented a generic DBus interface for this app, and I'm posting
this to the dbus mailing list as others may be interested in this idea
and may want to implement it in their own desktop environments.
The service we've implemented is called org.freedesktop.Screenshot
(we're using the freedesktop namespace because we truly want the
service to be DE or platform agnostic).
Commendable spirit, but that's not how it works — we've been bitten by
this in the past already. Please, use org.kde.* for your DBus
interfaces, and *then* propose a org.freedesktop.* interface up for
discussion. Otherwise you'll have to start versioning your own methods
because any shared interface will likely not map to what you expose
right now.
Implementing multiple interfaces is easy; breaking them because you
proposed them for discussion *after* release is going to be painful
for everybody.
The XML definition of the
https://raw.githubusercontent.com/KDE/spectacle/master/dbus/org.freedesktop.Screenshot.xml
You'll notice that we define 4 different types of screenshots that can
be taken, and a StartAgent method. The StartAgent method should just
start the application GUI, the other 4 methods should take the
appropriate shot, save the image in a default location, and quit.
StartAgent would show the UI? Why? That can be done with a simple hot
key, or via DBus activation of a service, instead of asking a service
to spawn another service. For instance, if I want to show a dialog to
save the screenshot I just took, the gnome-screenshot tool is what I
applications like GIMP (or Krita) may ask the compositor to take a
screenshot; this means that the UI is already running, and it most
definitely is not something that should be spawned by the compositor
itself in reply to a DBus method call. If you want to keep the
StartAgent method then it's probably good to ensure in the
documentation that the method is not mandatory.
The API is also missing the ability to take a screenshot of an area.
https://git.gnome.org/browse/gnome-shell/tree/data/org.gnome.Shell.Screenshot.xml
GNOME Shell also has an equivalent screencast API, which may be
interesting to standardise alongside the screenshot one.
Ciao,
Emmanuele.
--
https://www.bassi.io
--
https://www.bassi.io
[@] ebassi [@gmail.com]
Boudhayan Gupta
2015-09-25 15:09:00 UTC
Permalink
Hi,

I'm moving this discussion over to the xdg mailing list, as per
suggestions from the dbus list.
Hi;
Hi,
In December we'll be releasing a new screenshot app for KDE. We've
implemented a generic DBus interface for this app, and I'm posting
this to the dbus mailing list as others may be interested in this idea
and may want to implement it in their own desktop environments.
The service we've implemented is called org.freedesktop.Screenshot
(we're using the freedesktop namespace because we truly want the
service to be DE or platform agnostic).
Commendable spirit, but that's not how it works — we've been bitten by
this in the past already. Please, use org.kde.* for your DBus
interfaces, and *then* propose a org.freedesktop.* interface up for
discussion. Otherwise you'll have to start versioning your own methods
because any shared interface will likely not map to what you expose
right now.
I'm going to move this over to the org.kde.* namespace for now until
we can all agree on something for a freedesktop API.

We haven't had any releases yet, so thankfully no damage was done.
Implementing multiple interfaces is easy; breaking them because you
proposed them for discussion *after* release is going to be painful
for everybody.
The XML definition of the
https://raw.githubusercontent.com/KDE/spectacle/master/dbus/org.freedesktop.Screenshot.xml
You'll notice that we define 4 different types of screenshots that can
be taken, and a StartAgent method. The StartAgent method should just
start the application GUI, the other 4 methods should take the
appropriate shot, save the image in a default location, and quit.
StartAgent would show the UI? Why? That can be done with a simple hot
key, or via DBus activation of a service, instead of asking a service
to spawn another service. For instance, if I want to show a dialog to
save the screenshot I just took, the gnome-screenshot tool is what I
applications like GIMP (or Krita) may ask the compositor to take a
screenshot; this means that the UI is already running, and it most
definitely is not something that should be spawned by the compositor
itself in reply to a DBus method call. If you want to keep the
StartAgent method then it's probably good to ensure in the
documentation that the method is not mandatory.
The use-case for StartAgent is simple - what if a supervisor (such as
the compositor on Wayland) is providing the service, but a separate
application (agent) provides manipulation, editing, saving etc.
functionality?
The API is also missing the ability to take a screenshot of an area.
https://git.gnome.org/browse/gnome-shell/tree/data/org.gnome.Shell.Screenshot.xml
KWin also provides its own D-Bus interface (org.kde.kwin.Screenshot -
an XML definition is unavailable), which is tailored to a compositor's
use-case, is similar to the Gnome Shell interface, and does provide a
method to capture regions.
GNOME Shell also has an equivalent screencast API, which may be
interesting to standardise alongside the screenshot one.
I agree, it would be interesting and perhaps quite beneficial if we
can standardise a screenshot (and perhaps also a screencast) interface
at the compositor level over D-Bus that we can all use. Let's have
some more discussions and throw ideas around in the xdg list?

-- Boudhayan
Jasper St. Pierre
2015-09-25 16:00:56 UTC
Permalink
On Fri, Sep 25, 2015 at 8:09 AM, Boudhayan Gupta <***@kde.org> wrote:
... snip ...
Post by Boudhayan Gupta
The use-case for StartAgent is simple - what if a supervisor (such as
the compositor on Wayland) is providing the service, but a separate
application (agent) provides manipulation, editing, saving etc.
functionality?
So what's the expected flow here? You don't have any way of providing
a filename to the Agent for further manipulation and publishing. Is
the Agent expected to show all recently taken thumbnails in a grid or
similar, and have the user select them? What's the expectation here?

Your proposed protocol also has a race condition -- if I call one of
the Screenshot methods twice in succession, it's impossible to know
which call maps to which signal. Please use a standard out parameter
for this.

Does the chosen filename have any pattern to it?

Your API also doesn't document if the screenshot will include padding
and a border for window-specific screenshots, or if it will simply
contain the window itself.

What image format will the screenshot be in? Probably one of PNG or
JPEG, but is there any guarantee on that?

I think we should also make some guarantees about where the file is
roughly expected to be placed, like to say it's placed in
$XDG_PICTURES_DIR.
--
Jasper
Boudhayan Gupta
2015-09-25 16:37:29 UTC
Permalink
Post by Jasper St. Pierre
So what's the expected flow here? You don't have any way of providing
a filename to the Agent for further manipulation and publishing. Is
the Agent expected to show all recently taken thumbnails in a grid or
similar, and have the user select them? What's the expectation here?
I think we're having a bit of a misunderstanding here. The interface
that I've proposed here is simply for activation purposes. It's not a
comprehensive communication protocol between the compositor and the
screenshooting agent.

I'll explain with an use-case. In KDE, a component called KHotkeys
(which is a daemon in its own right in X11 and a component (shared
library inside) of KWin in Wayland, manages global hotkeys. KHotkeys
is configured to invoke KSnapshot when the PrintScreen key is pressed.

Now that we've retired KSnapshot and are replacing it with a new tool,
we thought we could improve on invokation by not hardcoding a single
command (in KHotkeys or in a config file), but use D-Bus activation to
fire up the application implementing the org.freedesktop.Screenshot
service.

This is why the interface is like what it is - the methods FullScreen,
CurrentScreen, ActiveWindow and WindowUnderCursor simply fire up the
agent, instruct them to take the respective type of screenshot in the
background, and then exit the agent. The StartAgent method starts the
agent, but instead of doing anything in the background, pulls up the
UI.

If the interface is being provided by a compositor instead of directly
by an agent, the compositor isn't activated/deactivated, but the four
methods still take screenshots and save them with some default
filename without showing any UI (a notification may be shown, but how
to do that is at the discretion of the compositor/agent). In this
case, however, the StartAgent function pulls up an UI, which may be a
trusted app or simply some component integrated into the compositor.

It's an (admittedly elaborate) way of mapping keyboard shortcuts to
DBus methods and not commands. That way, swapping out screenshot tools
does not require re-mapping hotkeys in the DE.

The interface does not allow you to specify filenames or advanced
options by design - the filename is returned by the ScreenshotTaken
signal.

Once the agent has started, it is entirely at the agent's discretion
on how to obtain an image, which it may do by invoking the X11 APIs
directly, or using the compositor's DBus APIs (such as
org.kde.kwin.Screenshot or org.gnome.Shell.Screenshot).

Yours,
Boudhayan Gupta
Simon McVittie
2015-09-25 17:20:08 UTC
Permalink
Post by Boudhayan Gupta
Now that we've retired KSnapshot and are replacing it with a new tool,
we thought we could improve on invokation by not hardcoding a single
command (in KHotkeys or in a config file), but use D-Bus activation to
fire up the application implementing the org.freedesktop.Screenshot
service.
"The" application?

Using D-Bus service activation for an implementation-neutral name is
problematic. Consider a machine shared between Gordon and Kate, who
prefer GNOME and KDE respectively; as a result, it has both desktop
environments installed. Kate logs in and takes a screenshot, but the
desktop environment does not have an org.freedesktop.Screenshot
implementation already running, and is relying on service activation.
How do you arrange for dbus-daemon to launch the KDE screenshot tool,
and not the GNOME screenshot tool?

In traditional D-Bus, it is technically possible for
/usr/share/dbus-1/services to contain .service files for both the GNOME
and KDE implementations; however, there is no concept of priority, so
dbus-daemon will pick one essentially at random (I think it's either the
first or last in readdir() order).

This is why we recommend that the implementation of the activatable
service com.example.foobar is always a file named exactly
com.example.foobar.service - that way, package managers won't allow a
conflict to exist (or if you're installing from source or your package
manager is awful, you get "last one installed wins" semantics, which are
not ideal but are at least deterministic). Unfortunately, we cannot
*require* that, for backwards compatibility with services that give
their .service files some other name.

In kdbus, which is a little less concerned about backwards
compatibility, I believe the plan is for the conflicting situation to be
considered an error.

This is solvable, for instance by desktop environments arranging to put
a symlink to your preferred implementation in
~/.local/share/dbus-1/services (which is higher priority in the search
path than /usr/share); however, you do have to go to some effort to
solve it.
--
Simon McVittie
Collabora Ltd. <http://www.collabora.com/>
Loading...