Open-source project
ubuntu/gnome-shell-extension-appindicator avatar
ubuntu/gnome-shell-extension-appindicator

AppIndicator and KStatusNotifierItem Support for GNOME Shell

Adds KStatusNotifierItem support to the Shell

1,580 stars258 forksJavaScriptGPL-2.0

At a glance

What is it?
AppIndicator/KStatusNotifierItem support restores Linux tray icons, indicator menus, and selected activation actions in GNOME Shell. It is useful for applications that expose these interfaces, but it cannot create an indicator for an application whose required client library or protocol support is absent.
Who is it for?
Adopt this extension if your desktop applications rely on AppIndicator, KStatusNotifierItem, or legacy tray icons and you want those controls in the GNOME panel. Do not expect it to restore missing icons for applications that do not implement a supported protocol or that lack libappindicator.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 18 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why GNOME Users Add AppIndicator Support

Some Linux applications place status icons in a system tray rather than drawing their controls inside a normal application window. AppIndicator/KStatusNotifierItem support for GNOME Shell provides a panel area for those indicators. The README describes support for Ubuntu AppIndicators, KStatusNotifierItems, and legacy tray icons, covering both newer status-notifier applications and older tray software.

The extension targets users whose applications depend on this desktop integration. A messaging client, background service, or utility may show an icon only after its tray implementation starts. The extension then gives that icon a place in the GNOME Shell panel. It also opens application menus when an indicator is clicked, attempts to activate an application window on a double click when the indicator implements that action, and sends a SecondaryActivate event to the application on a middle click.

Those actions depend on cooperation from the application. Double-click activation is conditional, and middle-click behavior requires the application to implement SecondaryActivate. The extension does not add controls that the indicator does not expose. It is therefore an interoperability layer for existing tray software, not a general-purpose taskbar replacement or a method of pinning arbitrary applications to GNOME Shell.

The D-Bus and Indicator Path Through GNOME Shell

The repository layout shows separate modules for protocol access and panel behavior. `statusNotifierWatcher.js` is dedicated to KStatusNotifierItem discovery, while `trayIconsManager.js` handles tray icon management. Files such as `dbusProxy.js`, `dbusUtils.js`, and `interfaces-xml/` indicate that the extension uses D-Bus interfaces and generated or packaged interface definitions rather than treating indicators as ordinary GNOME application windows.

When a supported application exposes an indicator, the protocol-facing code obtains the D-Bus object it provides. The relevant implementation can then create a panel status item through `indicatorStatusIcon.js`. `iconCache.js` and `pixmapsUtils.js` separate icon retrieval and representation from interaction logic. This is consistent with an extension that must receive icons exposed by external applications and place them in the Shell.

Menu support has its own path. `dbusMenu.js`, `menuUtils.js`, and the menu-related utilities handle menu data and its presentation. The README specifically says that clicking an indicator reveals its menu, so menu rendering is a core part of the bridge rather than an optional decoration. `appIndicator.js` covers the AppIndicator side, while the watcher and tray manager cover KStatusNotifierItem and legacy tray handling.

The presence of `extension.js` at the top level provides the extension entry point, and `prefs.js` handles preferences. Settings are represented by `settingsManager.js` and the schema files under `schemas/`. This separation suggests that protocol adapters, UI objects, preferences, and persistence are distinct concerns within the extension.

Install the Extension and Enable It in GNOME Shell

The README recommends obtaining the extension from `extensions.gnome.org`. For a source checkout, it documents the following build, install, and enable sequence. Run these commands from the parent directory in which you want the repository cloned. The install target shown in the README is the user's local GNOME Shell extension directory.

bash
git clone https://github.com/ubuntu/gnome-shell-extension-appindicator.git
meson gnome-shell-extension-appindicator /tmp/g-s-appindicators-build
ninja -C /tmp/g-s-appindicators-build install
gnome-extensions enable [email protected]

The README describes an alternative workflow in which a clone is symlinked from `~/.local/share/gnome-shell/extensions/[email protected]`, but it does not give a separate command block for creating that symlink. The documented `ninja` install command is the more complete sequence shown.

After enabling the extension, open or start one of the affected applications. Based on the README's feature description, its supported indicator should appear in the GNOME Shell panel. Click the icon to check whether its application menu is revealed. A double click is meaningful only if the application implements window activation, and a middle click is meaningful only if it handles `SecondaryActivate`.

Shell activation differs by session type. Under X11, the README says GNOME Shell may need to be restarted with `Alt`+`F2`, then `r`, then `Enter`. Under Wayland, it says to log out and log in again. The README does not document an automated verification command, so the first practical check is whether the relevant application's icon and menu appear after the session reload.

Application Library Requirements and Missing Icons

Installing the extension does not guarantee that every tray-based application will appear. The README identifies a direct application dependency: many applications support indicators through `libappindicator`, sometimes by dynamically loading that library. If `libappindicator` is absent, the application may produce no icon for the extension to display.

This is an important boundary in diagnosis. An extension can watch the supported tray interfaces and manage exposed icons, but it cannot manufacture protocol support inside an application that fails to register one. Dynamic loading makes the failure less obvious. The application might start normally while its tray component never reaches the extension.

The application must also support one of the covered mechanisms: AppIndicator, KStatusNotifierItem, or a legacy tray icon. The README does not claim support for arbitrary GTK menu exports or for embedding an application icon into GNOME Shell independently of those protocols. It also lists no configuration for forcing unsupported applications into panel mode.

For a missing icon, the useful evidence starts with the application itself. The README's bug-report guidance requests the distribution, GNOME Shell version, extension version, affected indicator, and reproduction instructions. It calls reproducible steps the most important part of a useful report. That guidance reflects a bridge extension whose behavior depends on the exact application and desktop environment involved.

Click Actions, Menu Behavior, and Tooltip Limits

The extension provides different interaction paths depending on what the indicator implements. A normal click opens the indicator menu. A double click asks the application to activate its window, but the README qualifies this behavior with "if implemented by the indicator." A middle mouse click sends a `SecondaryActivate` event, although that event also requires support in the application.

These qualifications prevent the panel icon from behaving like a conventional window launcher. An indicator with a useful menu may have no useful double-click action. An application may display an icon but ignore middle clicks. The visible interaction can therefore differ between applications even though GNOME Shell handles the common registration and panel display work.

Tooltips are an explicit omission. The README says tooltips are not implemented in `libappindicator` or Unity and notes the author's preference to follow GNOME's decision not to include them in the Shell. No replacement tooltip behavior is documented. Users who rely on hover text to identify an icon need another way to determine its application, because this extension does not promise that information.

This limitation is different from an installation failure. The icon can load and the menu can open while tooltips remain unavailable. It is a designed feature boundary, not merely a missing dependency.

ClassicMenu Freeze Risk and Compatibility Boundaries

The README names ClassicMenu Indicator as a known problematic case. It says this indicator can take a long time to load and has been reported to freeze the Shell indefinitely. The stated cause is likely the large number of embedded PNG icons, and the README tells users to try it at their own risk.

That warning matters because an extension runs inside the Shell process. The documented report describes a possible Shell freeze, so an application-specific compatibility problem can affect the desktop session rather than remaining confined to one utility window. The repository provides `indicator-test-tool` and a `tests/` directory, but the README does not claim that these cover every third-party indicator or reproduce the ClassicMenu case.

GNOME Shell version compatibility is another boundary worth checking in a bug report. The release process states that extension versions must remain synchronized with versions submitted to `extensions.gnome.org`. Recent repository tags include v64, v65, and v66, but the README does not publish a table mapping each tag to a specific GNOME Shell release. It also does not provide a general rollback procedure for users who find a release incompatible with their session.

For evaluation purposes, the safe first step is to test the extension with an affected application on the user's distribution and Shell version, not to infer compatibility from the JavaScript language or the extension's release number alone.

Release Maintenance, Packaging, and GPL-2.0

The repository is not archived, and its last push was on 2026-10-05. Recent listed releases are v66 on 2026-09-22, v65 on 2026-07-25, and v64 on 2026-03-21. These dates support recent project activity, but they do not by themselves guarantee compatibility with every GNOME Shell release or eliminate application-specific failures.

Maintenance still has a manual release path. The README says the maintainer decides when to release, tags and signs versions, updates the Meson version, and creates a zip file with `ninja -C <build-dir> zip-file`. The package is supposed to be tested before upload to `extensions.gnome.org`, after which the tag is pushed. Version synchronization between the repository and `extensions.gnome.org` is an explicit maintainer responsibility.

This creates a release dependency beyond JavaScript editing. Changes must remain consistent with Meson metadata, the packaged extension, and the version accepted by `extensions.gnome.org`. The README does not describe a migration or rollback guide, so upgrade planning should account for testing an extension release on the target GNOME Shell version.

The repository uses GPL-2.0. Anyone redistributing modified source or packaged copies must account for the license's applicable notices and source-distribution obligations. Distribution through another package channel should also check whether maintainers include the required license text and metadata. This is a compliance consideration rather than evidence about software quality, and it does not determine whether the extension is suitable for a particular desktop.

AppIndicator Support Compared with Leaving Legacy Tray Software Unbridged

The practical alternative is to leave the extension uninstalled and use the application's own window controls instead. That approach avoids compatibility problems inside GNOME Shell, but applications designed around AppIndicator, KStatusNotifierItem, or a legacy tray may offer no equivalent panel icon. Users would lose the shell-hosted status entry and the indicator menu exposed through D-Bus.

This extension's approach differs because it places indicator-backed controls in GNOME Shell after those controls are registered. It does not recreate every application's interface. It passes through icons, menus, and supported activation events. That makes it suitable for conventional tray clients, while leaving unsupported interaction patterns, such as tooltips, outside its scope.

The choice is therefore between panel integration with protocol-dependent behavior and application-only operation without that integration. For applications that expose no useful window controls, the alternative may not provide equivalent access. For applications that do not implement a supported indicator protocol, installing the extension will not create one. The README's dependency note and known-issue warning make that distinction more concrete than a general claim that GNOME and KDE tray behavior is identical.

Editorial conclusion

Adopt this extension if your desktop applications rely on AppIndicator, KStatusNotifierItem, or legacy tray icons and you want those controls in the GNOME panel. Do not expect it to restore missing icons for applications that do not implement a supported protocol or that lack libappindicator. Before installing system-wide, verify the indicator appears for the affected applications, confirm that menus and click actions work on your GNOME Shell version, and check that libappindicator is installed when an application loads it dynamically.

Frequently asked questions

How do I install AppIndicator/KStatusNotifierItem support for GNOME Shell?

The README recommends `extensions.gnome.org`. It also documents cloning the repository, building it with Meson, installing it with Ninja, and enabling `[email protected]`.

Why is an application tray icon missing after I install the extension?

Many applications rely on `libappindicator`, sometimes by loading it dynamically. If that library is not installed, the application may not expose an indicator for the GNOME Shell extension to display.

Does the extension support tooltips, double-click activation, and middle-click actions?

Tooltips are explicitly not supported. Double-click window activation and middle-click `SecondaryActivate` events are supported only when the relevant indicator and application implement them.

What should I check before reporting an AppIndicator support bug?

The README requests the distribution, GNOME Shell version, extension version, affected indicator, and steps that reproduce the problem. It considers reproducible instructions the most important part of a useful report.

Official sources

  1. License: GPL-2.0
  2. Project website
  3. README
  4. Releases
  5. ubuntu/gnome-shell-extension-appindicator on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ubuntu-gnome-shell-extension-appindicator.svg)](https://hysenlabs.com/projects/ubuntu-gnome-shell-extension-appindicator)

Was this useful?