From 5374faa314960a4b1a2239a1eb4e04202976eab5 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Jan 15 2021 06:11:28 +0000 Subject: introspect-backports.patch patch_name: introspect-backports.patch present_in_specfile: true location_in_specfile: 35 --- diff --git a/data/dbus-interfaces/org.gnome.Shell.Introspect.xml b/data/dbus-interfaces/org.gnome.Shell.Introspect.xml index 9508681..d71f241 100644 --- a/data/dbus-interfaces/org.gnome.Shell.Introspect.xml +++ b/data/dbus-interfaces/org.gnome.Shell.Introspect.xml @@ -57,5 +57,19 @@ + + + + + diff --git a/js/misc/introspect.js b/js/misc/introspect.js index f7a7f2f..7c62113 100644 --- a/js/misc/introspect.js +++ b/js/misc/introspect.js @@ -1,9 +1,11 @@ -const { Gio, GLib, Meta, Shell } = imports.gi; +const { Gio, GLib, Meta, Shell, St } = imports.gi; const INTROSPECT_SCHEMA = 'org.gnome.shell'; const INTROSPECT_KEY = 'introspect'; const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk']; +const INTROSPECT_DBUS_API_VERSION = 2; + const { loadInterfaceXML } = imports.misc.fileUtils; const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect'); @@ -21,6 +23,7 @@ var IntrospectService = class { this._runningApplicationsDirty = true; this._activeApplication = null; this._activeApplicationDirty = true; + this._animationsEnabled = true; this._appSystem = Shell.AppSystem.get_default(); this._appSystem.connect('app-state-changed', @@ -29,7 +32,9 @@ var IntrospectService = class { this._syncRunningApplications(); }); - this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA }); + this._introspectSettings = new Gio.Settings({ + schema_id: INTROSPECT_SCHEMA, + }); let tracker = Shell.WindowTracker.get_default(); tracker.connect('notify::focus-app', @@ -39,6 +44,20 @@ var IntrospectService = class { }); this._syncRunningApplications(); + + this._whitelistMap = new Map(); + APP_WHITELIST.forEach(appName => { + Gio.DBus.watch_name(Gio.BusType.SESSION, + appName, + Gio.BusNameWatcherFlags.NONE, + (conn, name, owner) => this._whitelistMap.set(name, owner), + (conn, name) => this._whitelistMap.delete(name)); + }); + + this._settings = St.Settings.get(); + this._settings.connect('notify::enable-animations', + this._syncAnimationsEnabled.bind(this)); + this._syncAnimationsEnabled(); } _isStandaloneApp(app) { @@ -48,11 +67,16 @@ var IntrospectService = class { } _isIntrospectEnabled() { - return this._settings.get_boolean(INTROSPECT_KEY); + return this._introspectSettings.get_boolean(INTROSPECT_KEY); } _isSenderWhitelisted(sender) { - return APP_WHITELIST.includes(sender); + return [...this._whitelistMap.values()].includes(sender); + } + + _getSandboxedAppId(app) { + let ids = app.get_windows().map(w => w.get_sandboxed_app_id()); + return ids.find(id => id != null); } _syncRunningApplications() { @@ -76,6 +100,10 @@ var IntrospectService = class { newActiveApplication = app.get_id(); } + let sandboxedAppId = this._getSandboxedAppId(app); + if (sandboxedAppId) + appInfo['sandboxed-app-id'] = new GLib.Variant('s', sandboxedAppId); + newRunningApplications[app.get_id()] = appInfo; } @@ -102,9 +130,18 @@ var IntrospectService = class { type == Meta.WindowType.UTILITY); } + _isInvocationAllowed(invocation) { + if (this._isIntrospectEnabled()) + return true; + + if (this._isSenderWhitelisted(invocation.get_sender())) + return true; + + return false; + } + GetRunningApplicationsAsync(params, invocation) { - if (!this._isIntrospectEnabled() && - !this._isSenderWhitelisted(invocation.get_sender())) { + if (!this._isInvocationAllowed(invocation)) { invocation.return_error_literal(Gio.DBusError, Gio.DBusError.ACCESS_DENIED, 'App introspection not allowed'); @@ -119,7 +156,7 @@ var IntrospectService = class { let apps = this._appSystem.get_running(); let windowsList = {}; - if (!this._isIntrospectEnabled()) { + if (!this._isInvocationAllowed(invocation)) { invocation.return_error_literal(Gio.DBusError, Gio.DBusError.ACCESS_DENIED, 'App introspection not allowed'); @@ -137,6 +174,7 @@ var IntrospectService = class { let frameRect = window.get_frame_rect(); let title = window.get_title(); let wmClass = window.get_wm_class(); + let sandboxedAppId = window.get_sandboxed_app_id(); windowsList[windowId] = { 'app-id': GLib.Variant.new('s', app.get_id()), @@ -153,8 +191,29 @@ var IntrospectService = class { if (wmClass != null) windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass); + + if (sandboxedAppId != null) + windowsList[windowId]['sandboxed-app-id'] = + GLib.Variant.new('s', sandboxedAppId); } } invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList])); } + + _syncAnimationsEnabled() { + let wasAnimationsEnabled = this._animationsEnabled; + this._animationsEnabled = this._settings.enable_animations; + if (wasAnimationsEnabled !== this._animationsEnabled) { + let variant = new GLib.Variant('b', this._animationsEnabled); + this._dbusImpl.emit_property_changed('AnimationsEnabled', variant); + } + } + + get AnimationsEnabled() { + return this._animationsEnabled; + } + + get version() { + return INTROSPECT_DBUS_API_VERSION; + } }; diff --git a/js/ui/main.js b/js/ui/main.js index 978f83c..1203b3c 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -147,6 +147,8 @@ function _initializeUI() { _loadOskLayouts(); _loadDefaultStylesheet(); + new AnimationsSettings(); + // Setup the stage hierarchy early layoutManager = new Layout.LayoutManager(); @@ -723,3 +725,46 @@ function showRestartMessage(message) { let restartMessage = new RestartMessage(message); restartMessage.open(); } + +var AnimationsSettings = class { + constructor() { + let backend = Meta.get_backend(); + if (!backend.is_rendering_hardware_accelerated()) { + St.Settings.get().inhibit_animations(); + return; + } + + let isXvnc = Shell.util_has_x11_display_extension( + global.display, 'VNC-EXTENSION'); + if (isXvnc) { + St.Settings.get().inhibit_animations(); + return; + } + + let remoteAccessController = backend.get_remote_access_controller(); + if (!remoteAccessController) + return; + + this._handles = new Set(); + remoteAccessController.connect('new-handle', + (_, handle) => this._onNewRemoteAccessHandle(handle)); + } + + _onRemoteAccessHandleStopped(handle) { + let settings = St.Settings.get(); + + settings.uninhibit_animations(); + this._handles.delete(handle); + } + + _onNewRemoteAccessHandle(handle) { + if (!handle.get_disable_animations()) + return; + + let settings = St.Settings.get(); + + settings.inhibit_animations(); + this._handles.add(handle); + handle.connect('stopped', this._onRemoteAccessHandleStopped.bind(this)); + } +}; diff --git a/src/shell-util.c b/src/shell-util.c index 31bb18e..fa3fc08 100644 --- a/src/shell-util.c +++ b/src/shell-util.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #ifdef HAVE__NL_TIME_FIRST_WEEKDAY @@ -613,3 +615,27 @@ shell_util_check_cloexec_fds (void) fdwalk (check_cloexec, NULL); g_info ("Open fd CLOEXEC check complete"); } + +/** + * shell_util_has_x11_display_extension: + * @display: A #MetaDisplay + * @extension: An X11 extension + * + * If the corresponding X11 display provides the passed extension, return %TRUE, + * otherwise %FALSE. If there is no X11 display, %FALSE is passed. + */ +gboolean +shell_util_has_x11_display_extension (MetaDisplay *display, + const char *extension) +{ + MetaX11Display *x11_display; + Display *xdisplay; + int op, event, error; + + x11_display = meta_display_get_x11_display (display); + if (!x11_display) + return FALSE; + + xdisplay = meta_x11_display_get_xdisplay (x11_display); + return XQueryExtension (xdisplay, extension, &op, &event, &error); +} diff --git a/src/shell-util.h b/src/shell-util.h index 6904f43..02b8404 100644 --- a/src/shell-util.h +++ b/src/shell-util.h @@ -59,6 +59,9 @@ cairo_surface_t * shell_util_composite_capture_images (ClutterCapture *captures void shell_util_check_cloexec_fds (void); +gboolean shell_util_has_x11_display_extension (MetaDisplay *display, + const char *extension); + G_END_DECLS #endif /* __SHELL_UTIL_H__ */ diff --git a/src/st/st-settings.c b/src/st/st-settings.c index 17f2c46..ebfd284 100644 --- a/src/st/st-settings.c +++ b/src/st/st-settings.c @@ -54,6 +54,7 @@ struct _StSettings gchar *gtk_theme; gchar *gtk_icon_theme; + int inhibit_animations_count; gboolean enable_animations; gboolean primary_paste; gboolean magnifier_active; @@ -62,6 +63,41 @@ struct _StSettings G_DEFINE_TYPE (StSettings, st_settings, G_TYPE_OBJECT) +static gboolean +get_enable_animations (StSettings *settings) +{ + if (settings->inhibit_animations_count > 0) + return FALSE; + else + return settings->enable_animations; +} + +void +st_settings_inhibit_animations (StSettings *settings) +{ + gboolean enable_animations; + + enable_animations = get_enable_animations (settings); + settings->inhibit_animations_count++; + + if (enable_animations != get_enable_animations (settings)) + g_object_notify_by_pspec (G_OBJECT (settings), + props[PROP_ENABLE_ANIMATIONS]); +} + +void +st_settings_uninhibit_animations (StSettings *settings) +{ + gboolean enable_animations; + + enable_animations = get_enable_animations (settings); + settings->inhibit_animations_count--; + + if (enable_animations != get_enable_animations (settings)) + g_object_notify_by_pspec (G_OBJECT (settings), + props[PROP_ENABLE_ANIMATIONS]); +} + static void st_settings_finalize (GObject *object) { @@ -95,7 +131,7 @@ st_settings_get_property (GObject *object, switch (prop_id) { case PROP_ENABLE_ANIMATIONS: - g_value_set_boolean (value, settings->enable_animations); + g_value_set_boolean (value, get_enable_animations (settings)); break; case PROP_PRIMARY_PASTE: g_value_set_boolean (value, settings->primary_paste); diff --git a/src/st/st-settings.h b/src/st/st-settings.h index c2c4fa2..8b25494 100644 --- a/src/st/st-settings.h +++ b/src/st/st-settings.h @@ -33,6 +33,10 @@ G_DECLARE_FINAL_TYPE (StSettings, st_settings, ST, SETTINGS, GObject) StSettings * st_settings_get (void); +void st_settings_inhibit_animations (StSettings *settings); + +void st_settings_uninhibit_animations (StSettings *settings); + G_END_DECLS #endif /* __ST_SETTINGS_H__ */