[gnome-shell/gbsneto/access-portal-ignore-focus-window-for-screenshot] accessDialog: Skip focus check for screenshot permissions




commit d6ebf826c03fdb11c7b836d251743bf31eec6238
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sun Aug 7 22:55:37 2022 -0300

    accessDialog: Skip focus check for screenshot permissions
    
    Screenshot is a special case compared to other permissions because
    apps might want to hide themselves from the desktop when a screenshot
    is about to be taken. In that case, this heuristic of checking if
    the focus window corresponds to the application that is requesting
    screenshot permissions becomes problematic.
    
    Special case the screenshot permission to skip the focused window
    check.
    
    See also: https://github.com/flatpak/xdg-desktop-portal/pull/851

 js/ui/accessDialog.js | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)
---
diff --git a/js/ui/accessDialog.js b/js/ui/accessDialog.js
index a162d65016..128ececdbb 100644
--- a/js/ui/accessDialog.js
+++ b/js/ui/accessDialog.js
@@ -131,6 +131,31 @@ var AccessDialogDBus = class {
         Gio.DBus.session.own_name('org.gnome.Shell.Portal', Gio.BusNameOwnerFlags.REPLACE, null, null);
     }
 
+    _isFocusWindow(appId, options) {
+        const IGNORE_FOCUS_CHECK_ALLOWLIST = [
+            {
+                table: 'screenshot',
+                id: 'screenshot',
+            },
+        ];
+
+        if (!appId)
+            return true;
+
+        if (options['permission']) {
+            const [table, id] = options['permission'].deep_unpack();
+            const skipFocusCheck = IGNORE_FOCUS_CHECK_ALLOWLIST.some(
+                permission => permission.table === table && permission.id === id);
+
+            if (skipFocusCheck)
+                return true;
+        }
+
+        // We probably want to use parentWindow and global.display.focus_window
+        // for this check in the future
+        return `${appId}.desktop` === this._windowTracker.focusApp.id;
+    }
+
     AccessDialogAsync(params, invocation) {
         if (this._accessDialog) {
             invocation.return_error_literal(Gio.DBusError,
@@ -140,9 +165,8 @@ var AccessDialogDBus = class {
         }
 
         let [handle, appId, parentWindow_, title, description, body, options] = params;
-        // We probably want to use parentWindow and global.display.focus_window
-        // for this check in the future
-        if (appId && `${appId}.desktop` !== this._windowTracker.focus_app.id) {
+
+        if (!this._isFocusWindow(appId, options)) {
             invocation.return_error_literal(Gio.DBusError,
                                             Gio.DBusError.ACCESS_DENIED,
                                             'Only the focused app is allowed to show a system access 
dialog');


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]