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

remote: Add API to allow for persistence on RemoteDesktop sessions #128

Merged
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
54 changes: 51 additions & 3 deletions libportal/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,12 @@ select_devices (CreateCall *call)
g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&options, "{sv}", "handle_token", g_variant_new_string (token));
g_variant_builder_add (&options, "{sv}", "types", g_variant_new_uint32 (call->devices));
if (call->portal->remote_desktop_interface_version >= 2)
{
g_variant_builder_add (&options, "{sv}", "persist_mode", g_variant_new_uint32 (call->persist_mode));
if (call->restore_token)
g_variant_builder_add (&options, "{sv}", "restore_token", g_variant_new_string (call->restore_token));
}
g_dbus_connection_call (call->portal->bus,
PORTAL_BUS_NAME,
PORTAL_OBJECT_PATH,
Expand Down Expand Up @@ -551,6 +557,48 @@ xdp_portal_create_remote_desktop_session (XdpPortal *portal,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer data)
{
xdp_portal_create_remote_desktop_session_full (portal,
devices,
outputs,
flags,
cursor_mode,
XDP_PERSIST_MODE_NONE,
NULL,
cancellable,
callback,
data);
}

/**
* xdp_portal_create_remote_desktop_session_full:
* @portal: a [class@Portal]
* @devices: which kinds of input devices to ofer in the new dialog
* @outputs: which kinds of source to offer in the dialog
* @flags: options for this call
* @cursor_mode: the cursor mode of the session
* @persist_mode: the persist mode of the session
* @restore_token: (nullable): the token of a previous screencast session to restore
* @cancellable: (nullable): optional [[email protected]]
* @callback: (scope async): a callback to call when the request is done
* @data: (closure): data to pass to @callback
*
* Creates a session for remote desktop.
*
* When the request is done, @callback will be called. You can then
* call [[email protected]_remote_desktop_session_finish] to get the results.
*/
void
xdp_portal_create_remote_desktop_session_full (XdpPortal *portal,
XdpDeviceType devices,
XdpOutputType outputs,
XdpRemoteDesktopFlags flags,
XdpCursorMode cursor_mode,
XdpPersistMode persist_mode,
const char *restore_token,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer data)
{
CreateCall *call;

Expand All @@ -563,8 +611,8 @@ xdp_portal_create_remote_desktop_session (XdpPortal *portal,
call->devices = devices;
call->outputs = outputs;
call->cursor_mode = cursor_mode;
call->persist_mode = XDP_PERSIST_MODE_NONE;
call->restore_token = NULL;
call->persist_mode = persist_mode;
call->restore_token = g_strdup (restore_token);
call->multiple = (flags & XDP_REMOTE_DESKTOP_FLAG_MULTIPLE) != 0;
call->task = g_task_new (portal, cancellable, callback, data);

Expand Down Expand Up @@ -1021,7 +1069,7 @@ xdp_session_pointer_motion (XdpSession *session,
*
* Moves the pointer to a new position in the given streams logical
* coordinate space.
*
*
* May only be called on a remote desktop session
* with `XDP_DEVICE_POINTER` access.
*/
Expand Down
13 changes: 13 additions & 0 deletions libportal/remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ void xdp_portal_create_remote_desktop_session (XdpPortal
GAsyncReadyCallback callback,
gpointer data);

XDP_PUBLIC
void xdp_portal_create_remote_desktop_session_full (XdpPortal *portal,
XdpDeviceType devices,
XdpOutputType outputs,
XdpRemoteDesktopFlags flags,
XdpCursorMode cursor_mode,
XdpPersistMode persist_mode,
const char *restore_token,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer data);


XDP_PUBLIC
XdpSession *xdp_portal_create_remote_desktop_session_finish (XdpPortal *portal,
GAsyncResult *result,
Expand Down
105 changes: 95 additions & 10 deletions tests/pyportaltest/test_remotedesktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ def create_session(
flags=Xdp.RemoteDesktopFlags.NONE,
cursor_mode=Xdp.CursorMode.HIDDEN,
start_session=True,
persist_mode=None,
restore_token=None,
) -> SessionSetup:
params = params or {}
# To make the tests easier, load ScreenCast automatically if we have
Expand All @@ -79,16 +81,28 @@ def create_session_done(portal, task, data):
session_error = e
self.mainloop.quit()

xdp.create_remote_desktop_session(
devices=devices,
outputs=outputs,
flags=flags,
cursor_mode=cursor_mode,
cancellable=cancellable,
callback=create_session_done,
data=None,
)

if restore_token is not None and persist_mode is not None:
xdp.create_remote_desktop_session_full(
devices=devices,
outputs=outputs,
flags=flags,
cursor_mode=cursor_mode,
persist_mode=persist_mode,
restore_token=restore_token,
cancellable=cancellable,
callback=create_session_done,
data=None,
)
else:
xdp.create_remote_desktop_session(
devices=devices,
outputs=outputs,
flags=flags,
cursor_mode=cursor_mode,
cancellable=cancellable,
callback=create_session_done,
data=None,
)
self.mainloop.run()
assert create_session_done_invoked
if session_error is not None:
Expand Down Expand Up @@ -166,8 +180,76 @@ def test_create_session(self):
assert list(options.keys()) == [
"handle_token",
"types",
"persist_mode",
]
assert options["types"] == devices
assert options["persist_mode"] == Xdp.PersistMode.NONE

method_calls = self.mock_interface.GetMethodCalls("SelectSources")
assert len(method_calls) == 1
_, args = method_calls.pop(0)
session_handle, options = args

assert list(options.keys()) == [
"handle_token",
"types",
"multiple",
"cursor_mode",
"persist_mode",
]

assert options["types"] == outputs
assert options["multiple"] == flags
assert options["cursor_mode"] == cursor_mode
assert options["persist_mode"] == Xdp.PersistMode.NONE

def test_create_session_restore(self):
"""
Create a session with some "random" values and ensure that they're
passed through to the portal.
"""
devices = Xdp.DeviceType.POINTER | Xdp.DeviceType.KEYBOARD
outputs = Xdp.OutputType.MONITOR | Xdp.OutputType.WINDOW
cursor_mode = Xdp.CursorMode.METADATA
flags = Xdp.RemoteDesktopFlags.MULTIPLE
persist_mode = Xdp.PersistMode.PERSISTENT
restore_token = "12345"

self.create_session(
devices=devices,
outputs=outputs,
flags=flags,
cursor_mode=cursor_mode,
persist_mode=persist_mode,
restore_token=restore_token,
start_session=False,
)

# Now verify our DBus calls were correct
method_calls = self.mock_interface.GetMethodCalls("CreateSession")
assert len(method_calls) == 1
_, args = method_calls.pop(0)
(options,) = args

assert list(options.keys()) == [
"handle_token",
"session_handle_token",
]

method_calls = self.mock_interface.GetMethodCalls("SelectDevices")
assert len(method_calls) == 1
_, args = method_calls.pop(0)
session_handle, options = args

assert list(options.keys()) == [
"handle_token",
"types",
"persist_mode",
"restore_token",
]
assert options["types"] == devices
assert options["persist_mode"] == persist_mode
assert options["restore_token"] == restore_token

method_calls = self.mock_interface.GetMethodCalls("SelectSources")
assert len(method_calls) == 1
Expand All @@ -180,6 +262,7 @@ def test_create_session(self):
"multiple",
"cursor_mode",
"persist_mode",
"restore_token",
]

assert options["types"] == outputs
Expand Down Expand Up @@ -223,8 +306,10 @@ def test_create_session_no_outputs(self):
assert list(options.keys()) == [
"handle_token",
"types",
"persist_mode",
]
assert options["types"] == devices
assert options["persist_mode"] == Xdp.PersistMode.NONE

# No outputs means this should never get called
method_calls = self.mock_interface.GetMethodCalls("SelectSources")
Expand Down