From 93cb931583c0f2397ee533d3c1abcf083c096fc6 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Fri, 24 Jan 2025 15:00:00 +0100 Subject: [PATCH 1/2] tests/py: Unexport request in access portal Needed for testing uninteractive screenshots. This will call the access portal first called and afterwards the screenshot portal with the same request handle. Unexport the request after the access portal is done so the screenshot portal can export a request at the same path afterwards. --- tests/templates/__init__.py | 3 +++ tests/templates/access.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/templates/__init__.py b/tests/templates/__init__.py index 466ee35f7..ba7160c85 100644 --- a/tests/templates/__init__.py +++ b/tests/templates/__init__.py @@ -107,6 +107,9 @@ def export(self, close_callback: Optional[Callable] = None): self._close_callback = close_callback return self + def unexport(self): + self.mock.RemoveObject(self.handle) + def __str__(self): return f"ImplRequest {self.handle}" diff --git a/tests/templates/access.py b/tests/templates/access.py index abb020362..824a103f6 100644 --- a/tests/templates/access.py +++ b/tests/templates/access.py @@ -53,9 +53,10 @@ def closed_callback(): logger.debug(f"AccessDialog Close() response {response}") cb_success(response.response, response.results) - def reply_callback(): + def reply_callback(request): response = Response(self.response, {}) logger.debug(f"AccessDialog with response {response}") + request.unexport() cb_success(response.response, response.results) request = ImplRequest(self, BUS_NAME, handle) @@ -65,7 +66,7 @@ def reply_callback(): request.export() logger.debug(f"scheduling delay of {self.delay}") - GLib.timeout_add(self.delay, reply_callback) + GLib.timeout_add(self.delay, reply_callback, request) except Exception as e: logger.critical(e) cb_error(e) From ce66423eba9381371fec3e9f509fe885345bf351 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Thu, 23 Jan 2025 09:52:54 +0100 Subject: [PATCH 2/2] screenshot: Forward to modality to access dialog --- src/screenshot.c | 6 ++++++ tests/test_screenshot.py | 17 +++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/screenshot.c b/src/screenshot.c index ffb48fc63..40d092e21 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -204,6 +204,7 @@ handle_screenshot_in_thread_func (GTask *task, GVariant *options; gboolean permission_store_checked = FALSE; gboolean interactive; + gboolean modal; const char *parent_window; const char *app_id; @@ -221,6 +222,9 @@ handle_screenshot_in_thread_func (GTask *task, if (!g_variant_lookup (options, "interactive", "b", &interactive)) interactive = FALSE; + if (!g_variant_lookup (options, "modal", "b", &modal)) + modal = TRUE; + if (!interactive && permission != XDP_PERMISSION_YES) { g_autoptr(GVariant) access_results = NULL; @@ -243,6 +247,8 @@ handle_screenshot_in_thread_func (GTask *task, "grant_label", g_variant_new_string (_("Allow"))); g_variant_builder_add (&access_opt_builder, "{sv}", "icon", g_variant_new_string ("applets-screenshooter-symbolic")); + g_variant_builder_add (&access_opt_builder, "{sv}", + "modal", g_variant_new_boolean (modal)); if (g_strcmp0 (app_id, "") != 0) { diff --git a/tests/test_screenshot.py b/tests/test_screenshot.py index a9dd78318..d0b2999be 100644 --- a/tests/test_screenshot.py +++ b/tests/test_screenshot.py @@ -21,6 +21,7 @@ @pytest.fixture def required_templates(): return { + "access": {}, "screenshot": { "results": SCREENSHOT_DATA, }, @@ -31,13 +32,12 @@ class TestScreenshot: def test_version(self, portals, dbus_con): xdp.check_version(dbus_con, "Screenshot", 2) - def test_screenshot_basic(self, portals, dbus_con, app_id): + @pytest.mark.parametrize("modal", [True, False]) + @pytest.mark.parametrize("interactive", [True, False]) + def test_screenshot_basic(self, portals, dbus_con, app_id, modal, interactive): screenshot_intf = xdp.get_portal_iface(dbus_con, "Screenshot") mock_intf = xdp.get_mock_iface(dbus_con) - modal = True - interactive = True - request = xdp.Request(dbus_con, screenshot_intf) options = { "modal": modal, @@ -62,6 +62,15 @@ def test_screenshot_basic(self, portals, dbus_con, app_id): assert args[3]["modal"] == modal assert args[3]["interactive"] == interactive + # check that args were forwarded to access portal correctly + if not interactive: + method_calls = mock_intf.GetMethodCalls("AccessDialog") + assert len(method_calls) > 0 + _, args = method_calls[-1] + assert args[1] == app_id + assert args[2] == "" # parent window + assert args[6]["modal"] == modal + @pytest.mark.parametrize( "template_params", ({"screenshot": {"expect-close": True}},) )