-
chevron_right
Ramayanapu Jagath: Bringing App Uninstallation to the GNOME Shell App Grid
news.movim.eu / PlanetGnome • 12:42 • 4 minutes
Hey y’all! I’m Jagath Ramayanapu (Shyam) from India, and I’m a GNOME GSoC intern this year. This summer, I’m working on bringing app uninstallation directly to the GNOME Shell App Grid.
Previously, to remove an app in GNOME, you had to open GNOME Software, find the app, and click Uninstall . With this feature, users will soon be able to uninstall apps directly from the App Grid’s context menu.
This is the first of a two-part blog on how we are building this feature. In this post, we’ll cover the changes in GNOME Shell’s JavaScript that make it possible.
The Problem: Talking to the App Store
GNOME Shell is great at drawing your desktop, but it actually has no idea how to delete an app or clean up user data. To do that, it needs to ask a App Store like GNOME Software to do the heavy lifting.
To solve this, we created a d-bus interface called AppStoreIntegration . You can think of it as a dedicated middleman whose only job is to talk to GNOME Software in the background.
We designed this helper with a few key goals in mind:
At first, I planned to have GNOME Software own this interface. However, that would have tightly coupled the feature to GNOME Software. Based on feedback from my mentor, Adrian Vovk , I moved the ownership of AppStoreIntegration into GNOME Shell instead.
This design makes the interface app store agnostic. Any app store can implement the interface, allowing GNOME Shell to work with different app stores without depending on a specific one.
This interface has two methods :
- GetUninstallableApps :
-
- What it does: The Shell calls this method to ask GNOME Software, “Give me a list of every installed app that the user is actually allowed to uninstall.”
- What it returns: It returns a dictionary that maps each app’s desktop ID to a set of metadata properties (for example, a boolean flag telling us if the app supports deleting personal data)
2. UninstallApp :
-
- What it does: When you click “Uninstall”, the Shell sends this command to GNOME Software.
- What it accepts: It takes a dictionary containing the app’s id and a boolean purge-data flag (which tells GNOME Software whether it should wipe the user’s saved data along with the app).
Building the Integration Manager
Now that we had our D-Bus contract, we built a helper module in GNOME Shell called js/ui/appStoreIntegration.js Inside this file, we built a class called AppStoreIntegrationManager whose sole purpose is to call those two D-Bus methods.
We designed this manager with a few key goals:
- Keep the Desktop Fast : When the manager connects to the D-Bus proxy, it does it asynchronously. This means if GNOME Software takes a second to wake up, your desktop won’t freeze.
- Cache the Data : We don’t want to call GetUninstallableApps every single time you right-click an icon. Instead, the manager listens for a signal called installed-changed from the system. When it hears this signal, it quietly fetches the list of apps and caches it in memory.
- Track the State : The manager keeps a list ( set ) of apps that are currently being uninstalled. This gives our UI a simple way to know exactly what is going on at any given moment.
Updating the App Menu
Once we had the cached data, we needed to update the UI in js/ui/appMenu.js .
We added a new “Uninstall” button to the right-click menu, but we had to be careful. We don’t want to show an “Uninstall” button for apps you aren’t allowed to remove (like core system apps).
To fix this, we tied the menu directly to our new manager using reactive signals. Every time you open the menu, a function called
_updateUninstallItem
runs. It asks the manager:
appStoreIntegrationManager.canUninstall(appId)
. If the answer is false, the button completely hides itself.
Handling the User Interaction
Uninstalling an app isn’t always as simple as deleting a folder. Modern software, like Flatpaks, often leaves behind saved files and personal configurations. We wanted to give users the option to clean up this data, but only if the app store actually supports it.
When you click Uninstall in the right-click menu, the UI triggers a smooth, step-by-step interactive flow:
- Checking for User Data : First, the code checks the metadata we got from D-Bus earlier to see if the app store supports wiping personal data for this specific app.
- The Confirmation Dialog : We pop up a small confirmation window. If the app supports it, this window includes a checkbox asking if you want to clean up your personal files too.
- Waiting in the Background : The desktop interface pauses the uninstallation logic and waits patiently in the background for you to make a decision, ensuring your system remains completely responsive.
- Executing the Uninstall : Once you confirm your choice, the UI fires off the D-Bus command to GNOME Software. It immediately adds the app to a tracking list to prevent you from accidentally clicking the uninstall button multiple times.
- Safe Error Handling : If GNOME Software runs into an unexpected error and fails to uninstall the app, the interface safely catches the problem. It removes the app from the busy tracker and displays a standard system notification to let you know what happened, keeping your desktop totally stable.
Thanks
Building this feature was a fantastic learning experience in bridging different parts of the GNOME ecosystem. A huge thanks to Adrian for mentoring me throughout this project and helping me navigate the architecture.
If you’d like to check out the changes, here’s my MR.