diff --git a/data/dbus-interfaces/org.gnome.Shell.Introspect.xml b/data/dbus-interfaces/org.gnome.Shell.Introspect.xml index 10c48d635..9508681af 100644 --- a/data/dbus-interfaces/org.gnome.Shell.Introspect.xml +++ b/data/dbus-interfaces/org.gnome.Shell.Introspect.xml @@ -33,5 +33,29 @@ + + + + + diff --git a/js/misc/introspect.js b/js/misc/introspect.js index fa0a66e00..5599e1a66 100644 --- a/js/misc/introspect.js +++ b/js/misc/introspect.js @@ -97,6 +97,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())) { @@ -107,5 +118,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])); } });