Commit Graph

152 Commits

Author SHA1 Message Date
Matthew Jakeman
789e1b288a extensions: Allow updating with only extension-manager installed
GNOME Shell will only update extensions if the org.gnome.Extensions
app is present. This commit adds alternative support for
com.mattjakeman.ExtensionManager to the extension updating mechanism.

It enables updates to occur when extension-manager is the sole installed
tool on the system. When both applications are installed,
org.gnome.Extensions is preferred at all times.

Fixes #5564

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2358>
2022-07-11 17:43:11 +00:00
Evan Welsh
a88e59c1a8 Adopt EventEmitter class instead of injecting Signal methods
Introduce a new class, EventEmitter, which implements signal
handling for pure JavaScript classes. EventEmitter still
utilizes GJS' addSignalMethods internally.

EventEmitter allows static typechecking to understand the
structure of event-emitting JS classes and makes creating
child classes simpler.

The name 'EventEmitter' mirrors a common name for this pattern
in Node and in JS libraries.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2043>
2022-07-04 18:30:49 -04:00
Florian Müllner
56d0b6d831 extensionSystem: Check metadata types
We currently check that an extension provides required metadata
properties, but then assume that all properties have the expected
type.

It turns out that this is putting too much trust in extensions,
so add an appropriate check.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5347

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2272>
2022-04-21 08:16:30 +00:00
Florian Müllner
a1dd1b25d8 js: Use templates for non-translatable strings
This reverts commit 9d941f8202 and replaces all additional
instances of .format() that have been added since.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2160>
2022-02-12 12:29:52 +00:00
Aleksandr Mezin
12c300a7a2 extensionSystem: Ignore spurious disable-extension-version-validation change
Ignore spurious change notificatons, when the setting didn't actually change
(triggered by `dconf update`)

Workaround for https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4808

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2047>
2022-01-14 15:23:09 +00:00
Ray Strode
d7b1264897 sessionMode: Drop allowExtensions property
Now that we allow extensions at the lock screens, extensions
are allowed for every session mode gnome-shell would typically
change to at runtime.

This means there's little advantage to having an allowExtensions
property in the session mode definition.

This commit simplifies the code a bit by dropping the property.

Third party session modes can still lock down extensions through
gsettings if they need to.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1967>
2021-10-14 18:40:53 +00:00
Ray Strode
2bf31dc49f sessionMode: Allow extensions at the login and unlock screens
Now extensions can specify which session modes they work in,
but specifying the login screen or unlock screen session modes in
an extensions metadata still won't work, because those session
modes disallow extensions.

This commit fixes that.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1967>
2021-10-14 18:40:53 +00:00
Ray Strode
242cff7abf extensionSystem: Allow extensions to run on the login screen
At the moment it's not realy possible to extend the login screen to do
things it doesn't have built-in support for. This means in order
to support niche use cases, those cases have to change the main
code base. For instance, oVirt and Vmware deployments want to be able
to automaticaly log in guest VMs when a user pre-authenticates through a
console on a management host. To support those use cases, we added
code to the login screen directly, even though most machines will never
be associated with oVirt or Vmware management hosts.

We also get requests from e.g. government users that need certain features
at the login screen that wouldn't get used much outside of government
deployments. For instance, we've gotten requests that a machine contains
prominently displays that it has "Top Secret" information.

All of these use cases seem like they would better handled via
extensions that could be installed in the specific deployments. The
problem is extensions only run in the user session, and get
disabled at the login screen automatically.

This commit changes that. Now extensions can specify in their metadata
via a new sessionModes property, which modes that want to run in. For
backward compatibility, if an extension doesn't specify which session
modes it works in, its assumed the extension only works in the user
session.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1967>
2021-10-14 18:40:53 +00:00
Ray Strode
7e5ee2c282 extensionSystem: Get rid of _enabled boolean optimization
At the moment a session mode either allows extensions or it doesn't.
If it allows extensions, then the entire available list of
configured extensions get enabled as soon as the session mode is
entered.

Since enabling or disabling extensions is an all or nothing situation,
the code tracks whether extensions are already enabled when entering
the session mode, and if so, avoids iterating through the extension list
needlessly. It does this using a boolean named _enabled.

In the future, the extensions themselves will be given some say on
whether or not they should be enabled in a given session mode. This
means, the configured extension list may contain extensions that
shouldn't be enabled for a given session mode, and the _enabled boolean
will no longer be appropriated.

This commit drops the _enabled boolean optimization.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1967>
2021-10-14 18:40:53 +00:00
Florian Müllner
ef70364e81 cleanup: Replace non-standard ByteArray module
gjs landed support for TextDecoder/TextEncoder. Use those instead
of gjs' own ByteArray module.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1946>
2021-09-01 14:49:30 +00:00
Florian Müllner
ddc2e0f4cb extensionSystem: Fix opening Extensions app from notification
Launching the app is implemented by the source's open() method, but
only external notifications are hooked up to call into the source
when no default action was provided.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1595>
2021-01-26 17:12:04 +01:00
Florian Müllner
112b139a9e cleanup: Remove old compatibility code
Since gjs moved to mozjs60, return values of int8_t arrays can
no longer be treated as strings. We originally made the conversion
conditional to keep working with the (then) stable gjs release.

That was two years ago and we require a more recent gjs nowadays,
so there's no good reason for keeping the old code path.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1407
2020-08-13 23:00:21 +00:00
Florian Müllner
48e6a58250 extensionSystem: Don't log error name
logExtensionError() currently saves the error message by calling
toString() on the passed error. That's convenient as it allows to
pass a string instead of a "proper" error, but the result isn't
great for the common Error case: Its toString() method prefixes
the message with the error name, which usually is just "Error:".

The plain message is more suitable for displaying it to users,
so use that for Error objects.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2337
2020-05-21 21:45:04 +00:00
Florian Müllner
6ddd43f361 extensionSystem: Prevent broken updates
Spidermonkey caches imports, which means that uninstalling an
old extension version and installing a new one doesn't work as
expected: If the previous version was loaded, then its code will
be imported instead.

For the last couple of releases this has been a reliable source
of extension bug reports after major GNOME updates. Thankfully
chrome-gnome-shell removed its update support in favor of our
built-in support now, but users may still use older versions
or perform those actions manually, so it still makes sense to
catch this case and set an appropriate error.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1248
2020-05-18 20:41:06 +00:00
Florian Müllner
3309031fd1 extensionSystem: Update canChange on error
Whether or not an extension has errors influences the 'canChange'
property, but so far we only update it for errors that occur when
initializing the extension, not when an extension is enabled later.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1249
2020-05-16 16:33:22 +00:00
Florian Müllner
6d5e93b00b extensionSystem: Disable extension before unloading stylesheet
Removing a stylesheet from the theme will trigger a style update. There's
little point in updating the extension actors that are about to be destroyed
(hopefully), so call the extension's disable() function first.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2757
2020-05-13 20:10:56 +02:00
Florian Müllner
153b7d525d cleanup: Don't linebreak before closing parentheses
Otherwise recent versions of eslint want "dangling" commas,
which is at least ugly considering that most functions don't
allow adding arguments at leasure.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1177
2020-04-28 09:04:49 +00:00
Florian Müllner
45bc850715 extensionSystem: Add method for opening extension prefs
Extension that want to expose their own preferences (for example as menu
items) do that by passing their UUID to gnome-shell-extension-prefs.

But since 3.36.1 the app is optional and no longer accepts arguments on
the command line. To adjust, extensions now need to make a D-Bus call
the extensions portal, just like the app and gnome-shell.

We will add a convenience method for that purpose, so it makes
sense to share the existing code. As it's extension-related, the
extension manager looks like the right place ...

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1163
2020-04-03 15:23:26 +02:00
Florian Müllner
660a2b6e62 extensionSystem: Require Extensions app for updates
While we don't technically need the app to download and apply
updates, we do require it for notifying the user about available
updates and listing extensions with pending updates.

So instead of intransparently applying updates in the background
without the user noticing, disable updates altogether if the
Extensions app is not installed.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2346
2020-03-27 13:28:41 +00:00
Florian Müllner
39f61fc41c extensionSystem: Catch errors when updating extensions
Extension updates are installed at startup, so any errors that bubble
up uncaught will prevent the startup to complete.

While the most likely error reason was addressed in the previous commit
(pending update for a no-longer exitent extension), it makes sense to
catch any kind of corrupt updates to not interfere with shell startup.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2343
2020-03-17 14:19:20 +00:00
Florian Müllner
9d941f8202 js: Don't use templates in files with translations
xgettext gained some support for template strings, and no longer
fails when encountering '/' somewhere between backticks.

Unfortunately its support is still buggy as hell, and it is now
silently dropping translatable strings, yay. I hate making the
code worse, but until xgettext really gets its shit together,
the only viable way forward seems to be to not use template
strings in any files listed in POTFILES.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1014
2020-02-17 23:20:40 +01:00
Florian Müllner
529829a561 extensionSystem: Periodically check for extension updates
Now that we can download, apply and display extension updates, it is time
to actually check for updates. Schedule an update check right on startup,
then every 24 hours.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:33:14 +01:00
Florian Müllner
ed84541050 extensionSystem: Show notification when updates are available
Now that the extensions app has the ability to handle updates, we
can use it as source of updates notifications.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968
2020-02-03 19:33:14 +01:00
Florian Müllner
db9ef11f28 extensionSystem: Install pending updates on startup
Now that we have a way to check for updates and download them, we
should actually apply them as well. Do this on startup before any
extensions are initialized, to make sure we don't run into any
conflicts with a previously loaded version.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/945
2020-01-30 13:37:47 +00:00
Florian Müllner
375d1892bf extensionSystem: Add hasUpdate state
The current support for extension updates is half-baked at best.
We are about to change that, and implement offline updates similar
to gnome-software.

As a first step, add a hasUpdate property to the extension state
which will communicate available updates.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/945
2020-01-30 13:37:47 +00:00
Florian Müllner
0a9e1b4173 fileUtils: Delete deleteGFile hack
It is true that delete is a javascript keyword, but that doesn't
prevent it from being used as method name - there are event built-in
types like Map or Set with delete() methods!

So if that hack was ever needed, this hasn't been the case for years
now; just removed the hack now.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/862
2019-11-26 22:17:28 +00:00
Benjamin Berg
f742484795 extensionSystem: Create a file to flag that extensions are being loaded
When the extension system is loaded, create the
gnome-shell-disable-extensions file in the users runtime directory. This
file is automatically removed 60s later. The sole purpose of this file
is to be consumed by the systemd units. If the file exists, the systemd
units will disable extensions when the gnome-shell fails.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/858
2019-11-25 21:49:49 +00:00
Florian Müllner
ebf77748a8 cleanup: Require "dangling" commas
Since ES5, trailing commas in arrays and object literals are valid.
We generally haven't used them so far, but they are actually a good
idea, as they make additions and removals in diffs much cleaner.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/805
2019-11-11 19:25:14 +00:00
Florian Müllner
682bd7e97c cleanup: Don't shadow variables
Having variables that share the same name in overlapping scopes is
confusing and error-prone, and is best avoided.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/805
2019-11-11 19:25:14 +00:00
Florian Müllner
67ea424525 cleanup: Avoid unnecessary braces
Our coding style has always been to avoid braces when all blocks
are single-lines.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/805
2019-11-11 19:25:14 +00:00
Florian Müllner
111f87a1b2 cleanup: Avoid pointless "renames" in destructuring
ES5 allows to rename variables in object destructuring, however this
only makes sense when we want to use a different name than the object
property.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/731
2019-09-15 16:02:45 +02:00
Florian Müllner
ce92270626 extensionSystem: Add missing return value
_callExtensionInit() should return whether the extension was initialized
successfully or not, but the early return added in commit 2a9e065cfb
doesn't.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/715
2019-09-12 12:45:05 +02:00
Jonas Dreßler
bdcf3037ca extensionSystem: Always disable multiple extensions in reverse order
Since disabling an extension will lead to disabling and re-enabling all
following extensions in the list, always disable multiple extensions by
looping through the list in reverse order.

This lowers the execution time of the event handlers quite a bit if many
extensions are installed.

Thanks to Philippe Troin for identifying the problem and proposing the
initial patch to change the extension order when reloading.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/177

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
9698ff491a extensionSystem: Only add to extensionOrder array if enabling worked
Only push uuids of newly enabled extensions to the `_extensionOrder`
array if enabling them was successful.

Otherwise, since `_callExtensionDisable()` doesn't remove uuids that
weren't successfully enabled from the array, those extensions get added
to the array multiple times when they're disabled and enabled.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
2a9e065cfb extensionSystem: Always enforce disallowing extensions using sessionMode
It's currently possible to circumvent the `sessionMode.allowExtensions`
property: For already enabled extensions one can call reloadExtension
via DBus, for new extensions it's possible by adding the extension to
the enabled-extensions gsettings key and setting the
disable-extension-version-validation key (which triggers a reload of
`this._enabledExtensions`) and then calling reloadExtension via DBus.

So to enforce `allowExtensions` while still allowing to update
extensions and keeping the extensionSystem synced with various gsettings
keys, replace the checks for `this._enabled` with simple checks for
`Main.sessionMode.allowExtensions` inside `_callExtensionInit()` and
`_callExtensionEnable()`.

The remaining checks for `this._enabled` are only small optimizations to
prevent running code on irrelevant sessionMode updates.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
4c93ef39fa extensionSystem: Handle added or removed sessionMode extensions
Right now we're only handling added sessionMode extensions correctly on
sessionMode updates, also handle the other case and disable removed
sessionMode extensions on sessionMode updates.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
22107c183b extensionSystem: Rename initted to initialized
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
c06eb5d0a7 extensionSystem: Log an extension error if loading the stylesheet failed
Instead of only logging a message that loading the extension stylesheet
failed and silently returning we should use `logExtensionError` for that
instead. This also sets the extension state to ERROR and makes sure we
don't try to enable it again.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
e76877c4b8 extensionSystem: Check if extension exists before accessing property
If the extension doesn't exist in the `this._extensions` Map, we'd try
to access `extension.dir` on undefined/null. So set the `dir` variable
after checking if `extension` is defined.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
2a32fb2e72 extensionSystem: Fix a wrong error message
The extension object is added to the `this._extensions` Map inside
`createExtensionObject`, not inside `loadExtension`.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Jonas Dreßler
de86920e0e extensionSystem: Remove unncessary return statements
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/96
2019-09-12 10:24:49 +00:00
Marco Trevisan (Treviño)
8a7e44ccf0 extensionSystem: Use logError to record extension errors with stack trace
Extensions might emit JS errors explicitly or implicitly, however GNOME
Shell doesn't present any stack trace for those making them quite hard
to debug.

Make this easier by logging errors with logError() whichs includes the
stack dump.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/700
2019-09-09 19:28:19 +00:00
Florian Müllner
e357559582 cleanup: Mark globals used from other modules as exported
eslint cannot figure out that those symbols are used from other modules
via imports, so they trigger unused-variable errors. To fix, explicitly
mark those symbols as exported.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/627
2019-07-24 00:28:45 +02:00
Florian Müllner
71759a0769 cleanup: Mark unused (but useful) variables as ignored
While we aren't using those destructured variables, they are still useful
to document the meaning of those elements. We don't want eslint to keep
warning about them though, so mark them accordingly.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/627
2019-07-24 00:28:45 +02:00
Didier Roche
ce1bee727a extensionSystem: Allow disabling session mode extensions
Trying to disable an extension that is enabled by the session mode
currently has no effect, which is clearly confusing. We could update
the various extension UIs to reflect that via sensitivity, but being
unable to configure extensions based on which session the user picked
at login isn't obvious either.

So instead, add a 'disabled-extensions' gsettings key to list extensions
that should not be enabled which takes precedence over 'enabled-extensions'
and can be used to disable session mode extensions.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
2019-07-20 14:17:35 +00:00
Florian Müllner
43cb3754d9 extensionSystem: Store extensions in a Map
After making the extensions map private to the ExtensionManager, we can
switch it to a proper hash table which is more appropriate.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
2019-07-20 14:17:35 +00:00
Florian Müllner
1d6ddf060b extensionSystem: Move extension loading into ExtensionManager
Now that extension loading and the extensions map are no longer shared
between the gnome-shell and gnome-shell-extension-prefs processes, we
can move both into the ExtensionManager which makes much more sense
conceptually.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
2019-07-20 14:17:35 +00:00
Didier Roche
4a3476266f extensionSystem: Add canChange property to extensions
Whether or not an extension can be enabled/disabled depends on various
factors: Whether the extension is in error state, whether user extensions
are disabled and whether the underlying GSettings keys are writable.

This is complex enough to share the logic, so add it to the extension
properties that are exposed over D-Bus.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
2019-07-20 14:17:35 +00:00
Florian Müllner
32e0b895a4 shellDBus: Add new 'ExtensionStateChanged' signal
The existing 'ExtensionStatusChanged' signal has a fixed set of parameters,
which means we cannot add additional state without an API break.  Deprecate
it in favor of a new 'ExtensionStateChanged' signal which addresses this
issue by taking the full serialized extension as parameter.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
2019-07-20 14:17:35 +00:00
Didier Roche
4589da957b extensionSystem: Add methods to enable/disable extensions
Extensions are currently enabled or disabled by directly changing the
list in the 'enabled-extensions' GSettings key. As we will soon add
an overriding 'disabled-extensions' key as well, it makes sense to
offer explicit API for enabling/disabling to avoid duplicating the
logic.

For the corresponding D-Bus API, the methods were even mentioned in
the GSettings schema, albeit unimplemented until now.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
2019-07-20 14:17:35 +00:00