Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a global shortcut portal #711

Merged
merged 1 commit into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile.am.inc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ PORTAL_IFACE_FILES =\
$(top_srcdir)/data/org.freedesktop.portal.FileChooser.xml \
$(top_srcdir)/data/org.freedesktop.portal.FileTransfer.xml \
$(top_srcdir)/data/org.freedesktop.portal.GameMode.xml \
$(top_srcdir)/data/org.freedesktop.portal.GlobalShortcuts.xml \
$(top_srcdir)/data/org.freedesktop.portal.Inhibit.xml \
$(top_srcdir)/data/org.freedesktop.portal.Location.xml \
$(top_srcdir)/data/org.freedesktop.portal.MemoryMonitor.xml \
Expand Down Expand Up @@ -38,6 +39,7 @@ PORTAL_IMPL_IFACE_FILES =\
$(top_srcdir)/data/org.freedesktop.impl.portal.DynamicLauncher.xml \
$(top_srcdir)/data/org.freedesktop.impl.portal.Email.xml \
$(top_srcdir)/data/org.freedesktop.impl.portal.FileChooser.xml \
$(top_srcdir)/data/org.freedesktop.impl.portal.GlobalShortcuts.xml \
$(top_srcdir)/data/org.freedesktop.impl.portal.Inhibit.xml \
$(top_srcdir)/data/org.freedesktop.impl.portal.Lockdown.xml \
$(top_srcdir)/data/org.freedesktop.impl.portal.Notification.xml \
Expand Down
4 changes: 3 additions & 1 deletion data/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ portal_sources = files(
'org.freedesktop.portal.FileChooser.xml',
'org.freedesktop.portal.FileTransfer.xml',
'org.freedesktop.portal.GameMode.xml',
'org.freedesktop.portal.GlobalShortcuts.xml',
'org.freedesktop.portal.Inhibit.xml',
'org.freedesktop.portal.Location.xml',
'org.freedesktop.portal.MemoryMonitor.xml',
Expand Down Expand Up @@ -41,6 +42,7 @@ portal_impl_sources = files(
'org.freedesktop.impl.portal.DynamicLauncher.xml',
'org.freedesktop.impl.portal.Email.xml',
'org.freedesktop.impl.portal.FileChooser.xml',
'org.freedesktop.impl.portal.GlobalShortcuts.xml',
'org.freedesktop.impl.portal.Inhibit.xml',
'org.freedesktop.impl.portal.Lockdown.xml',
'org.freedesktop.impl.portal.Notification.xml',
Expand All @@ -58,4 +60,4 @@ portal_impl_sources = files(

install_data([portal_sources, portal_impl_sources],
install_dir: datadir / 'dbus-1' / 'interfaces',
)
)
168 changes: 168 additions & 0 deletions data/org.freedesktop.impl.portal.GlobalShortcuts.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<?xml version="1.0"?>
<!--
Copyright (C) 2022 Aleix Pol Gonzalez <[email protected]>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.

Author: Aleix Pol Gonzalez <[email protected]>
-->

<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<!--
org.freedesktop.impl.portal.GlobalShortcut:
@short_description: GlobalShortcut portal backend interface

This portal lets applications register global shortcuts so they can
act regardless of the system state upon an input event.
-->
<interface name="org.freedesktop.impl.portal.GlobalShortcuts">
<!--
CreateSession:
@handle: Object path for the #org.freedesktop.impl.portal.Request object representing this call
@session_handle: Object path for the #org.freedesktop.impl.portal.Session object representing the session being created
@app_id: App id of the application
@options: Vardict with optional further information. See @org.freedesktop.portal.GlobalShortcuts.CreateSession
@response: Numeric Request response
@results: Vardict with the results of the call

Create a global shortcuts session.

The following results get returned via the #org.freedesktop.portal.Request::Response signal:
<variablelist>
<varlistentry>
<term>shortcuts a(sa{sv})</term>
<listitem><para>
The different shortcut ids that the app needs. For those that had already been bound on previous runs, they are mapped to user-readable descriptions of the trigger. This can be used by the app to describe the shortcut to the user.

By default these shortcuts are not bound. To bind them, BindShortcuts needs to be called for the portal
to assign a trigger to a shortcut.

They are mapped to a list of pairs including:
- description: User-readable text describing what the shortcut does
- shortcut: A string that contains a suggestion of a default shortcut, defined as described in the "shortcuts" xdg-spec.
</para></listitem>
aleixpol marked this conversation as resolved.
Show resolved Hide resolved
</varlistentry>
</variablelist>
-->
<method name="CreateSession">
<arg type="o" name="handle" direction="in"/>
<arg type="o" name="session_handle" direction="in"/>
<arg type="s" name="app_id" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In3" value="QVariantMap"/>
<arg type="u" name="response" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/>
<arg type="a{sv}" name="results" direction="out"/>
</method>

<!--
ListShortcuts:
@handle: Object path for the #org.freedesktop.impl.portal.Request object representing this call
@session_handle: Object path for the #org.freedesktop.impl.portal.Session object representing the session
@results: Vardict with the results of the call

List the shortcuts registered in the @p handle session.

The following results get returned via the #org.freedesktop.portal.Request::Response signal:
<variablelist>
<varlistentry>
<term>shortcuts a(sa{sv})</term>
<listitem><para>
The registered shortcut ids mapped to a list of pairs including:
- description: User-readable text describing what the shortcut does
- trigger: User-readable text describing how to trigger the shortcut
</para></listitem>
aleixpol marked this conversation as resolved.
Show resolved Hide resolved
</varlistentry>
</variablelist>
-->
<method name="ListShortcuts">
<arg type="o" name="handle" direction="in"/>
<arg type="o" name="session_handle" direction="in"/>
<arg type="a{sv}" name="results" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
</method>

<!--
BindShortcuts:
@handle: Object path for the #org.freedesktop.impl.portal.Request object representing this call
@session_handle: Object path for the #org.freedesktop.impl.portal.Session object representing the session
@parent_window: Identifier for the application window, see <link linkend="parent_window">Common Conventions</link>
@shortcuts: The identifier of the shortcuts we intend to register, empty for all shortcuts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if one tries to bind shortcuts not part of the CreateSession call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should error out. I am not sure how this is generally communicated, do you know what would be a good example?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not allowed to bind shortcuts that wasn't specified in CreateSession the documentation should specify that it'll fail. I guess it will via the response signal.

How would an application that doesn't know its wanted global shortcuts immediately add new ones? Does it have to have one session per added binding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can close the session and start a new one with the previous + the added one. This is how I imagined it at least.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Re-creating the session is racy; if one triggers a binding right at the time the app decides to recreate the session, it can be lost. Maybe not a big deal since it's very unlikely to happen very often. Then again, could just as well be one session per binding couldn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-creating the session is racy; if one triggers a binding right at the time the app decides to recreate the session, it can be lost. Maybe not a big deal since it's very unlikely to happen very often.

Correct. It shouldn't happen though during general runtime of the app.

Then again, could just as well be one session per binding couldn't it?

Yes.

@results: Vardict with the results of the call

Shows a dialog with all shortcuts to configure and offers them back to the app when done.

The results get returned via the #org.freedesktop.portal.Request::Response signal. See ListShortcuts results format.
-->
<method name="BindShortcuts">
<arg type="o" name="handle" direction="in"/>
<arg type="o" name="session_handle" direction="in"/>
<arg type="as" name="shortcuts" direction="in"/>
<arg type="s" name="parent_window" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
GeorgesStavracas marked this conversation as resolved.
Show resolved Hide resolved
<arg type="a{sv}" name="results" direction="out"/>
aleixpol marked this conversation as resolved.
Show resolved Hide resolved
<annotation name="org.qtproject.QtDBus.QtTypeName.In4" value="QVariantMap"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
</method>

<!--
Activated:
Notifies about a shortcut becoming active.

@session_handle: Session that requested the shortcut
@shortcut_id: the application-provided ID for the notification
@timestamp: The timestamp, as seconds and microseconds since the Unix epoch.
@options: unused
-->
<signal name="Activated">
<arg type="o" name="session_handle" direction="in"/>
<arg type="s" name="shortcut_id" direction="in"/>
<arg type="t" name="timestamp" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In4" value="QVariantMap"/>
</signal>

<!--
Deactivated:
Notifies that a shortcut is not active anymore.

@session_handle: Session that requested the shortcut
@shortcut_id: the application-provided ID for the notification
@timestamp: The timestamp, as seconds and microseconds since the Unix epoch.
@options: unused
-->
<signal name="Deactivated">
<arg type="o" name="session_handle" direction="in"/>
<arg type="s" name="shortcut_id" direction="in"/>
<arg type="t" name="timestamp" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In4" value="QVariantMap"/>
</signal>
aleixpol marked this conversation as resolved.
Show resolved Hide resolved

<!--
ShortcutsChanged:
@session_handle: Session that requested the shortcut
@shortcuts: The different shortcut ids that have been registered. They are mapped to a list of pairs including:
- description: User-readable text describing what the shortcut does
- trigger: User-readable text describing how to trigger the shortcut
-->
<signal name="ShortcutsChanged">
<arg type="o" name="session_handle" direction="out"/>
<arg type="a(sa{sv})" name="shortcuts" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QMap&lt;QString,QVariantMap&gt;"/>
</signal>

<property name="version" type="u" access="read"/>
</interface>
</node>
Loading