Compare commits

...

7 Commits

Author SHA1 Message Date
Benjamin Berg
ff1b411f74 data: Add desktop autostart file for extension warning
Adding this file allows gnome-session to trigger the warning after it
disabled extensions in the non-systemd case.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/695
2019-08-30 18:58:50 +02:00
Benjamin Berg
098114f4c8 data: Add systemd service file for extension disabled warning
Show the extension preferences UI right after login if the last session
failed and extensions have been disabled because of this.

This adds the files for the systemd session case.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/695
2019-08-30 18:58:50 +02:00
Benjamin Berg
9a49b20fac extensionPrefs: Delete disabled warning marker
It isn't possible to easily delete the marker from an XDG autostart
file, so make it on startup to simplify that. This is in preparation
for the next commit which adds the appropriate autostart file.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/695
2019-08-30 18:58:50 +02:00
Benjamin Berg
d9775e41b2 extensionSystem: Allow disabling extensions when globally disabled
The canChange property was not actually reflecting whether
the enableExtension or disableExtension can change the underlying
setting. Instead the property was showing whether such a change will
have an effect.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/695
2019-08-30 18:58:30 +02:00
Benjamin Berg
5796a5d193 extensionPrefs: Reflect whether extension is requested in active state
To do this, simply use the new isRequested property to properly reflect
the underlying settings key rather than the actual loaded state of the
extension.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/695
2019-08-30 18:56:24 +02:00
Benjamin Berg
afefc88e02 extensionSystem: Add isRequested property for extensions
The property reflects whether the extension is enabled in the setting.
This does not mean that the extension is actually loaded, the API user
must check the state property for this information.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/695
2019-08-30 17:19:23 +02:00
Benjamin Berg
44cd1ae25b extensionPrefs: Add ability to warn about extensions being disabled
If we disable extensions after a gnome-shell failure, then we should
warn the user about this happening. The old concept was to do so in the
fail-whale, but we can't even show the fail-whale when running on
wayland.

Adding this option allows starting up the preference dialog on the next
log in and telling the user what happened then. This means we can both
tell the user what is going on and enable them to solve the issue at the
same time.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/695
2019-08-30 16:09:26 +02:00
8 changed files with 116 additions and 9 deletions

View File

@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
Name=GNOME Shell Extensions Disabled Warning
Comment=Warning shown if extensions were disabled due to a failure
Exec=@bindir@/gnome-shell-extension-prefs --disabled-warning
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=@VERSION@
OnlyShowIn=GNOME;
AutostartCondition=if-exists gnome-shell-extensions-disabled-warning
X-GNOME-HiddenUnderSystemd=@systemd_hidden@

View File

@ -0,0 +1,13 @@
[Unit]
Description=Warn about GNOME Shell extensions being disabled
ConditionPathExists=%E/gnome-shell-extensions-disabled-warning
Requisite=gnome-session.target
After=gnome-session.target
[Service]
Type=simple
ExecStartPre=-/bin/rm %E/gnome-shell-extensions-disabled-warning
ExecStart=@bindir@/gnome-shell-extension-prefs --disabled-warning
Restart=no

View File

@ -8,3 +8,5 @@ Before=gnome-session-initialized.target
Requires=gnome-shell-wayland.service Requires=gnome-shell-wayland.service
After=gnome-shell-wayland.service After=gnome-shell-wayland.service
Wants=gnome-shell-extensions-disabled-warning.service

View File

@ -8,3 +8,5 @@ Before=gnome-session-initialized.target
Requires=gnome-shell-x11.service Requires=gnome-shell-x11.service
After=gnome-shell-x11.service After=gnome-shell-x11.service
Wants=gnome-shell-extensions-disabled-warning.service

View File

@ -31,6 +31,19 @@ foreach desktop_file : desktop_files
) )
endforeach endforeach
i18n.merge_file('desktop',
input: configure_file(
input: 'gnome-shell-extensions-disabled-warning.desktop.in.in',
output: 'gnome-shell-extensions-disabled-warning.desktop.in',
configuration: desktopconf
),
output: 'gnome-shell-extension-disabled-warning.desktop',
po_dir: po_dir,
install: true,
install_dir: autostartdir,
type: 'desktop'
)
serviceconf = configuration_data() serviceconf = configuration_data()
serviceconf.set('libexecdir', libexecdir) serviceconf.set('libexecdir', libexecdir)
foreach service_file : service_files foreach service_file : service_files

View File

@ -10,7 +10,7 @@ const _ = Gettext.gettext;
const Config = imports.misc.config; const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML, deleteGFile } = imports.misc.fileUtils;
const { ExtensionState } = ExtensionUtils; const { ExtensionState } = ExtensionUtils;
@ -219,10 +219,33 @@ var Application = GObject.registerClass({
Gio.SettingsBindFlags.DEFAULT | Gio.SettingsBindFlags.DEFAULT |
Gio.SettingsBindFlags.INVERT_BOOLEAN); Gio.SettingsBindFlags.INVERT_BOOLEAN);
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
this._window.add(vbox);
this.disabledInfobar = new Gtk.InfoBar({
message_type: Gtk.MessageType.ERROR,
revealed: false,
show_close_button: true
});
this.disabledInfobar.connect('response', () => {
this.disabledInfobar.revealed = false;
});
let contentArea = this.disabledInfobar.get_content_area();
let label = new Gtk.Label({
label: _('A problem was detected and extensions were automatically disabled. It is recommended to disable or reconfigure any extensions that may have caused the issue before re-enabling them at the top.'),
ellipsize: Pango.EllipsizeMode.END,
wrap: true,
lines: 2,
xalign: 0,
margin: 6
});
contentArea.add(label);
vbox.add(this.disabledInfobar);
this._mainStack = new Gtk.Stack({ this._mainStack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE transition_type: Gtk.StackTransitionType.CROSSFADE
}); });
this._window.add(this._mainStack); vbox.add(this._mainStack);
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER }); let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
@ -338,6 +361,20 @@ var Application = GObject.registerClass({
let args = commandLine.get_arguments(); let args = commandLine.get_arguments();
if (args.length) { if (args.length) {
if (args[0] == '--disabled-warning') {
if (!this._settings.is_writable('disable-user-extensions'))
this.quit();
this.disabledInfobar.set_revealed(true);
let file = GLib.build_filenamev ([GLib.get_user_config_dir(), 'gnome-shell-extensions-disabled-warning']);
let gfile = Gio.File.new_for_path(file);
if (gfile.query_exists(null))
deleteGFile(gfile);
return 0;
}
let uuid = args[0]; let uuid = args[0];
this._skipMainWindow = true; this._skipMainWindow = true;
@ -574,8 +611,11 @@ class ExtensionRow extends Gtk.ListBoxRow {
this._extension = ExtensionUtils.deserializeExtension(newState); this._extension = ExtensionUtils.deserializeExtension(newState);
let state = (this._extension.state == ExtensionState.ENABLED); let state = (this._extension.state == ExtensionState.ENABLED);
this._switch.freeze_notify();
this._switch.state = state; this._switch.state = state;
this._switch.active = this._extension.isRequested;
this._switch.sensitive = this._canToggle(); this._switch.sensitive = this._canToggle();
this._switch.thaw_notify();
}); });
this.connect('destroy', this._onDestroy.bind(this)); this.connect('destroy', this._onDestroy.bind(this));
@ -644,7 +684,6 @@ class ExtensionRow extends Gtk.ListBoxRow {
this._switch = new Gtk.Switch({ this._switch = new Gtk.Switch({
valign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER,
sensitive: this._canToggle(), sensitive: this._canToggle(),
state: this._extension.state === ExtensionState.ENABLED
}); });
this._switch.connect('notify::active', () => { this._switch.connect('notify::active', () => {
if (this._switch.active) if (this._switch.active)
@ -653,6 +692,11 @@ class ExtensionRow extends Gtk.ListBoxRow {
this._app.shellProxy.DisableExtensionRemote(this.uuid); this._app.shellProxy.DisableExtensionRemote(this.uuid);
}); });
this._switch.connect('state-set', () => true); this._switch.connect('state-set', () => true);
this._switch.freeze_notify();
this._switch.state = this._extension.state === ExtensionState.ENABLED;
this._switch.active = this._extension.isRequested;
this._switch.thaw_notify();
hbox.add(this._switch); hbox.add(this._switch);
} }

View File

@ -31,7 +31,7 @@ var ExtensionState = {
UNINSTALLED: 99 UNINSTALLED: 99
}; };
const SERIALIZED_PROPERTIES = ['type', 'state', 'path', 'error', 'hasPrefs', 'canChange']; const SERIALIZED_PROPERTIES = ['type', 'state', 'path', 'error', 'hasPrefs', 'canChange', 'isRequested'];
/** /**
* getCurrentExtension: * getCurrentExtension:

View File

@ -22,6 +22,7 @@ var ExtensionManager = class {
this._extensions = new Map(); this._extensions = new Map();
this._enabledExtensions = []; this._enabledExtensions = [];
this._requestedExtensions = [];
this._extensionOrder = []; this._extensionOrder = [];
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
@ -250,6 +251,9 @@ var ExtensionManager = class {
// Default to error, we set success as the last step // Default to error, we set success as the last step
extension.state = ExtensionState.ERROR; extension.state = ExtensionState.ERROR;
let requested = this._requestedExtensions.includes(extension.uuid);
extension.isRequested = requested;
let checkVersion = !global.settings.get_boolean(EXTENSION_DISABLE_VERSION_CHECK_KEY); let checkVersion = !global.settings.get_boolean(EXTENSION_DISABLE_VERSION_CHECK_KEY);
if (checkVersion && ExtensionUtils.isOutOfDate(extension)) { if (checkVersion && ExtensionUtils.isOutOfDate(extension)) {
@ -363,10 +367,7 @@ var ExtensionManager = class {
? DISABLE_USER_EXTENSIONS_KEY ? DISABLE_USER_EXTENSIONS_KEY
: ENABLED_EXTENSIONS_KEY; : ENABLED_EXTENSIONS_KEY;
extension.canChange = extension.canChange = global.settings.is_writable(ENABLED_EXTENSIONS_KEY);
!hasError &&
global.settings.is_writable(changeKey) &&
(isMode || !modeOnly);
} }
_getEnabledExtensions() { _getEnabledExtensions() {
@ -380,6 +381,14 @@ var ExtensionManager = class {
return extensions.filter(item => !disabledExtensions.includes(item)); return extensions.filter(item => !disabledExtensions.includes(item));
} }
_getRequestedExtensions() {
let extensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
// filter out 'disabled-extensions' which takes precedence
let disabledExtensions = global.settings.get_strv(DISABLED_EXTENSIONS_KEY);
return extensions.filter(item => !disabledExtensions.includes(item));
}
_onUserExtensionsEnabledChanged() { _onUserExtensionsEnabledChanged() {
this._onEnabledExtensionsChanged(); this._onEnabledExtensionsChanged();
this._onSettingsWritableChanged(); this._onSettingsWritableChanged();
@ -391,6 +400,16 @@ var ExtensionManager = class {
if (!this._enabled) if (!this._enabled)
return; return;
// Updated requested state and emit change notifications
this._requestedExtensions = this._getRequestedExtensions();
for (let extension of this._extensions.values()) {
let requested = this._requestedExtensions.includes(extension.uuid);
if (extension.isRequested == requested)
continue;
extension.isRequested = requested;
this.emit('extension-state-changed', extension);
}
// Find and enable all the newly enabled extensions: UUIDs found in the // Find and enable all the newly enabled extensions: UUIDs found in the
// new setting, but not in the old one. // new setting, but not in the old one.
newEnabledExtensions.filter( newEnabledExtensions.filter(
@ -451,6 +470,7 @@ var ExtensionManager = class {
this._onSettingsWritableChanged.bind(this)); this._onSettingsWritableChanged.bind(this));
this._enabledExtensions = this._getEnabledExtensions(); this._enabledExtensions = this._getEnabledExtensions();
this._requestedExtensions = this._getRequestedExtensions();
let perUserDir = Gio.File.new_for_path(global.userdatadir); let perUserDir = Gio.File.new_for_path(global.userdatadir);
FileUtils.collectFromDatadirs('extensions', true, (dir, info) => { FileUtils.collectFromDatadirs('extensions', true, (dir, info) => {
@ -512,8 +532,9 @@ var ExtensionManager = class {
// property; it might make sense to make enabledExtensions independent // property; it might make sense to make enabledExtensions independent
// from allowExtensions in the future // from allowExtensions in the future
if (Main.sessionMode.allowExtensions) { if (Main.sessionMode.allowExtensions) {
if (this._initted) if (this._initted) {
this._enabledExtensions = this._getEnabledExtensions(); this._enabledExtensions = this._getEnabledExtensions();
}
this._enableAllExtensions(); this._enableAllExtensions();
} else { } else {
this._disableAllExtensions(); this._disableAllExtensions();