Blame SOURCES/0002-introspect-Add-GetWindows-method.patch

c7fac9
From 13afa15130a50aab36e7a61dea5f6d595cd978a1 Mon Sep 17 00:00:00 2001
c7fac9
From: Olivier Fourdan <ofourdan@redhat.com>
c7fac9
Date: Wed, 12 Dec 2018 16:02:29 +0100
c7fac9
Subject: [PATCH 2/2] introspect: Add GetWindows method
c7fac9
c7fac9
The `GetWindows` method gives access to the list of windows for each
c7fac9
application with some of their properties, so utilities such as dogtail
c7fac9
can pick the window of their choice to interfere with using the provided
c7fac9
window id.
c7fac9
c7fac9
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/326
c7fac9
(cherry picked from commit 0f45b438e2b956d3cf52622db875dedab45e49b9)
c7fac9
---
c7fac9
 data/org.gnome.Shell.Introspect.xml | 24 ++++++++++++
c7fac9
 js/misc/introspect.js               | 58 +++++++++++++++++++++++++++++
c7fac9
 2 files changed, 82 insertions(+)
c7fac9
c7fac9
diff --git a/data/org.gnome.Shell.Introspect.xml b/data/org.gnome.Shell.Introspect.xml
c7fac9
index 10c48d635..9508681af 100644
c7fac9
--- a/data/org.gnome.Shell.Introspect.xml
c7fac9
+++ b/data/org.gnome.Shell.Introspect.xml
c7fac9
@@ -33,5 +33,29 @@
c7fac9
     <method name="GetRunningApplications">
c7fac9
       <arg name="apps" direction="out" type="a{sa{sv}}" />
c7fac9
     </method>
c7fac9
+
c7fac9
+    
c7fac9
+        GetWindows:
c7fac9
+        @short_description: Retrieves the current list of windows and their properties
c7fac9
+
c7fac9
+        A window is exposed as:
c7fac9
+        * t ID: unique ID of the window
c7fac9
+        * a{sv} properties: high-level properties
c7fac9
+
c7fac9
+          Known properties:
c7fac9
+
c7fac9
+          - "title"       (s): (readonly) title of the window
c7fac9
+          - "app-id"      (s): (readonly) application ID of the window
c7fac9
+          - "wm-class"    (s): (readonly) class of the window
c7fac9
+          - "client-type" (u): (readonly) 0 for Wayland, 1 for X11
c7fac9
+          - "is-hidden"   (b): (readonly) if the window is currently hidden
c7fac9
+          - "has-focus"   (b): (readonly) if the window currently have
c7fac9
+                                          keyboard focus
c7fac9
+          - "width"       (u): (readonly) width of the window
c7fac9
+          - "height"      (u): (readonly) height of the window
c7fac9
+    -->
c7fac9
+    <method name="GetWindows">
c7fac9
+      <arg name="windows" direction="out" type="a{ta{sv}}" />
c7fac9
+    </method>
c7fac9
   </interface>
c7fac9
 </node>
c7fac9
diff --git a/js/misc/introspect.js b/js/misc/introspect.js
c7fac9
index 05ef9e637..5999fc1f0 100644
c7fac9
--- a/js/misc/introspect.js
c7fac9
+++ b/js/misc/introspect.js
c7fac9
@@ -14,6 +14,9 @@ const IntrospectDBusIface = '<node> \
c7fac9
     <method name="GetRunningApplications"> \
c7fac9
       <arg name="apps" direction="out" type="a{sa{sv}}" /> \
c7fac9
     </method> \
c7fac9
+    <method name="GetWindows"> \
c7fac9
+      <arg name="windows" direction="out" type="a{ta{sv}}" /> \
c7fac9
+    </method> \
c7fac9
   </interface> \
c7fac9
 </node>';
c7fac9
 
c7fac9
@@ -102,6 +105,17 @@ var IntrospectService = new Lang.Class({
c7fac9
         this._activeApplicationDirty = false;
c7fac9
     },
c7fac9
 
c7fac9
+    _isEligibleWindow(window) {
c7fac9
+        if (window.is_override_redirect())
c7fac9
+            return false;
c7fac9
+
c7fac9
+        let type = window.get_window_type();
c7fac9
+        return (type == Meta.WindowType.NORMAL ||
c7fac9
+                type == Meta.WindowType.DIALOG ||
c7fac9
+                type == Meta.WindowType.MODAL_DIALOG ||
c7fac9
+                type == Meta.WindowType.UTILITY);
c7fac9
+    },
c7fac9
+
c7fac9
     GetRunningApplicationsAsync(params, invocation) {
c7fac9
         if (!this._isIntrospectEnabled() &&
c7fac9
             !this._isSenderWhitelisted(invocation.get_sender())) {
c7fac9
@@ -112,5 +126,49 @@ var IntrospectService = new Lang.Class({
c7fac9
         }
c7fac9
 
c7fac9
         invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
c7fac9
+    },
c7fac9
+
c7fac9
+    GetWindowsAsync(params, invocation) {
c7fac9
+        let focusWindow = global.display.get_focus_window();
c7fac9
+        let apps = this._appSystem.get_running();
c7fac9
+        let windowsList = {};
c7fac9
+
c7fac9
+        if (!this._isIntrospectEnabled()) {
c7fac9
+            invocation.return_error_literal(Gio.DBusError,
c7fac9
+                                            Gio.DBusError.ACCESS_DENIED,
c7fac9
+                                            'App introspection not allowed');
c7fac9
+            return;
c7fac9
+        }
c7fac9
+
c7fac9
+        for (let app of apps) {
c7fac9
+            let windows = app.get_windows();
c7fac9
+            for (let window of windows) {
c7fac9
+
c7fac9
+                if (!this._isEligibleWindow(window))
c7fac9
+                    continue;
c7fac9
+
c7fac9
+                let windowId = window.get_id();
c7fac9
+                let frameRect = window.get_frame_rect();
c7fac9
+                let title = window.get_title();
c7fac9
+                let wmClass = window.get_wm_class();
c7fac9
+
c7fac9
+                windowsList[windowId] = {
c7fac9
+                    'app-id': GLib.Variant.new('s', app.get_id()),
c7fac9
+                    'client-type': GLib.Variant.new('u', window.get_client_type()),
c7fac9
+                    'is-hidden': GLib.Variant.new('b', window.is_hidden()),
c7fac9
+                    'has-focus': GLib.Variant.new('b', (window == focusWindow)),
c7fac9
+                    'width': GLib.Variant.new('u', frameRect.width),
c7fac9
+                    'height': GLib.Variant.new('u', frameRect.height)
c7fac9
+                };
c7fac9
+
c7fac9
+                // These properties may not be available for all windows:
c7fac9
+                if (title != null)
c7fac9
+                    windowsList[windowId]['title'] = GLib.Variant.new('s', title);
c7fac9
+
c7fac9
+                if (wmClass != null)
c7fac9
+                    windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
c7fac9
+            }
c7fac9
+        }
c7fac9
+        invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
c7fac9
     }
c7fac9
 });
c7fac9
-- 
c7fac9
2.20.1
c7fac9