Skip to content

Commit a59e8f3

Browse files
committed
FEAT(client): Add support to XDG Desktop Portal GlobalShortcuts
This makes it possible to have global shortcuts on systems running the XDG Desktop Portal service. This is especially relevant on Wayland where we are not able to run a system-wide keylogger to get the global shortcuts triggers. Fixes mumble-voip#5257
1 parent fc4db91 commit a59e8f3

10 files changed

+641
-29
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
Copyright (C) 2022 Aleix Pol Gonzalez <[email protected]>
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library. If not, see <http://www.gnu.org/licenses/>.
17+
18+
Author: Aleix Pol Gonzalez <[email protected]>
19+
-->
20+
21+
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
22+
<!--
23+
org.freedesktop.portal.GlobalShortcut:
24+
@short_description: GlobalShortcut portal backend interface
25+
26+
This portal lets applications create global shortcuts sessions, and
27+
register shortcuts to them. These shortcuts are activated regardless of
28+
the focused state of the application window.
29+
30+
To use this portal, applications have to create a session under which its
31+
actions will be collected. Then shortcuts can be bound (see
32+
org.freedesktop.portal.GlobalShortcuts.Bind), and listed (see
33+
org.freedesktop.portal.GlobalShortcuts.ListShortcuts).
34+
35+
All global shortcuts are bound to a session, and all sessions are bound to
36+
the application that created them.
37+
38+
The #org.freedesktop.portal.GlobalShortcuts::Activated and
39+
#org.freedesktop.portal.GlobalShortcuts::Deactivated signals are emitted,
40+
respecitvely, whenever a shortcut is activated and deactivated.
41+
42+
This documentation describes version 1 of this interface.
43+
-->
44+
<interface name="org.freedesktop.portal.GlobalShortcuts">
45+
<!--
46+
CreateSession:
47+
@options: Vardict with optional further information
48+
@handle: Object path for the #org.freedesktop.portal.Request object representing this call
49+
50+
Creates a global shortcuts session.
51+
52+
Supported keys in the @options vardict include:
53+
<variablelist>
54+
<varlistentry>
55+
<term>handle_token s</term>
56+
<listitem><para>
57+
A string that will be used as the last element of the @handle. Must be a valid
58+
object path element. See the #org.freedesktop.portal.Request documentation for
59+
more information about the @handle.
60+
</para></listitem>
61+
</varlistentry>
62+
<varlistentry>
63+
<term>session_handle_token s</term>
64+
<listitem><para>
65+
A string that will be used as the last element of the session handle. Must be a valid
66+
object path element. See the #org.freedesktop.portal.Session documentation for
67+
more information about the session handle.
68+
</para></listitem>
69+
</varlistentry>
70+
</variablelist>
71+
72+
The following results get returned via the #org.freedesktop.portal.Request::Response signal:
73+
<variablelist>
74+
<varlistentry>
75+
<term>session_handle o</term>
76+
<listitem><para>
77+
The session handle. An object path for the
78+
#org.freedesktop.portal.Session object representing the created
79+
session.
80+
</para></listitem>
81+
</varlistentry>
82+
</variablelist>
83+
-->
84+
<method name="CreateSession">
85+
<arg type="a{sv}" name="options" direction="in"/>
86+
<arg type="o" name="handle" direction="out"/>
87+
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
88+
</method>
89+
90+
<!--
91+
BindShortcuts:
92+
@session_handle: Object path for the #org.freedesktop.impl.portal.Session object representing the session
93+
@shortcuts: The list of shortcuts to bind
94+
@parent_window: Identifier for the application window, see <link linkend="parent_window">Common Conventions</link>
95+
@options: Vardict with optional further information
96+
@request_handle: Object path for the #org.freedesktop.portal.Request object representing this call
97+
98+
Bind the shortcuts. This will typically result the portal presenting a
99+
dialog showing the shortcuts and allowing users to configure the shortcuts.
100+
An application can only attempt bind shortcuts of a session once.
101+
102+
Each element of the @shortcuts array is a tuple composed of a shortcut id,
103+
and a vardict with the following keys:
104+
<variablelist>
105+
<varlistentry>
106+
<term>description s</term>
107+
<listitem><para>
108+
User-readable text describing what the shortcut does.
109+
</para></listitem>
110+
</varlistentry>
111+
<varlistentry>
112+
<term>preferred_trigger s</term>
113+
<listitem><para>
114+
The preferred shortcut trigger, defined as described by the "shortcuts"
115+
XDG specification. Optional.
116+
</para></listitem>
117+
</varlistentry>
118+
</variablelist>
119+
120+
Supported keys in the @options vardict include:
121+
<variablelist>
122+
<varlistentry>
123+
<term>handle_token s</term>
124+
<listitem><para>
125+
A string that will be used as the last element of the
126+
@handle. Must be a valid object path element. See the
127+
#org.freedesktop.portal.Request documentation for more
128+
information about the @handle.
129+
</para></listitem>
130+
</varlistentry>
131+
</variablelist>
132+
133+
The following results get returned via the #org.freedesktop.portal.Request::Response signal:
134+
<variablelist>
135+
<varlistentry>
136+
<term>shortcuts a(sa{sv})</term>
137+
<listitem><para>
138+
A list of shortcuts. The list of keys it may contain is described
139+
below, and is different from the @shortcuts variable of this method.
140+
</para></listitem>
141+
</varlistentry>
142+
</variablelist>
143+
144+
Each element of the @shortcuts array returned by the
145+
#org.freedesktop.portal.Request::Response signal is a tuple composed of
146+
a shortcut id, and a vardict with the following keys:
147+
<variablelist>
148+
<varlistentry>
149+
<term>description s</term>
150+
<listitem><para>
151+
User-readable text describing what the shortcut does.
152+
</para></listitem>
153+
</varlistentry>
154+
<varlistentry>
155+
<term>trigger_description s</term>
156+
<listitem><para>
157+
User-readable text describing how to trigger the shortcut for the
158+
client to render.
159+
</para></listitem>
160+
</varlistentry>
161+
</variablelist>
162+
-->
163+
<method name="BindShortcuts">
164+
<arg type="o" name="session_handle" direction="in"/>
165+
<arg type="a(sa{sv})" name="shortcuts" direction="in"/>
166+
<arg type="s" name="parent_window" direction="in"/>
167+
<arg type="a{sv}" name="options" direction="in"/>
168+
<arg type="o" name="request_handle" direction="out"/>
169+
170+
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QList&lt;QPair&lt;QString,QVariantMap&gt;&gt;"/>
171+
<annotation name="org.qtproject.QtDBus.QtTypeName.In3" value="QVariantMap"/>
172+
</method>
173+
174+
<!--
175+
ListShortcuts:
176+
@session_handle: Object path for the #org.freedesktop.impl.portal.Session object representing the session
177+
@options: Vardict with optional further information
178+
179+
Lists all shortcuts.
180+
181+
Supported keys in the @options vardict include:
182+
<variablelist>
183+
<varlistentry>
184+
<term>handle_token s</term>
185+
<listitem><para>
186+
A string that will be used as the last element of the
187+
@handle. Must be a valid object path element. See the
188+
#org.freedesktop.portal.Request documentation for more
189+
information about the @handle.
190+
</para></listitem>
191+
</varlistentry>
192+
</variablelist>
193+
194+
The following results get returned via the #org.freedesktop.portal.Request::Response signal:
195+
<variablelist>
196+
<varlistentry>
197+
<term>shortcuts a(sa{sv})</term>
198+
<listitem><para>
199+
A list of shortcuts.
200+
201+
See the #org.freedesktop.portal.Request::Response signal of the
202+
org.freedesktop.portal.GlobalShortcuts.BindShortcuts() method for
203+
the list of supported properties of shortcuts.
204+
</para></listitem>
205+
</varlistentry>
206+
</variablelist>
207+
-->
208+
<method name="ListShortcuts">
209+
<arg type="o" name="session_handle" direction="in"/>
210+
<arg type="a{sv}" name="options" direction="in"/>
211+
<arg type="o" name="request_handle" direction="out"/>
212+
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
213+
</method>
214+
215+
<!--
216+
Activated:
217+
@session_handle: Session that requested the shortcut
218+
@shortcut_id: the application-provided ID for the notification
219+
@timestamp: The timestamp, as seconds and microseconds since the Unix epoch.
220+
@options: Vardict with optional further information
221+
222+
Notifies about a shortcut becoming active.
223+
-->
224+
<signal name="Activated">
225+
<arg type="o" name="session_handle" direction="out"/>
226+
<arg type="s" name="shortcut_id" direction="out"/>
227+
<arg type="t" name="timestamp" direction="out"/>
228+
<arg type="a{sv}" name="options" direction="out"/>
229+
<annotation name="org.qtproject.QtDBus.QtTypeName.Out3" value="QVariantMap"/>
230+
</signal>
231+
232+
<!--
233+
Deactivated:
234+
@session_handle: Session that requested the shortcut
235+
@shortcut_id: the application-provided ID for the notification
236+
@timestamp: The timestamp, as seconds and microseconds since the Unix epoch.
237+
@options: Vardict with optional further information
238+
239+
Notifies that a shortcut is not active anymore.
240+
-->
241+
<signal name="Deactivated">
242+
<arg type="o" name="session_handle" direction="out"/>
243+
<arg type="s" name="shortcut_id" direction="out"/>
244+
<arg type="t" name="timestamp" direction="out"/>
245+
<arg type="a{sv}" name="options" direction="out"/>
246+
<annotation name="org.qtproject.QtDBus.QtTypeName.Out3" value="QVariantMap"/>
247+
</signal>
248+
249+
<!--
250+
ShortcutsChanged:
251+
@session_handle: Session that requested the shortcut
252+
@shortcuts: The different shortcuts that have been registered. See org.freedesktop.portal.GlobalShortcuts.
253+
254+
Indicates that the information associated with some of the shortcuts has changed.
255+
256+
See the #org.freedesktop.portal.Request::Response signal of the
257+
org.freedesktop.portal.GlobalShortcuts.BindShortcuts() method for the
258+
list of supported properties of shortcuts.
259+
-->
260+
<signal name="ShortcutsChanged">
261+
<arg type="o" name="session_handle" direction="out"/>
262+
<arg type="a(sa{sv})" name="shortcuts" direction="out"/>
263+
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QList&lt;QPair&lt;QString,QVariantMap&gt;&gt;"/>
264+
</signal>
265+
266+
<property name="version" type="u" access="read"/>
267+
</interface>
268+
</node>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
Copyright (C) 2015 Red Hat, Inc.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library. If not, see <http://www.gnu.org/licenses/>.
17+
18+
Author: Alexander Larsson <[email protected]>
19+
-->
20+
21+
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
22+
<!--
23+
org.freedesktop.portal.Request:
24+
@short_description: Shared request interface
25+
26+
The Request interface is shared by all portal interfaces. When a
27+
portal method is called, the reply includes a handle (i.e. object path)
28+
for a Request object, which will stay alive for the duration of the
29+
user interaction related to the method call.
30+
31+
The portal indicates that a portal request interaction is over by
32+
emitting the #org.freedesktop.portal.Request::Response signal on the
33+
Request object.
34+
35+
The application can abort the interaction calling
36+
org.freedesktop.portal.Request.Close() on the Request object.
37+
38+
Since version 0.9 of xdg-desktop-portal, the handle will be of the form
39+
/org/freedesktop/portal/desktop/request/SENDER/TOKEN,
40+
where SENDER is the callers unique name, with the initial ':' removed and
41+
all '.' replaced by '_', and TOKEN is a unique token that the caller provided
42+
with the handle_token key in the options vardict.
43+
44+
This change was made to let applications subscribe to the Response signal before
45+
making the initial portal call, thereby avoiding a race condition. It is recommended
46+
that the caller should verify that the returned handle is what it expected, and update
47+
its signal subscription if it isn't. This ensures that applications will work with both
48+
old and new versions of xdg-desktop-portal.
49+
50+
The token that the caller provides should be unique and not guessable. To avoid clashes
51+
with calls made from unrelated libraries, it is a good idea to use a per-library prefix
52+
combined with a random number.
53+
-->
54+
<interface name="org.freedesktop.portal.Request">
55+
56+
<!--
57+
Close:
58+
59+
Closes the portal request to which this object refers and ends all
60+
related user interaction (dialogs, etc).
61+
A Response signal will not be emitted in this case.
62+
-->
63+
<method name="Close">
64+
</method>
65+
66+
<!--
67+
Response:
68+
@response: Numeric response
69+
@results: Vardict with results. The keys and values in the vardict depend on the request.
70+
71+
Emitted when the user interaction for a portal request is over.
72+
73+
The @response indicates how the user interaction ended:
74+
<simplelist>
75+
<member>0: Success, the request is carried out</member>
76+
<member>1: The user cancelled the interaction</member>
77+
<member>2: The user interaction was ended in some other way</member>
78+
</simplelist>
79+
-->
80+
<signal name="Response">
81+
<arg type="u" name="response"/>
82+
<arg type="a{sv}" name="results"/>
83+
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/>
84+
</signal>
85+
</interface>
86+
</node>

src/mumble/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,16 @@ if(dbus AND NOT WIN32 AND NOT APPLE)
839839
PRIVATE
840840
"DBus.cpp"
841841
"DBus.h"
842+
"GlobalShortcut_xdp.cpp"
842843
)
843844

845+
qt5_add_dbus_interface(mumble_xdp_SRCS ${CMAKE_SOURCE_DIR}/auxiliary_files/org.freedesktop.portal.GlobalShortcuts.xml globalshortcuts_portal_interface)
846+
qt5_add_dbus_interface(mumble_xdp_SRCS ${CMAKE_SOURCE_DIR}/auxiliary_files/org.freedesktop.portal.Request.xml portalsrequest_interface)
847+
target_sources(mumble_client_object_lib PRIVATE ${mumble_xdp_SRCS})
844848
target_compile_definitions(mumble_client_object_lib PUBLIC "USE_DBUS")
845849
target_link_libraries(mumble_client_object_lib PUBLIC Qt5::DBus)
850+
target_include_directories(mumble_client_object_lib PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
851+
846852
endif()
847853

848854
if(translations)

0 commit comments

Comments
 (0)