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