GNOME Shell breaks catastrophically every few months

Every time GNOME updates to a new version—it feels like it happens every few months—it breaks all my extensions.

I rely on a number of extensions to get GNOME Shell to behave the way I want it to:

  • Argos, so that I can display the output of commands I need to monitor
  • Dash to Dock, to have a nicely working dock
  • Pop Shell, for window tiling
  • Tray Icons, so I can see what, e.g., Megasync is doing, without having a window open
  • GSConnect, to interface with my phone
  • Multi Monitors addon, since I use more than one monitor

… and more, like those which add search functionality to the activities overview search.

The trouble is, every time GNOME updates to a new version, basically all extensions break catastrophically, and can no longer be enabled.

For me, that suddenly makes GNOME almost unusable, since nothing is behaving the way I need it to.

Does GNOME have to change its entire codebase every six months, forcibly invalidating every extension that used to work with it? Do all these extensions really cease to work every few months, as a result?

I remember when Firefox switched its extensions system, and it invalidated all of the extensions that previously used to work with it. That was a major inconvenience, but at least then, the extension developers had lots of advance warning, where they could rewrite their extensions to fit the new API. But more importantly, it only happened once. (In recent memory, that is.) In contrast, GNOME Shell seems to do this all the time, and it’s really annoying.

I know I could hack my system to pin GNOME shell to a particular version, but this would probably affect the rest of the ecosystem, as well, and would be a pain to have to maintain.

Isn’t there anything that can be done about this? Like, automatically mark extensions as compatible with the latest version, unless their tests fail? It seems like there should be a better solution, no?

GNOME Shell automatically disables all extensions that do not support the current version—unless you (or your Linux distribution) explicitly opt out of that behaviour. Which means what you’re seeing:

Isn’t a catastrophic break, but just a way to avoid breaking your session by loading an incompatible extension. It doesn’t mean that GNOME internal changes have led to extensions breaking at all.

Extension authors should have time to port their code to a new version of GNOME; they should also have better tools to do that, but it’s a complicated topic.

I think your expectations are misplaced tbh. You’re basically asking us to stop developing GNOME Shell altogether. That’s not likely to happen. The other alternative would be to block extensions from monkey patching GNOME Shell, and instead provide stable APIs for extensions to use instead, like Firefox does. That sounds fine to me, but it would mean most of those extensions you currently use would cease to exist, because extensions would be limited to doing only what GNOME developers allow them to do. Currently extensions can do anything, and that would be a big change.

Extensions are a trade-off: you can do anything you want currently because you can change any code you want, but your extension requires continuous maintenance or it’s going to break in the next version. I don’t see any extension developers requesting a stable extensions API, but if we want to go that route I wouldn’t be opposed to it either. You just need to have realistic expectations. You can have extensions that are stable but limited (hypothetical extensions API), or unstable but powerful (status quo, monkey patching). You can’t have both. Got to pick…

This is a goal of Extensions Rebooted, I think.

1 Like

Most extensions don’t break between releases, with notable exceptions like GNOME 40 where big changes landed. Starting with GNOME 40 the version validation was re-enabled for that reason, but there are other good reasons for this to happen as well.

Many folks don’t realize this, but there is no way to unload JavaScript once it has been loaded by GNOME Shell. This means that if an extension does break it can cause problems throughout the desktop that can only be fixed by uninstalling the extension and restarting the session. These problems could be subtle and benign, or they could cause massive CPU usage spikes, memory leaks or even make it difficult to remove the offending code and restart.

While our extension review process does not check for feature bugs, we do review for things we know can cause major problems that spill out into the standard user experience. By enabling the version validation, users can be reasonably confident that nothing truly catastrophic will happen to their hardware or data and that the author of extension considers the current release as supported.

This may make it seem like every extension breaks every release, but to be fair, that’s the kind of reductionist meme we’ve been dealing with anyways. I understand it’s aggravating when your extensions don’t load with the latest release, but with the amount of misinformation being spread about how they work it’s unfair to expect users to understand what’s actually happening.

In a nutshell, we’re already sorry so we might as well be safe :slight_smile:

2 Likes

To be fair, this is actually requested often! But you are absolutely right about the tradeoff, and if we had one it likely wouldn’t be as powerful as its advocates hoped…

1 Like

By extension developers? I’ve mostly seen it requested by users on places like Reddit, but not by actual developers (on the places I go to, at least). Once you start developing an extension, you realize an API would drastically limit what is possible.

No, you can have both, and you don’t have to pick.

There’s nothing about the existence of a stable extensions API that prevents extensions from being written and executed the way they already are, in an ad-hoc way. But the advantage of having a stable API of sorts, even if it’s incomplete, is that, for those developers that use it, it’s a contract that says that their extension isn’t going to become obsolete in a month. It’s also reassurance to the user that the extension they rely on isn’t going to suddenly break with the next update.

Honestly, who would want to develop an extension at all, if they knew it was going to be declared broken or invalid in a month? Especially when it’s not really broken—when the recent GNOME updates don’t actually affect the functionality covered by the extension. And who would even want to use extensions, when they’re virtually guaranteed to break every few months?

Now, of course there can be no real guarantees, in the grand scheme of things: so long as GNOME code is being written, some aspects of the API are bound to change eventually. I get that. But that doesn’t mean there can’t be some guarantees about what extensions will work with the next minor release. Or major release.

How about this: if a GNOME Shell update doesn’t break the way an extension works, don’t mark the extension as incompatible.

And how is gnome-shell supposed to know “the way an extension works” and whether an update broke that?

An extension that adds an icon with a menu to the top bar is probably fine. One that rips out part of the UI and replaces it with its own (like dash-to-dock) is much more likely to be affected by code changes. But gnome-shell has no way of telling (in particular not before trying to load it, at which point damage may have been done detecting failure)

1 Like

I think there is some confusion here. Yes the shell could implement them both at the same time. But that statement applies down to the individual extension, e.g. if you want to have a powerful extension that uses features not provided by the stable API, that extension will continue to use the “unstable monkey-patching API” (or whatever you want to call it) and will have the same issues as it does now. So it still would be up to extension authors to choose if they wanted it or not. And likely if you use a lot of complex extensions that break often, you would probably be using extensions that choose to use the unstable API.

In my opinion, if there was a desire to make an API that was stable and safe, it would either have to be:

  1. Run the extensions in a separate JS context with their own very limited JS API, no access to any shell globals. Maybe even run it in a separate thread. (AFAIK this all is essentially what Chrome/Firefox do)
  2. Implement the stable API in D-Bus and run the extension as a separate process. Then extensions could be written in other languages. Although this seems it’s kind of going back to the old model where things like panel applets were all separate processes combined using Xembed…

Or some kind of combination of the two.

1 Like

I’m not a GNOME developer, just a user. So you tell me.

But if I were to hazard a guess, it would be: tests. If an extension’s test suite passes with a new version of GNOME Shell, keep on marking it as compatible, unless the tests start failing, or unless someone reports it as broken.

That’s actually an angle I never thought of before. We’d effectively just be moving the burden from one set of volunteers to another, even if it were a mandate.

The question is quite rhetorical :slight_smile:. As I mentioned, there is no way for JavaScript engines to unload JavaScript once it has been loaded. This is the same reason why we don’t do “live” updates, since you end up trying to patch a patch.

If an extensions fails during loading, whether with critical failures or just loss of functionality, the only way to undo that is to restart the session. This is in fact, why most of the review guidelines and process centers around the enable()/disable() cycle in extensions.

There are possibly a half-dozen extensions out of the some thousand available that have tests at all. The ones that do have unit tests, while what you are describing are the definition of integration tests.

Of course we’ve had many conversations about better automated testing, including using openQA, GNOME OS, conventions for Jasmine-based tests that could be hooked into, and so on. I assure you; no one enjoys reviewing thousands of lines of amateur JavaScript per day :slight_smile:

1 Like
  1. Argos, so that I can display the output of commands I need to monitor
  1. Tray Icons, so I can see what, e.g., Megasync is doing, without having a window open
  1. GSConnect, to interface with my phone

Out of the use cases you have provided I see three which could be served by an updated DbusMenuModel api which ebassi discussed here .

As for the other use cases

  1. Dash to Dock, to have a nicely working dock

The functionality of dash to dock could be potentially be upstreamed, e.g just add ability to autohide, place on bottom of screen or side from settings like MacOS .

  1. Pop Shell, for window tiling

Window tiling was something GNOME was investigating integrating before PopOS, it just hasn’t gotten around to it yet from what I understand.

  1. Multi Monitors addon, since I use more than one monitor

My guess is that GNOME want to facilitate multi monitor systems out of the box.

@andyhomes Does the issue with not being able to unload javascript without uninstalling and restarting the session still effect something which targets DbusMenuModel api?

I do think that keeping the monkeypatching api around while simultaneously providing more restrictive stable api’s makes a lot of sense for people who are unconvinced.

I think that one aspect that is largely overlooked when it comes to the flexibility argument is what happens when you run an extension designed for a desktop on a phone.

A more restrictive api like what was described is at least somewhat doable when targeting multiple form factors which physically restrict what you are capable of achieving(small screen vs large).

The monkey patching approach might completely block you from delivering your experience to users. I would hardly call that flexible. Hopefully nobody takes this the wrong way. Im just trying to say flexibility is debatable here.

Its definitely worth further thought, if gnome-shell does try and target mobile devices everything is going to get even more complex from a QA perspective, unless of course you just disable extensions completely.

Well if it’s not really broken, it’s just a matter of adding the Shell version number to the extension’s manifest. This ensures that the extension has been tested. If the developer doesn’t do it in a timely manner, contributions are always welcome.

I fail to see how restricting extensions to an icon and menus is flexible. That means extensions like Dash to dock, Dash to panel, Desktop icons, Custom hot corners, Just Perfection, Blur my shell, User themes and the like will become impossible. Is that what users want?

I fail to see how restricting extensions to an icon and menus is flexible. That means extensions like Dash to dock, Dash to panel, Desktop icons, Custom hot corners, Just Perfection, Blur my shell, User themes and the like will become impossible. Is that what users want?

Well its flexible in that it is easier to get running across different form factors. Its easier to adapt an extension which is essentially an icon and menu for a mobile form factor than it is to get something which has been designed explicitly for a desktop form factor.

I already kind of covered how to approach dash to dock but honestly, if you want to monkey patch the shell that’s fine, don’t expect your extension to work everywhere though.

If I do write an extension and that extension is already essentially an icon and menu like the vast majority of extensions available today then I as an extension developer would like to target a stable api so that on each release the extension isn’t disabled because someone else doesn’t like the idea of constraints.

Id like to target a stable api so the design team can iterate and improve how it is surfaced to users and insure consistent ux.

Someone pointed out on that reddit thread that you would need to convince third parties, often closed source, to integrate with your api which is difficult considering the marketshare. Sure that’s true, but it’s a worse proposition if you’re expecting them to update on each release. At that point they will look at it, compare it to the other platforms they target already and potential marketshare they are capable of capturing and make a decision based on the amount of work they will need to put in to deliver and maintain. If you make that process a pain in the name of freedom then they will likely just not bother.

And whether or not some extension developers like the idea of constraints or not is irrelevant when it comes to mobile. You are going to be constrained whether you like it or not because there are physical constraints. Your option will be to use a defined api or be completely blocked from that form factor.

As a side note I think that some extensions should probably not be considered extensions anymore as well. A good example is Patterned Wallpapers. There’s no real justifiable reason why it should be automatically disabled every release or even be restricted to GNOME, it should probably just be distributed as a flatpak where it could be used on different freedesktop de’s and form factors.

In short monkey patching is flexible in some ways but restrictive in others. There is a cost to the flexibility that it brings which ironically makes it fragile and inflexible for some. Im not suggesting that GNOME gets rid of monkey patching either, there’s no reason why there can’t be stable api’s for people who don’t need the freedom to shoot their kneecaps off. If you would like to continue to monkey patch then nobody would be stopping you.

This would not really apply to GSConnect, FWIW. GSConnect uses this precise method for exporting the menu already. The rest requires rewriting or subclassing the internals of GNOME Shell; removing this ability would make it virtually irrelevant.

No, these two concepts are unrelated.

For what it’s worth, the API for adding panel buttons and menus has effectively been stable since 3.2 (yes, 3.2). The only real exception there was when we migrated to ES6, which is totally worth the breakage.

The API for doing anything real there (beyond the abilities of DBusMenuModel) also seems to include St, Clutter, the shell CSS, and probably a few other things that people may not be willing to have set in stone forever…

1 Like

Yes, that’s true. Although if they’re simple argument additions or function renames then overriding the prototype is not much of hassle and there are pretty well-defined methods to safely polyfill in JS.

We did discuss the possibility of a copy-paste JavaScript lib, similar to the one for WebExtension that Firefox uses to retain compatibility with Chrome.